Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17252 Discussions

Verilog with ANSI-style regs, non-zero initial value is not synthesised correctly!

Altera_Forum
Honored Contributor II
2,069 Views

Hi,  

We raised this with Altera and had it confirmed in Quartus V13, but the issue is not fixed in 13.sp1 so I thought I would raise awareness here in the hope it might save anyone else debugging time. 

If you have a Verilog module with 'ANSI-style' port lists, any 'reg' output ports that are initialised in line to be non-zero will incorrectly initialise to zero after synthesis. Value of y also has to be modified, ie. not reducible to a constant expression. 

 

module mux8 ( output reg y = 8'd4, input wire a, input wire b, input wire clk); ... always @(posedge clk) y <= a ? y : y + 1; endmodule 

 

We debugged this from a hardware mismatch, and luckily, if you simulate the post-synthesis netlist with vendor part library you can spot the difference against the same module under HDL simulation! 

 

Altera stated that in-line initialisation/default value is not a supported V2001 language feature, and added a feature request. We argued this should be a bug fix for the service pack cycle, since you get a simulation/synthesis mismatch with zero warnings. Tools should either synthesise correctly or fail! Modelsim etc. follows V2001 correctly. 

 

The obvious workaround is to convert the port to a wire, then use an explicit assign from a register declared internally.  

 

module mux8 ( output wire y, input wire a, input wire b, input wire clk); ... reg yreg = 8'd4; assign y = yreg; ... always @(posedge clk) yreg <= a ? yreg : yreg + 1; endmodule 

 

Happy debugging! 

Chris 

 

(Updated to indicate the process is clocked)
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
1,096 Views

module mux8 ( output reg y = 8'd4, input wire a, input wire b, input wire en); ... y <= a ? y : y + 1; endmodule 

 

The code example doesn't seem to make sense without an edge-sensitive always block. 

 

P.S.: The workaround must increment yreg instead of output variable y.
0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

Yeah, I've updated to indicate it's clocked and driven yreg in the workaround. The example posted in the service request was somewhat more detailed. Thanks.

0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

This came up for me around a year ago. It took a while to track it down to being a Quartus problem since the simulations passed and there were no errors or warnings in Quartus. When I mentioned it to an field applications engineer (not a direct Altera FAE, rather a local distributor FAE who happens to cover Altera), the response was "well, don't write your code like that."  

 

 

--- Quote Start ---  

 

The obvious workaround is to convert the port to a wire, then use an explicit assign from a register declared internally.  

 

--- Quote End ---  

 

 

Personally, I go with initial statements because the meaning and intention are a little clearer to me. Initial statements are supported by Quartus.  

 

module mux8 ( output reg y, input wire a, input wire b, input wire clk); ... initial begin y = 8'd4; end always @(posedge clk) y <= a ? y : y + 1; endmodule
0 Kudos
Altera_Forum
Honored Contributor II
1,096 Views

I'm sure everyone who's bitten by this learns the hard way. Probably cost us about 20 hours engineering time to go from malfunction all the way back through reproducing in post-synthesis then observing the difference vs. original HDL synthesis. Really is a nasty one to catch you out if you happen to drift a bit to much into the "new style" Verilog spec.

0 Kudos
Reply