Thursday, December 10, 2009

UART Verilog code with testbench

reference www.asic-world.com
module uart2 (
reset ,
txclk ,
ld_tx_data ,
tx_data ,
tx_enable ,
tx_out ,
tx_empty ,
rxclk ,
uld_rx_data ,
rx_data ,
rx_enable ,
rx_in ,
rx_empty
);
// Port declarations
input reset ;
input txclk ;
input ld_tx_data ;
input [7:0] tx_data ;
input tx_enable ;
output tx_out ;
output tx_empty ;
input rxclk ;
input uld_rx_data ;
output [7:0] rx_data ;
input rx_enable ;
input rx_in ;
output rx_empty ;
wire rx_in;

assign rx_in=tx_out ; // connect receiver to transmitter interconnect
assign uld_rx_data=~rx_empty; // unload data when rx buffer is full
// Internal Variables
reg [7:0] tx_reg ;
reg tx_empty ;
reg tx_over_run ;
reg [3:0] tx_cnt ;
reg tx_out ;
reg [7:0] rx_reg ;
reg [7:0] rx_data ;
reg [3:0] rx_sample_cnt ;
reg [3:0] rx_cnt ;
reg rx_frame_err ;
reg rx_over_run ;
reg rx_empty ;
reg rx_d1 ;
reg rx_d2 ;
reg rx_busy ;

// UART RX Logic
always @ (posedge rxclk or posedge reset)
if (reset) begin
rx_reg <= 0;
rx_data <= 0;
rx_sample_cnt <= 0;
rx_cnt <= 0;
rx_frame_err <= 0;
rx_over_run <= 0;
rx_empty <= 1;
rx_d1 <= 1;
rx_d2 <= 1;
rx_busy <= 0;
end else begin
// Synchronize the asynch signal
rx_d1 <= rx_in;
rx_d2 <= rx_d1;
// Uload the rx data
if (uld_rx_data) begin
rx_data <= rx_reg;
rx_empty <= 1;
end
// Receive data only when rx is enabled
if (rx_enable) begin
// Check if just received start of frame
if (!rx_busy && !rx_d2) begin
rx_busy <= 1;
rx_sample_cnt <= 1;
rx_cnt <= 0;
end
// Start of frame detected, Proceed with rest of data
if (rx_busy) begin
rx_sample_cnt <= rx_sample_cnt + 1;
// Logic to sample at middle of data
if (rx_sample_cnt == 7) begin
if ((rx_d2 == 1) && (rx_cnt == 0)) begin
rx_busy <= 0;
end else begin
rx_cnt <= rx_cnt + 1;
// Start storing the rx data
if (rx_cnt > 0 && rx_cnt < 9) begin
rx_reg[rx_cnt - 1] <= rx_d2;
end
if (rx_cnt == 9) begin
rx_busy <= 0;
// Check if End of frame received correctly
if (rx_d2 == 0) begin
rx_frame_err <= 1;
end else begin
rx_empty <= 0;
rx_frame_err <= 0;
// Check if last rx data was not unloaded,
rx_over_run <= (rx_empty) ? 0 : 1;
end
end
end
end
end
end
if (!rx_enable) begin
rx_busy <= 0;
end
end

// UART TX Logic
always @ (posedge txclk or posedge reset)
if (reset) begin
tx_reg <= 0;
tx_empty <= 1;
tx_over_run <= 0;
tx_out <= 1;
tx_cnt <= 0;
end else begin
if (ld_tx_data) begin
if (!tx_empty) begin
tx_over_run <= 0;
end else begin
tx_reg <= tx_data;
tx_empty <= 0;
end
end
if (tx_enable && !tx_empty) begin
tx_cnt <= tx_cnt + 1;
if (tx_cnt == 0) begin
tx_out <= 0;
end
if (tx_cnt > 0 && tx_cnt < 9) begin
tx_out <= tx_reg[tx_cnt -1];
end
if (tx_cnt == 9) begin
tx_out <= 1;
tx_cnt <= 0;
tx_empty <= 1;
end
end
if (!tx_enable) begin
tx_cnt <= 0;
end
end

endmodule
downloadclick

test bench for the above
module uartcontroller(data,load,unload,rxen,txem,rxem,txen,reset,rxin,txout,clkL,clkH);
inout [7:0]data;
output load;
output clkL,clkH;
output unload;
output rxen;
output txen;
output reset;
input txem,rxem;
reg txemt;
reg rxemt;
output txout;
input rxin;
reg clkL,clkH;
wire rxen,txen;
reg reset;
wire [2:0]sel;
wire [7:0]datain,dataout;
uart m1(
.reset(reset) ,
.txclk(clkH) ,
.ld_tx_data(load) ,
.tx_data(datain) ,
.tx_enable(txen) ,
.tx_out(txout) ,
.tx_empty(txem) ,
.rxclk(clkL) ,
.uld_rx_data(unload) ,
.rx_data(dataout) ,
.rx_enable(rxen) ,
.rx_in(rxin) ,
.rx_empty(rxem)
);
assign rxin=txout;
assign sel[0]=load;
assign sel[1]=unload;
bidirectionalbuffer m2(.A(data),.B(datain),.C(dataout),.sel(sel)); // using same data lines for loading data into tx register and reading data from rx buffer
initial begin
clkL<=1'b0;
clkH<=1'b0;
reset<=1;
#10 reset <=0;
end
// clock generation
always
#10 clkL<=~clkL; // clock for rx

always
#160 clkH<=~clkH; // clock for tx
endmodule




happy coding

15 comments:

  1. I tried to run your code and it's not working! the bidirectionalbuffer m2 is missing?

    Do you have this coded?

    Thanks

    ReplyDelete
  2. can u copy paste the error ...... i didnt face any problems .......
    Nataraja

    ReplyDelete
  3. ERROR:Xst:871 - "uartest.v" line 53: Invalid use of input signal as target.
    ERROR:Xst:871 - "uartest.v" line 54: Invalid use of input signal as target.

    when synthesing the above code.
    my id :kundenaravikiran@gmail.com

    ReplyDelete
  4. bidirectional buffer is @ http://miniprojects-be-btech.blogspot.com/2009/12/verilog-codes.html

    ReplyDelete
  5. Hello Sir,

    I am doing a project on UART with BIST implementation. I need a code for UART which should contain all the registers like status, parity, data etc and baud rate generators. Can you please provide this or gimme some suggestions.

    Thank You

    ReplyDelete
  6. what about bidirectional module ...? its not simulating

    ReplyDelete
  7. error: ** Error: (vsim-3033) C:/Documents and Settings/user/Desktop/ajay/uart_new/stimulus/my_uart_tb.v(39): Instantiation of 'bidirectionalbuffer' failed. The design unit was not found.

    ReplyDelete
  8. ya i got bidirectionalbuffer link...

    ReplyDelete
  9. sir i tried this code no errors but output is not coming as u showed .where we are giving data 10101010 as input in testbench or directly forcing while running?. i am developing a UVM environment for uart so i am taking this rtl code as my dut and i am trying but it is not working propely and will you please tell me the exact spec for this code

    ReplyDelete
  10. The lines before initializing internal ports i.e., assign rx_in = tx_out and next line are showing as errors. Please help me out to overcome those errors!

    ReplyDelete
  11. this code doesn't contain "baud rate" generate , so it's should not be work.

    ReplyDelete
  12. sir
    hey
    how to enter values in testbench for this module.may u provide us??please need urgent my email: sunny.k003.sk@gmail.com

    ReplyDelete
    Replies
    1. sir have you got how to enter values in testbench?

      Delete
  13. how to give input 10101010 as there is in the screenshot...my wave is different with input xxxxxxxx how togive input?

    ReplyDelete