verilator / verilator

Verilator open-source SystemVerilog simulator and lint system
https://verilator.org
GNU Lesser General Public License v3.0
2.52k stars 603 forks source link

fsm style w.r.t cycle based verilator simulation #672

Closed veripoolbot closed 10 years ago

veripoolbot commented 11 years ago

Author Name: Fabrizio Ferrandi Original Redmine Issue: 672 from https://www.veripool.org Original Date: 2013-08-29


Dears,

Attached you will find a verilog project generated with a tool we are developing at Politecnico di Milano. The tool starting from a generic C description creates a Verilog synthesizable design plus some scripts to perform synthesis and simulation. A first version of the source code of the tool was released more than a year ago through this website (http://panda.dei.polimi.it). In the tar.bz2 files I've added the initial C specification (a function doing some simple computations on an array storing some data) and a simple xml file used to specify the input tests. Such C file is translated in top.v design that you may find in simple_addr_expr_0 or in simple_addr_expr_1. The two directories contain the same generated design but two different scripts and testbenches. simple_addr_expr_0 targets the verification of the design by using verilator as verilog simulator while simple_addr_expr_1 targets icarus as verilog compiler. As testbench flavor I've used the C++ based one. It should be equivalent to the verilog version even if it is not truly the same. Doing some testing on the standard version of Verilator distributed with Ubuntu 13.04 for x86_64 and on the git HEAD version I've found some mismatches between the verilog and c++ based testbenches. The design is a single clock synchronous design and so a cycle based simulator, as Verilator is, should give exactly the same results of an event driven simulator like icarus (I've tested the design even with modelsim from Mentor and ISIM from Xilinx). Unfortunately something does not work. Looking to the lint messages there are some UNOPTFLAT problems. Mainly they are due to the unbounded reads and writes operations performed on a very simple memory model integrated in the two testbenches. The loop actually insist on a finite state machine that shouldn't create problem to the cycle based simulator. Maybe the style adopted or the verilog we generated has break some simularor rules we are not aware. So, I'm wondering if you have any suggestion to properly write the verilog code. The FSM style we used is a standard two processes based FSM.

thank you for your help and patience.

kind regards,

Fabrizio

veripoolbot commented 11 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2013-08-30T12:18:40Z


This is a very interesting project. I'd really like to dig into all of the details, but I really don't have time at the moment unfortunately. If you could convert this to a verilator "test_regress" style bug which I can run on multiple simulators, and by running waveforms point at the earliest signal that is wrong, it will be a lot quicker to debug.

As to UNOPTFLAT if the messages are related to clocking you may have mismatches. If it's only on the FSM as you indicate it can probably be ignored. You didn't include the compile time error, but assuming it's related to a test of a variable that you are setting, the key is to separate the output variables into separate always statements. That is in place of

always @(_present_state or OUT_UNBOUNDED_spec_1462_1548 or OUT_CONDITION_spec_1462_1542 or OUT_UNBOUNDED_spec_1462_1519 or $ begin case (_present_state) S_0 : if(~start_port) begin _next_state = S_0; end else begin wrenable_reg_0 = 1'b1; wrenable_reg_1 = 1'b1; _next_state = S_6; end

to:

// Compute _next_state always @ begin case (_present_state) S_0 : if(~start_port) begin _next_state = S_0; end else begin _next_state = S_6; end // Compute wrenable_reg_0 always @ begin wrenable_reg_0 = 1'b0; case (_present_state) S_0 : if(~start_port) begin end else begin wrenable_reg_0 = 1'b1; end

This should synthesize the same but is a lot more code, so if you want to get fancier you can do a graph optimization to see what signals across always are both inputs and outputs, and only split those out. (Or as said above ignore the problem and accept it simulates a bit slower due the UNOPTFLATs.)

BTW I'm sure the tools you're using now days supports Verilog 2001, so you might as well use "always @*".

veripoolbot commented 10 years ago

Original Redmine Comment Author Name: Wilson Snyder (@wsnyder) Original Date: 2013-12-15T00:17:13Z


Closing due to no response.