Do test benches work with Verilog modules?

I was trying to write a memory module in Verilog, following the patterns given by the components provided in Labs. It wasn’t working so I wrote a test bench and started whittling away. I now have “ram” that just writes a constant value all of the time while my test bench shows it as a undefined.

Code follows.

The module holding the place of RAM.

module verilog_ram (
    input clk,  // clock
    output reg [8-1:0] read_data
);
    always @(posedge clk) begin
        read_data <= 8'h20; //ram[address];
    end
endmodule

The test bench.

testbench test_verilog_ram {
    sig clk

    fun tick_clock() {
        clk = 1
        $silent_tick() // tick without capturing signals
        clk = 0
        $tick()
    }
    
    .clk(clk) {
        verilog_ram ram
    }

    test myTest {
        clk = 0 // initialize the value
        $tick() // capture initial state

        // test goes here
        repeat(8) {
            $print(ram.read_data)
            $tick_clock()
        }
        
    }
}

The result.

Running test_verilog_ram.myTest...
ram.read_data = {xxxxxxxx}
ram.read_data = {xxxxxxxx}
ram.read_data = {xxxxxxxx}
ram.read_data = {xxxxxxxx}
ram.read_data = {xxxxxxxx}
ram.read_data = {xxxxxxxx}
ram.read_data = {xxxxxxxx}
ram.read_data = {xxxxxxxx}
Done.

When I had my real attempt in the RAM module, I was getting undefined coming out. I assumed originally that I had an issue with my write to memory. This points to an issue with the read, or with the way the test bench is interacting with the Verilog module. Any thoughts?

I built the module and had it illuminate the LEDs. On the real board, it seems to behave as expected, at least in this simple case. Seems that the test bench capability is not working in this situation. It also does not seem to work in simulation in Labs.

The simulations in Lucid currently don’t support Verilog. Any Verilog modules are just treated as black boxes with all outputs undefined. It’s a planned future update.

As a workaround, you could implement the RAM in pure Lucid instead. This just isn’t ideal for synthesis as the tools seem to be very picky about the format to pack it into block RAM.

If that’s the case, it really should be documented. And if it is documented somewhere, emphasized. It can be hard enough to debug a design. Having some parts simulated in unexpected/unsupported ways is a time-sink on top.

This ripples up, of course, so that if you have a module in Lucid that itself uses a module in Verilog, the dependency can be obscured a bit. Rather than treating it this way silently, some sort of warning from the software would help too. (It’s really the opposite of a “black box” in some sense, right?)

You’re definitely correct. It kind of just happened this way (support for Verilog at all was added after the base simulator) and I haven’t improved it yet.

I created a new GitHub issue to track it Support Verilog in simulations · Issue #62 · alchitry/Alchitry-Labs-V2 · GitHub