| 
									
										
										
										
											2025-05-19 11:42:28 +02:00
										 |  |  | `timescale 1ns/1ps | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module hc_sr04_tb; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // === Signaux === | 
					
						
							|  |  |  |     reg clk = 0; | 
					
						
							|  |  |  |     reg start = 0; | 
					
						
							|  |  |  |     wire sensor_pin; // Signal bidirectionnel entre driver et capteur | 
					
						
							|  |  |  |     wire [15:0] distance; | 
					
						
							|  |  |  |     wire busy; | 
					
						
							|  |  |  |     wire done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // === Paramètres === | 
					
						
							|  |  |  |     localparam CLK_FREQ = 27_000_000; // 27 MHz | 
					
						
							|  |  |  |     localparam CLK_PERIOD = 37; // Période en ns (~37 ns pour 27 MHz) | 
					
						
							| 
									
										
										
										
											2025-05-20 14:24:41 +02:00
										 |  |  |     localparam CLK_MS = CLK_PERIOD * 100; | 
					
						
							| 
									
										
										
										
											2025-05-19 11:42:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Génération de l'horloge 27 MHz | 
					
						
							|  |  |  |     always #(CLK_PERIOD/2) clk = ~clk; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // === Instanciation des modules === | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Capteur HC-SR04 simulé | 
					
						
							|  |  |  |     hc_sr04_model #( | 
					
						
							|  |  |  |         .CLK_FREQ_MHZ(27) | 
					
						
							|  |  |  |     ) fake_sensor ( | 
					
						
							|  |  |  |         .clk(clk), | 
					
						
							|  |  |  |         .sensor_pin(sensor_pin) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Driver pour contrôler le capteur | 
					
						
							|  |  |  |     ultrason_driver #( | 
					
						
							|  |  |  |         .CLK_FREQ(CLK_FREQ) | 
					
						
							|  |  |  |     ) driver ( | 
					
						
							|  |  |  |         .clk(clk), | 
					
						
							|  |  |  |         .start(start), | 
					
						
							|  |  |  |         .sig(sensor_pin), | 
					
						
							|  |  |  |         .distance(distance), | 
					
						
							|  |  |  |         .busy(busy), | 
					
						
							|  |  |  |         .done(done) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // === Tâches pour simplifier les tests === | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Tâche pour déclencher une mesure | 
					
						
							|  |  |  |     task trigger_measurement; | 
					
						
							|  |  |  |         begin | 
					
						
							|  |  |  |             $display("[%0t ns] Déclenchement d'une mesure", $time); | 
					
						
							|  |  |  |             start = 1; | 
					
						
							| 
									
										
										
										
											2025-05-20 14:24:41 +02:00
										 |  |  |             #CLK_PERIOD; | 
					
						
							| 
									
										
										
										
											2025-05-19 11:42:28 +02:00
										 |  |  |             start = 0; | 
					
						
							|  |  |  |             // Attendre que la mesure soit terminée | 
					
						
							|  |  |  |             wait(done); | 
					
						
							|  |  |  |             $display("[%0t ns] Mesure terminée, distance=%0d, busy=%b", $time, distance, busy); | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     endtask | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Tâche pour vérifier la distance | 
					
						
							|  |  |  |     task check_distance(input [15:0] expected_distance); | 
					
						
							|  |  |  |         begin | 
					
						
							|  |  |  |             if (distance == expected_distance) begin | 
					
						
							|  |  |  |                 $display("[%0t ns] Distance correcte: %0d", $time, distance); | 
					
						
							|  |  |  |             end else begin | 
					
						
							|  |  |  |                 $display("[%0t ns] ERREUR: Distance reçue=%0d, attendu=%0d", $time, distance, expected_distance); | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |     endtask | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // === Stimulus de test === | 
					
						
							|  |  |  |     initial begin | 
					
						
							|  |  |  |         $dumpfile("runs/sim.vcd"); | 
					
						
							|  |  |  |         $dumpvars(0, hc_sr04_tb); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $display("==== Début Test HC-SR04 ===="); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Initialisation | 
					
						
							|  |  |  |         #(CLK_PERIOD * 10); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Test 1: Mesure unique | 
					
						
							|  |  |  |         $display("=== Test 1: Mesure unique ==="); | 
					
						
							| 
									
										
										
										
											2025-05-20 14:24:41 +02:00
										 |  |  |         @(posedge clk); // Synchroniser avec l'horloge | 
					
						
							| 
									
										
										
										
											2025-05-19 11:42:28 +02:00
										 |  |  |         trigger_measurement(); | 
					
						
							|  |  |  |         // Supposons que hc_sr04_model simule une distance fixe, par exemple 1000 (à ajuster) | 
					
						
							|  |  |  |         check_distance(16'd1000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Test 2: Mesures multiples | 
					
						
							|  |  |  |         $display("=== Test 2: Mesures multiples ==="); | 
					
						
							|  |  |  |         repeat (3) begin | 
					
						
							| 
									
										
										
										
											2025-05-20 14:24:41 +02:00
										 |  |  |             #(CLK_MS * 100); // Attendre entre mesures | 
					
						
							|  |  |  |             @(posedge clk); // Synchroniser avec l'horloge | 
					
						
							|  |  |  |             $display("[%0t ns] Déclenchement d'une nouvelle mesure", $time); | 
					
						
							| 
									
										
										
										
											2025-05-19 11:42:28 +02:00
										 |  |  |             trigger_measurement(); | 
					
						
							|  |  |  |             check_distance(16'd1000); | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Test 3: Vérification de busy | 
					
						
							|  |  |  |         $display("=== Test 3: Vérification de busy ==="); | 
					
						
							|  |  |  |         start = 1; | 
					
						
							|  |  |  |         #(CLK_PERIOD * 2); | 
					
						
							|  |  |  |         start = 0; | 
					
						
							|  |  |  |         #(CLK_PERIOD * 10); | 
					
						
							|  |  |  |         if (busy) begin | 
					
						
							|  |  |  |             $display("[%0t ns] Busy actif pendant la mesure, OK", $time); | 
					
						
							|  |  |  |         end else begin | 
					
						
							|  |  |  |             $display("[%0t ns] ERREUR: Busy devrait être actif", $time); | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |         wait(done); | 
					
						
							|  |  |  |         if (!busy) begin | 
					
						
							|  |  |  |             $display("[%0t ns] Busy inactif après done, OK", $time); | 
					
						
							|  |  |  |         end else begin | 
					
						
							|  |  |  |             $display("[%0t ns] ERREUR: Busy devrait être inactif", $time); | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Test 4: Pas de déclenchement | 
					
						
							|  |  |  |         $display("=== Test 4: Pas de déclenchement ==="); | 
					
						
							|  |  |  |         #(CLK_PERIOD * 10000); | 
					
						
							|  |  |  |         if (!busy && !done) begin | 
					
						
							|  |  |  |             $display("[%0t ns] Aucune activité sans déclenchement, OK", $time); | 
					
						
							|  |  |  |         end else begin | 
					
						
							|  |  |  |             $display("[%0t ns] ERREUR: Activité détectée sans déclenchement", $time); | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Fin de la simulation | 
					
						
							|  |  |  |         $display("==== Fin Test HC-SR04 ===="); | 
					
						
							|  |  |  |         #(CLK_PERIOD * 1000); | 
					
						
							|  |  |  |         $finish; | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // === Surveillance des signaux === | 
					
						
							|  |  |  |     initial begin | 
					
						
							|  |  |  |         $monitor("[%0t ns] sensor_pin=%b, start=%b, busy=%b, done=%b, distance=%0d",  | 
					
						
							|  |  |  |                  $time, sensor_pin, start, busy, done, distance); | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | endmodule |