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

How to avoid register "optimisation" in DSP

Altera_Forum
Honored Contributor II
4,638 Views

Hello everyone, 

 

I can't seem to solve this by my own: 

I'm using multipliers in my code, as you might know, on Stratix4 getting out of a DSP block has a timing cost of ~0.350ns 

 

So, I'm willing to spend 1 clock cycle to go out of a DSP block, BUT the synthesis aggressively wants to locate any register that I place after inside the DSP. Instanciating explicitely the alt_multadd module or lpm_mult does not change anything. 

 

The only way I found to avoid that is to place 2 "wasted" registers after, thus exhausting the register resources of any DSP slice, but that is ugly and only show that I don't know how to properly constrain my synthesis. 

Setting the following attributes does not change anything: 

preserve 

keep 

 

So, do you know of any assignment, or directive to "protect" my general register from this effect ? 

BTW what is this effect? (register merging, dsp balancing?)
0 Kudos
13 Replies
Altera_Forum
Honored Contributor II
2,735 Views

Quartus is doing that to optimize timing. Why do you want to disable it? 

 

Anyway, check http://quartushelp.altera.com/current/master.htm#mergedprojects/logicops/logicops/def_register_packing.htm
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

Thanks, it is indeed the register packing that is the cause of my troubles. 

 

Let me explain it a bit further: 

I have the following very simple pipeline: 

 

->FF_1-*(MULT)->FF_2->FF_3-(random combinatorial)->FF_4->... 

 

Note the FF_2-FF_3 is an empty cycle just to get out of the DSP, since it is empty it can be packed inside a DSP register slice as you will see. 

 

What I want is that: 

FF_1 is packed at the input register level of a DSP 

FF_2 is packed at the output register in a "DATAOUT" level of the DSP 

FF_3 is NOT packed 

 

indeed, if I do a block level synthesis (the module alone on the FPGA), it is what I get. 

 

BUT if I look at the complete synthesis output I have: 

FF_1 is NOT packed at the input register level of a DSP 

FF_2 is packed at the output register in a "First Adder0" level of the DSP 

FF_3 is packed at the output register in a "DATAOUT" level of the DSP 

 

Then of course the FF_3 to FF_4 timing arc is failing.... 

 

 

Do I have a way to know the reasons of those choices? How can I enforce what I actually want ? 

I had a look in the fitter messages and both block level and top level synthesis do what they do in the name of "Timing optimization".... 

 

many thanks
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

 

--- Quote Start ---  

Thanks, it is indeed the register packing that is the cause of my troubles. 

 

Let me explain it a bit further: 

I have the following very simple pipeline: 

 

->FF_1-*(MULT)->FF_2->FF_3-(random combinatorial)->FF_4->... 

 

Note the FF_2-FF_3 is an empty cycle just to get out of the DSP, since it is empty it can be packed inside a DSP register slice as you will see. 

 

What I want is that: 

FF_1 is packed at the input register level of a DSP 

FF_2 is packed at the output register in a "DATAOUT" level of the DSP 

FF_3 is NOT packed 

 

indeed, if I do a block level synthesis (the module alone on the FPGA), it is what I get. 

 

BUT if I look at the complete synthesis output I have: 

FF_1 is NOT packed at the input register level of a DSP 

FF_2 is packed at the output register in a "First Adder0" level of the DSP 

FF_3 is packed at the output register in a "DATAOUT" level of the DSP 

 

Then of course the FF_3 to FF_4 timing arc is failing.... 

 

 

Do I have a way to know the reasons of those choices? How can I enforce what I actually want ? 

I had a look in the fitter messages and both block level and top level synthesis do what they do in the name of "Timing optimization".... 

 

many thanks 

--- Quote End ---  

 

 

The reason is that given to you by Rbugalho and the keyword is register packing. When compiling a module on its own there is no shortage of registers in the fabrique and so the fitter does not pack them into dsp block. When compiled at project level you are likely short of registers and the fitter packed them in dsp blocks. 

You can disable this option at either project level or lower. see above link. 

Similarly if your dsp block is short of registers due to high interna l pipeline then fabrique registers are used.
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

Hello Kaz, 

I will have to rephrase a bit: 

 

Register packing happens in both cases, block or top level synthesis. What changes is the registers that get chosen for inclusion inside the DSP. 

 

You are mentionning the heuristic of the resource usage (the fitter will tend to use "free" resources, internal registers are free since if you use a dsp the registers are used alongside), but this is not the only driving force since the inputs are no longer registered using packed regs for a full design. (timing heuristic might prevail here, but my point is: this is unpredictable, I want to give the fitter a hint on what to prioritize) 

 

Also, I don't want to disable register packing on a module basis (I obviously want my multiplier to be used at its maximum speed thus surrounded by DSP regs) but on a set of register to help the fitter in its choices. is my understanding correct that this option has a module for minimal ganularity ? 

 

But to sumup my question: I have studied the DSP architecture, I know what I want. I am ready to sacrifice resources and design portability: how do I instruct Quartus to follow my directions? (ie. tell which register to use.)  

 

As no pragma seems to suit my needs I can think of 2 solutions: 

Solution1: direct instantiation of a lpm_mult or similar module with the proper options set. => I think this is useless, the fitter will repack/unpack if it thinks its clever, direct instantiation does not carry options to the fitter (ie. the map netlist will not be different). 

 

Solution2: design around the fitter algorithm and force it to take the decision we want (ie. small useless combinatorial on the output path that it can't find inside a DSP to avoid packing) 

 

But this seems dirty isn't it ?
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

You set "auto register packing" to off on your selected registers(not whole module). That way I expect the fitter to respect its promise.

0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

Thanks, I'm experimenting with it right now. It is working fine. 

 

Can those assignments be integrated in the source files ? for the moment those are assignments in the .qsf
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

 

--- Quote Start ---  

Thanks, I'm experimenting with it right now. It is working fine. 

 

Can those assignments be integrated in the source files ? for the moment those are assignments in the .qsf 

--- Quote End ---  

 

 

I just made up this syntax. Probably you need to chase it. 

 

attribute altera_attribute : string; 

attribute altera_attribute of my_reg : signal is "auto_register_packing OFF";
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

well here is better guess 

 

attribute altera_attribute : string; 

attribute altera_attribute of my_reg : signal is "-name auto_packed_registers OFF";
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

Mmmmm... 

the syntax is correct, but the vhdl embedded assignments are ignored: 

 

in fitter report: 

Warning (171167): Found invalid Fitter assignments. See the Ignored Assignments panel in the Fitter Compilation Report for more information. 

 

 

+------------------------------------------------------------------------------------------------------------------+ 

; Ignored Assignments ; 

+-----------------------+-----------------+--------------+------------+---------------+----------------------------+ 

; Name ; Ignored Entity ; Ignored From ; Ignored To ; Ignored Value ; Ignored Source ; 

+-----------------------+-----------------+--------------+------------+---------------+----------------------------+ 

; Auto Packed Registers ; power_estimator ; ; p1_x[0] ; OFF ; Compiler or HDL Assignment ; 

; Auto Packed Registers ; power_estimator ; ; p1_x[10] ; OFF ; Compiler or HDL Assignment ; 

; Auto Packed Registers ; power_estimator ; ; p1_x[11] ; OFF ; Compiler or HDL Assignment ; 

; Auto Packed Registers ; power_estimator ; ; p1_x[12] ; OFF ; Compiler or HDL Assignment ;
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

I am trying to follow the syntax described here: 

http://quartushelp.altera.com/current/mergedprojects/hdl/vhdl/vhdl_file_dir_attribute.htm 

 

here it is: 

attribute altera_attribute of p1_x : signal is "-name auto_packed_registers ""MINIMIZE AREA WITH CHAINS"""; 

 

and the result is: 

Error (271002): Can't process assignment. Attribute value "MINIMIZE AREA WITH CHAINS" for attribute "auto_packed_registers" is illegal -- use a legal attribute value for assignment in ALTERA_ATTRIBUTE assignment. 

Error (271002): Can't process assignment. Attribute value "MINIMIZE AREA WITH CHAINS" for attribute "auto_packed_registers" is illegal -- use a legal attribute value for assignment in ALTERA_ATTRIBUTE assignment. 

 

 

I have copied it from the qsf so it should be good....
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

ok, the syntax is good, because that: 

attribute altera_attribute of p1_x : signal is "-name auto_packed_registers ""MINIMIZE AREA"""; 

 

works. 

 

There seems to be a problem with "MINIMIZE AREA WITH CHAINS". 

 

 

anyway, regardless of that minor bug, all HDL assignments are joyfully ignored...
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

try this: 

attribute altera_attribute of p1_x : signal is "-name auto_packed_registers MINIMIZE AREA WITH CHAINS";
0 Kudos
Altera_Forum
Honored Contributor II
2,735 Views

This time I can contribute some usefull tric, the right assignment syntax is: 

 

attribute altera_attribute of p1_x : signal is "-name AUTO_PACKED_REGISTERS_STRATIXII ""MINIMIZE AREA WITH CHAINS"""; 

 

Even if the target is STRATIXIV.... 

(copied exactly from the .qsf file)
0 Kudos
Reply