Confusing myself with a very simple verilog testbench - Page 1
Forum section: electronics / general

author: jeremy
author_rank: Super Contributor
timestamp: June 06, 2016, 12:29:33 pm
content: Hi all,Not sure if this is the right place to ask this, but I am really confusing myself and could use some helpI'm trying to write a verilog testbench. It's basically supposed to be a waveform that represents an AXI stream transaction:Code:module master_stream_handshake();reg axis_aresetn;reg axis_aclk;reg [7:0] axis_tdata;reg axis_tready;reg axis_tvalid;initial begin$dumpfile("stream.vcd");$dumpvars;axis_aclk = 0;axis_aresetn = 0;axis_tdata = 0;axis_tvalid = 0;axis_tready = 0;#3 axis_aresetn = 1;#4 axis_tvalid = 1;axis_tready = 1; // set by slave#2 axis_tdata = 5;#2 axis_tdata = 6;#2 axis_tdata = 7;#2 axis_tdata = 8;#2 axis_tdata = 9;#2 axis_tready = 0;#10 $finish();endalways begin#1 axis_aclk = axis_aclk ^ 1;endendmoduleI'm simulating it in iverilog and viewing it with GTKWave (clock period is 2 seconds):The thing I am getting really confused with is the timing of "writes" (for lack of better word). Basically, my question boils down to this: if I had a bunch of ideal rising edge triggered flip-flops connected to "axis_tdata", what would be its state just after the marker (let's say, 9.1 seconds)? Would it be storing the old value (0x00) or would it be storing 0x05?I thought that in verilog all "reads" of signals were performed before any "writes", so I would have thought that the register would have 0x00 clocked in at the cursor, then 0x05 would be at the next rising edge. However, GTKWave says the value is 0x05Looking at the specification itself makes a lot more sense, because all of the waves aren't locked to the clock edges:Can anyone please point me in the right direction?

author: 6thimage
author_rank: Regular Contributor
timestamp: June 06, 2016, 01:58:37 pm
content: Quote from: jeremy on June 06, 2016, 12:29:33 pmThat really depends - if you are doing behaviourally simulation it will be 0x05, if you are dealing with a real device (post place simulation) it will likely violate timing.Quote from: jeremy on June 06, 2016, 12:29:33 pmYes, normally reads happen on rising edges of clocks with writes being on the falling edge. But you're simulation isn't clocked - you are setting arbitrary values to signals. If you want the read on rising, write on falling you need to use an 'always @(posedge clk)' where clk is your clock signal, otherwise you have to ensure that the correct clock edges are used.The best way to simulate this is to either write a module that outputs the data - i.e. something that will work in hardware - or to write yourself a task. If you write it as a task, use a lot of '@(posedge sig)' where sig is the signal you want to align to (i.e. a clock or module output signal).

author: kfnight
author_rank: Regular Contributor
timestamp: June 06, 2016, 06:10:37 pm
content: In Verilog RTL, if the design's ports change value at the positive edge of the clock, then you can unambiguously drive and sample the ports in your testbench at the negative edge of the clock. So rather thanCode:#3 axis_aresetn = 1;useCode:@(negedge axis_aclk); axis_aresetn = 1;If you want to wait multiple clock cycles, you can use the repeat loop.Code:repeat (5) @(negedge axis_aclk);