Project

General

Profile

[logo] 
 
Home
About/Contact
Major Tools
  Dinotrace
  Verilator
  Verilog-mode
  Verilog-Perl
Other Tools
  IPC::Locker
  Parallel::Forker
  Voneline
General Info
  Papers

Problem with reset?

Added by Krzysztof Marcinek about 5 years ago

Hi,

I've got multicore processor design written in verilog. The design is FPGA and ASIC proven. Still, I have some issues with getting it work with verilator. I disabled all clock gating logic, asynchronous reset is unchanged though. When I compiled single core design without caches the simulation was ok.

After enabling it the simulation went wrong on cache. It looked like the data written to the tag memory was set one clock cycle befor it was assigned by the controller! Or at least half cycle before. I displayd values on both edges.

The cache tag memory used asynchronous reset to cleat its content. When I removed reset signal the simulation when ok once again.

However I compiler the design to have more cores. And once again the simulation stopps in the same point.

I tried to use -Wwarn-IMPERFECTSCH and insert /* verilator clock_enable */ in some places. I had two warnings of that kind in the other part of the design so i was not surprised it didn't help.

Any ideas where to start from?


Replies (15)

RE: Problem with reset? - Added by Jie Xu about 5 years ago

One thing you can check is the signal list in the generated _change_request function in your C++ file. I found it quite useful to check whether there are some clock signals in the list and give them a further investigation.

Also, you could try the "-clk signal" option which was recently added to Verilator, basically it will help Verilator to do the scheduling work better.

RE: Problem with reset? - Added by Krzysztof Marcinek about 5 years ago

I do not have any clock signals in _change_request funciton. I can recognized only some reset signals. Most of them are indicated by IMPERFECTSCH warning. Should using /* verilator clock_enable */ cause fix it or how to indicate that some signals are reset? Sorry for a newbie question but how do I know how many times I should call eval() function before changing clock edge? Will stat file be any kind of help on this problem?

Used switches: -Wno-lint -Wno-COMBDLY -Wwarn-IMPLICIT -Wwarn-IMPERFECTSCH --clk clk -O3 -CFLAGS '-O3' --x-assign fast --stats --noassert --top-module testbench

RE: Problem with reset? - Added by Jie Xu about 5 years ago

You only need to call eval() once after each clock change.

Adding the option -clk clk didn't help? Have you tried without this option?

RE: Problem with reset? - Added by Krzysztof Marcinek about 5 years ago

With and without -clk clk is the same. It looks like problem with internal generated reset signal for each core.

RE: Problem with reset? - Added by Krzysztof Marcinek about 5 years ago

Still have no idea. Attached waves show that the same module (tag memory model) is simulated correctly in one processor configuration and wrong in another. Rst signal is hardwired to 1.

assign  rdata = dwrite ? dwdata : int_rdata;

always @(posedge clk or negedge rst)
begin
    if (~rst) begin
        dwdata <= 0;
        dwrite <= 0;
    end else begin
        if (en) begin
            dwdata <= wdata;
            dwrite <= write;
        end
    end
end

always @(posedge clk or negedge rst)
begin
    if (~rst) begin
        for (i = 0; i < 2**AWIDTH; i = i + 1) begin
            mem[i] = 0;
        end
        int_rdata = 0;
    end else begin
        if (en) begin
            int_rdata = `DEF_DEL_1 mem[addr];
            if (write) begin
                mem[addr] = wdata;
            end
        end
    end
end

correct.jpg View (153 KB)

fail.jpg View (151 KB)

RE: Problem with reset? - Added by Jie Xu about 5 years ago

One way to figure this out is to minimise the design to reproduce the issue. In your case, may be you can try with only the tag memory module and some other writing and clock logics? If you can reproduce this in a minimised example, it would be much easier for us to help.

There is another thing which could be helpful. Check the generated C++ _eval() function, in the _eval() function a sequence of functions will be called. Try to find out if the clk signal is assigned/changed very early in the sequence. Compare the two successful and failing cases. If correctly scheduled, the clock signal should be assigned earlier than the other assignment in your code block. If you indeed find the clock signal is assigned quite late in the failing case, then you need to check where the clock is assigned and which signal it is depended on. Most probably there will be some circular dependency back to the signals in the tag memory model. Once you get there, then it may be fixed by inserting some /*verilator clock_enable*/ comments.

RE: Problem with reset? - Added by Krzysztof Marcinek about 5 years ago

I have a cluse but need help how to solve it correctly.

Example working (simplified)

module(
    input wire clk,
    ...
)

    cache ( .clk(clk)   // cache works correctly

endmodule

Example not working:

module(
    input wire clk,
    output wire clk_out,
    ...
)

    assign clk_out = clk;

    cache ( .clk(clk_out)    // cacge works incorrectly

endmodule

I already tried.

output wire clk_out /*verilator sc_clock*/,

RE: Problem with reset? - Added by Krzysztof Marcinek about 5 years ago

One more update. I think the key may be the definition of clock in form of vector like internal_clock[x:0].

module( input wire clk, ... )

wire [1:0] clk_out,
assign clk_out[0] = clk;
cache ( .clk(clk_out[0])    // cache works incorrectly

endmodule

Is it wrong for verilator?

RE: Problem with reset? - Added by Jie Xu about 5 years ago

It is not wrong for Verilator to use vector clocks. The thing is that it is a lot harder for Verilator to decide the scheduling order of the signal clock_out. That is because Verilator takes the clock_out as one signal and all the dependencies on its elements will be counted. BTW, did you get any UNOPTFLAT warnings? Maybe there is one UNOPTFLAT warning about the clock signal.

You can test this by splitting the clock vector, if this is the cause, splitting should fix your problem.

RE: Problem with reset? - Added by Krzysztof Marcinek about 5 years ago

I don't recall having UNOPTFLAT warnings. I used preprocessor macro to replace while using verilator all my internally assigned clock nets ant vectors to the simplest input clk signal. There was still the problem with initialization of cache tag array on reset but I also removed this signal as the cache controller clears tag array on its own. Now it's working.

I suppose this modifications will improve the performance as from the start the idea was to have cycle accurate simulator. Some low-power features are missing now but I think they are not necessary for the simulator. I just made rough calculation and I get ca 100kHz real time operation. Do verilator support multicore cpus?

RE: Problem with reset? - Added by Jie Xu about 5 years ago

Glad you got it sorted out.

AFAIK, Verilator has no issue with supporting multicore cpu.

RE: Problem with reset? - Added by Todd Strader about 5 years ago

Krzysztof Marcinek wrote:

Do verilator support multicore cpus?

If you're talking about evaluating independent parts of your design in parallel, I haven't seen anything like that in Verilator. However, if you know how to subdivide your design, you could just build each sub-component separately with Verilator and then handle the parallelism yourself. Obviously, this would be way easier to handle if you ensured that you split things only at sequential boundaries. You could do all this manually, or possibly with the Verilog-Perl library.

RE: Problem with reset? - Added by Krzysztof Marcinek almost 5 years ago

Sory, but I have again a lot of strange results. Please find the code and files below. Maybe I'm missing something but the simulation goes wrong. What is very strange that the simulation results become ok when I comment cnt_1_stop = 0; line. What is the reason of such behaviour?

module test(rst, clk);

input wire    rst;
input wire    clk;

reg [7:0]    cnt_1;
reg [7:0]    cnt_2;

reg cnt_1_stop;

always @(posedge clk or negedge rst)
begin
    if (~rst) begin
        cnt_2 = 0;
        cnt_1_stop = 0;         // simulation is ok when I comment this line
    end else begin
        cnt_2 = cnt_1 + 5;
    end
end

always @(posedge clk or negedge rst)
begin
    if (~rst) begin
        cnt_1 = 0;
    end else begin
        cnt_1 = cnt_1 + 1;
    end
end

endmodule

make_simulator.sh View (147 Bytes)

test.v (440 Bytes)

verilator_args.list View (167 Bytes)

verilator_files.list View (7 Bytes)

sim_test.cpp View (864 Bytes)

Screenshot-1.png View (9.96 KB)

RE: Problem with reset? - Added by Wilson Snyder almost 5 years ago

Does the code work when you use the correct assignment style ("<=")? While Verilator has additional rules, even a compliant simulator can race and get different results when blocking assignments are used.

RE: Problem with reset? - Added by Krzysztof Marcinek almost 5 years ago

My bad... I just earlier got BLKLOOPINIT error so I carelessly made the assigment blocking... And start to make mistakes like the one above...

    (1-15/15)