How to define test bench ?

Status
Not open for further replies.

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,313
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Visit site
Activity points
9,442
Guys,

I have a 32 bits port, how can I define it on testbench ? I'm a learner on testing so, I need a help if you guys don't mind.

the code :
Code:
module pci(reset,clk,frame,irdy,trdy,devsel,idsel,ad,cbe,par,stop,inta,led_out);
    input reset;
    input clk;
    input frame;
    input irdy;
    output trdy;
    output devsel;
    input idsel;
    inout [31:0] ad;
    input [3:0] cbe;
    inout par;
    output stop;
    output inta;
    output [3:0] led_out;

.
.
.

the testbench :
Code:
module pci_testbench;

supply0 frame;
reg [31:0] t_ad;
reg [3:0] t_cbe;
supply0 t_irdy;
supply0 t_reset;

pci my_pci(frame, .ad(t_ad), cbe(t_cbe), irdy(t_irdy), reset(t_reset),clk);

initial
begin
    
	 
    $monitor(frame,t_ad,t_cbe,t_irdy,t_reset);

end
endmodule

and I got error on modelsim :
Code:
# ** Error: (vsim-3043) PCI32V3/pci_testbench.v(12): Unresolved reference to 'ad'.
#         Region: /pci_testbench
# ** Error: (vsim-3043) PCI32V3/pci_testbench.v(12): Unresolved reference to 'cbe'.
#         Region: /pci_testbench
# ** Error: (vsim-3043) PCI32V3/pci_testbench.v(12): Unresolved reference to 'irdy'.
#         Region: /pci_testbench
# ** Error: (vsim-3043) PCI32V3/pci_testbench.v(12): Unresolved reference to 'reset'.
#         Region: /pci_testbench
# ** Warning: (vsim-3017) PCI32V3/pci_testbench.v(12): [TFMPC] - Too few port connections. Expected 13, found 6.
#         Region: /pci_testbench/my_pci
# ** Error: (vsim-3053) PCI32V3/pci_testbench.v(12): Illegal output or inout port connection (port 'trdy').
#         Region: /pci_testbench/my_pci

Any helps or attention will be appreciated,
Thanks
 

It pays to actually RTFM on verilog commands you use. See syntax for $monitor: https://www.asic-world.com/verilog/sys_task_func1.html

$monitor ("format_string", par_1, par_2, ... );

You forgot to provide a format string.

I'm following this example :
Code:
module or_gate_testbench;
wire t_y;
reg t_a, t_b;

orgate my_gate( .a(t_a), .b(t_b), .y(t_y) );

initial
begin

  [B]  $monitor(t_a, t_b, t_y);[/B]

    t_a = 1'b0;
    t_b = 1'b0;

    #10
    t_a = 1'b0;
    t_b = 1'b1;

    #15
    t_a = 1'b1;
    t_b = 1'b0;

    #20
    t_a = 1'b1;
    t_b = 1'b1;

end
endmodule

and it's working allright.....
Do I miss something else ?
thanks

- - - Updated - - -

I recompiled it again and it was fine only I got this when tring to simulate it:
Error: (vsim-3053) C:/Users/Antonius/Documents/FPGA Project/PCI32V3/pci_testbench.v(12): Illegal output or inout port connection (port 'ad').
# Region: /pci_testbench/my_pci


What should I do with "output or inout port connection" ?
thanks
 

How can I see the response in modelsim ?
there's no error on compiling already and I can see the "view" but still don't understand if it's working properly or not...
Please correct me if there's mistake....

The testbench :
Code:
/* testbench for PCI
File: PCI_testbench.v */

module pci_testbench;


wire [31:0] t_ad;  //input output data multiplex with address
reg [3:0] t_cbe;  //command or byte enable
reg t_frame;      //input
reg t_clk;        //input
reg t_ad_value;
reg t_irdy;       //input
reg t_devsel;     //output
reg t_trdy;       //output

pci my_pci(.ad(t_ad), .cbe(t_cbe), .clk(t_clk), .frame(t_frame), .irdy(t_irdy));

assign t_ad = t_ad_value;
initial
 t_clk = 1'b0 ;
always
 #5 t_clk =~t_clk;

initial 
begin
    /*
	 Cycle 1 - The bus is idle
	 */
	 
	 /*
	 Cycle 2 - The initiator assets a valid address and places a read command on CBE
	 ==>Address phase
	 */
    #1  t_frame = 1'b0;              //active low, the device is ready to perform
	 //#10 t_ad = 32'b1010100010;
	 #1  t_cbe = 4'b0010;             //read command
	 #2  t_ad_value = 32'h0000_000F; //insert address
	 
	 /*
	 Cycle 3 ->
	 The initiator tristates the address, prepare for reading data.
	 Drive a valid byte enable information on CBE.
	 Asserts IRDY ==> LOW , indicating it's ready to capture read data.
	 Asserts DEVSEL ==> LOW, in this cycle or the next as an acknowledgment it has positively decoded the address
	 The target drives TRDY==>HIGH indicating it is not yet providing valid read data.
	 */
	 #1  t_ad_value = 32'bz; //insert tristate value
	 //#3  t_cbe = //drive a valid byte enable
 	 #2  t_irdy = 1'b0;
	 //t_devsel = 1'b0;
	 //t_trdy = 1'b1;
   
	 /*Cycle 4 ->
	 Target provides valid data and asserts TRDY ==> LOW indicating to the initiator that data is valid.
	 TRDY and IRDY now are both LOW during this cycle causing a data transfer to take place.
	 The initiator captures the data. 
	 This is the first data phase.
	 */
	 //#2 t_trdy = 1'b0;
	 /*
	  Cycle 5 - The target deasserts TRDY# high
		indicating it needs more time to prepare the next data
		transfer.
	 */
	  //#1 t_trdy = 1'b1;
	  /*
	  Cycle 6 - The second data phase occurs as both
		IRDY# and TRDY# are low. The initiator captures
		the data provided by the target.
     */
     //#2 t_trdy = 1'b0;
	  /*
	  Cycle 7 - The target provides valid data for the third
	  data phase, but the initiator indicates it is not ready
		by deasserting IRDY# high.
	  */
	  //#2 t_trdy = 1'b0;
      /*
	  Cycle 8 - The initiator re-asserts IRDY# low to
		complete the third data phase. The initiator captures
		the data provided by the target. The initiator drives
		FRAME# high indicating this is the final data phase
		(master termination).
		*/
	   #1  t_frame = 1'b1;              //final data phase ( master termination)
		/*
		Cycle 9 - FRAME#, AD, and C/BE# are tri-stated, as
		IRDY#, TRDY#, and DEVSEL# are driven inactive
		high for one cycle prior to being tri-stated.[5]
      */
      #1  t_frame = 1'bz;              //final data phase ( master termination)
      t_ad_value = 32'bz;
		t_cbe = 4'bz;
		
	end
endmodule
 

Just noticed this in your code:

Code:
pci my_pci(frame, .ad(t_ad), cbe(t_cbe), irdy(t_irdy), reset(t_reset),clk);

How do you think that is going to connect those ports? Mixing named port mapping & positional port mapping is a bad idea. If you do that, verilog will happily synthesize it (but but, it compiles so it must be right, right? wrong!). But the synthesized result typically ends up with the signals wired up wrong.

Try something like this instead, where you check if I got the names right. All I did is add some period '.' characters to show you what I mean, and how to use named port mapping in this case:

Code:
pci my_pci(.frame(frame), .ad(t_ad), .cbe(t_cbe), .irdy(t_irdy), .reset(t_reset), .clk(clk));

Also, I see a whole bunch of signals on the "pci" module that you don't connect. You have of course made damn sure by design that it will not require those connections and then still synthesize/simulate as intended, right? Right? Because if you didn't, all bets are off.

Also, rtfm on $monitor. You are not providing a format string. If you do that you will get sortof the right result for just binary registers. And you get confusing results when using anything else. Precisely like you are doing one might add.

Do you know how to provide a format string for printf in C? It's the same idea here...

Some examples with $monitor and actual formatting:
http://www.asic-world.com/verilog/syntax3.html
**broken link removed**

I hope that helps.
 


thanks for the links mate,

Here's the code I have modified :
Code:
/* testbench for PCI
File: PCI_testbench.v */
//`timescale 10ns / 10ns
module pci_testbench;


wire [31:0] t_ad;  //input output data multiplex with address
reg [3:0] t_cbe;  //command or byte enable
reg t_frame;      //input
reg t_clk;        //input
reg t_ad_value;
reg t_irdy;       //input
reg t_devsel;     //output
reg t_trdy;       //output

pci my_pci(.ad(t_ad), .cbe(t_cbe), .clk(t_clk), .frame(t_frame), .irdy(t_irdy));

assign t_ad = t_ad_value;
initial
 t_clk = 1'b0 ;
always
 #5 t_clk =~t_clk;

initial 
begin
    /*
	 Cycle 1 - The bus is idle
	 */
	 
	 /*
	 Cycle 2 - The initiator assets a valid address and places a read command on CBE
	 ==>Address phase
	 */
    #1  t_frame = 1'b0;              //active low, the device is ready to perform
	 //#10 t_ad = 32'b1010100010;
	 #1  t_cbe = 4'b0010;             //read command
	 #2  t_ad_value = 32'h0000_000F; //insert address
	 
	 /*
	 Cycle 3 ->
	 The initiator tristates the address, prepare for reading data.
	 Drive a valid byte enable information on CBE.
	 Asserts IRDY ==> LOW , indicating it's ready to capture read data.
	 Asserts DEVSEL ==> LOW, in this cycle or the next as an acknowledgment it has positively decoded the address
	 The target drives TRDY==>HIGH indicating it is not yet providing valid read data.
	 */
	 #1  t_ad_value = 32'bz; //insert tristate value
	 //#3  t_cbe = //drive a valid byte enable
 	 #2  t_irdy = 1'b0;
	 //t_devsel = 1'b0;
	 //t_trdy = 1'b1;
   
	 /*Cycle 4 ->
	 Target provides valid data and asserts TRDY ==> LOW indicating to the initiator that data is valid.
	 TRDY and IRDY now are both LOW during this cycle causing a data transfer to take place.
	 The initiator captures the data. 
	 This is the first data phase.
	 */
	 //#2 t_trdy = 1'b0;
	 /*
	  Cycle 5 - The target deasserts TRDY# high
		indicating it needs more time to prepare the next data
		transfer.
	 */
	  //#1 t_trdy = 1'b1;
	  /*
	  Cycle 6 - The second data phase occurs as both
		IRDY# and TRDY# are low. The initiator captures
		the data provided by the target.
     */
     //#2 t_trdy = 1'b0;
	  /*
	  Cycle 7 - The target provides valid data for the third
	  data phase, but the initiator indicates it is not ready
		by deasserting IRDY# high.
	  */
	  //#2 t_trdy = 1'b0;
      /*
	  Cycle 8 - The initiator re-asserts IRDY# low to
		complete the third data phase. The initiator captures
		the data provided by the target. The initiator drives
		FRAME# high indicating this is the final data phase
		(master termination).
		*/
	   #1  t_frame = 1'b1;              //final data phase ( master termination)
		/*
		Cycle 9 - FRAME#, AD, and C/BE# are tri-stated, as
		IRDY#, TRDY#, and DEVSEL# are driven inactive
		high for one cycle prior to being tri-stated.[5]
      */
      #1  t_frame = 1'bz;              //final data phase ( master termination)
      t_ad_value = 32'bz;
		t_cbe = 4'bz;
		
	end
endmodule
and the result in Modelsim :


How can I know I put the right simulation on PCI ?
any ideas ?
Yes I haven't connected all the ports since I wanna learn for the syntax if I'm doing it right, otherwise I have written the whole bunch and all are wrong, it's more frustating...
bit by bit.....not write all and then all wrong,

remember, I'm still learning here...

thanks

- - - Updated - - -

how can I connect an output or inout ?
by "reg" or by "wire" ?
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…