Menu

#686 XSpice Verilog Vector Input Bug

v1.0 (example)
open-fixed
None
5
2024-08-17
2024-08-08
No

I recently ran into an issue using ngspice vlnggen where only continuos 1's from the LSB of the vector input would be registered in the verilog simulation.

This is a very simple ngspice circuit and verilog module showcasing the issue. There is a register input [7:0] "data" which is mapped to ngspice nodes from power supplies set to vcc or 0. The issue is the circuit only registers 1's that are continuous from the LSB e.g. 10111111 is mapped as 00111111.

Attached below is a test case showing the issue, the example prints TEST: data=00111111.

  • test.v
module test (
    input wire clk,
    input reg [7:0] data
);

    initial begin
        $display("TEST: data=%b", data);
    end

endmodule
  • test.cir
Test Circuit

.param vcc=3.3
vcc vcc 0 {vcc}

Vd7 d7 0 dc vcc
Vd6 d6 0 dc 0
Vd5 d5 0 dc vcc
Vd4 d4 0 dc vcc
Vd3 d3 0 dc vcc
Vd2 d2 0 dc vcc
Vd1 d1 0 dc vcc
Vd0 d0 0 dc vcc

Ven en 0 dc vcc

aclock 0 clk clock
.model clock d_osc cntl_array=[-1 1] freq_array=['100Meg' '100Meg']

ahdldevice [ clk d7 d6 d5 d4 d3 d2 d1 d0 ] null null dut
.model dut d_cosim simulation="./test.so"

.control
tran 1n 10u
.endc

I have confirmed this to be a bug reviewing ngspice-43 source within
src/xspice/verilog/verilator_shim.cpp:43

The following macro is used to set the inputs:

#define VL_DATA(size, name, msb, lsb)     \
  if (index >= msb - lsb + 1) {           \
    index -= msb - lsb + 1;               \
  } else if (msb == 0 && lsb == 0) {      \
    topp->name = val ? 1 : 0;             \
    return;                               \
  } else {                                \
    if (val)                              \
      topp->name |= (1 << (msb - index)); \
    else                                  \
      topp->name &= (1 << (msb - index)); \
    return;                               \
  }

Line 53 of the file is missing a ~. When a zero is set it would reset the whole input port to 0. Leaving only the successive ones without a following zero which explains the behaviour. This line needs to be:
topp->name &= ~(1 << (msb - index)); \

I will send a merge request with the following change.

Discussion

  • Giles Atkinson

    Giles Atkinson - 2024-08-08
    • status: open --> open-accepted
    • assigned_to: Giles Atkinson
     
  • Giles Atkinson

    Giles Atkinson - 2024-08-08

    Ouch! It seems an elementary blunder crept through ...
    There is another instance in the code for inout ports that should also be fixed (they are supported in Verilator's interface but the documentation implies that they do not work, and that seems to be true).

    I have never merged a Sourceforge PR. so expect to push the fix as a new commit, also that may be simpler as the code has changed.

    Many thanks for the bug report and fix.

     
  • Giles Atkinson

    Giles Atkinson - 2024-08-17
    • status: open-accepted --> open-fixed
     
  • Giles Atkinson

    Giles Atkinson - 2024-08-17

    Fix committed as b03dd906949f.

     

Log in to post a comment.