1
votes

I coded something like the following:

always @(state or i1 or i2 or i3 or i4) begin
next = 5'bx;
err = 0; n_o1 = 1;
o2 = 0; o3 = 0; o4 = 0;
case (state) // synopsys full_case parallel_case
IDLE: begin
if (!i1) next = IDLE;
else if ( i2) next = S1;
else if ( i3) next = S2;
else next = ERROR;
end
S1: begin
if (!i2) next = S1;
else if ( i3) next = S2;
else if ( i4) next = S3;
else next = ERROR;**strong text**
...

My manager, of course I don't want to argue with him before I have some strong argument, but he reviewed my code and said writing

next = 5'bx;
err = 0; n_o1 = 1;
o2 = 0; o3 = 0; o4 = 0;

in a combinational logic without putting the right side in the sensitivity list will cause problems in synthesis.By not having these 3 lines, I need to explicitly write the else part inside each individual case, and he said yes.

I am wondering is there anything wrong with this coding style? And will it cause a synthesis problem or any sort of problem(maybe some version or old synthesis tool won't synthesize?) by initializing these values in the combinational logic? What he said does make sense to me and I actually never thought about it because he said this is software logic, and every wire gets its initial value from the logic before it with the initial condition. I told him school taught us this, he was like school cares less any synthesis but industry does.

Thank you for your help! Guess I am not trying to convince him anything even I have a answer, since the team need to stick with one style anyways, but i am confused by him since I have seen others doing this all the time and he is also a guy with tons of experience, so...confused

2
Looks like code from about 15 years ago...Sean Houlihane

2 Answers

2
votes

First of all, you should be using always @(*) from Verilog-2001 or even better always_comb from SystemVerilog so the sensitivity list get constructed automatically for you.

The problem with your code is the use of the full case synthesis pragma as described in this paper. Your coding style removes the need for full case as long as you are sure you made assignments to every variable in the always block for all possible flows through the block.

1
votes

I think what your boss means by "software logic" is that your coding style requires the designer to think sequentially. In other words, when I read your always block, I am first forced to think about all the values being initialized to their default values, then I must evaluate the case logic. In reality, the logic will synthesize into the equivalent of a default case. This causes a disparity between the logic that represents the RTL and the logic of how I evaluate your expression in my mind. If you know what your doing, then this should be fine most of the time. But you are working for a company, so your code should be considerate of the other engineers working on a project. Each different team in the design flow is going to view the same logic through a potentially different lens (for example, the physical design team is not concerned with Verilog but the synthesized RTL). If we write our Verilog to reflect the final RTL (i.e. "hardware logic"), then everyone is analyzing the logic in a similar fashion. If I look at an output in a circuit and I know all the values of the inputs at a given time step, then I can visually trace the output through the circuit and determine its value without giving any consideration to the other logic. Your Verilog code should be written in the same way.

To summarize, your initialization statements are nothing more than another case in the selection mux in the RTL. So, you should write it that way. Use a default case and explicitly assign every output of the block in each case. This is generally considered best practice. It may not be the most clever or elegant way to write Verilog, but it is the most readable and results in far fewer errors (and in industry, people are more concerned with design verification to reduce costs than the cleverness of Verilog).

Also, as @dave_59 brought up, if you use the full_case Synopsis directive, then it will create default output drivers for you where the outputs are set to "don't cares." This is not a result that anyone wants, and it would be flagged by the verification team. To fix it, you would need to make sure every output is being assigned by adding them to all the cases like your boss mentioned. If you are forced to do this anyways, then full_case is redundant because you have explicitly made the case statement full. As for older synthesis tools, I don't see that being as big of an issue for this particular subject, but it is a consideration that is always given in industry. What would be more of an issue is if your company has configured downstream tools to force older constructs in an effort to reduce verification costs.

Trust your manager's experience on this issue. Coding style in industry is largely affected by collaboration with other engineers, costs, and legacy than by technical details. This is where your manager's experience will be valuable.