1
0
forked from tanchou/Verilog

Init et début de réflexion sur le projet

This commit is contained in:
Gamenight77
2025-04-22 09:56:06 +02:00
parent 39acfbe25b
commit 3bb56e2f57
48 changed files with 21 additions and 0 deletions

BIN
Semaine_1/UART/memo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -0,0 +1,69 @@
`timescale 1ns / 1ps
module tb_top_uart_rx_tx;
parameter CLK_FREQ = 27_000_000;
parameter BAUD_RATE = 115200;
// Signaux
reg clk = 0;
reg start = 0;
reg [7:0] data_in = 0;
wire [7:0] data_out;
wire valid;
wire tx;
wire rx; // On connecte tx directement à rx pour le test
// Instance du module à tester
top_uart_rx_tx #(
.CLK_FREQ(CLK_FREQ),
.BAUD_RATE(BAUD_RATE)
) uut (
.clk(clk),
.start(start),
.data_in(data_in),
.rx(rx),
.data_out(data_out),
.valid(valid),
.tx(tx)
);
// Boucle le tx sur rx
assign rx = tx;
// Clock à 50 MHz (20 ns période)
always #10 clk = ~clk;
// Simulation principale
initial begin
$display("Début de la simulation");
$dumpfile("uart_loopback.vcd"); // Pour GTKWave
$dumpvars(0, tb_top_uart_rx_tx);
// Attendre un peu
#(20 * 10);
// Envoi d'une valeur
data_in = 8'hA5; // Exemple de data
start = 1;
#20;
start = 0;
// Attendre la réception (valeur valid = 1)
wait(valid == 1);
// Affichage des résultats
$display("Data envoyee : 0x%h", data_in);
$display("Data recue : 0x%h", data_out);
if (data_out == data_in)
$display("Test reussi !");
else
$display("Test echoue...");
// Fin de simulation
#(20 * 10);
$finish;
end
endmodule

View File

@@ -0,0 +1,64 @@
`timescale 1ns / 1ps
module tb_uart_rx;
reg clk = 0;
reg rx = 1;
wire [7:0] data;
wire valid;
wire ready;
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;
uart_rx #(
.CLK_FREQ(CLK_FREQ),
.BAUD_RATE(BAUD_RATE)
) rx_instance (
.clk(clk),
.rx(rx),
.data(data),
.valid(valid),
.ready(ready)
);
always #(CLK_PERIOD_NS/2) clk = ~clk;
task send_bit(input reg b);
begin
rx <= b;
#(BIT_PERIOD * CLK_PERIOD_NS);
end
endtask
integer i;
task send_byte(input [7:0] byte);
begin
send_bit(0);
for (i = 0; i < 8; i = i + 1)
send_bit(byte[i]);
send_bit(1);
#(BIT_PERIOD * CLK_PERIOD_NS);
end
endtask
initial begin
$display("Start UART RX test");
#100;
send_byte(8'b01010101);
#(10 * BIT_PERIOD * CLK_PERIOD_NS);
if (valid && data == 8'b01010101)
$display("Test ok : data = %b", data);
else
$display("Test pas ok : data = %b, valid = %b", data, valid);
$finish;
end
endmodule

View File

@@ -0,0 +1,49 @@
`timescale 1ns/1ps
module tb_uart_tx;
reg clk = 0;
reg start = 0;
reg [7:0] data = 8'h00;
wire tx;
wire busy;
always #18.5 clk = ~clk;
uart_tx #(
.CLK_FREQ(27_000_000),
.BAUD_RATE(115_200)
)tx_instance (
.clk(clk),
.start(start),
.data(data),
.tx(tx),
.busy(busy)
);
initial begin
$dumpfile("uart_tx.vcd");
$dumpvars(0, tb_uart_tx);
#100;
data <= 8'hA5; // 10100101 0xA5
start <= 1;
#37 start <= 0;
// Attendre
wait (busy == 0);
#1000;
data <= 8'h3C; // 00111100 0x3C
start <= 1;
#37 start <= 0;
wait (busy == 0);
#1000;
$stop;
end
endmodule

View File

@@ -0,0 +1,61 @@
module top_led_uart(
input wire clk,
input wire rx,
output wire tx,
output reg [5:0] leds
);
wire [7:0] data_out;
wire valid;
reg start_tx = 0;
reg [7:0] data_in = 0;
top_uart_rx_tx uart (
.clk(clk),
.start(start_tx),
.data_in(data_in),
.rx(rx),
.data_out(data_out),
.valid(valid),
.tx(tx)
);
reg [1:0] state = 0;
localparam IDLE = 2'd0;
localparam TOGGLE = 2'd1;
localparam SEND_BACK = 2'd2;
always @(posedge clk) begin
case (state)
INIT: begin
leds <= 6'b000000;
start_tx <= 0;
if (valid) begin
leds <= data_out[5:0];
state <= SEND_BACK;
end
end
IDLE: begin
start_tx <= 0;
if (valid) begin
leds <= data_out[5:0];
state <= SEND_BACK;
end
end
SEND_BACK: begin
data_in <= data_out;
start_tx <= 1;
state <= TOGGLE;
end
TOGGLE: begin
start_tx <= 0;
state <= IDLE;
end
endcase
end
endmodule

View File

@@ -0,0 +1,34 @@
module top_uart_rx_tx(
input wire clk,
input wire start, // Commencer l'ecriture
input wire [7:0] data_in,
input wire rx,
output wire [7:0] data_out,
output wire valid, // Si 1 alors on peut lire
output wire tx
);
parameter CLK_FREQ = 27_000_000;
parameter BAUD_RATE = 115_200;
uart_tx #(
.CLK_FREQ(CLK_FREQ),
.BAUD_RATE(BAUD_RATE)
) tx_instance (
.clk(clk),
.start(start),
.data(data_in),
.tx(tx)
);
uart_rx #(
.CLK_FREQ(CLK_FREQ),
.BAUD_RATE(BAUD_RATE)
) rx_instance (
.clk(clk),
.rx(rx),
.data(data_out),
.valid(valid)
);
endmodule

72
Semaine_1/UART/uart_rx.v Normal file
View File

@@ -0,0 +1,72 @@
module uart_rx (
input wire clk,
input wire rx, // signal reçues
output reg [7:0] data, // Données decoder
output reg valid = 0, // Indicateur de données valides
output reg ready = 1 // Indicateur de réception prête
);
parameter CLK_FREQ = 27_000_000;
parameter BAUD_RATE = 115_200;
localparam BIT_PERIOD = CLK_FREQ / BAUD_RATE;
localparam IDLE = 2'b00;
localparam START = 2'b01;
localparam DATA = 2'b10;
localparam STOP = 2'b11;
reg [1:0] state = IDLE;
reg [3:0] bit_index;
reg [15:0] clk_count;
reg [7:0] rx_data = 0;
always @(posedge clk) begin
case (state)
IDLE: begin
ready <= 1;
if (!rx) begin // start bit (0)
state <= START;
clk_count <= 0;
bit_index <= 0;
valid <= 0;
ready <= 0;
end
end
START: begin
if (clk_count < (BIT_PERIOD / 2) - 1) begin // Attendre juste 0.5 bit
clk_count <= clk_count + 1;
end else begin
clk_count <= 0;
state <= DATA;
end
end
DATA: begin
if (clk_count < BIT_PERIOD - 1) begin
clk_count <= clk_count + 1;
end else begin
clk_count <= 0;
rx_data[bit_index] <= rx; // Recevoir les données (8 bits)
bit_index <= bit_index + 1;
if (bit_index == 7) begin
state <= STOP; // Passer à l'état d'arrêt
end
end
end
STOP: begin
if (clk_count < BIT_PERIOD - 1) begin
clk_count <= clk_count + 1;
end else begin
state <= IDLE;
data <= rx_data;
valid <= 1;
ready <= 1;
end
end
endcase
end
endmodule

74
Semaine_1/UART/uart_tx.v Normal file
View File

@@ -0,0 +1,74 @@
module uart_tx(
input wire clk,
input wire start,
input wire [7:0] data,
output reg tx = 1,
output reg busy = 0
);
parameter CLK_FREQ = 27_000_000;
parameter BAUD_RATE = 115_200;
localparam BIT_PERIOD = CLK_FREQ / BAUD_RATE;
localparam IDLE = 2'b00;
localparam START = 2'b01;
localparam DATA = 2'b10;
localparam STOP = 2'b11;
reg [1:0] state = IDLE;
reg [3:0] bit_index = 0;
reg [15:0] clk_count = 0;
reg [7:0] tx_data = 0;
always @(posedge clk) begin
case(state)
IDLE: begin
tx <= 1;
if (start) begin
tx_data <= data;
bit_index <= 0;
clk_count <= 0;
busy <= 1;
state <= START;
end
end
START: begin
if (clk_count < BIT_PERIOD - 1) begin
clk_count <= clk_count + 1;
tx <= 0;
end else begin
state <= DATA;
clk_count <= 0;
end
end
DATA: begin
if (clk_count < BIT_PERIOD - 1) begin
clk_count <= clk_count + 1;
end else if (bit_index < 8) begin
tx <= tx_data[bit_index];
bit_index <= bit_index + 1;
clk_count <= 0;
end else begin
state <= STOP;
end
end
STOP: begin
tx <= 1;
if (clk_count < BIT_PERIOD - 1) begin
clk_count <= clk_count + 1;
end else begin
clk_count <= 0;
busy <= 0;
state <= IDLE;
end
end
endcase
end
endmodule

View File

@@ -0,0 +1,57 @@
module uart_tx(
input wire clk,
input wire start, // Signal de démarrage de la transmission
input wire [7:0] data, // Données à transmettre
output reg tx, // Sortie de transmission
output reg busy // Indicateur de transmission en cours
);
parameter CLK_FREQ = 27_000_000;
parameter BAUD_RATE = 115_200;
localparam BIT_PERIOD = CLK_FREQ / BAUD_RATE;
reg [3:0] bit_index;
reg [15:0] clk_count;
reg [7:0] tx_data = 0;
initial begin
tx = 1; // État idle (1)
busy = 0; // Pas de transmission en cours
end
always @(posedge clk) begin
if (start && !busy) begin
busy <= 1; // Démarrer la transmission
bit_index <= 0; // Réinitialiser l'index du bit
clk_count <= 0; // Réinitialiser le compteur d'horloge
tx_data <= data;
tx <= 1; // État idle (1)
end else if (busy) begin
if (clk_count < BIT_PERIOD - 1) begin
clk_count <= clk_count + 1;
end else begin
clk_count <= 0;
if (bit_index == 0) begin
tx <= 0; // Start bit (0)
end else if (bit_index < 9) begin
tx <= tx_data[bit_index - 1]; // Transmettre les données (8 bits)
end else if (bit_index == 9) begin
tx <= 1; // Stop bit (1)
end else begin
busy <= 0; // Fin de la transmission
end
bit_index <= bit_index + 1; // Passer au bit suivant
end
end else begin
tx <= 1; // État idle (1)
end
end
endmodule