From 861c9869f58fa58b6b2a7e776cc2a4aa768b44c7 Mon Sep 17 00:00:00 2001 From: Gamenight77 Date: Wed, 14 May 2025 14:40:16 +0200 Subject: [PATCH] Add DHT11 interface and UART integration for ultrasonic sensor project - Created DHT11 interface in Verilog to handle communication with DHT11 sensor. - Implemented LED control logic to indicate sensor status and data readiness. - Added project scripts for building, cleaning, and simulating the design. - Established constraints for FPGA pin assignments. - Developed testbench for DHT11 UART communication. - Updated README files to reflect project functionality and commands. --- Semaine_5/DHT11/scripts/simulate.bat | 2 +- Semaine_5/DHT11/src/verilog/dht11_interface.v | 35 +-- Semaine_5/DHT11/src/verilog/dht_sensor_sim.v | 110 +++++++++ Semaine_5/DHT11/tests/verilog/tb_dht11.v | 38 +++- Semaine_5/DHT11_LEDS/.gitignore | 5 + .../DHT11_LEDS/IP/verilog/dht11_interface.v | 211 ++++++++++++++++++ Semaine_5/DHT11_LEDS/README.md | 9 + .../DHT11_LEDS/constraints/dht11_leds.cst | 21 ++ Semaine_5/DHT11_LEDS/project.bat | 6 + Semaine_5/DHT11_LEDS/scripts/build.bat | 45 ++++ Semaine_5/DHT11_LEDS/scripts/clean.bat | 4 + Semaine_5/DHT11_LEDS/scripts/gtkwave.bat | 3 + Semaine_5/DHT11_LEDS/scripts/simulate.bat | 29 +++ Semaine_5/DHT11_LEDS/src/verilog/dht11_leds.v | 58 +++++ .../DHT11_LEDS/tests/verilog/tb_dht11_uart.v | 27 +++ Semaine_5/DHT11_UART/.gitignore | 5 + .../DHT11_UART/IP/verilog/dht11_interface.v | 210 +++++++++++++++++ Semaine_5/DHT11_UART/README.md | 9 + .../DHT11_UART/constraints/dht11_uart.cst | 21 ++ Semaine_5/DHT11_UART/project.bat | 6 + Semaine_5/DHT11_UART/scripts/build.bat | 45 ++++ Semaine_5/DHT11_UART/scripts/clean.bat | 4 + Semaine_5/DHT11_UART/scripts/gtkwave.bat | 3 + Semaine_5/DHT11_UART/scripts/simulate.bat | 29 +++ Semaine_5/DHT11_UART/src/verilog/dht11_uart.v | 208 +++++++++++++++++ .../DHT11_UART/tests/verilog/tb_dht11_uart.v | 27 +++ 26 files changed, 1149 insertions(+), 21 deletions(-) create mode 100644 Semaine_5/DHT11/src/verilog/dht_sensor_sim.v create mode 100644 Semaine_5/DHT11_LEDS/.gitignore create mode 100644 Semaine_5/DHT11_LEDS/IP/verilog/dht11_interface.v create mode 100644 Semaine_5/DHT11_LEDS/README.md create mode 100644 Semaine_5/DHT11_LEDS/constraints/dht11_leds.cst create mode 100644 Semaine_5/DHT11_LEDS/project.bat create mode 100644 Semaine_5/DHT11_LEDS/scripts/build.bat create mode 100644 Semaine_5/DHT11_LEDS/scripts/clean.bat create mode 100644 Semaine_5/DHT11_LEDS/scripts/gtkwave.bat create mode 100644 Semaine_5/DHT11_LEDS/scripts/simulate.bat create mode 100644 Semaine_5/DHT11_LEDS/src/verilog/dht11_leds.v create mode 100644 Semaine_5/DHT11_LEDS/tests/verilog/tb_dht11_uart.v create mode 100644 Semaine_5/DHT11_UART/.gitignore create mode 100644 Semaine_5/DHT11_UART/IP/verilog/dht11_interface.v create mode 100644 Semaine_5/DHT11_UART/README.md create mode 100644 Semaine_5/DHT11_UART/constraints/dht11_uart.cst create mode 100644 Semaine_5/DHT11_UART/project.bat create mode 100644 Semaine_5/DHT11_UART/scripts/build.bat create mode 100644 Semaine_5/DHT11_UART/scripts/clean.bat create mode 100644 Semaine_5/DHT11_UART/scripts/gtkwave.bat create mode 100644 Semaine_5/DHT11_UART/scripts/simulate.bat create mode 100644 Semaine_5/DHT11_UART/src/verilog/dht11_uart.v create mode 100644 Semaine_5/DHT11_UART/tests/verilog/tb_dht11_uart.v diff --git a/Semaine_5/DHT11/scripts/simulate.bat b/Semaine_5/DHT11/scripts/simulate.bat index 020d5d2..fbe0ee2 100644 --- a/Semaine_5/DHT11/scripts/simulate.bat +++ b/Semaine_5/DHT11/scripts/simulate.bat @@ -6,7 +6,7 @@ setlocal enabledelayedexpansion set OUT=runs/sim.vvp :: Top-level testbench module -set TOP=dht11_interface +set TOP=tb_dht11 :: Répertoires contenant des fichiers .v set DIRS=src/verilog tests/verilog IP/verilog diff --git a/Semaine_5/DHT11/src/verilog/dht11_interface.v b/Semaine_5/DHT11/src/verilog/dht11_interface.v index 27753ad..66ada0c 100644 --- a/Semaine_5/DHT11/src/verilog/dht11_interface.v +++ b/Semaine_5/DHT11/src/verilog/dht11_interface.v @@ -1,18 +1,19 @@ -module dht11_interface ( - input wire i_clk, // 27 MHz +module dht11_interface #( + parameter CLK_FREQ = 27_000_000 +)( + input wire i_clk, inout wire io_dht11_sig, input wire i_start, output reg o_dht11_data_ready, output reg o_busy, - output wire [7:0] o_temp_data, - output wire [7:0] o_hum_data, + output reg [7:0] o_temp_data, + output reg [7:0] o_hum_data, output reg o_dht11_error ); // === DHT11 INTERFACE === // === PARAMÈTRES === - parameter CLK_FREQ = 27_000_000; localparam T_18MS = CLK_FREQ * 18 / 1000; // cycles pour 18ms localparam T_80US = CLK_FREQ * 81 / 1_000_000; localparam T_79US = CLK_FREQ * 79 / 1_000_000; @@ -22,6 +23,7 @@ module dht11_interface ( localparam T_49US = CLK_FREQ * 49 / 1_000_000; localparam T_40US = CLK_FREQ * 40 / 1_000_000; localparam T_28US = CLK_FREQ * 28 / 1_000_000; + localparam T_26US = CLK_FREQ * 26 / 1_000_000; localparam T_20US = CLK_FREQ * 20 / 1_000_000; @@ -43,6 +45,17 @@ module dht11_interface ( reg [5:0] bit_index; reg [39:0] raw_data; + // === FSM === + localparam IDLE = 4'd0, // Pull up la ligne + START = 4'd1, // Pull low 18ms + WAIT_RESPONSE = 4'd2, // Release la ligne (entre 20 et 40us) + RESPONSE_LOW = 4'd3, // DHT11 pull low 80us + RESPONSE_HIGH = 4'd4, // DHT11 pull high 80us + READ_BITS_LOW = 4'd5, + READ_BITS_HIGH = 4'd6, + DONE = 4'd7, + ERROR = 4'd8; + // === INITIALISATION === initial begin sig_dir = 0; @@ -54,18 +67,6 @@ module dht11_interface ( o_dht11_data_ready = 0; o_dht11_error = 0; end - - // === FSM === - localparam IDLE = 4'd0, // Pull up la ligne - START = 4'd1, // Pull low 18ms - WAIT_RESPONSE = 4'd2, // Release la ligne (entre 20 et 40us) - RESPONSE_LOW = 4'd3, // DHT11 pull low 80us - RESPONSE_HIGH = 4'd4, // DHT11 pull high 80us - READ_READ_BITS_LOW = 4'd5, - READ_READ_BITS_HIGH = 4'd6, - DONE = 4'd7, - ERROR = 4'd8; - // === FSM principale === always @(posedge i_clk) begin diff --git a/Semaine_5/DHT11/src/verilog/dht_sensor_sim.v b/Semaine_5/DHT11/src/verilog/dht_sensor_sim.v new file mode 100644 index 0000000..2de23f0 --- /dev/null +++ b/Semaine_5/DHT11/src/verilog/dht_sensor_sim.v @@ -0,0 +1,110 @@ +module dht11_sensor_sim( + inout wire sig, + input wire clk +); + reg sig_out = 1; + reg sig_dir = 0; // 0 = haute impédance (entrée), 1 = output (écriture) + assign sig = sig_dir ? sig_out : 1'bz; + + // Clk counter pour timings + reg [31:0] clk_counter = 0; + + // FSM + reg [3:0] state = 0; + + // Constantes de timing (à 27 MHz) + localparam T_80US = 2160; // 27MHz * 80us + localparam T_50US = 1350; + localparam T_70US = 1890; + localparam T_28US = 756; + + // Données à envoyer (40 bits : Humidité, Humidité décimale, Température, Température décimale, checksum) + reg [39:0] data_to_send = {8'd55, 8'd0, 8'd23, 8'd0, 8'd78}; // 55 + 0 + 23 + 0 = 78 + + reg [5:0] bit_index = 0; + + always @(posedge clk) begin + clk_counter <= clk_counter + 1; + + case (state) + + 0: begin // Attente du signal LOW pendant ~18ms + if (sig === 1'b0) begin + clk_counter <= 0; + state <= 1; + end + end + + 1: begin // Confirmer que LOW dure assez longtemps + if (sig === 1'b1) begin + if (clk_counter >= 480_000) begin // ~18ms @27MHz + clk_counter <= 0; + state <= 2; + end else begin + state <= 0; // reset si trop court + end + end + end + + 2: begin // Capteur tire LOW pendant 80µs + sig_dir <= 1; + sig_out <= 0; + if (clk_counter >= T_80US) begin + clk_counter <= 0; + state <= 3; + sig_out <= 1; // ensuite tire HIGH + end + end + + 3: begin // Capteur tire HIGH pendant 80µs + if (clk_counter >= T_80US) begin + clk_counter <= 0; + bit_index <= 0; + state <= 4; + sig_dir <= 0; // libère la ligne pour début d'envoi + end + end + + 4: begin // Attente que host tire la ligne LOW (début bit start) + if (sig === 1'b0) begin + clk_counter <= 0; + state <= 5; + end + end + + 5: begin // Attente du front montant (bit start terminé) + if (sig === 1'b1) begin + clk_counter <= 0; + sig_dir <= 1; + sig_out <= 1; // commence bit + state <= 6; + end + end + + 6: begin // Envoi du bit en fonction de la valeur + if (clk_counter == T_50US) begin + sig_out <= 0; // fin du bit + clk_counter <= 0; + state <= 7; + end + end + + 7: begin // Repos entre les bits + if (clk_counter == (data_to_send[39 - bit_index] ? T_70US : T_28US)) begin + clk_counter <= 0; + sig_dir <= 0; // libère la ligne + bit_index <= bit_index + 1; + if (bit_index == 39) + state <= 8; // Terminé + else + state <= 4; + end + end + + 8: begin + // Tout est terminé. On reste ici. + end + + endcase + end +endmodule diff --git a/Semaine_5/DHT11/tests/verilog/tb_dht11.v b/Semaine_5/DHT11/tests/verilog/tb_dht11.v index 2bfe946..e64f9bb 100644 --- a/Semaine_5/DHT11/tests/verilog/tb_dht11.v +++ b/Semaine_5/DHT11/tests/verilog/tb_dht11.v @@ -5,11 +5,32 @@ module tb_dht11; reg clk = 0; always #18.5 clk = ~clk; // Génère une clock 27 MHz - // === Simulation du module DHT11 === + // === Registres === + wire io_dht11_sig; + reg dht11_start; + wire dht11_data_ready; + wire dht11_busy; + wire [7:0] dht11_temp_data; + wire [7:0] dht11_hum_data; + wire dht11_error; + // === Simulation du module DHT11 === + dht11_sensor_sim dht11_sim ( + .sig(io_dht11_sig), + .clk(clk) + ); // === Module DHT11 INTERFACE === - + dht11_interface dht11_interface ( + .i_clk(clk), + .io_dht11_sig(io_dht11_sig), + .i_start(dht11_start), + .o_dht11_data_ready(dht11_data_ready), + .o_busy(dht11_busy), + .o_temp_data(dht11_temp_data), + .o_hum_data(dht11_hum_data), + .o_dht11_error(dht11_error) + ); // === TEST SEQUENCE === initial begin @@ -18,7 +39,18 @@ module tb_dht11; $display("==== Start DHT11 Test ===="); - + #100; + dht11_start = 1; // Démarre la lecture des données + $display("DHT11 start..."); + + wait(dht11_busy); // Attend que le module soit occupé + $display("DHT11 busy..."); + + wait(dht11_data_ready); // Attend que les données soient prêtes + $display("DHT11 data ready..."); + + $display("Température : %d.%d °C", dht11_temp_data); + $display("Humidité : %d.%d %%", dht11_hum_data); $display("==== End DHT11 Test ===="); $finish; diff --git a/Semaine_5/DHT11_LEDS/.gitignore b/Semaine_5/DHT11_LEDS/.gitignore new file mode 100644 index 0000000..029ea4f --- /dev/null +++ b/Semaine_5/DHT11_LEDS/.gitignore @@ -0,0 +1,5 @@ +runs +.vscode +workspace.code-workspace +*.pyc +.idea \ No newline at end of file diff --git a/Semaine_5/DHT11_LEDS/IP/verilog/dht11_interface.v b/Semaine_5/DHT11_LEDS/IP/verilog/dht11_interface.v new file mode 100644 index 0000000..66ada0c --- /dev/null +++ b/Semaine_5/DHT11_LEDS/IP/verilog/dht11_interface.v @@ -0,0 +1,211 @@ +module dht11_interface #( + parameter CLK_FREQ = 27_000_000 +)( + input wire i_clk, + inout wire io_dht11_sig, + input wire i_start, + output reg o_dht11_data_ready, + output reg o_busy, + output reg [7:0] o_temp_data, + output reg [7:0] o_hum_data, + output reg o_dht11_error +); + + // === DHT11 INTERFACE === + + // === PARAMÈTRES === + localparam T_18MS = CLK_FREQ * 18 / 1000; // cycles pour 18ms + localparam T_80US = CLK_FREQ * 81 / 1_000_000; + localparam T_79US = CLK_FREQ * 79 / 1_000_000; + localparam T_71US = CLK_FREQ * 71 / 1_000_000; + localparam T_51US = CLK_FREQ * 51 / 1_000_000; + localparam T_50US = CLK_FREQ * 50 / 1_000_000; + localparam T_49US = CLK_FREQ * 49 / 1_000_000; + localparam T_40US = CLK_FREQ * 40 / 1_000_000; + localparam T_28US = CLK_FREQ * 28 / 1_000_000; + localparam T_26US = CLK_FREQ * 26 / 1_000_000; + localparam T_20US = CLK_FREQ * 20 / 1_000_000; + + + // === Signal bidirectionnel === + reg sig_dir; + reg sig_out; + wire sig_in; + + assign io_dht11_sig = sig_dir ? sig_out : 1'bz; // Si sig_dir = 1, on force la valeur de sig_out sur la ligne, sinon on laisse la ligne libre (1'bz) + assign sig_in = io_dht11_sig; + + // === REGISTRES === + reg [3:0] state; + reg [31:0] timer; + + reg [7:0] temp_data, hum_data; + reg [7:0] temp_dec, hum_dec, checksum; + reg [2:0] bit_count; + reg [5:0] bit_index; + reg [39:0] raw_data; + + // === FSM === + localparam IDLE = 4'd0, // Pull up la ligne + START = 4'd1, // Pull low 18ms + WAIT_RESPONSE = 4'd2, // Release la ligne (entre 20 et 40us) + RESPONSE_LOW = 4'd3, // DHT11 pull low 80us + RESPONSE_HIGH = 4'd4, // DHT11 pull high 80us + READ_BITS_LOW = 4'd5, + READ_BITS_HIGH = 4'd6, + DONE = 4'd7, + ERROR = 4'd8; + + // === INITIALISATION === + initial begin + sig_dir = 0; + sig_out = 1; + timer = 0; + state = IDLE; + bit_index = 0; + raw_data = 0; + o_dht11_data_ready = 0; + o_dht11_error = 0; + end + + // === FSM principale === + always @(posedge i_clk) begin + case (state) + + IDLE: begin + sig_dir <= 0; + sig_out <= 1; + timer <= 0; + bit_index <= 0; + raw_data <= 0; + + o_busy <= 0; + + if (i_start) begin + sig_dir <= 1; + sig_out <= 0; + timer <= 0; + o_busy <= 1; + state <= START; + o_dht11_data_ready <= 0; + o_dht11_error <= 0; + end + end + + START: begin + timer <= timer + 1; + if (timer >= T_18MS) begin + sig_dir <= 0; // libérer la ligne + timer <= 0; + state <= WAIT_RESPONSE; + end + end + + WAIT_RESPONSE: begin + timer <= timer + 1; + if (sig_in == 0) begin + if (timer > T_20US && timer < T_40US) begin + timer <= 0; + state <= RESPONSE_LOW; + end else begin + state <= ERROR; + end + end else if (timer > T_40US) begin + state <= ERROR; + end + end + + RESPONSE_LOW: begin + timer <= timer + 1; + + if (sig_in == 1) begin + if (timer > T_79US && timer < T_80US) begin + timer <= 0; + state <= RESPONSE_HIGH; + end else begin + state <= ERROR; + end + end else if (timer > T_80US) begin + state <= ERROR; + end + end + + RESPONSE_HIGH: begin + timer <= timer + 1; + + if (sig_in == 0) begin + if (timer > T_79US && timer < T_80US) begin + timer <= 0; + state <= READ_BITS_LOW; + end else begin + state <= ERROR; + end + end else if (timer > T_80US) begin + state <= ERROR; + end + end + + READ_BITS_LOW: begin + timer <= timer + 1; + if (sig_in == 1) begin + if (timer > T_49US && timer < T_51US) begin + timer <= 0; + state <= READ_BITS_HIGH; + end else begin + state <= ERROR; + end + end else if (timer > T_28US) begin + state <= ERROR; + end + end + + READ_BITS_HIGH: begin // entre 26 et 28us = 0 et ~70us = 1 + timer <= timer + 1; + if (sig_in == 0) begin + if (timer < T_26US) begin + state <= ERROR; + end + + raw_data <= {raw_data[38:0], (timer > T_28US)}; // 1 si high > ~28us + timer <= 0; + bit_index <= bit_index + 1; + + if (bit_index == 39) begin // Code a testé ici pour etre sur de capter le dernier bit + state <= DONE; + end else begin + state <= READ_BITS_LOW; + end + + end else if (timer > T_71US) begin + state <= ERROR; + end + end + + DONE: begin + hum_data <= raw_data[39:32]; + hum_dec <= raw_data[31:24]; + temp_data <= raw_data[23:16]; + temp_dec <= raw_data[15:8]; + checksum <= raw_data[7:0]; + + if (checksum == (raw_data[39:32] + raw_data[31:24] + raw_data[23:16] + raw_data[15:8])) begin + o_hum_data <= raw_data[39:32]; + o_temp_data <= raw_data[23:16]; + o_dht11_data_ready <= 1; + end else begin + o_dht11_error <= 1; + end + + o_busy <= 0; + state <= IDLE; + end + + ERROR: begin + o_dht11_error <= 1; + state <= IDLE; + end + + endcase + end + +endmodule diff --git a/Semaine_5/DHT11_LEDS/README.md b/Semaine_5/DHT11_LEDS/README.md new file mode 100644 index 0000000..34702e3 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/README.md @@ -0,0 +1,9 @@ +# ULTRASON VIA UART + +## Description +This project is designed to control an ultrasonic sensor using UART communication. The ultrasonic sensor is used to measure distance, and the data is transmitted via UART to a connected device. + +## Commands +0x01: Start one mesurement of the distance. +0x02: Start continuous mesurement of the distance. +0x03: Stop continuous mesurement of the distance. \ No newline at end of file diff --git a/Semaine_5/DHT11_LEDS/constraints/dht11_leds.cst b/Semaine_5/DHT11_LEDS/constraints/dht11_leds.cst new file mode 100644 index 0000000..a76b978 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/constraints/dht11_leds.cst @@ -0,0 +1,21 @@ +IO_LOC "clk" 4; +IO_PORT "clk" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; + +IO_LOC "dht11_sig" 73; +IO_PORT "dht11_sig" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; + +IO_LOC "start" 88; +IO_PORT "start" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; + +IO_LOC "leds[0]" 15; +IO_PORT "leds[0]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[1]" 16; +IO_PORT "leds[1]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[2]" 17; +IO_PORT "leds[2]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[3]" 18; +IO_PORT "leds[3]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[4]" 19; +IO_PORT "leds[4]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[5]" 20; +IO_PORT "leds[5]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; \ No newline at end of file diff --git a/Semaine_5/DHT11_LEDS/project.bat b/Semaine_5/DHT11_LEDS/project.bat new file mode 100644 index 0000000..6998748 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/project.bat @@ -0,0 +1,6 @@ +@call c:\oss-cad-suite\environment.bat +@echo off +if "%1"=="sim" call scripts\simulate.bat +if "%1"=="wave" call scripts\gtkwave.bat +if "%1"=="clean" call scripts\clean.bat +if "%1"=="build" call scripts\build.bat diff --git a/Semaine_5/DHT11_LEDS/scripts/build.bat b/Semaine_5/DHT11_LEDS/scripts/build.bat new file mode 100644 index 0000000..2a16131 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/scripts/build.bat @@ -0,0 +1,45 @@ +@echo off +setlocal + +rem === Aller à la racine du projet === +cd /d %~dp0\.. + +rem === Config de base === +set DEVICE=GW2AR-LV18QN88C8/I7 +set BOARD=tangnano20k +set TOP=dht11_leds +set CST_FILE=%TOP%.cst +set JSON_FILE=runs/%TOP%.json +set PNR_JSON=runs/pnr_%TOP%.json +set BITSTREAM=runs/%TOP%.fs + +rem === Créer le dossier runs si nécessaire === +if not exist runs ( + mkdir runs +) + +echo === Étape 1 : Synthèse avec Yosys === +yosys -p "read_verilog -sv src/verilog/%TOP%.v IP/verilog/dht11_interface.v; synth_gowin -top %TOP% -json %JSON_FILE%" +if errorlevel 1 goto error + +echo === Étape 2 : Placement & Routage avec nextpnr-himbaechel === +nextpnr-himbaechel --json %JSON_FILE% --write %PNR_JSON% --device %DEVICE% --vopt cst=constraints/%CST_FILE% --vopt family=GW2A-18C +if errorlevel 1 goto error + +echo === Étape 3 : Packing avec gowin_pack === +gowin_pack -d %DEVICE% -o %BITSTREAM% %PNR_JSON% +if errorlevel 1 goto error + +echo === Étape 4 : Flash avec openFPGALoader === +openFPGALoader -b %BOARD% %BITSTREAM% +if errorlevel 1 goto error + +echo === Compilation et flash réussis === +goto end + +:error +echo === Une erreur est survenue === + +:end +endlocal +pause diff --git a/Semaine_5/DHT11_LEDS/scripts/clean.bat b/Semaine_5/DHT11_LEDS/scripts/clean.bat new file mode 100644 index 0000000..6192ae1 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/scripts/clean.bat @@ -0,0 +1,4 @@ +@echo off +echo === Nettoyage du dossier runs === +rd /s /q runs +mkdir runs diff --git a/Semaine_5/DHT11_LEDS/scripts/gtkwave.bat b/Semaine_5/DHT11_LEDS/scripts/gtkwave.bat new file mode 100644 index 0000000..c4180e0 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/scripts/gtkwave.bat @@ -0,0 +1,3 @@ +@echo off +echo === Lancement de GTKWave === +gtkwave runs/wave.vcd diff --git a/Semaine_5/DHT11_LEDS/scripts/simulate.bat b/Semaine_5/DHT11_LEDS/scripts/simulate.bat new file mode 100644 index 0000000..020d5d2 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/scripts/simulate.bat @@ -0,0 +1,29 @@ +@echo off +echo === Simulation avec Icarus Verilog === +setlocal enabledelayedexpansion + +:: Dossier de sortie +set OUT=runs/sim.vvp + +:: Top-level testbench module +set TOP=dht11_interface + +:: Répertoires contenant des fichiers .v +set DIRS=src/verilog tests/verilog IP/verilog + +:: Variable pour stocker les fichiers +set FILES= + +:: Boucle sur chaque dossier +for %%D in (%DIRS%) do ( + for %%F in (%%D\*.v) do ( + set FILES=!FILES! %%F + ) +) + +:: Compilation avec Icarus Verilog +iverilog -g2012 -o %OUT% -s %TOP% %FILES% + +endlocal + +vvp runs/sim.vvp \ No newline at end of file diff --git a/Semaine_5/DHT11_LEDS/src/verilog/dht11_leds.v b/Semaine_5/DHT11_LEDS/src/verilog/dht11_leds.v new file mode 100644 index 0000000..b81e206 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/src/verilog/dht11_leds.v @@ -0,0 +1,58 @@ +module dht11_leds ( + input wire clk, // 27 MHz + inout wire dht11_sig, + input wire start, + output reg [5:0] leds +); + // === Registres === + wire io_dht11_sig; + reg dht11_start; + wire dht11_data_ready; + wire dht11_busy; + wire [7:0] dht11_temp_data; + wire [7:0] dht11_hum_data; + wire dht11_error; + + dht11_interface dht11_interface ( + .i_clk(clk), + .io_dht11_sig(io_dht11_sig), + .i_start(dht11_start), + .o_dht11_data_ready(dht11_data_ready), + .o_busy(dht11_busy), + .o_temp_data(dht11_temp_data), + .o_hum_data(dht11_hum_data), + .o_dht11_error(dht11_error) + ); + + initial begin + dht11_start = 0; + leds = 6'b000000; + end + + always @(posedge clk) begin + if (start) begin + dht11_start = 1; // Démarre la lecture des données + leds[0] = 1; // LED verte allumée + end else begin + dht11_start = 0; // Arrête la lecture des données + leds[0] = 0; // LED verte éteinte + end + + if (dht11_busy) begin + leds[1] = 1; // LED jaune allumée + end else begin + leds[1] = 0; // LED jaune éteinte + end + + if (dht11_data_ready) begin + leds = {dht11_temp_data[7:4], dht11_hum_data[7:4]}; // Affiche les données sur les LEDs + end + + if (dht11_error) begin + leds[5:3] = 3'b111; // Toutes les LEDs allumées en cas d'erreur + end else begin + leds[5:3] = 3'b000; // Éteint les LEDs si pas d'erreur + end + end + +endmodule diff --git a/Semaine_5/DHT11_LEDS/tests/verilog/tb_dht11_uart.v b/Semaine_5/DHT11_LEDS/tests/verilog/tb_dht11_uart.v new file mode 100644 index 0000000..2bfe946 --- /dev/null +++ b/Semaine_5/DHT11_LEDS/tests/verilog/tb_dht11_uart.v @@ -0,0 +1,27 @@ +`timescale 1ns/1ps + +module tb_dht11; + + reg clk = 0; + always #18.5 clk = ~clk; // Génère une clock 27 MHz + + // === Simulation du module DHT11 === + + + // === Module DHT11 INTERFACE === + + + // === TEST SEQUENCE === + initial begin + $dumpfile("runs/wave.vcd"); + $dumpvars(0, tb_dht11); + + $display("==== Start DHT11 Test ===="); + + + + $display("==== End DHT11 Test ===="); + $finish; + end + +endmodule \ No newline at end of file diff --git a/Semaine_5/DHT11_UART/.gitignore b/Semaine_5/DHT11_UART/.gitignore new file mode 100644 index 0000000..029ea4f --- /dev/null +++ b/Semaine_5/DHT11_UART/.gitignore @@ -0,0 +1,5 @@ +runs +.vscode +workspace.code-workspace +*.pyc +.idea \ No newline at end of file diff --git a/Semaine_5/DHT11_UART/IP/verilog/dht11_interface.v b/Semaine_5/DHT11_UART/IP/verilog/dht11_interface.v new file mode 100644 index 0000000..27753ad --- /dev/null +++ b/Semaine_5/DHT11_UART/IP/verilog/dht11_interface.v @@ -0,0 +1,210 @@ +module dht11_interface ( + input wire i_clk, // 27 MHz + inout wire io_dht11_sig, + input wire i_start, + output reg o_dht11_data_ready, + output reg o_busy, + output wire [7:0] o_temp_data, + output wire [7:0] o_hum_data, + output reg o_dht11_error +); + + // === DHT11 INTERFACE === + + // === PARAMÈTRES === + parameter CLK_FREQ = 27_000_000; + localparam T_18MS = CLK_FREQ * 18 / 1000; // cycles pour 18ms + localparam T_80US = CLK_FREQ * 81 / 1_000_000; + localparam T_79US = CLK_FREQ * 79 / 1_000_000; + localparam T_71US = CLK_FREQ * 71 / 1_000_000; + localparam T_51US = CLK_FREQ * 51 / 1_000_000; + localparam T_50US = CLK_FREQ * 50 / 1_000_000; + localparam T_49US = CLK_FREQ * 49 / 1_000_000; + localparam T_40US = CLK_FREQ * 40 / 1_000_000; + localparam T_28US = CLK_FREQ * 28 / 1_000_000; + localparam T_20US = CLK_FREQ * 20 / 1_000_000; + + + // === Signal bidirectionnel === + reg sig_dir; + reg sig_out; + wire sig_in; + + assign io_dht11_sig = sig_dir ? sig_out : 1'bz; // Si sig_dir = 1, on force la valeur de sig_out sur la ligne, sinon on laisse la ligne libre (1'bz) + assign sig_in = io_dht11_sig; + + // === REGISTRES === + reg [3:0] state; + reg [31:0] timer; + + reg [7:0] temp_data, hum_data; + reg [7:0] temp_dec, hum_dec, checksum; + reg [2:0] bit_count; + reg [5:0] bit_index; + reg [39:0] raw_data; + + // === INITIALISATION === + initial begin + sig_dir = 0; + sig_out = 1; + timer = 0; + state = IDLE; + bit_index = 0; + raw_data = 0; + o_dht11_data_ready = 0; + o_dht11_error = 0; + end + + // === FSM === + localparam IDLE = 4'd0, // Pull up la ligne + START = 4'd1, // Pull low 18ms + WAIT_RESPONSE = 4'd2, // Release la ligne (entre 20 et 40us) + RESPONSE_LOW = 4'd3, // DHT11 pull low 80us + RESPONSE_HIGH = 4'd4, // DHT11 pull high 80us + READ_READ_BITS_LOW = 4'd5, + READ_READ_BITS_HIGH = 4'd6, + DONE = 4'd7, + ERROR = 4'd8; + + + // === FSM principale === + always @(posedge i_clk) begin + case (state) + + IDLE: begin + sig_dir <= 0; + sig_out <= 1; + timer <= 0; + bit_index <= 0; + raw_data <= 0; + + o_busy <= 0; + + if (i_start) begin + sig_dir <= 1; + sig_out <= 0; + timer <= 0; + o_busy <= 1; + state <= START; + o_dht11_data_ready <= 0; + o_dht11_error <= 0; + end + end + + START: begin + timer <= timer + 1; + if (timer >= T_18MS) begin + sig_dir <= 0; // libérer la ligne + timer <= 0; + state <= WAIT_RESPONSE; + end + end + + WAIT_RESPONSE: begin + timer <= timer + 1; + if (sig_in == 0) begin + if (timer > T_20US && timer < T_40US) begin + timer <= 0; + state <= RESPONSE_LOW; + end else begin + state <= ERROR; + end + end else if (timer > T_40US) begin + state <= ERROR; + end + end + + RESPONSE_LOW: begin + timer <= timer + 1; + + if (sig_in == 1) begin + if (timer > T_79US && timer < T_80US) begin + timer <= 0; + state <= RESPONSE_HIGH; + end else begin + state <= ERROR; + end + end else if (timer > T_80US) begin + state <= ERROR; + end + end + + RESPONSE_HIGH: begin + timer <= timer + 1; + + if (sig_in == 0) begin + if (timer > T_79US && timer < T_80US) begin + timer <= 0; + state <= READ_BITS_LOW; + end else begin + state <= ERROR; + end + end else if (timer > T_80US) begin + state <= ERROR; + end + end + + READ_BITS_LOW: begin + timer <= timer + 1; + if (sig_in == 1) begin + if (timer > T_49US && timer < T_51US) begin + timer <= 0; + state <= READ_BITS_HIGH; + end else begin + state <= ERROR; + end + end else if (timer > T_28US) begin + state <= ERROR; + end + end + + READ_BITS_HIGH: begin // entre 26 et 28us = 0 et ~70us = 1 + timer <= timer + 1; + if (sig_in == 0) begin + if (timer < T_26US) begin + state <= ERROR; + end + + raw_data <= {raw_data[38:0], (timer > T_28US)}; // 1 si high > ~28us + timer <= 0; + bit_index <= bit_index + 1; + + if (bit_index == 39) begin // Code a testé ici pour etre sur de capter le dernier bit + state <= DONE; + end else begin + state <= READ_BITS_LOW; + end + + end else if (timer > T_71US) begin + state <= ERROR; + end + end + + DONE: begin + hum_data <= raw_data[39:32]; + hum_dec <= raw_data[31:24]; + temp_data <= raw_data[23:16]; + temp_dec <= raw_data[15:8]; + checksum <= raw_data[7:0]; + + if (checksum == (raw_data[39:32] + raw_data[31:24] + raw_data[23:16] + raw_data[15:8])) begin + o_hum_data <= raw_data[39:32]; + o_temp_data <= raw_data[23:16]; + o_dht11_data_ready <= 1; + end else begin + o_dht11_error <= 1; + end + + o_busy <= 0; + state <= IDLE; + end + + ERROR: begin + o_dht11_error <= 1; + state <= IDLE; + end + + endcase + end + +endmodule diff --git a/Semaine_5/DHT11_UART/README.md b/Semaine_5/DHT11_UART/README.md new file mode 100644 index 0000000..34702e3 --- /dev/null +++ b/Semaine_5/DHT11_UART/README.md @@ -0,0 +1,9 @@ +# ULTRASON VIA UART + +## Description +This project is designed to control an ultrasonic sensor using UART communication. The ultrasonic sensor is used to measure distance, and the data is transmitted via UART to a connected device. + +## Commands +0x01: Start one mesurement of the distance. +0x02: Start continuous mesurement of the distance. +0x03: Stop continuous mesurement of the distance. \ No newline at end of file diff --git a/Semaine_5/DHT11_UART/constraints/dht11_uart.cst b/Semaine_5/DHT11_UART/constraints/dht11_uart.cst new file mode 100644 index 0000000..4bcefef --- /dev/null +++ b/Semaine_5/DHT11_UART/constraints/dht11_uart.cst @@ -0,0 +1,21 @@ +IO_LOC "tx" 69; +IO_PORT "tx" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; + +IO_LOC "clk" 4; +IO_PORT "clk" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; + +IO_LOC "dht11_sig" 73; +IO_PORT "dht11_sig" IO_TYPE=LVCMOS33 PULL_MODE=UP DRIVE=8 BANK_VCCIO=3.3; + +IO_LOC "leds[0]" 15; +IO_PORT "leds[0]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[1]" 16; +IO_PORT "leds[1]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[2]" 17; +IO_PORT "leds[2]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[3]" 18; +IO_PORT "leds[3]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[4]" 19; +IO_PORT "leds[4]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "leds[5]" 20; +IO_PORT "leds[5]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; \ No newline at end of file diff --git a/Semaine_5/DHT11_UART/project.bat b/Semaine_5/DHT11_UART/project.bat new file mode 100644 index 0000000..6998748 --- /dev/null +++ b/Semaine_5/DHT11_UART/project.bat @@ -0,0 +1,6 @@ +@call c:\oss-cad-suite\environment.bat +@echo off +if "%1"=="sim" call scripts\simulate.bat +if "%1"=="wave" call scripts\gtkwave.bat +if "%1"=="clean" call scripts\clean.bat +if "%1"=="build" call scripts\build.bat diff --git a/Semaine_5/DHT11_UART/scripts/build.bat b/Semaine_5/DHT11_UART/scripts/build.bat new file mode 100644 index 0000000..89520d5 --- /dev/null +++ b/Semaine_5/DHT11_UART/scripts/build.bat @@ -0,0 +1,45 @@ +@echo off +setlocal + +rem === Aller à la racine du projet === +cd /d %~dp0\.. + +rem === Config de base === +set DEVICE=GW2AR-LV18QN88C8/I7 +set BOARD=tangnano20k +set TOP=top_uart_ultrason_command +set CST_FILE=%TOP%.cst +set JSON_FILE=runs/%TOP%.json +set PNR_JSON=runs/pnr_%TOP%.json +set BITSTREAM=runs/%TOP%.fs + +rem === Créer le dossier runs si nécessaire === +if not exist runs ( + mkdir runs +) + +echo === Étape 1 : Synthèse avec Yosys === +yosys -p "read_verilog -sv src/verilog/%TOP%.v IP/verilog/ultrasonic_fpga.v IP/verilog/uart_tx_fifo.v IP/verilog/uart_rx_fifo.v IP/verilog/rxuartlite.v IP/verilog/fifo.v IP/verilog/uart_tx.v; synth_gowin -top %TOP% -json %JSON_FILE%" +if errorlevel 1 goto error + +echo === Étape 2 : Placement & Routage avec nextpnr-himbaechel === +nextpnr-himbaechel --json %JSON_FILE% --write %PNR_JSON% --device %DEVICE% --vopt cst=constraints/%CST_FILE% --vopt family=GW2A-18C +if errorlevel 1 goto error + +echo === Étape 3 : Packing avec gowin_pack === +gowin_pack -d %DEVICE% -o %BITSTREAM% %PNR_JSON% +if errorlevel 1 goto error + +echo === Étape 4 : Flash avec openFPGALoader === +openFPGALoader -b %BOARD% %BITSTREAM% +if errorlevel 1 goto error + +echo === Compilation et flash réussis === +goto end + +:error +echo === Une erreur est survenue === + +:end +endlocal +pause diff --git a/Semaine_5/DHT11_UART/scripts/clean.bat b/Semaine_5/DHT11_UART/scripts/clean.bat new file mode 100644 index 0000000..6192ae1 --- /dev/null +++ b/Semaine_5/DHT11_UART/scripts/clean.bat @@ -0,0 +1,4 @@ +@echo off +echo === Nettoyage du dossier runs === +rd /s /q runs +mkdir runs diff --git a/Semaine_5/DHT11_UART/scripts/gtkwave.bat b/Semaine_5/DHT11_UART/scripts/gtkwave.bat new file mode 100644 index 0000000..c4180e0 --- /dev/null +++ b/Semaine_5/DHT11_UART/scripts/gtkwave.bat @@ -0,0 +1,3 @@ +@echo off +echo === Lancement de GTKWave === +gtkwave runs/wave.vcd diff --git a/Semaine_5/DHT11_UART/scripts/simulate.bat b/Semaine_5/DHT11_UART/scripts/simulate.bat new file mode 100644 index 0000000..020d5d2 --- /dev/null +++ b/Semaine_5/DHT11_UART/scripts/simulate.bat @@ -0,0 +1,29 @@ +@echo off +echo === Simulation avec Icarus Verilog === +setlocal enabledelayedexpansion + +:: Dossier de sortie +set OUT=runs/sim.vvp + +:: Top-level testbench module +set TOP=dht11_interface + +:: Répertoires contenant des fichiers .v +set DIRS=src/verilog tests/verilog IP/verilog + +:: Variable pour stocker les fichiers +set FILES= + +:: Boucle sur chaque dossier +for %%D in (%DIRS%) do ( + for %%F in (%%D\*.v) do ( + set FILES=!FILES! %%F + ) +) + +:: Compilation avec Icarus Verilog +iverilog -g2012 -o %OUT% -s %TOP% %FILES% + +endlocal + +vvp runs/sim.vvp \ No newline at end of file diff --git a/Semaine_5/DHT11_UART/src/verilog/dht11_uart.v b/Semaine_5/DHT11_UART/src/verilog/dht11_uart.v new file mode 100644 index 0000000..4ab8f4b --- /dev/null +++ b/Semaine_5/DHT11_UART/src/verilog/dht11_uart.v @@ -0,0 +1,208 @@ +module dht11_uart ( + input wire i_clk, // 27 MHz + inout wire io_dht11_sig, + input wire i_start, + output wire [7:0] o_leds, + output wire [7:0] o_hum_data, + output reg o_dht11_error +); + + // === DHT11 INTERFACE === + + // === PARAMÈTRES === + parameter CLK_FREQ = 27_000_000; + localparam T_18MS = CLK_FREQ * 18 / 1000; // cycles pour 18ms + localparam T_80US = CLK_FREQ * 81 / 1_000_000; + localparam T_79US = CLK_FREQ * 79 / 1_000_000; + localparam T_71US = CLK_FREQ * 71 / 1_000_000; + localparam T_51US = CLK_FREQ * 51 / 1_000_000; + localparam T_50US = CLK_FREQ * 50 / 1_000_000; + localparam T_49US = CLK_FREQ * 49 / 1_000_000; + localparam T_40US = CLK_FREQ * 40 / 1_000_000; + localparam T_28US = CLK_FREQ * 28 / 1_000_000; + localparam T_20US = CLK_FREQ * 20 / 1_000_000; + + + // === Signal bidirectionnel === + reg sig_dir; + reg sig_out; + wire sig_in; + + assign io_dht11_sig = sig_dir ? sig_out : 1'bz; // Si sig_dir = 1, on force la valeur de sig_out sur la ligne, sinon on laisse la ligne libre (1'bz) + assign sig_in = io_dht11_sig; + + // === REGISTRES === + reg [3:0] state; + reg [31:0] timer; + + reg [7:0] temp_data, hum_data; + reg [7:0] temp_dec, hum_dec, checksum; + reg [2:0] bit_count; + reg [5:0] bit_index; + reg [39:0] raw_data; + + // === INITIALISATION === + initial begin + sig_dir = 0; + sig_out = 1; + timer = 0; + state = IDLE; + bit_index = 0; + raw_data = 0; + o_dht11_data_ready = 0; + o_dht11_error = 0; + end + + // === FSM === + localparam IDLE = 4'd0, // Pull up la ligne + START = 4'd1, // Pull low 18ms + WAIT_RESPONSE = 4'd2, // Release la ligne (entre 20 et 40us) + RESPONSE_LOW = 4'd3, // DHT11 pull low 80us + RESPONSE_HIGH = 4'd4, // DHT11 pull high 80us + READ_READ_BITS_LOW = 4'd5, + READ_READ_BITS_HIGH = 4'd6, + DONE = 4'd7, + ERROR = 4'd8; + + + // === FSM principale === + always @(posedge i_clk) begin + case (state) + + IDLE: begin + sig_dir <= 0; + sig_out <= 1; + timer <= 0; + bit_index <= 0; + raw_data <= 0; + + o_busy <= 0; + + if (i_start) begin + sig_dir <= 1; + sig_out <= 0; + timer <= 0; + o_busy <= 1; + state <= START; + o_dht11_data_ready <= 0; + o_dht11_error <= 0; + end + end + + START: begin + timer <= timer + 1; + if (timer >= T_18MS) begin + sig_dir <= 0; // libérer la ligne + timer <= 0; + state <= WAIT_RESPONSE; + end + end + + WAIT_RESPONSE: begin + timer <= timer + 1; + if (sig_in == 0) begin + if (timer > T_20US && timer < T_40US) begin + timer <= 0; + state <= RESPONSE_LOW; + end else begin + state <= ERROR; + end + end else if (timer > T_40US) begin + state <= ERROR; + end + end + + RESPONSE_LOW: begin + timer <= timer + 1; + + if (sig_in == 1) begin + if (timer > T_79US && timer < T_80US) begin + timer <= 0; + state <= RESPONSE_HIGH; + end else begin + state <= ERROR; + end + end else if (timer > T_80US) begin + state <= ERROR; + end + end + + RESPONSE_HIGH: begin + timer <= timer + 1; + + if (sig_in == 0) begin + if (timer > T_79US && timer < T_80US) begin + timer <= 0; + state <= READ_BITS_LOW; + end else begin + state <= ERROR; + end + end else if (timer > T_80US) begin + state <= ERROR; + end + end + + READ_BITS_LOW: begin + timer <= timer + 1; + if (sig_in == 1) begin + if (timer > T_49US && timer < T_51US) begin + timer <= 0; + state <= READ_BITS_HIGH; + end else begin + state <= ERROR; + end + end else if (timer > T_28US) begin + state <= ERROR; + end + end + + READ_BITS_HIGH: begin // entre 26 et 28us = 0 et ~70us = 1 + timer <= timer + 1; + if (sig_in == 0) begin + if (timer < T_26US) begin + state <= ERROR; + end + + raw_data <= {raw_data[38:0], (timer > T_28US)}; // 1 si high > ~28us + timer <= 0; + bit_index <= bit_index + 1; + + if (bit_index == 39) begin // Code a testé ici pour etre sur de capter le dernier bit + state <= DONE; + end else begin + state <= READ_BITS_LOW; + end + + end else if (timer > T_71US) begin + state <= ERROR; + end + end + + DONE: begin + hum_data <= raw_data[39:32]; + hum_dec <= raw_data[31:24]; + temp_data <= raw_data[23:16]; + temp_dec <= raw_data[15:8]; + checksum <= raw_data[7:0]; + + if (checksum == (raw_data[39:32] + raw_data[31:24] + raw_data[23:16] + raw_data[15:8])) begin + o_hum_data <= raw_data[39:32]; + o_temp_data <= raw_data[23:16]; + o_dht11_data_ready <= 1; + end else begin + o_dht11_error <= 1; + end + + o_busy <= 0; + state <= IDLE; + end + + ERROR: begin + o_dht11_error <= 1; + state <= IDLE; + end + + endcase + end + +endmodule diff --git a/Semaine_5/DHT11_UART/tests/verilog/tb_dht11_uart.v b/Semaine_5/DHT11_UART/tests/verilog/tb_dht11_uart.v new file mode 100644 index 0000000..2bfe946 --- /dev/null +++ b/Semaine_5/DHT11_UART/tests/verilog/tb_dht11_uart.v @@ -0,0 +1,27 @@ +`timescale 1ns/1ps + +module tb_dht11; + + reg clk = 0; + always #18.5 clk = ~clk; // Génère une clock 27 MHz + + // === Simulation du module DHT11 === + + + // === Module DHT11 INTERFACE === + + + // === TEST SEQUENCE === + initial begin + $dumpfile("runs/wave.vcd"); + $dumpvars(0, tb_dht11); + + $display("==== Start DHT11 Test ===="); + + + + $display("==== End DHT11 Test ===="); + $finish; + end + +endmodule \ No newline at end of file