Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15378 Discussions

Quartus synthesis deletes bits of a variable that gets a constant value

NitzanD
Employee
519 Views

Hi  
I am running synthesis on a module that has to reg variables of [11:0] bits.
These variables are getting constant values according to a switch case on two of the inputs. 
This is my code: 

module HT3Input12 (
input selector_msb,
input selector_lsb,
input [11:0] InData0,
input [11:0] InData1,
output check
);

wire [11:0] Data0 = InData0;
wire [11:0] Data1 = InData1;

reg [11:0] Compare_data0A0;
reg [11:0] Compare_data1A1;

//assign Compare = ( reset_n == 1'b1 ) ? 12'hFFF : 12'd0 ;

//-------------------------------------------------------
// Selectors MAP
//-------------------------------------------------------
// 00 - Send 0s on all pins
// 01 - Send a series of '101010...' , first bit is '1'
// 10 - Send a series of '010101...' , first bit is '0'
// 11 - Send 1s on all pins
//-------------------------------------------------------


always @(*)
case ({selector_msb,selector_lsb})
2'b00:
begin
Compare_data0A0 <= 12'd0;
Compare_data1A1 <= 12'd0;
end
2'b01:
begin
Compare_data0A0 <= 12'hABC;
Compare_data1A1 <= 12'h789;
end
2'b10:
begin
Compare_data0A0 <= 12'b101010101010;
Compare_data1A1 <= 12'b101010101010;
end
2'b11:
begin
Compare_data0A0 <= 12'hFFF;
Compare_data1A1 <=12'hFFF;
end

endcase

//assign Compare = ( selector_msb == 1'b1 ) ? 12'hFFF : 12'd0 ;

assign check = ((Data0 == Compare_data0A0) && (Data1 == Compare_data1A1)) ? 1'b1 : 1'b0 ;

 

In synthesis  - there is only one of the two regs left (only Compare_data0A0) and it has only 2 bits instead of 12. It can also be seen in the SignalTap pre-synthesis signals and Schematics - the 9 LSB are deleted. 
Can you explain why this is happening?
When I declare them both as output reg - problem solved and they're both declared as expected after synthesis. 
In my .v file you can see Compare_data0A0 and Compare_data1A1 that are assigned in the case and in synthesis most of their bits are gone. 
the path to the .v file in the zip file that I attached  is: for_check/DIE1/HT3Input12.v 

0 Kudos
1 Solution
JDP
Employee
355 Views

JDP_0-1626706072452.png

The input patterns requested all match to 4 possible cases – the MSB exactly, the LSB exactly, Or values E or 8

This seems to match exactly to the design being inferred by synthesis – what is being compared is ambiguous in the netlist viewer diagram, but it is using the MSB, LSB and these two 4-bit constants to accomplish the comparison.

Since every individual bit takes resources in an FPGA, it makes sense to minimize the functions like this to save resources.

View solution in original post

11 Replies
Nurina
Employee
498 Views

Hi,


What version of Quartus did you use?


Regards,

Nurina


NitzanD
Employee
481 Views
ak6dn
Valued Contributor II
492 Views

Simply, Quartus synthesis optimization is 'smart'. It will reduce logic to make it simpler. It will detect logic that is constant and eliminate it, and replace it with the constant value. So that is what is going on.

This optimization is a feature and not a bug.

If you really want to preserve the (constant) register bits, you need to forcefully tell Quartus to do so, making the registers outputs, or using some of the attributes you can apply to signals and registers. Like 'syn_preserve':

See: https://www.intel.com/content/www/us/en/programmable/quartushelp/17.0/hdl/vlog/vlog_file_dir_preserv...

NitzanD
Employee
479 Views

Thanks for your answer !  
I tried the syntax in the link that you added but it only kept several bits and not all of them, but I will check if it remains correct and update. 
What you are explaining is wrong in my opinion because its not an optimization - its a bug. it creates a different constant which makes it a bug in the code. 

 

 

ak6dn
Valued Contributor II
427 Views

I respectfully disagree. What I explained is the correct behavior that that Quartus optimization should show. Constant logic is evaluated and replaced by constants. That is normal behavior. If an output is not used, it can be pruned back until all logic basically disappears as Quartus detects and keeps removing unused logic. This is the default optimization behavior. You can override it with synthesis directives as I explained.

Now the allegation that you say Quartus is incorrectly replacing the constant logic with incorrect constants is another issue. It could certainly be that you uncovered a bug in Quartus.

But in your test check.zip code there are multiple instances of your module, and each instance will be optimized differently. So my suspicion is you think you are looking a the optimized version of instance A when you are really looking at the optimized version of instance B (or C or D).

Just my guess at this point. Your test code is way to big for me to go thru. You need to make a smaller test example to exhibit the issue.

NitzanD
Employee
417 Views

I tried to make it smaller now, having only one .v file - Is it something that you can look at now? 

ak6dn
Valued Contributor II
400 Views

Sorry, no. I am a user of this forum. If you can show simulation waveforms or outputs which you believe demonstrate error(s) we can comment on them. But I am not in a position to analyze your design in detail looking for a possible error.

NitzanD
Employee
392 Views

It can be seen in Signal Tap tool: 
You can see here that compare_data0 has only 2 bits, and compare_data1 is not even there. 

NitzanD_0-1626241894340.png


And also in scheme it can be seen that the constant that goes to comparison is incorrect: 

NitzanD_1-1626243219905.png

In the lab on the FPGA itself it does not compare it correctly. I get 0x800 or 0xC00 for the constants which means only the two MSBs are changing. 

I am adding here again the code: 

//---------------------------------------------------------------------------------------------------
module HT3Input12 (
input selector_msb,
input selector_lsb,
input [11:0] InData0,
input [11:0] InData1,
output check 
);

wire [11:0] Data0 = InData0;
wire [11:0] Data1 = InData1;

reg [11:0] Compare_data0;
reg [11:0] Compare_data1;


//-------------------------------------------------------
// Selectors MAP
//-------------------------------------------------------
// 00 - Send 0s on all pins
// 01 - Send a series of '101010...' , first bit is '1'
// 10 - Send a series of '010101...' , first bit is '0'
// 11 - Send 1s on all pins
//-------------------------------------------------------


always @(*)
case ({selector_msb,selector_lsb})
2'b00:
begin
Compare_data0 = 12'd0;
Compare_data1 = 12'd0;
end
2'b01:
begin
Compare_data0 = 12'hABC;
Compare_data1 = 12'h789;
end
2'b10:
begin
Compare_data0 = 12'b101010101010;
Compare_data1 = 12'b101010101010;
end
2'b11:
begin
Compare_data0 = 12'hFFF;
Compare_data1 =12'hFFF;
end
endcase


assign check = ((Data0 == Compare_data0) && (Data1 == Compare_data1)) ? 1'b1 : 1'b0 ;


endmodule

//---------------------------------------------------------------------------------------------------

Do you know how can I report a bug on Quartos?

sstrell
Honored Contributor III
386 Views

That's just weird.  I'd try deleting the compilation database files (db and incremental_db folders in Standard, qdb folder in Pro) and synthesize again.

NitzanD
Employee
363 Views

Thanks ! Do you have any conclusions? 

JDP
Employee
356 Views

JDP_0-1626706072452.png

The input patterns requested all match to 4 possible cases – the MSB exactly, the LSB exactly, Or values E or 8

This seems to match exactly to the design being inferred by synthesis – what is being compared is ambiguous in the netlist viewer diagram, but it is using the MSB, LSB and these two 4-bit constants to accomplish the comparison.

Since every individual bit takes resources in an FPGA, it makes sense to minimize the functions like this to save resources.

Reply