RS232 testbench

Thread Starter

domino89

Joined Sep 24, 2013
22
I have wierd problem with RS232 implementation it works on board but dunno whats wrong with testbench it just doesnt work. Could somone take a look on this testbench code...
Rich (BB code):
`timescale 1ns

module testbench;

	// Inputs
	reg RXD_i;
	reg clk_i;

	// Outputs
	wire TXD_o;

	// Instantiate the Unit Under Test (UUT)
	main uut (
		.RXD_i(RXD_i), 
		.clk_i(clk_i), 
		.TXD_o(TXD_o)
	);

	initial 
	begin
		// Initialize Inputs
	clk_i=0;
	RXD_i=1'b1;

	#100 RXD_i=0;
	#10 RXD_i=0;
	#10 RXD_i=1;
	#10 RXD_i=0;
	#10 RXD_i=1;
	#10 RXD_i=1;
	#10 RXD_i=1;
	#10 RXD_i=0;
	#10 RXD_i=1;
	#10 RXD_i=0;
		end

		always
		#5 clk_i =~clk_i;      
endmodule
And I get on TxD_o "1" for whole simulation
 

Brownout

Joined Jan 10, 2012
2,390
Since I don't know how the UUT is coded, I cannot verify your expected results. If it use a UART, you need to write something to the TX buffer.
 

Thread Starter

domino89

Joined Sep 24, 2013
22
This rs232 code which i was testing. This version transmitts what it receives. Parameter N is reduced for testbench purpose. As a said before wierd thing is that it works on board with hyperterminal, but i struggle with this testbench
Rich (BB code):
********************************
*******MAIN MODULE***************
********************************
`timescale 1ns / 1ps

module main (RXD_i, clk_i, TXD_o
    );

input RXD_i, clk_i;
output TXD_o;
wire [9:0]receive;

receiver A(RXD_i, receive, clk_i, save);
transmitter B(TXD_o, receive, clk_i, save);

endmodule

********************************
*******RECEIVER MODULE***********
********************************

`timescale 1ns / 1ps

module receiver (RXD_i, receive, clk_i, save);

input RXD_i, clk_i;
output reg [9:0]receive, save=0;
integer div1=0, bits_counter1=0, start1=0;
reg [9:0]send;
parameter N = 2; //5208

always @(posedge clk_i)
begin
save=0;
if(start1==0)
begin 
	receive[0]=1'b1;
	receive[1]=1'b1;
	receive[2]=1'b1;
	receive[3]=1'b1;
	receive[4]=1'b1;
	receive[5]=1'b1;
	receive[6]=1'b1;
	receive[7]=1'b1;
	receive[8]=1'b1;
	receive[9]=1'b1;
	end
	
if(RXD_i==1'b0 && start1==0)
start1=1;

if(start1==1)
begin	
	if(div1==N)
	div1=0;
	else if(div1==N/2)
	begin
	div1=div1+1;
	bits_counter1=bits_counter1+1;
	case(bits_counter1)
	0	:	receive[0]=RXD_i;
	1	:	receive[1]=RXD_i;
	2	:	receive[2]=RXD_i;
	3	:	receive[3]=RXD_i;
	4	:	receive[4]=RXD_i;
	5	:	receive[5]=RXD_i;
	6	:	receive[6]=RXD_i;
	7	:	receive[7]=RXD_i;
	8	:	receive[8]=RXD_i;
	9	:	receive[9]=RXD_i;
	endcase
	end
	else
	div1=div1+1;

	if(bits_counter1>9)
	begin
	save=1;
	start1=0;
	bits_counter1=0;
	div1=0;
	end
	end
	end
endmodule

********************************
*******TRANSMITTER MODULE********
********************************

`timescale 1ns / 1ps

module transmitter (TXD_o, receive, clk_i, save);
	 
input [9:0]receive, clk_i, save=0;
output reg TXD_o;
integer div=0, bits=0, start=0;
reg [9:0]send;
parameter N = 2; //5208

always @(posedge clk_i)
begin	
if(save==1)
begin
send<=receive;
start=1;
end
if(start==1)
begin
	if(div==N)
		div=0;
	else if(div==N/2)
	begin
	div=div+1;
	bits=bits+1;
		case(bits)
	0	:	TXD_o<=send[0];
	1	:	TXD_o<=send[1];
	2	:	TXD_o<=send[2];
	3	:	TXD_o<=send[3];
	4	:	TXD_o<=send[4];
	5	:	TXD_o<=send[5];
	6	:	TXD_o<=send[6];
	7	:	TXD_o<=send[7];
	8	:	TXD_o<=send[8];
	9	:	TXD_o<=send[9];
	endcase
	end
	else
	div=div+1;
	
	if(bits>9)
	begin
	bits=0;
	start=0;
	div=0;
	end
	end
	else if(start==0)
	TXD_o<=1'b1;
	end
endmodule
 
Last edited:

Brownout

Joined Jan 10, 2012
2,390
I would start by fixing all the "start1" statements. eg:
Rich (BB code):
 start1 1=0;
After that, start a wave window and begin looking at waveforms. That's how debug gets done.
 

Thread Starter

domino89

Joined Sep 24, 2013
22
It works... I had an error in testbench clk declaration (forget that #5 refers to time of low/high time not a period of clock)
 

Brownout

Joined Jan 10, 2012
2,390
Glad you got it to work. You might try something like this for your testbench code in the future:

Rich (BB code):
 ....
  
 always
 #5 clk <= ~clk;
  
 initial begin
 wire [0:15] RXD_BUFF = 16'b101010.....;
 integer i = 0;
 end
 
 always @posedge(clk) begin
    if(i<16)
     RXD <= RXD_BUFF;
 end
 ....
 
 
Last edited:
Top