简体   繁体   中英

Verilog multiple simultaneous independant signal assignments in testbench

In VHDL I can write this in my testbench:

    signal clk      : std_logic := '0';
    signal count_in     : std_logic_vector(3 downto 0) := "0000";
    signal load     : std_logic := '0';
    signal reset        : std_logic := '0';
    signal count_out    : std_logic_vector(3 downto 0)  := "0000";
    ...

    clk <= not clk after 50 ns;
    reset <= '1' after 1400 ns, '0' after 1900 ns;
    count_in <= "1010" after 2500 ns;
    load <= '1' after 2700 ns, '0' after 3000 ns;

The signal declarations are before the "begin" of the testbench architecture while the portion after the elipse is in the body of the testbench architecture. A much better way is to use a process which ends with "wait" statement when writing testbenches. I understand how to do this in verilog as well as VHDL.

In verilog we can have an initial block that assigns value once. It is also possible to have multiple initial blocks. I have not tried this, but I don't think that it is wise to drive the same signal from multiple initial blocks.

Now my question is, how do I translate the above code for the DUT stimulus into Verilog? I expect that I shall use an assign statement with multiple #delay values. Is that correct? How do I do it?

In Verilog 2001 and above, you can initialize variables upon declaration, like VHDL. Another interesting, but perhaps less common way to do this is to use use a fork-join block with blocking assignments. In the following code, each line in the fork-join block is executed independently and concurrently.

module test;
    reg clk, load, reset;
  reg [3:0] count_in, count_out;
    initial 
    begin
        fork 
            begin clk   = 0;        while (1) #50 clk = ~clk;               end 
            begin count_in  = 0;    #2500 ; count_in = 4'b1010;             end
            begin load      = 0;    #2700 ; load = 1 ; #3000; load = 0;     end
            begin reset = 0;        #1400 ; reset = 1; #1900; reset = 1;    end
            count_out   = 0;
        join
    end
endmodule

Working example on edaplayground .

Also, notice that the clk signal in your code only toggles once. I slightly modified it so that the clock is running endlessly.

I'm not too familiar with VHDL, but this looks like a test bench stimulus. I generated the runnable testcase for comparison here .

The Verilog equivalent would look something like:

reg clk = 1'b0;
reg [3:0] count_in = 4'b0000;
reg load = 1'b0;
reg reset = 1'b0;
wire [3:0] count_out; // test bench is not driving this
...

initial begin
  clk <= #50 !clk;
  reset <= #1400 1'b1;
  reset <= #1900 1'b0;
  count_in <= #2500 4'b1010;
  load <= #2700 1'b1;
  load <= #3000 1'b0;
end

This will generate the same waveform, except count_out is floating instead of all zeros. By the naming convention I consider count_out should be driven by the device-under-test, which needs to be a wire type.

A SystemVerilog may look something like:

/* Note: bit cannot be X or Z
 * initializes equivalent to 'logic clk = 1'b0;' or 'reg clk = 1'b0;'
 */
bit clk; 
bit [3:0] count_in;
bit load;
bit reset;
wire [3:0] count_out; // logic type is also okay
...

initial begin
  clk <= #50ns !clk;
  reset <= #1400ns 1'b1;
  reset <= #1900ns 1'b0;
  count_in <= #2500ns 4'b1010;
  load <= #2700ns 1'b1;
  load <= #3000ns 1'b0;
end

Working example of Verilog and System Verilog here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM