forked from tanchou/Verilog
uart v3
This commit is contained in:
131
Semaine_3/UARTV3/uart_tx.v
Normal file
131
Semaine_3/UARTV3/uart_tx.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_data_valid,
|
||||
|
||||
output wire tx,
|
||||
output reg tx_data_ready
|
||||
);
|
||||
|
||||
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_data_valid == 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_data_ready block
|
||||
if(rst_p == 1'b1)
|
||||
tx_data_ready <= 1'b0; // Reset
|
||||
else if(state == IDLE && tx_data_valid == 1'b1)
|
||||
tx_data_ready <= 1'b0; // Pas prêt tant que les données sont valides
|
||||
else if(state == IDLE)
|
||||
tx_data_ready <= 1'b1;
|
||||
else if(state == STOP && cycle_cnt == CYCLE - 1)
|
||||
tx_data_ready <= 1'b1; // Prêt une fois le bit STOP envoyé
|
||||
else
|
||||
tx_data_ready <= tx_data_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_data_valid == 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
|
Reference in New Issue
Block a user