Trouble simulating altera-generated floating point units
Added by Evan Andersen 19 days ago
It is my first time using verilator. I wrote a simple program to test the floating point units generated by altera's tool. Add and multiply work great, but the divide circuit produces the wrong result. I believe it's related to memory, as the divider circuit uses them as look up tables.
I've attached a small demo folder to show the problem. It creates an adder, multiplier, and divider, gives them all the same static inputs, and then sims for 50 clocks to get the answer.
Input: 3.5 and 2.0
When I run the simulation, I get:
Add: 5.500000
Mult: 7.000000
Div: 1.000000
The first two being correct, the divider being wrong (correct is 1.75). When I run the simulation with altera-modelsim, I get the correct answer.
What is wrong here? I did have to use -Wno-fatal as it generates a ton of warnings. However, many of the warnings I investigated proved to be innocuous (and in fact part of altera's libs - quartus prints them as well during synthesis!). Perhaps someone more familiar with Verilator could provide some insight here. I used the scripts from https://github.com/twosigma/verilator_support to convert the altera libraries.
divider_problem.zip (486 KB)
Replies (6)
RE: Trouble simulating altera-generated floating point units - Added by Wilson Snyder 18 days ago
Glad you're giving Verilator a try. It's most likely something simple, perhaps with a hint buried in a warning as you suggest.
I would suggest making a waves dump under both simulators and tracing forwards the major signals until you see a difference and the culprit signal. If the problem still isn't evident a small (~~100 line) failing test is closer to the size that I would be able to find the time to debug.
RE: Trouble simulating altera-generated floating point units - Added by Evan Andersen 17 days ago
Ok, I have figured out the issue, but I am unsure how to solve it. Inside the altera memory sim libraries, there is code like this:
reg x;
initial begin
x = 0;
end
always @ (posedge clk) begin
x <= ~x;
end
always @ (x) begin
// do things
end
In modelsim, the code in the always (x) block is triggered once at the start, and then on each clock thereafter. In verilator, the
(x) block is only triggered once at the start of simulation. In this case, the "do things" included updating the output register of the altera "altsyncram", which caused them to all output only 0 (since that is the correct output on cycle 0 and it never triggers again).
RE: Trouble simulating altera-generated floating point units - Added by Wilson Snyder 16 days ago
You could try the --x-initial-edge flag. Or, add an initial statement.
RE: Trouble simulating altera-generated floating point units - Added by Evan Andersen 16 days ago
Hmm, I don't think it's related to that. I just used 'x' as a variable name in my previous code example. There is already an initial block that sets the variable to 0. Both verilator and modelsim toggle the x variable between 0 and 1, but only modelsim triggers the always @(x) block more than once.
Further, I was playing around with the example, and now verilator errors "%Error: Vcounter.cpp:84: Verilated model didn't DC converge". I renamed the 'x' variable to 'tmp' for clarity, and added a counter.
reg tmp;
reg [7:0]counter;
initial begin
tmp = 0;
counter = 0;
end
always @ (posedge clk) begin
$display("tmp: %d", tmp);
tmp <= ~tmp;
end
always @ (tmp) begin
$display("count it: %d", counter);
counter <= counter + 1;
end
Modelsim output is:
# tmp: 0
# count it: 0
# count it: 1
# tmp: 1
# count it: 2
# tmp: 0
# count it: 3
# tmp: 1
... etc
RE: Trouble simulating altera-generated floating point units - Added by Evan Andersen 14 days ago
Is this problem fundamentally due to verilator being a cycle simulator instead of an event simulator? Will it be possible to get verilator to simulate this library or do I need to write my own version?
RE: Trouble simulating altera-generated floating point units - Added by Wilson Snyder 14 days ago
It's a fundamental problem, try rewriting.