uart_design_verilog
uart_design_verilog
always@(posedge i_clock)
begin
case(main)
IDLE:
begin
o_TX_serial <= 1'b1;
r_TX_done <= 1'b0;
r_clock_count <= 0;
r_bit_index <= 0;
if(i_TX_DV == 1'b1)
begin
r_TX_active <= 1'b1;
r_TX_data <= i_TX_byte;
main <= TX_START_BIT;
end
else
main <= IDLE;
end
TX_START_BIT:
begin
o_TX_serial <= 1'b0;
TX_DATA_BITS :
begin
o_TX_serial <= r_TX_data[r_bit_index];
if (r_bit_index < 7)
begin
r_bit_index <= r_bit_index+1;
main <= TX_DATA_BITS;
end
else
begin
r_bit_index <= 0;
main <= TX_STOP_BIT;
end
end
end
TX_STOP_BIT :
begin
o_TX_serial <= 1'b1;
CLEANUP :
begin
r_TX_done <= 1'b1;
main <= IDLE;
end
default :
main <= IDLE;
endcase
end
endmodule
//uart receiver
module uart_rx #(parameter clks_per_bit=217)
(input i_clock,
input i_RX_serial,
output o_RX_DV,
output [7:0] o_RX_byte);
always@(posedge i_clock)
begin
case(main)
IDLE :
begin
r_RX_DV <= 1'b0;
r_clock_count <= 0;
r_bit_index <= 0;
RX_START_BIT :
begin
if(r_clock_count == (clks_per_bit-1)/2) //to check middile of start
bit
begin
if(i_RX_serial == 1'b0)
begin
r_clock_count <= 0; // reset counter, found the middle
main <= RX_DATA_BITS;
end
else
main <= IDLE;
end
else
begin
r_clock_count <=r_clock_count+1;
main <= RX_START_BIT;
end
end
RX_DATA_BITS :
begin
if (r_clock_count < clks_per_bit-1)
begin
r_clock_count <= r_clock_count+1;
main <= RX_DATA_BITS;
end
else
begin
r_clock_count <= 0;
r_RX_byte[r_bit_index] <=i_RX_serial;
RX_STOP_BIT :
begin
if(r_clock_count < clks_per_bit-1) // wait clks_per_bit-1 clock
cycles for Stop bit to finish
begin
r_clock_count <= r_clock_count+1;
main <= RX_STOP_BIT;
end
else
begin
r_RX_DV <= 1'b1;
r_clock_count <= 0;
main <=CLEANUP;
end
end
CLEANUP :
begin
main <= IDLE;
r_RX_DV <=1'b0;
end
assign o_RX_DV=r_RX_DV;
assign o_RX_byte=r_RX_byte;
endmodule