Menu

#947 Procedural continuous assignment affects other structural connections to source vector

devel
closed-fixed
None
6
2014-09-22
2014-02-23
Russ Dill
No

In the below testcase, a small delay chain is setup using assign statements, from delay_0 to delay_1 to delay_2. The value assigned to out, delay_0 or delay_2 is determined by switch statement.

Instead of data being passed from delay_0 to delay_1 to delay_2, an incorrect value is passed from delay_0 to delay_1. It seems like it might be getting a value from delay_2 instead of delay_0 (from some experimentation).

gtkwave screenshot attached, you can see the bogus transition at 3.1ns

This was discovered in s20121218-427-g320f6d0 but also is confirmed to exist in s20130827.

Testcase:

`timescale 1ps / 1ps

module test();
reg clk = 0;
reg [1:0] dly = 0;
reg t = 1;

    reg [1:0] dly_r;
    reg out = 0;
    wire delay_0, delay_1, delay_2;

    initial begin
            $dumpfile("tmp.vcd");
            $dumpvars(0);
            #2900 t = 0;
            dly = 2;
            #1000 $finish;
    end

    always
            #1000 clk <= ~clk;

    always @(posedge clk)
            dly_r = dly;

    assign delay_0 = t ? 1'bx : 1'b1;
    assign #100 delay_1 = delay_0;
    assign #100 delay_2 = delay_1;

    always @(dly_r) begin
            case (dly_r)
            0: assign out = delay_0;
            2: assign out = delay_2;
            endcase
    end

endmodule

1 Attachments

Discussion

  • Russ Dill

    Russ Dill - 2014-02-23

    This is the same test program, but with the 'assign #100 delay_2 = delay_1;' removed. From this, it appears that delay_1 is getting its value from delay_2 instead of delay_0.

     

    Last edit: Russ Dill 2014-02-23
  • Martin Whitaker

    Martin Whitaker - 2014-02-23

    The bug is in the vvp code that handles the procedural continuous assignments to 'out'. Changing your final 'always' block to

    always @* begin
            case (dly_r)
            0: out = delay_0;
            2: out = delay_2;
            endcase
    end
    

    will work round the bug (and is probably a bit more efficient as well).

     
  • Martin Whitaker

    Martin Whitaker - 2014-02-23
    • summary: Reading value effects it --> Procedural continuous assignment affects other structural connections to source vector
    • Priority: 5 --> 6
     
  • Russ Dill

    Russ Dill - 2014-02-23

    This bug is reduced from a form found in the Xilinx simulation libraries. If they use that design pattern in one place, its likely that its found in other places too.

     
  • Russ Dill

    Russ Dill - 2014-02-24

    When I use that workaround in the original code, I get 'internal warning: NetCAssign::nex_input() not implemented.'

     
  • Martin Whitaker

    Martin Whitaker - 2014-02-24

    That will be because you haven't removed the "assign" keywords from the assignments, so they are still being treated as continuous assignments.

    Not a particularly helpful warning message, I agree. What it means is that the variables on the RHS of the continuous assignments are not being included in the sensitivity list for the always block. Given that they are continuous assignments, and hence permanently sensitive to those variables, this won't affect the simulated behaviour, but still, this should be tidied up.

     
  • Martin Whitaker

    Martin Whitaker - 2014-02-26
    • assigned_to: Martin Whitaker
     
  • Martin Whitaker

    Martin Whitaker - 2014-02-27

    I've pushed a fix for this to the git master branch.

     
  • Martin Whitaker

    Martin Whitaker - 2014-02-27
    • status: open --> closed-fixed
     

Log in to post a comment.