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

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

NitzanD
Employee
1,962 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
1,798 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

0 Kudos
11 Replies
Nurina
Employee
1,941 Views

Hi,


What version of Quartus did you use?


Regards,

Nurina


0 Kudos
NitzanD
Employee
1,924 Views
0 Kudos
ak6dn
Valued Contributor III
1,935 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_preserve.htm

0 Kudos
NitzanD
Employee
1,922 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. 

 

 

0 Kudos
ak6dn
Valued Contributor III
1,870 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
1,860 Views

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

0 Kudos
ak6dn
Valued Contributor III
1,843 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.

0 Kudos
NitzanD
Employee
1,835 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?

0 Kudos
sstrell
Honored Contributor III
1,829 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.

0 Kudos
NitzanD
Employee
1,806 Views

Thanks ! Do you have any conclusions? 

0 Kudos
JDP
Employee
1,799 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.

0 Kudos
Reply