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

quartus 7.1 SP1 produces WRONG rtl !

Altera_Forum
Honored Contributor II
1,669 Views

Can somebody verify ? This thing is giving me nightmares .... 

 

module wrong ( inout cs, output selected, input enable, input override, input something ); always_comb begin if (override) begin // if 'override' cs = something; // drive the CS with 'something' selected = 1'b0; // 'selected' is zero end else begin // if not 'override' : cs = 1'bz; // tristate CS selected = (cs & enable ); // incoming CS signal AND 'enable' end end endmodule  

 

This produces completely wrong RTL. 

The else clause does not work. It should logically and the INCOMING value on the CS pin with the 'enable' signal. 

 

Look at the RTL output. the bidirectional pin has no input path !!!! 

 

how do i fix this ? I have a very large block that switches a whole system around using tristating mechanism there are a bunch of these constructions in there. What's worse : Some work some don't... and they are cut copy and pastes of the above mechanism ...
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
729 Views

It gets worse in Quartus 7. 2 !  

the output is even MORE wrong ! 

 

This is the circuit i want : 

TRI | |SOMETHING>--| >------o-----<CS> |/ | _____ | |_| | |OVERRIDE>----+--|>0----|AND3 |---<SELECTED| |-|_____| |ENABLE>--------------|  

 

if OVERRIDE is low. the SELECTED output is the logical AND of 'ENABLE' and the incoming level on CS. 

if OVERRIDE is HIGH , SELECTED is zero and the CS pin is controlled by 'SOMETHING'. 

 

 

This is what quartus 7.2 produces ... 

|OVERRIDE>--------+---------- | _|_ |ENABLE> (gnd) | | \ | 0-|0 | | | |--|SELECTED> | 0-|1 | | |___/ | | |SOMETHING>------| >----<CS> |/ TRI
0 Kudos
Altera_Forum
Honored Contributor II
729 Views

There's nothing wrong with the software. You're assigning cs = 1'bz (a blocking assignment), then referring to cs in an expression immediately following assignment. Effectively, you're assigning selected = (1'bz & en) in the else statement. The expression returns don't-care according to the Verilog standard. The software is free to select 0 or 1 for the don't care condition. It obviously chooses 0 in this case.  

 

Do you mean to say: 

 

assign selected = (override) ? 1'b0 : cs & enable; assign cs = (override) ? something : 1'bz;
0 Kudos
Altera_Forum
Honored Contributor II
729 Views

and it gets even WORSE ! 

 

if i swap the 'Z' assigment and the next line : 

 

This : cs = 1'bz; // tristate CS selected = (cs & enable ); // incoming CS signal AND 'enable' change to: selected = (cs & enable ); // incoming CS signal AND 'enable' cs = 1'bz; // tristate CS  

 

it DOES compile correctly ! 

 

This is a mayor problem. I have a complex block where,depending on a bunch of control signals i switch this tristate driver either hard to zero , hard to 1 , under control of a logic equasion 

 

cs=1'bz; // by default we are 'z' if (condition) begin case (state) // except ... case 4'b1100 : cs = something; case 4'b0000 : cs = something_else case 4'b1010 : cs = 1'b0; case 4'b1101 : cs = 1'b1; case 4'b1110 : begin if yadayada then cs = 1'b1; else cs = 1'bz; end case 4'b1001 : begin if so_and_so then cs = this; else cs = 1'bz; end default : cs = 1'bz; end endcase  

 

( the real decision block is even more complex since there are a lot more sub 'case statements' that decide on the state of CS ) 

 

Why does this not work? this is normal scheduled code.... its 'z' excpet if so and so and this and that ... or does scheduling not work in this case ?
0 Kudos
Altera_Forum
Honored Contributor II
729 Views

An always construct contains a sequential block of code. That is, the statements execute in a particular sequence or order. A blocking assignment updates the value of the target BEFORE any of the following statements execute. So if you reverse the order of the assignments, you don't update cs to 1'bz prior to using it in your expression. Even so, it's not a safe transformation. If the always construct re-executed for any reason, you'd get the result you don't want.

0 Kudos
Altera_Forum
Honored Contributor II
729 Views

 

--- Quote Start ---  

There's nothing wrong with the software. You're assigning cs = 1'bz (a blocking assignment), then referring to cs in an expression immediately following assignment. Effectively, you're assigning selected = (1'bz & en) in the else statement. The expression returns don't-care according to the Verilog standard. The software is free to select 0 or 1 for the don't care condition. -snip- 

 

 

--- Quote End ---  

 

 

I agree that the synthesizer is free to squash a 'Z' to "don't care" if this would be an OUTPUt or an INPUT.  

 

In my case the CS signal is a tristatable (inout) signal !  

 

Assigning a 'Z' means : tristate it. The remaining logic should still sense the real value of CS in the equasion ! There is no other way in verilog to declare ; i want you to 'tristate' this signal , then assigning it a 'Z'. 

 

See my previous post about how i control this CS pin from a complex case statement. How on earth do i write the verilog code to reproduce that correctly ? 

 

Would defining CS as a reg and using non-blocking assignments solve this ?
0 Kudos
Altera_Forum
Honored Contributor II
729 Views

I tried it. It works. 

 

module wrong ( inout reg cs , output reg selected, input enable, input override , input something); if (override) begin cs <= something; selected <= 1'b0; end else begin selected <= (cs & enable ); cs <= 1'bz; end end endmodule  

 

here i can swap the 'z' assignemt line freely. It works correctly in both cases. 

This is a source of ambiguity that should not be there. 

 

The synthesizer should detect : hey, this is defined as a bidirectional signal (inout) ... If it is assigned 'z' (whether blocking or non-blocking), it means: that signal is tristated, but someone else can still be driving this signal... i should not minimize attached logic away !!!! 

 

And even if that is the way verilog works, it does not explain why the RTL generated in Quartus 7.1 is completely different from 7.2 ( for -EXACTLY- the same source code ! ) I coudln't find a mentioning of a verilog bugfix in the release notes.
0 Kudos
Altera_Forum
Honored Contributor II
729 Views

I avoid blocking statements in always statements like the plague. Unless I really feel they help, and I understand what it's going to synthesize to, they tend to cause much more trouble than they are worth(there are reasons for them, but most HDL books don't sufficiently warn users of their downside). They also can simulate differently than what they synthesize to, and I worked with someone who wasted week/s trying to work around this, where if they had used non-blocking statements they would have been fine.  

And of course, the same code can be synthesized in different ways. The one you show for 7.2 looks correct, just not what you wanted. I'm guessing the one for 7.1 was correct too, just different and again, not what you wanted. Anyway, once you stick with non-blocking assignments, you should be a lot happier.
0 Kudos
Altera_Forum
Honored Contributor II
729 Views

yep. i converted everything to non blocking and it works fine now. 

 

Still if find it very distrubing that seemingly correct code synthesized completely wrong ! 

Again , i understand that the synthesizer is free to minimize away 'Z' lines if you assign this to a UNIDIRECTIONAL signal. 

 

but assigning a 'Z' to a BIDIRECTIONAL ( inout ) should trigger the synthesizer ; this is bidirectional , all i need to do is tristate the driver. the 'sensing' logic should not be impacted by this. 

 

This is an ambiguity in the language. There should be a specific statement for 'make the line 'high impedant' but don;t touch the sensing logic attached to it. 

 

The FPGA interfaces to a bunch of external logic that all uses bidirectional data and control buses. That's where i ran into trouble. 

 

The really frustrating part is that i originally intende to draw this in a schematic ! there is NO possibility ambiguity there.  

 

time for Verilog2008 ?
0 Kudos
Altera_Forum
Honored Contributor II
729 Views

I don't disagree that it's unintuitive and I really don't like it, but it's defined by the verilog language, and I believe every synthesizer would give you similar results. So the code was not correct for what you intended. There is definitely an ambiguity to HDLs. This has some great pros(like being able to write high-level transactions, state-machines without encoding them, portability across different targets, parameterizable code, etc.) but that also has issues. You're doing the right thing though, writing some code and looking at what comes out. It'll quickly become second nature where you know approximately how the HDL you write will get synthesized, and it'll be as easy, if not easier, than doing schematics.

0 Kudos
Altera_Forum
Honored Contributor II
729 Views
0 Kudos
Reply