0
\$\begingroup\$

Here's the Verilog code for my UsedBeforeAssign module:

module UsedBeforeAssign(Din, latch, Dout);
    input latch ;
    input Din;
    output Dout;
    reg Dout;
    reg temp;
    always @(latch or Din or temp)
        if (latch) begin
            Dout = temp;
            temp = Din;
        end
endmodule

From a behavioral perspective, I believe that when latch=1, temp synchronizes with the current Din, and Dout will be the previous Din.

Here's my testbench:

`timescale  1ns / 1ns
module tb_UsedBeforeAssign;

reg         latch     ;
reg         Din       ;
wire        Dout      ;

sram uut (
    .latch     (    latch     ),
    .Din       (    Din       ),
    .Dout      (    Dout      )
);

reg clk;
parameter PERIOD = 10;

initial begin
    $dumpfile("db_tb_sram.vcd");
    $dumpvars(0, tb_sram);
    clk = 1'b0;
    forever
        #(PERIOD/2) clk = ~clk;
end

initial begin
   Din = 0;
   latch = 1;
   #PERIOD;
   Din = 1;
   latch = 1;
   #PERIOD;
   Din = 0;
   latch = 1;
   #PERIOD;
   Din = 0;
   latch = 1;
   #PERIOD;
   Din = 1;
   latch = 1;
   #PERIOD;
   Din = 0;
   latch = 1;
   #PERIOD;
    $finish;
end

endmodule

I simulated this using Icarus Verilog (iverilog) and the simulation waveform is consistent with my expected behavior.

enter image description here

However, when I synthesized it using Quartus II 18.0, the RTL viewer showed the following:

enter image description here

You'll notice that there are two latches in the diagram. When the input latch remains at 1, if Din changes, due to the latch behavior, the OUT0 of the temp latch will immediately change. Consequently, the input to dout$latch changes to match the OUT0 of the temp latch, causing the OUT0 of dout$latch to change immediately. In this case, Dout will not always be the previous Din, but will instead always match Din. This is inconsistent with the simulation results. Why is there a discrepancy between the simulation and the RTL diagram?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You are using blocking assignment, which means the statements in the always block will be processed in order.

When latch goes high, you have:

        Dout = temp;
        temp = Din;

First, Dout = temp; is executed - this means that the Dout signal is expected to take the value that temp held when the block was triggered - i.e. the current value.

Then you have temp = Din;, which will update temp to its new value based on the input.

What this implies is that temp and Dout signals must both be latches (because they are non-clocked but can hold a previous value). Then because Dout takes the current value of temp, the input of the Dout latch must be connected to the output of the temp latch. Hence you see a latch chain in the RTL viewer.

In behavioural simulation, the issue appears to be that the always block is not being retriggered. If we try this instead:

`timescale  1ns / 1ns

...

always @(latch or Din or temp) begin
    #1;
    $display("%t: Triggered", $time);
    if (latch) begin
        Dout = temp;
        temp = Din;
    end
end

With that extra simulation delay, you should now expect to see Dout changing value 1ns after temp changes if the block retriggered, and the triggered message printed twice.

However this doesn't happen. The changing of temp doesn't retrigger the always block due to the way the sensitivity lists work, and therefore you don't see Dout updated. This is where simulation and synthesis start to differ, and its the synthesis that is doing the correct thing. Using latches like this is a headache waiting to happen.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you! I still have 2 questions: 1. I believe the behavioral simulation is incorrect. Why can't the behavioral simulation retrigger? If it can retrigger, it would be in agreement with the synthesis result. 2. I modified always @(latch or Din or temp) to always @(latch or Din). This change should not affect the behavioral simulation results, but the synthesis results, particularly the RTL view, should be altered. However, the RTL view of the synthesis results remains unchanged. \$\endgroup\$
    – Tokubara
    Sep 5, 2023 at 0:53

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .