forked from tanchou/Verilog
Création de la structure du uart fifo
This commit is contained in:
3
Semaine_4/UART/README.md
Normal file
3
Semaine_4/UART/README.md
Normal file
@@ -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.
|
@@ -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,30 +36,49 @@ 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
|
||||
|
@@ -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
|
||||
|
||||
|
4
Semaine_4/UART_FIFO/.gitignore
vendored
Normal file
4
Semaine_4/UART_FIFO/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
runs
|
||||
.vscode
|
||||
workspace.code-workspace
|
||||
*.pyc
|
19
Semaine_4/UART_FIFO/constraints/top_uart_loopback.cst
Normal file
19
Semaine_4/UART_FIFO/constraints/top_uart_loopback.cst
Normal file
@@ -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;
|
6
Semaine_4/UART_FIFO/project.bat
Normal file
6
Semaine_4/UART_FIFO/project.bat
Normal file
@@ -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
|
45
Semaine_4/UART_FIFO/scripts/build.bat
Normal file
45
Semaine_4/UART_FIFO/scripts/build.bat
Normal file
@@ -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
|
4
Semaine_4/UART_FIFO/scripts/clean.bat
Normal file
4
Semaine_4/UART_FIFO/scripts/clean.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
echo === Nettoyage du dossier runs ===
|
||||
rd /s /q runs
|
||||
mkdir runs
|
3
Semaine_4/UART_FIFO/scripts/gtkwave.bat
Normal file
3
Semaine_4/UART_FIFO/scripts/gtkwave.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
echo === Lancement de GTKWave ===
|
||||
gtkwave runs/uart.vcd
|
29
Semaine_4/UART_FIFO/scripts/simulate.bat
Normal file
29
Semaine_4/UART_FIFO/scripts/simulate.bat
Normal file
@@ -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
|
67
Semaine_4/UART_FIFO/src/verilog/top_uart_loopback_fifo.v
Normal file
67
Semaine_4/UART_FIFO/src/verilog/top_uart_loopback_fifo.v
Normal file
@@ -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
|
145
Semaine_4/UART_FIFO/src/verilog/uart_rx_fifo.v
Normal file
145
Semaine_4/UART_FIFO/src/verilog/uart_rx_fifo.v
Normal file
@@ -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
|
131
Semaine_4/UART_FIFO/src/verilog/uart_tx_fifo.v
Normal file
131
Semaine_4/UART_FIFO/src/verilog/uart_tx_fifo.v
Normal file
@@ -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
|
43
Semaine_4/UART_FIFO/tests/Python/uart_loopback_test.py
Normal file
43
Semaine_4/UART_FIFO/tests/Python/uart_loopback_test.py
Normal file
@@ -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()
|
84
Semaine_4/UART_FIFO/tests/verilog/tb_uart_fifo.v
Normal file
84
Semaine_4/UART_FIFO/tests/verilog/tb_uart_fifo.v
Normal file
@@ -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
|
67
Semaine_4/UART_FIFO/tests/verilog/tb_uart_rx_fifo.v
Normal file
67
Semaine_4/UART_FIFO/tests/verilog/tb_uart_rx_fifo.v
Normal file
@@ -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
|
77
Semaine_4/UART_FIFO/tests/verilog/tb_uart_tx_fifo.v
Normal file
77
Semaine_4/UART_FIFO/tests/verilog/tb_uart_tx_fifo.v
Normal file
@@ -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
|
Reference in New Issue
Block a user