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

Mixed sign math problem

Altera_Forum
Honored Contributor II
1,484 Views

The background: I'm working on QAM modulation from a Cyclone II dev board with a DAC board I made connected to it. Works great as a DDS and everything other than the QAM math. 

The main QAM calculation is icos(t)-qsin(t). I implemented sin and cos as lookup tables in a module. The following simulates properly in iverilog: 

 

// leaving out standard stuff, only relevant lines shown (full paste at the end) input signed i; // input values input signed q; output dacval; // output to the DAC wire signed sin; // the values back from the lookup tables wire signed cos; reg signed dacfull; // holds the full size value always @(negedge clk) begin dacfull=(i*cos)-(q*sin); // the qam value dacval=(dacfull/64)+512; // scale down, then add to make positive end endmodule 

 

Here's the problem: the above simulates great, but when I go to synthesize it with Altera, I get the following at the end:  

Warning (13410): Pin "dacval" is stuck at GND Warning (13410): Pin "dacval" is stuck at GND 

 

However, if I change the math section above to just: 

dacval=(sin*4)+512; // multiply to full range, then add to make positive  

It synthesizes without error, and runs perfectly in hardware (outputting a beautiful sine). 

I spent hours today fooling with different ways to present the signed+unsigned math, but I can't get the Altera synth to like it. What's the proper way? 

 

The sin/cos LUT: http://paste.ubuntu.com/5763310 

The IQ mod code: http://paste.ubuntu.com/5763316 

Full output from synthesis: http://paste.ubuntu.com/5763317
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
484 Views

The problem is that a signed multiply effectively wastes one bit, which is necessary to avoid an overflow with -128*-128. To effectively utilize the result number range, dacfull must be resized to 15 bit with saturation logic applied, means 0x4000 (-16384) must be truncated to 0x3FFF (-16383). 

 

ieee.fixed_pkg has a built-in saturation logic feature and is the most convient way to handle these problems. Or write your own functions to handle signed arithmetic with saturation.
0 Kudos
Altera_Forum
Honored Contributor II
484 Views

You're right about the extra bit for a full-range multiply, but I handled that problem by generating the LUT to go from -127 to 127. 

 

The problem gets weirder though... it synthesesizes and runs correctly in hardware if the input vars are registers: 

 

reg signed ri; reg signed rq; dacfull=(ri*cos)-(rq*sin); dacval=(dacfull/64)+512; 

 

I set ri and rq in the initial to exactly the same values I set i and q to in the top-level module. Using the registers like that, the synth figures out that I need multiplication (which it never did without the registers): 

 

Info (278003): Inferred multiplier megafunction ("lpm_mult") from the following logic: "iqmod:myiq|Mult0" 

 

But here's the weird part: if I set ri and rq to i and q anywhere, it does the same thing it did before: no multiplier infered, and dacval is always 0. I tried "ri=i; rq=q;" just above the math lines, as well as adding a separate block @(i,q) where the registers are set, and both ways fail. 

 

I verified throughout the code that i+q are exactly the same type as ri and rq (signed 8-bit registers), except ri and rq are defined in this module and i and q are defined in the above level. What am I missing?
0 Kudos
Altera_Forum
Honored Contributor II
484 Views

It looks like if the synth sees that ri and rq can change anywhere, it just gives up and decides the multiplication expression will always be 0. Whenever it decides they don't change (ie, when it works), it notes that one input to the multiplier is constant: 

 

Info (278001): Inferred 1 megafunctions from design logic Info (278003): Inferred multiplier megafunction ("lpm_mult") from the following logic: "iqmod:iq0|Mult0" Info (12130): Elaborated megafunction instantiation "iqmod:iq0|lpm_mult:Mult0" Info (12133): Instantiated megafunction "iqmod:iq0|lpm_mult:Mult0" with the following parameter: Info (12134): Parameter "LPM_WIDTHA" = "8" Info (12134): Parameter "LPM_WIDTHB" = "8" Info (12134): Parameter "LPM_WIDTHP" = "16" Info (12134): Parameter "LPM_WIDTHR" = "16" Info (12134): Parameter "LPM_WIDTHS" = "1" Info (12134): Parameter "LPM_REPRESENTATION" = "SIGNED" Info (12134): Parameter "INPUT_A_IS_CONSTANT" = "YES" Info (12134): Parameter "INPUT_B_IS_CONSTANT" = "NO" Info (12134): Parameter "MAXIMIZE_SPEED" = "5" Info (12131): Elaborated megafunction instantiation "iqmod:iq0|lpm_mult:Mult0|multcore:mult_core", which is child of megafunction instantiation "iqmod:iq0|lpm_mult:Mult0" Info (12131): Elaborated megafunction instantiation "iqmod:iq0|lpm_mult:Mult0|multcore:mult_core|mpar_add:padder", which is child of megafunction instantiation "iqmod:iq0|lpm_mult:Mult0" Info (12131): Elaborated megafunction instantiation "iqmod:iq0|lpm_mult:Mult0|multcore:mult_core|mpar_add:padder|lpm_add_sub:adder", which is child of megafunction instantiation "iqmod:iq0|lpm_mult:Mult0" Info (12021): Found 1 design units, including 1 entities, in source file db/add_sub_qfh.tdf Info (12023): Found entity 1: add_sub_qfh Info (12131): Elaborated megafunction instantiation "iqmod:iq0|lpm_mult:Mult0|altshift:external_latency_ffs", which is child of megafunction instantiation "iqmod:iq0|lpm_mult:Mult0"
0 Kudos
Reply