diff --git a/Semaine_4/UART/README.md b/Semaine_4/UART/README.md new file mode 100644 index 0000000..4389218 --- /dev/null +++ b/Semaine_4/UART/README.md @@ -0,0 +1,3 @@ +# UART + +Faire deux modules : un pour l'émetteur et un pour le récepteur. Le module émetteur doit être capable d'envoyer des données sur le port série, tandis que le module récepteur doit être capable de recevoir des données sur le port série. Les deux modules doivent être capables de communiquer entre eux. \ No newline at end of file diff --git a/Semaine_4/UART/src/verilog/top_uart_loopback.v b/Semaine_4/UART/src/verilog/top_uart_loopback.v index a83d995..e7fc073 100644 --- a/Semaine_4/UART/src/verilog/top_uart_loopback.v +++ b/Semaine_4/UART/src/verilog/top_uart_loopback.v @@ -13,7 +13,7 @@ module top_uart_loopback ( wire tx_ready; initial begin - leds = 6'b000000; // Initialiser les LEDs à 0 + leds = 6'b111111; end // === UART RX === @@ -36,32 +36,51 @@ module top_uart_loopback ( .tx(tx) ); - // === FSM pour déclencher la transmission === - localparam IDLE = 0, SEND = 1; - reg state = IDLE; + // === FSM avec délai === + localparam IDLE = 0, WAIT = 1, SEND = 2; + reg [1:0] state = IDLE; + reg [8:0] delay_counter = 0; always @(posedge clk) begin leds[5] <= rx; + leds[4] <= tx; + case (state) IDLE: begin tx_enable <= 0; + delay_counter <= 0; + if (rx_received && tx_ready) begin tx_data <= rx_data; - tx_enable <= 1; - state <= SEND; - leds[0] <= 1; - leds[5:1] <= 0; + state <= WAIT; + leds[0] <= 0; + leds[1] <= 1; end end + WAIT: begin + delay_counter <= delay_counter + 1; + + if (delay_counter == 8'd400 && tx_ready) begin + tx_enable <= 1; + state <= SEND; + end else begin + tx_enable <= 0; + end + + leds[0] <= 1; + leds[1] <= 0; + end + + SEND: begin tx_enable <= 0; state <= IDLE; - leds[0] <= 0; // LED 0 allumée pour indiquer la réception - leds[1] <= 1; // LED 1 éteinte pour indiquer l'attente de transmission + leds[0] <= 0; + leds[1] <= 0; // Envoi terminé end endcase end -endmodule +endmodule \ No newline at end of file diff --git a/Semaine_4/UART/src/verilog/uart_tx.v b/Semaine_4/UART/src/verilog/uart_tx.v index cbc9505..9f48d93 100644 --- a/Semaine_4/UART/src/verilog/uart_tx.v +++ b/Semaine_4/UART/src/verilog/uart_tx.v @@ -84,7 +84,7 @@ module uart_tx #( if(rst_p == 1'b1) begin tx_data_latch <= 8'd0; end else if(state == IDLE && tx_enable == 1'b1) begin - tx_data_latch <= data; // Charger les données de `data` dans `tx_data_latch` + tx_data_latch <= data; // Charger les données de data dans tx_data_latch end end diff --git a/Semaine_4/UART_FIFO/.gitignore b/Semaine_4/UART_FIFO/.gitignore new file mode 100644 index 0000000..33b5bda --- /dev/null +++ b/Semaine_4/UART_FIFO/.gitignore @@ -0,0 +1,4 @@ +runs +.vscode +workspace.code-workspace +*.pyc diff --git a/Semaine_4/UART_FIFO/constraints/top_uart_loopback.cst b/Semaine_4/UART_FIFO/constraints/top_uart_loopback.cst new file mode 100644 index 0000000..e1fb732 --- /dev/null +++ b/Semaine_4/UART_FIFO/constraints/top_uart_loopback.cst @@ -0,0 +1,19 @@ +IO_LOC "rx" 70; +IO_PORT "rx" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "tx" 69; +IO_PORT "tx" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8; +IO_LOC "clk" 4; +IO_PORT "clk" PULL_MODE=UP BANK_VCCIO=1.8; + +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_4/UART_FIFO/project.bat b/Semaine_4/UART_FIFO/project.bat new file mode 100644 index 0000000..6998748 --- /dev/null +++ b/Semaine_4/UART_FIFO/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_4/UART_FIFO/scripts/build.bat b/Semaine_4/UART_FIFO/scripts/build.bat new file mode 100644 index 0000000..aed8469 --- /dev/null +++ b/Semaine_4/UART_FIFO/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_loopback +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 src/verilog/uart_rx.v src/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_4/UART_FIFO/scripts/clean.bat b/Semaine_4/UART_FIFO/scripts/clean.bat new file mode 100644 index 0000000..6192ae1 --- /dev/null +++ b/Semaine_4/UART_FIFO/scripts/clean.bat @@ -0,0 +1,4 @@ +@echo off +echo === Nettoyage du dossier runs === +rd /s /q runs +mkdir runs diff --git a/Semaine_4/UART_FIFO/scripts/gtkwave.bat b/Semaine_4/UART_FIFO/scripts/gtkwave.bat new file mode 100644 index 0000000..ae1cd1b --- /dev/null +++ b/Semaine_4/UART_FIFO/scripts/gtkwave.bat @@ -0,0 +1,3 @@ +@echo off +echo === Lancement de GTKWave === +gtkwave runs/uart.vcd diff --git a/Semaine_4/UART_FIFO/scripts/simulate.bat b/Semaine_4/UART_FIFO/scripts/simulate.bat new file mode 100644 index 0000000..a681db1 --- /dev/null +++ b/Semaine_4/UART_FIFO/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=tb_uart + +:: 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_4/UART_FIFO/src/verilog/top_uart_loopback_fifo.v b/Semaine_4/UART_FIFO/src/verilog/top_uart_loopback_fifo.v new file mode 100644 index 0000000..a83d995 --- /dev/null +++ b/Semaine_4/UART_FIFO/src/verilog/top_uart_loopback_fifo.v @@ -0,0 +1,67 @@ +module top_uart_loopback ( + input wire clk, // 27 MHz + input wire rx, + output wire tx, + output reg [5:0] leds +); + + wire rx_received; + wire [7:0] rx_data; + reg [7:0] tx_data; + reg tx_enable; + + wire tx_ready; + + initial begin + leds = 6'b000000; // Initialiser les LEDs à 0 + end + + // === UART RX === + uart_rx uart_rx_inst ( + .clk(clk), + .rst_p(1'b0), + .rx_pin(rx), + .rx_received(rx_received), + .rx_enable(1'b1), + .rx_data(rx_data) + ); + + // === UART TX === + uart_tx uart_tx_inst ( + .clk(clk), + .rst_p(1'b0), + .data(tx_data), + .tx_enable(tx_enable), + .tx_ready(tx_ready), + .tx(tx) + ); + + // === FSM pour déclencher la transmission === + localparam IDLE = 0, SEND = 1; + reg state = IDLE; + + always @(posedge clk) begin + leds[5] <= rx; + case (state) + IDLE: begin + tx_enable <= 0; + if (rx_received && tx_ready) begin + tx_data <= rx_data; + tx_enable <= 1; + state <= SEND; + leds[0] <= 1; + leds[5:1] <= 0; + end + end + + SEND: begin + tx_enable <= 0; + state <= IDLE; + + leds[0] <= 0; // LED 0 allumée pour indiquer la réception + leds[1] <= 1; // LED 1 éteinte pour indiquer l'attente de transmission + end + endcase + end + +endmodule diff --git a/Semaine_4/UART_FIFO/src/verilog/uart_rx_fifo.v b/Semaine_4/UART_FIFO/src/verilog/uart_rx_fifo.v new file mode 100644 index 0000000..6723b5f --- /dev/null +++ b/Semaine_4/UART_FIFO/src/verilog/uart_rx_fifo.v @@ -0,0 +1,145 @@ +module uart_rx #( + parameter CLK_FREQ = 27_000_000, + parameter BAUD_RATE = 115200 +)( + input clk, //clock input + input rst_p, //asynchronous reset input, high active + input rx_enable, //data receiver module ready + input rx_pin, //serial data input + + output reg[7:0] rx_data, //received serial data + output reg rx_received //received serial data is valid +); + +localparam CYCLE = CLK_FREQ / BAUD_RATE; + +//state machine code +localparam S_IDLE = 1; +localparam S_START = 2; //start bit +localparam S_REC_BYTE = 3; //data bits +localparam S_STOP = 4; //stop bit +localparam S_DATA = 5; + +reg[2:0] state; +reg[2:0] next_state; + +reg rx_d0; //delay 1 clock for rx_pin +reg rx_d1; //delay 1 clock for rx_d0 +wire rx_negedge; //negedge of rx_pin +reg[7:0] rx_bits; //temporary storage of received data +reg[15:0] cycle_cnt; //baud counter +reg[2:0] bit_cnt; //bit counter + +assign rx_negedge = rx_d1 && ~rx_d0; // Front déscendant + +always@(posedge clk or posedge rst_p) // Filtrage du signial +begin + if(rst_p == 1'b1)begin + rx_d0 <= 1'b0; + rx_d1 <= 1'b0; + + end else begin + rx_d0 <= rx_pin; + rx_d1 <= rx_d0; + end +end + + +always@(posedge clk or posedge rst_p)begin // Compteur d'etat + if(rst_p == 1'b1) + state <= S_IDLE; + else + state <= next_state; +end + +always@(*)begin + case(state) + S_IDLE: + if(rx_negedge) // Detection du start bit + next_state = S_START; + else + next_state = S_IDLE; + + S_START: + if(cycle_cnt == CYCLE - 1) //one data cycle + next_state = S_REC_BYTE; + else + next_state = S_START; + + S_REC_BYTE: + if(cycle_cnt == CYCLE - 1 && bit_cnt == 3'd7) //receive 8bit data + next_state = S_STOP; + else + next_state = S_REC_BYTE; + + S_STOP: + if(cycle_cnt == CYCLE/2 - 1) //half bit cycle,to avoid missing the next byte receiver + next_state = S_DATA; + else + next_state = S_STOP; + + S_DATA: + if(rx_enable) //data receive complete + next_state = S_IDLE; + else + next_state = S_DATA; + + default: + next_state = S_IDLE; + endcase +end + +always@(posedge clk or posedge rst_p) +begin + if(rst_p == 1'b1) + rx_received <= 1'b0; + else if(state == S_STOP && next_state != state) + rx_received <= 1'b1; + else if(state == S_DATA && rx_enable) + rx_received <= 1'b0; +end + +always@(posedge clk or posedge rst_p) +begin + if(rst_p == 1'b1) + rx_data <= 8'd0; + else if(state == S_STOP && next_state != state) + rx_data <= rx_bits;//latch received data +end + +always@(posedge clk or posedge rst_p) +begin + if(rst_p == 1'b1) + begin + bit_cnt <= 3'd0; + end + else if(state == S_REC_BYTE) + if(cycle_cnt == CYCLE - 1) + bit_cnt <= bit_cnt + 3'd1; + else + bit_cnt <= bit_cnt; + else + bit_cnt <= 3'd0; +end + + +always@(posedge clk or posedge rst_p) +begin + if(rst_p == 1'b1) + cycle_cnt <= 16'd0; + else if((state == S_REC_BYTE && cycle_cnt == CYCLE - 1) || next_state != state) + cycle_cnt <= 16'd0; + else + cycle_cnt <= cycle_cnt + 16'd1; +end +//receive serial data bit data +always@(posedge clk or posedge rst_p) +begin + if(rst_p == 1'b1) + rx_bits <= 8'd0; + else if(state == S_REC_BYTE && cycle_cnt == CYCLE/2 - 1) + rx_bits[bit_cnt] <= rx_pin; + else + rx_bits <= rx_bits; +end +endmodule \ No newline at end of file diff --git a/Semaine_4/UART_FIFO/src/verilog/uart_tx_fifo.v b/Semaine_4/UART_FIFO/src/verilog/uart_tx_fifo.v new file mode 100644 index 0000000..cbc9505 --- /dev/null +++ b/Semaine_4/UART_FIFO/src/verilog/uart_tx_fifo.v @@ -0,0 +1,131 @@ +module uart_tx #( + parameter CLK_FREQ = 27_000_000, + parameter BAUD_RATE = 115200 +)( + input wire clk, + input wire rst_p, + input wire[7:0] data, + input wire tx_enable, + + output reg tx_ready, + output wire tx +); + + localparam CYCLE = CLK_FREQ / BAUD_RATE; + + localparam IDLE = 2'd0; + localparam START = 2'd1; + localparam DATA = 2'd2; + localparam STOP = 2'd3; + + reg [1:0] state = IDLE; + reg [1:0] next_state; + reg [15:0] cycle_cnt; //baud counter + reg tx_reg; + reg [2:0] bit_cnt; + reg [7:0] tx_data_latch = 0; + + + assign tx = tx_reg; + + always@(posedge clk or posedge rst_p)begin // Avance d'etat + if(rst_p == 1'b1) + state <= IDLE; + else + state <= next_state; + end + + always@(*) begin + case(state) + IDLE: + if(tx_enable == 1'b1) + next_state = START; + else + next_state = IDLE; + + START: + if(cycle_cnt == CYCLE - 1) + next_state = DATA; + else + next_state = START; + + DATA: + if(cycle_cnt == CYCLE - 1 && bit_cnt == 3'd7) + next_state = STOP; + else + next_state = DATA; + + STOP: + if(cycle_cnt == CYCLE - 1) + next_state = IDLE; + else + next_state = STOP; + default: + next_state = IDLE; + endcase + end + + always@(posedge clk or posedge rst_p)begin // tx_ready block + if(rst_p == 1'b1) + tx_ready <= 1'b0; // Reset + else if(state == IDLE && tx_enable == 1'b1) + tx_ready <= 1'b0; // Pas prêt tant que les données sont valides + else if(state == IDLE) + tx_ready <= 1'b1; + else if(state == STOP && cycle_cnt == CYCLE - 1) + tx_ready <= 1'b1; // Prêt une fois le bit STOP envoyé + else + tx_ready <= tx_ready; // Reste inchangé dans d'autres cas + end + + + + always@(posedge clk or posedge rst_p) begin // tx_data_latch block + if(rst_p == 1'b1) begin + tx_data_latch <= 8'd0; + end else if(state == IDLE && tx_enable == 1'b1) begin + tx_data_latch <= data; // Charger les données de `data` dans `tx_data_latch` + end + end + + + always@(posedge clk or posedge rst_p)begin // DATA bit_cnt block + if(rst_p == 1'b1)begin + bit_cnt <= 3'd0; + + end else if(state == DATA) + if(cycle_cnt == CYCLE - 1) + bit_cnt <= bit_cnt + 3'd1; + else + bit_cnt <= bit_cnt; + else + bit_cnt <= 3'd0; + end + + + always@(posedge clk or posedge rst_p)begin // Cycle counter + if(rst_p == 1'b1) + cycle_cnt <= 16'd0; + + else if((state == DATA && cycle_cnt == CYCLE - 1) || next_state != state) + cycle_cnt <= 16'd0; + else + cycle_cnt <= cycle_cnt + 16'd1; + end + + always@(posedge clk or posedge rst_p)begin // tx state managment + if(rst_p == 1'b1) + tx_reg <= 1'b1; + else + case(state) + IDLE,STOP: + tx_reg <= 1'b1; + START: + tx_reg <= 1'b0; + DATA: + tx_reg <= tx_data_latch[bit_cnt]; // SENDING BYTE HERE + default: + tx_reg <= 1'b1; + endcase + end +endmodule diff --git a/Semaine_4/UART_FIFO/tests/Python/uart_loopback_test.py b/Semaine_4/UART_FIFO/tests/Python/uart_loopback_test.py new file mode 100644 index 0000000..ca96240 --- /dev/null +++ b/Semaine_4/UART_FIFO/tests/Python/uart_loopback_test.py @@ -0,0 +1,43 @@ +import serial +import time + +# À adapter selon ton système +PORT = 'COM7' # ex: COM3 sur Windows ou /dev/ttyUSB0 sur Linux +BAUDRATE = 115200 +TIMEOUT = 3 # en secondes + +def main(): + try: + with serial.Serial(PORT, BAUDRATE, timeout=TIMEOUT) as ser: + print(f"[INFO] Connecté à {PORT} à {BAUDRATE} bauds.") + print("Tape un nombre entre 0 et 255. Ctrl+C pour quitter.\n") + + while True: + user_input = input("Nombre à envoyer (0-255) : ") + + if not user_input.isdigit(): + print("⚠️ Entrée invalide. Tape un entier entre 0 et 255.") + continue + + value = int(user_input) + if value < 0 or value >= 255: + print("⚠️ Valeur hors limites.") + continue + + byte = bytes([value]) + ser.write(byte) + print(f"[TX] Envoyé : {value} (0x{value:02X})") + + time.sleep(0.01) # petite pause si nécessaire + + rx = ser.read(1) + if rx: + print(f"[RX] Reçu : {int.from_bytes(rx, 'little')} (0x{rx.hex()})\n") + else: + print("⚠️ Aucun octet reçu (timeout ?)\n") + + except serial.SerialException as e: + print(f"[ERREUR] Port série : {e}") + +if __name__ == "__main__": + main() diff --git a/Semaine_4/UART_FIFO/tests/verilog/tb_uart_fifo.v b/Semaine_4/UART_FIFO/tests/verilog/tb_uart_fifo.v new file mode 100644 index 0000000..0788abc --- /dev/null +++ b/Semaine_4/UART_FIFO/tests/verilog/tb_uart_fifo.v @@ -0,0 +1,84 @@ +`timescale 1ns/1ps + +module tb_uart; + + reg clk = 0; + reg tx_enable = 0; + reg tx_ready; + reg [7:0] data_in = 8'h00; + reg [7:0] data_out; + + reg rx_received; + wire rx_enable = 1'b1; + + wire pin; + + always #18.5 clk = ~clk; + + localparam CLK_FREQ = 27_000_000; + localparam BAUD_RATE = 115_200; + + uart_rx #( + .CLK_FREQ(CLK_FREQ), + .BAUD_RATE(BAUD_RATE) + ) rx_instance ( + .clk(clk), + .rx_pin(pin), + .rx_data(data_out), + .rx_received(rx_received), + .rx_enable(rx_enable) + ); + + uart_tx #( + .CLK_FREQ(CLK_FREQ), + .BAUD_RATE(BAUD_RATE) + )tx_instance ( + .clk(clk), + .tx_enable(tx_enable), + .tx_ready(tx_ready), + .data(data_in), + .tx(pin), + .rst_p(1'b0) + ); + + initial begin + $dumpfile("runs/uart.vcd"); + $dumpvars(0, tb_uart); + + $display("======== Start UART LOOPBACK test ========="); + + #100; + + data_in <= 8'd234; // 234 + tx_enable <= 1; + wait(tx_ready == 1'b0); + tx_enable <= 0; + + // Attendre + wait (rx_received == 1'b1); // Attendre que le signal de reception soit actif + + $display("Data received: %d", data_out); // Afficher la valeur recu + $display("Data expected: %d", data_in); // Afficher la valeur envoyee + + #1000; + + wait(tx_ready == 1'b1); // Attendre que le signal de reception soit actif + + data_in <= 8'd202; // 202 + tx_enable <= 1; + wait(tx_ready == 1'b0); + tx_enable <= 0; + + // Attendre + wait (rx_received == 1'b1); // Attendre que le signal de reception soit actif + + $display("Data received: %d", data_out); // Afficher la valeur recu + $display("Data expected: %d", data_in); // Afficher la valeur envoyee + + $display("======== END UART TX test ========="); + + #1000; + $stop; + end + +endmodule \ No newline at end of file diff --git a/Semaine_4/UART_FIFO/tests/verilog/tb_uart_rx_fifo.v b/Semaine_4/UART_FIFO/tests/verilog/tb_uart_rx_fifo.v new file mode 100644 index 0000000..2fce3dc --- /dev/null +++ b/Semaine_4/UART_FIFO/tests/verilog/tb_uart_rx_fifo.v @@ -0,0 +1,67 @@ +`timescale 1ns / 1ps + +module tb_uart_rx; + + reg clk = 0; + reg rx; + reg [7:0] data_in; + reg [7:0] data_out; + + reg tx_data_valid; + reg tx_data_ready; + + reg rx_received; + wire rx_enable = 1'b1; // Enable the receiver + + localparam CLK_FREQ = 27_000_000; + localparam BAUD_RATE = 115_200; + localparam BIT_PERIOD = CLK_FREQ / BAUD_RATE; + localparam CLK_PERIOD_NS = 1000000000 / CLK_FREQ; + + other_uart_tx tx_instance ( + .clk(clk), + .tx_pin(rx), + .tx_data(data_in), + .tx_data_valid(tx_data_valid), + .tx_data_ready(tx_data_ready), + .rst_n(1'b1) + ); + + uart_rx #( + .CLK_FREQ(CLK_FREQ), + .BAUD_RATE(BAUD_RATE) + ) rx_instance ( + .clk(clk), + .rx_pin(rx), + .rx_data(data_out), + .rx_received(rx_received), + .rx_enable(rx_enable) + ); + + always #(CLK_PERIOD_NS/2) clk = ~clk; + + initial begin + $dumpfile("runs/uart_rx.vcd"); + $dumpvars(0, tb_uart_rx); + $display("======== Start UART RX test ========="); + #100; + + data_in = 8'd123; // Data to send + wait(tx_data_ready); // Wait for the transmitter to be ready + #1; // Small delay to ensure the data is latched + + tx_data_valid = 1'b1; // Indicate that the data is valid + + wait(tx_data_ready == 0); + + tx_data_valid = 1'b0; // Clear the valid signal + + wait(rx_received); // Wait for the receiver to receive the data + + $display("Data sent: %d", data_in); + $display("Data received: %d", data_out); // Display the received data + + $display("======== END UART RX test ========="); + $finish; + end +endmodule diff --git a/Semaine_4/UART_FIFO/tests/verilog/tb_uart_tx_fifo.v b/Semaine_4/UART_FIFO/tests/verilog/tb_uart_tx_fifo.v new file mode 100644 index 0000000..85921f2 --- /dev/null +++ b/Semaine_4/UART_FIFO/tests/verilog/tb_uart_tx_fifo.v @@ -0,0 +1,77 @@ +`timescale 1ns/1ps + +module tb_uart_tx; + + reg clk = 0; + reg tx_enable = 0; + reg [7:0] data_in = 8'h00; + reg [7:0] data_out; + wire tx; + reg tx_ready; + + wire rx_recieved; + + always #18.5 clk = ~clk; + + other_uart_rx rx_instance( + .clk(clk), + .rx_pin(tx), // tx is connected to rx for testing + .rst_n(1'b1), + .rx_data(data_out), + .rx_data_valid(rx_recieved), + .rx_data_ready(1'b1) + ); + + uart_tx #( + .CLK_FREQ(27_000_000), + .BAUD_RATE(115_200) + )tx_instance ( + .clk(clk), + .tx_enable(tx_enable), + .tx_ready(tx_ready), + .data(data_in), + .tx(tx), + .rst_p(1'b0) + ); + + initial begin + $dumpfile("runs/uart_tx.vcd"); + $dumpvars(0, tb_uart_tx); + + $display("======== Start UART TX test ========="); + + #100; + + data_in <= 8'd234; // 234 + tx_enable <= 1; + wait(tx_ready == 1'b0); + tx_enable <= 0; + + // Attendre + wait (rx_recieved == 1'b1); // Attendre que le signal de reception soit actif + + $display("Data received: %d", data_out); // Afficher la valeur recu + $display("Data expected: %d", data_in); // Afficher la valeur envoyee + + #1000; + + wait(tx_ready == 1'b1); // Attendre que le signal de reception soit actif + + data_in <= 8'd202; // 202 + tx_enable <= 1; + wait(tx_ready == 1'b0); + tx_enable <= 0; + + // Attendre + wait (rx_recieved == 1'b1); // Attendre que le signal de reception soit actif + + $display("Data received: %d", data_out); // Afficher la valeur recu + $display("Data expected: %d", data_in); // Afficher la valeur envoyee + + $display("======== END UART TX test ========="); + + #1000; + $stop; + end + +endmodule \ No newline at end of file