forked from tanchou/Verilog
Init et début de réflexion sur le projet
This commit is contained in:
BIN
Semaine_1/UART/memo.png
Normal file
BIN
Semaine_1/UART/memo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
69
Semaine_1/UART/tb_top_uart_rx_tx.v
Normal file
69
Semaine_1/UART/tb_top_uart_rx_tx.v
Normal 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
|
64
Semaine_1/UART/tb_uart_rx.v
Normal file
64
Semaine_1/UART/tb_uart_rx.v
Normal 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
|
49
Semaine_1/UART/tb_uart_tx.v
Normal file
49
Semaine_1/UART/tb_uart_tx.v
Normal 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
|
61
Semaine_1/UART/top_led_uart.v
Normal file
61
Semaine_1/UART/top_led_uart.v
Normal 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
|
34
Semaine_1/UART/top_uart_rx_tx.v
Normal file
34
Semaine_1/UART/top_uart_rx_tx.v
Normal 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
72
Semaine_1/UART/uart_rx.v
Normal 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
74
Semaine_1/UART/uart_tx.v
Normal 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
|
57
Semaine_1/UART/uart_tx_old.v
Normal file
57
Semaine_1/UART/uart_tx_old.v
Normal 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
|
Reference in New Issue
Block a user