1
\$\begingroup\$

I simulated a 32-bit register with an enable input in Vivado. enter image description here The following things are unclear to me:

  1. I don't understand why 0xFFFFFFFF is latched at 5 ns and not the previous value 0x0abcdeff. Because the change of the input signal from 0x0abcdeff to 0xFFFFFFFF is initiated by the rising clock edge at 5 ns. Until this signal change propagates to the register input in my opinion the old value 0x0abcdeff should have been latched.

  2. Doesn't the input signal need to be stable before the clock edge for at least the setup time to be latched correctly?

  3. Would a real circuit with the same signal changes as shown in the simulation latch 0xFFFFFFFF or 0x0abcdeff?
    In other words does the simulation describe the waveforms that occur in the hardware?

  4. Am I using the enable signal correctly to make it work in hardware? For example if I want to latch a value at the rising edge at 25 ns, do I have to set the enable signal already at the rising edge at 15 ns and reset it at 35 ns? Because if I set enable at 25 ns the propagation time until it reaches the flip-flops would perhaps prevent them from latching the value correctly.

Here's the verilog code:

module Nbit_register(
// inputs
clk, enable, d, reset,
// outputs
q
);

parameter N = 32;

input clk;
input enable;
input reset;
input [N-1:0] d;
output reg [N-1:0] q;

always @ (posedge clk or posedge reset)
begin
    if (reset == 1) begin
        q <= 0;
    end else if (enable == 1) begin
        q <= d;
    end
end                
endmodule

And here's the testbench code:

module tb_register;

reg clk;
reg reset;
reg enable;
reg[31:0] d;

wire[31:0] q;

Nbit_register register (
    .clk(clk),
    .reset(reset),
    .enable(enable),
    .d(d),
    .q(q)
    );

initial
begin
    clk = 0;
    reset = 0;
    enable = 0;
    d = 32'h11111111;
end

always
    #5 clk =  !clk; 

initial
begin
    d = 32'hABCDEFF;
#5  enable = 1;
    d = 32'hFFFFFFFF;
#10 enable = 0;
    d = 32'hAAAAAAAA;        
end
endmodule

Ok, I connected two 32-bit registers in series now as suggested by Sean Houlihane and this is the simulation result: enter image description here These results make sense to me, but I have one question left. Is it ok to reset the enable already at 25 ns or do I have to wait until the next rising clock edge at 35 ns for it to work in hardware?

\$\endgroup\$
5
  • \$\begingroup\$ Show the verilog pease. Simulations typically work zero-delay, and can be a bit confusing in these aspects. \$\endgroup\$ May 28, 2016 at 8:23
  • \$\begingroup\$ I've just added the verilog code. \$\endgroup\$
    – dr_exmat
    May 28, 2016 at 9:59
  • 2
    \$\begingroup\$ The confusion does arise from your testbench. The sequence between clock and enable is not well defined. Either skew the inputs away from the clock edge (which is expensive in simulation since it adds more internal clocks), or drive the inputs from synthesisable code too (enable and data need to be outputs from flops). \$\endgroup\$ May 28, 2016 at 10:47
  • \$\begingroup\$ So the simulation results would be different if I drive enable and data via flops? \$\endgroup\$
    – dr_exmat
    May 28, 2016 at 10:51
  • \$\begingroup\$ yep. so long as you use the same clock for all the flops. \$\endgroup\$ May 28, 2016 at 10:57

2 Answers 2

0
\$\begingroup\$

In general, you should avoid having the inputs to any register change at the same instant as the active clock edge. In physical circuits, this could lead to metastability issues, and simulators give results that are confusing at best.

In this case, the clk, enable and d signals all changed at the same instant in the testbench, so by the time the Nbit_register module was evaluated, it "saw" the rising edge of clk with enable = 1 and d = 0xFFFFFFFF, so that is what it captured.

In a real circuit, the enable and d signals would likely have been driven by the clock themselves, and would have changed slightly after the clock edge. Even with a zero-delay simulation, this could have changed the order of evaluation in the simulator, giving very different results.

If you increase that first delay in your testbench slightly, you'll avoid this problem and get consistent results from the simulator.

initial
begin
    d = 32'hABCDEFF;
#5.1  enable = 1;
    d = 32'hFFFFFFFF;
#10 enable = 0;
    d = 32'hAAAAAAAA;        
end

EDIT: You say, "#5.1 and #10 work, but unfortunately @(posedge clock) gives the same result as #5"

Yes, this is not surprising. While this makes enable and d dependent on the clock, they are still effectively simultaneous, with the emphasis on "effectively".

Keep in mind that while the simulator is doing its best to present the illusion that it is evaluating change events in parallel, it is still fundamentally a software (sequential) program, and can only evaluate one statement at a time, creating an implicit ordering among events that are supposedly "simultaneous" (i.e., within the same simulation timestep). The actual ordering that occurs is "implementation dependent" — i.e., a crap shoot.

In this case, it is not at all surprising that the simulator processes the events in the following sequence:

  • At #5 clk goes from low to high, which triggers all events keyed on @posedge(clk).
  • The statements in the testbench module get evaluated next, setting enable high and setting d to 0xFFFFFFFF.
  • Then the statements in the Nbit_register module get evaluated, setting q to 0xFFFFFFFF.

In most situations, this implicit ordering of events does not matter very much at all. But when it does, you need to be aware of it, and take pains to explicitly specify the sequencing of events. Most simulators have the concept of "unit delays" (one simulation timestep) for gates and FFs, just to make sure that their outputs don't change simultaneously with their inputs. This is what allows structures like shift registers to work correctly.


EDIT #2: A related issue is that you used blocking assignment statements (= instead of the non-blocking <=) in your testbench. I found this reference that does a good job of explaining the significance of this.

Basically, blocking assignments take effect immediately, during the current simulation timestep, while non-blocking assignments don't take effect until after the timestep — i.e., after all change events triggered for the timestep have been evaluated.

If you had said

@(posedge clk)  enable <= 1;
    d <= 32'hFFFFFFFF;

then the assignments to enable and d would not have taken effect until after the assignment to q had been processed, and q would not have changed until the second clock edge.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ You can also do @(posedge clock) rather than #5.1 and #10 as this will ensure that the action is done just after the rising edge which ensures that everything remains synchronous. \$\endgroup\$ May 28, 2016 at 12:49
  • \$\begingroup\$ #5.1 and #10 work, but unfortunately @(posedge clock) gives the same result as #5 \$\endgroup\$
    – dr_exmat
    May 28, 2016 at 14:51
  • \$\begingroup\$ See my edits above, which explain this. \$\endgroup\$
    – Dave Tweed
    May 28, 2016 at 16:59
  • \$\begingroup\$ @Dave Tweed Thanks for your explanation. So is there a way to tell the simulator that the stimuli signals of the testbench are outputs of previous FFs without instantiating more FFs? Because then, as I wrote in the second part of my question (with the two registers in series), the simulation results are the same as when a slight delay like with #5.1 is added. \$\endgroup\$
    – dr_exmat
    May 28, 2016 at 16:59
  • \$\begingroup\$ @DaveTweed Your EDIT #2 answers my question. Thanks a lot! \$\endgroup\$
    – dr_exmat
    May 28, 2016 at 17:03
-1
\$\begingroup\$

The 'problem' is indeed the enable signal. At 5ns the enable signal is not active so the rising edge of the clock samples this signal as disabled.

If you want to sample enable as high at t=25 ns you have to set it at 15ns and it must remain set at least until t=25ns. As it is now, enable is sampled as logic high at t=15 ns in your simulation. It is the only clock rising_edge that sees the clock as enabled, again, in your simulation.

After seeing your sources, please notice you don't assert reset at all in your simulation. Also, if you want to latch some data, you have to assert clock enable and data together and wait for the raising edge of clock to sample them.

With this testbench it should work okay:

reset = 1;
#10 reset = 0;
#15  enable = 1;
    d = 32'habcdefff;
#25 enable = 0;
end
\$\endgroup\$
12
  • \$\begingroup\$ Almost all simulations have transitions at posedge clk only. never put delays in a simulation unless its a netlist, shows something is wrong. \$\endgroup\$ May 28, 2016 at 8:53
  • \$\begingroup\$ @Sean Houlihane where did I say to put delays or to have transitions at negedge. I said neither, so I don't understand your comment. \$\endgroup\$ May 28, 2016 at 9:32
  • 1
    \$\begingroup\$ This answer is essentially incorrect. It's clear that the simulator did evaluate enable as active at the first rising clock edge, but it also evaluated the d as already having been changed to 0xFFFFFFFF at that same time. \$\endgroup\$
    – Dave Tweed
    May 28, 2016 at 11:17
  • 1
    \$\begingroup\$ @ClaudioAviChami I just tested it with a different value than 0xFFFFFFFF and it still samples this value at 5 ns \$\endgroup\$
    – dr_exmat
    May 28, 2016 at 14:09
  • 2
    \$\begingroup\$ You seem to have gotten off the rails at some point. Instead of explaining how the code that the OP posted gave the results that he shows (which I explained), you seem to be arguing about some other hypothetical scenario. Please focus on the question at hand. \$\endgroup\$
    – Dave Tweed
    May 28, 2016 at 16:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.