From cbebf620d59dea031fcd16023a78e8d33563163c Mon Sep 17 00:00:00 2001 From: tanchou Date: Tue, 20 May 2025 15:55:21 +0200 Subject: [PATCH] Add DHT11 interface and model, update testbench and scripts for simulation --- Semaine_6/DHT11/.gitignore | 5 + Semaine_6/DHT11/README.md | 9 + .../DHT11/constraints/dht11_interface.cst | 24 ++ Semaine_6/DHT11/project.bat | 6 + Semaine_6/DHT11/project.sh | 24 ++ Semaine_6/DHT11/scripts/linux/build.sh | 46 ++++ Semaine_6/DHT11/scripts/linux/clean.sh | 4 + Semaine_6/DHT11/scripts/linux/gtkwave.sh | 5 + Semaine_6/DHT11/scripts/linux/simulate.sh | 17 ++ Semaine_6/DHT11/scripts/windows/build.bat | 45 ++++ Semaine_6/DHT11/scripts/windows/clean.bat | 4 + Semaine_6/DHT11/scripts/windows/gtkwave.bat | 3 + Semaine_6/DHT11/scripts/windows/simulate.bat | 29 +++ Semaine_6/DHT11/src/verilog/dht11_interface.v | 211 ++++++++++++++++++ Semaine_6/DHT11/src/verilog/dht11_model.v | 142 ++++++++++++ Semaine_6/DHT11/tests/verilog/tb_dht11.v | 63 ++++++ 16 files changed, 637 insertions(+) create mode 100644 Semaine_6/DHT11/.gitignore create mode 100644 Semaine_6/DHT11/README.md create mode 100644 Semaine_6/DHT11/constraints/dht11_interface.cst create mode 100644 Semaine_6/DHT11/project.bat create mode 100755 Semaine_6/DHT11/project.sh create mode 100755 Semaine_6/DHT11/scripts/linux/build.sh create mode 100755 Semaine_6/DHT11/scripts/linux/clean.sh create mode 100755 Semaine_6/DHT11/scripts/linux/gtkwave.sh create mode 100755 Semaine_6/DHT11/scripts/linux/simulate.sh create mode 100644 Semaine_6/DHT11/scripts/windows/build.bat create mode 100644 Semaine_6/DHT11/scripts/windows/clean.bat create mode 100644 Semaine_6/DHT11/scripts/windows/gtkwave.bat create mode 100644 Semaine_6/DHT11/scripts/windows/simulate.bat create mode 100644 Semaine_6/DHT11/src/verilog/dht11_interface.v create mode 100644 Semaine_6/DHT11/src/verilog/dht11_model.v create mode 100644 Semaine_6/DHT11/tests/verilog/tb_dht11.v diff --git a/Semaine_6/DHT11/.gitignore b/Semaine_6/DHT11/.gitignore new file mode 100644 index 0000000..029ea4f --- /dev/null +++ b/Semaine_6/DHT11/.gitignore @@ -0,0 +1,5 @@ +runs +.vscode +workspace.code-workspace +*.pyc +.idea \ No newline at end of file diff --git a/Semaine_6/DHT11/README.md b/Semaine_6/DHT11/README.md new file mode 100644 index 0000000..34702e3 --- /dev/null +++ b/Semaine_6/DHT11/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_6/DHT11/constraints/dht11_interface.cst b/Semaine_6/DHT11/constraints/dht11_interface.cst new file mode 100644 index 0000000..110a02b --- /dev/null +++ b/Semaine_6/DHT11/constraints/dht11_interface.cst @@ -0,0 +1,24 @@ +IO_LOC "tx" 69; +IO_PORT "tx" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; + +IO_LOC "rx" 70; +IO_PORT "rx" 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 "ultrason_sig" 73; +IO_PORT "ultrason_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_6/DHT11/project.bat b/Semaine_6/DHT11/project.bat new file mode 100644 index 0000000..c087898 --- /dev/null +++ b/Semaine_6/DHT11/project.bat @@ -0,0 +1,6 @@ +@call c:\oss-cad-suite\environment.bat +@echo off +if "%1"=="sim" call scripts\windows\simulate.bat +if "%1"=="wave" call scripts\windows\gtkwave.bat +if "%1"=="clean" call scripts\windows\clean.bat +if "%1"=="build" call scripts\windows\build.bat \ No newline at end of file diff --git a/Semaine_6/DHT11/project.sh b/Semaine_6/DHT11/project.sh new file mode 100755 index 0000000..c759d7c --- /dev/null +++ b/Semaine_6/DHT11/project.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Charger l'environnement OSS CAD Suite +source /home/louis/oss-cad-suite/environment + +mkdir -p runs + +case "$1" in + sim) + bash scripts/linux/simulate.sh + ;; + wave) + bash scripts/linux/gtkwave.sh + ;; + clean) + bash scripts/linux/clean.sh + ;; + build) + bash scripts/linux/build.sh + ;; + *) + echo "Usage: $0 {sim|wave|clean|build}" + ;; +esac diff --git a/Semaine_6/DHT11/scripts/linux/build.sh b/Semaine_6/DHT11/scripts/linux/build.sh new file mode 100755 index 0000000..3c59fe2 --- /dev/null +++ b/Semaine_6/DHT11/scripts/linux/build.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Aller à la racine du projet +cd "$(dirname "$0")/../.." || exit 1 + +# Config de base +DEVICE="GW2AR-LV18QN88C8/I7" +BOARD="tangnano20k" +TOP="top_uart_ultrason_command" +CST_FILE="$TOP.cst" +JSON_FILE="runs/$TOP.json" +PNR_JSON="runs/pnr_$TOP.json" +BITSTREAM="runs/$TOP.fs" + +# Créer le dossier runs si nécessaire +mkdir -p 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 [ $? -ne 0 ]; then + echo "=== Erreur lors de la synthèse ===" + exit 1 +fi + +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 [ $? -ne 0 ]; then + echo "=== Erreur lors du placement/routage ===" + exit 1 +fi + +echo "=== Étape 3 : Packing avec gowin_pack ===" +gowin_pack -d "$DEVICE" -o "$BITSTREAM" "$PNR_JSON" +if [ $? -ne 0 ]; then + echo "=== Erreur lors du packing ===" + exit 1 +fi + +echo "=== Étape 4 : Flash avec openFPGALoader ===" +openFPGALoader -b "$BOARD" "$BITSTREAM" +if [ $? -ne 0 ]; then + echo "=== Erreur lors du flash ===" + exit 1 +fi + +echo "=== Compilation et flash réussis ===" diff --git a/Semaine_6/DHT11/scripts/linux/clean.sh b/Semaine_6/DHT11/scripts/linux/clean.sh new file mode 100755 index 0000000..a505cb7 --- /dev/null +++ b/Semaine_6/DHT11/scripts/linux/clean.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +echo "=== Nettoyage des fichiers générés ===" +rm -rf runs/* diff --git a/Semaine_6/DHT11/scripts/linux/gtkwave.sh b/Semaine_6/DHT11/scripts/linux/gtkwave.sh new file mode 100755 index 0000000..f623377 --- /dev/null +++ b/Semaine_6/DHT11/scripts/linux/gtkwave.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +echo "=== Lancement de GTKWave ===" +gtkwave runs/sim.vcd +echo "=== GTKWave terminé ===" \ No newline at end of file diff --git a/Semaine_6/DHT11/scripts/linux/simulate.sh b/Semaine_6/DHT11/scripts/linux/simulate.sh new file mode 100755 index 0000000..24d3f6e --- /dev/null +++ b/Semaine_6/DHT11/scripts/linux/simulate.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +echo "=== Simulation avec Icarus Verilog ===" + +OUT="runs/sim.vvp" +TOP="tb_dht11" +DIRS=("src/verilog" "tests/verilog") + +FILES=() +for dir in "${DIRS[@]}"; do + for file in "$dir"/*.v; do + FILES+=("$file") + done +done + +iverilog -g2012 -o "$OUT" -s "$TOP" "${FILES[@]}" +vvp "$OUT" diff --git a/Semaine_6/DHT11/scripts/windows/build.bat b/Semaine_6/DHT11/scripts/windows/build.bat new file mode 100644 index 0000000..89520d5 --- /dev/null +++ b/Semaine_6/DHT11/scripts/windows/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_6/DHT11/scripts/windows/clean.bat b/Semaine_6/DHT11/scripts/windows/clean.bat new file mode 100644 index 0000000..6192ae1 --- /dev/null +++ b/Semaine_6/DHT11/scripts/windows/clean.bat @@ -0,0 +1,4 @@ +@echo off +echo === Nettoyage du dossier runs === +rd /s /q runs +mkdir runs diff --git a/Semaine_6/DHT11/scripts/windows/gtkwave.bat b/Semaine_6/DHT11/scripts/windows/gtkwave.bat new file mode 100644 index 0000000..c4180e0 --- /dev/null +++ b/Semaine_6/DHT11/scripts/windows/gtkwave.bat @@ -0,0 +1,3 @@ +@echo off +echo === Lancement de GTKWave === +gtkwave runs/wave.vcd diff --git a/Semaine_6/DHT11/scripts/windows/simulate.bat b/Semaine_6/DHT11/scripts/windows/simulate.bat new file mode 100644 index 0000000..fbe0ee2 --- /dev/null +++ b/Semaine_6/DHT11/scripts/windows/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=tb_dht11 + +:: 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_6/DHT11/src/verilog/dht11_interface.v b/Semaine_6/DHT11/src/verilog/dht11_interface.v new file mode 100644 index 0000000..c61fbc6 --- /dev/null +++ b/Semaine_6/DHT11/src/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 <= 1; + 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_6/DHT11/src/verilog/dht11_model.v b/Semaine_6/DHT11/src/verilog/dht11_model.v new file mode 100644 index 0000000..22a8bb3 --- /dev/null +++ b/Semaine_6/DHT11/src/verilog/dht11_model.v @@ -0,0 +1,142 @@ +module dht11_model ( + inout wire data, // Ligne de données bidirectionnelle + input wire clk, // Horloge système (50 MHz) + input wire rst_n // Reset actif bas +); + + // Paramètres pour les timings (basés sur une horloge de 50 MHz, période 20 ns) + localparam CLK_FREQ = 50_000_000; // 50 MHz + localparam START_LOW_TIME = 18_000 / 20; // 18 ms pour le signal de démarrage + localparam START_HIGH_TIME = 40_000 / 20; // 20-40 µs pour le relâchement + localparam RESPONSE_LOW = 80_000 / 20; // 80 µs pour la réponse basse + localparam RESPONSE_HIGH = 80_000 / 20; // 80 µs pour la réponse haute + localparam BIT0_LOW = 50_000 / 20; // 50 µs pour bit '0' + localparam BIT1_LOW = 70_000 / 20; // 70 µs pour bit '1' + localparam DATA_BITS = 40; // 40 bits de données + + // États de la machine à états + localparam IDLE = 3'd0, + START = 3'd1, + RESPONSE = 3'd2, + SEND_DATA = 3'd3, + ENDED = 3'd4; + + reg [2:0] state, next_state; + reg [15:0] counter; // Compteur pour les timings + reg [5:0] bit_index; // Index du bit à envoyer + reg data_out; // Valeur de sortie sur la ligne data + reg data_oe; // Contrôle de l'output enable (1 = sortie, 0 = haute impédance) + wire data_in; // Valeur lue sur la ligne data + + // Données simulées (exemple : humidité = 45.0%, température = 23.0°C) + reg [7:0] humidity_int = 8'h2D; // 45 en décimal + reg [7:0] humidity_dec = 8'h00; // 0 + reg [7:0] temp_int = 8'h17; // 23 en décimal + reg [7:0] temp_dec = 8'h00; // 0 + reg [7:0] checksum; // Checksum = sum des 4 octets + + reg [39:0] data_shift; // Registre pour les 40 bits de données + + // Gestion de la ligne bidirectionnelle + assign data = data_oe ? data_out : 1'bz; + assign data_in = data; + + // Calcul du checksum + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + checksum <= 8'h00; + end else begin + checksum <= humidity_int + humidity_dec + temp_int + temp_dec; + end + end + + // Concaténation des données à envoyer + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + data_shift <= 40'b0; + end else begin + data_shift <= {humidity_int, humidity_dec, temp_int, temp_dec, checksum}; + end + end + + // Machine à états + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + state <= IDLE; + counter <= 16'b0; + bit_index <= 6'b0; + data_out <= 1'b1; + data_oe <= 1'b0; + end else begin + state <= next_state; + case (state) + IDLE: begin + counter <= 16'b0; + bit_index <= 6'b0; + data_out <= 1'b1; + data_oe <= 1'b0; + end + START: begin + counter <= counter + 1; + data_out <= 1'b0; + data_oe <= 1'b1; + end + RESPONSE: begin + counter <= counter + 1; + if (counter < RESPONSE_LOW) begin + data_out <= 1'b0; + data_oe <= 1'b1; + end else begin + data_out <= 1'b1; + data_oe <= 1'b1; + end + end + SEND_DATA: begin + counter <= counter + 1; + if (counter == 0) begin + data_out <= 1'b0; // Début du bit (toujours bas) + data_oe <= 1'b1; + end else if (counter == (data_shift[39-bit_index] ? BIT1_LOW : BIT0_LOW)) begin + data_out <= 1'b1; // Fin du bit + data_oe <= 1'b1; + end else if (counter >= (data_shift[39-bit_index] ? BIT1_LOW + 50 : BIT0_LOW + 50)) begin + counter <= 16'b0; + bit_index <= bit_index + 1; + end + end + ENDED: begin + data_out <= 1'b1; + data_oe <= 1'b0; + counter <= 16'b0; + end + endcase + end + end + + // Logique de transition des états + always @(*) begin + next_state = state; + case (state) + IDLE: begin + if (data_in == 1'b0) // Détection du signal de démarrage + next_state = START; + end + START: begin + if (counter >= START_LOW_TIME && data_in == 1'b1) + next_state = RESPONSE; + end + RESPONSE: begin + if (counter >= RESPONSE_LOW + RESPONSE_HIGH) + next_state = SEND_DATA; + end + SEND_DATA: begin + if (bit_index >= DATA_BITS) + next_state = ENDED; + end + ENDED: begin + next_state = IDLE; + end + endcase + end + +endmodule \ No newline at end of file diff --git a/Semaine_6/DHT11/tests/verilog/tb_dht11.v b/Semaine_6/DHT11/tests/verilog/tb_dht11.v new file mode 100644 index 0000000..58723dc --- /dev/null +++ b/Semaine_6/DHT11/tests/verilog/tb_dht11.v @@ -0,0 +1,63 @@ +`timescale 1ns/1ps + +module tb_dht11; + + reg clk = 0; + always #18.5 clk = ~clk; // Génère une clock 27 MHz + + // === 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_model dht11_model ( + .data(io_dht11_sig), + .clk(clk), + .rst_n(1'b1) // Reset non utilisé dans ce test + ); + + // === 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 + $dumpfile("runs/sim.vcd"); + $dumpvars(0, tb_dht11); + dht11_start = 0; + + $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..."); + + dht11_start = 0; + + 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; + end + +endmodule \ No newline at end of file