BrianHG
Occasional Contributor
3 years agoHaving trouble with a 'real' floating point parameter.
I'm having trouble with my code which is designed to generate an integer look-up table, however, the formula requires a few numbers which a real/floating point.
The code simulates properly in Modelsim, however, within Quartus, all the results return '0' except for the last entry.
Example working Modelsim output:
# ** Warning: ****************************************************** # ** Warning: *** BrianHG's BHG_jt49_exp.v dlut table generator. *** # ** Warning: ********************************************************************* # ** Warning: *** dlut[0:31]='{ 0, 1, 2, 3, 4, 6, 7, 9, *** # ** Warning: *** 11, 13, 16, 19, 22, 26, 30, 34, *** # ** Warning: *** 39, 45, 51, 59, 67, 76, 86, 97, *** # ** Warning: *** 110, 124, 140, 158, 178, 201, 226, 255} *** # ** Warning: *********************************************************************
Example Quartus output:
Warning (10977): SystemVerilog $warning at BHG_jt49_exp.v(66): ****************************************************** Warning (10977): SystemVerilog $warning at BHG_jt49_exp.v(67): *** BrianHG's BHG_jt49_exp.v dlut table generator. *** Warning (10977): SystemVerilog $warning at BHG_jt49_exp.v(68): ********************************************************************* Warning (10977): SystemVerilog $warning at BHG_jt49_exp.v(69): *** dlut[0:31]='{ 0, 0, 0, 0, 0, 0, 0, 0, *** Warning (10977): SystemVerilog $warning at BHG_jt49_exp.v(70): *** 0, 0, 0, 0, 0, 0, 0, 0, *** Warning (10977): SystemVerilog $warning at BHG_jt49_exp.v(71): *** 0, 0, 0, 0, 0, 0, 0, 0, *** Warning (10977): SystemVerilog $warning at BHG_jt49_exp.v(72): *** 0, 0, 0, 0, 0, 0, 0, 255} *** Warning (10977): SystemVerilog $warning at BHG_jt49_exp.v(73): *********************************************************************
The Quartus lookup table is all empty until the last byte which has the correct 256.
Here is the source code:
module BHG_jt49_exp #( parameter DAC_BITS = 8, // The number of DAC bits for each channel of the YM2149 PSG. Supports 8 thru 12. parameter VOL_ATT_DB = 0 // The decibel attenuation volume at 1 of 31. Range = -10 to 20*log(1/(2^DAC_BITS-1)). // Use 0 for the optimum dynamic range based on parameter 'YM2149_DAC_BITS'. )( input clk, input [1:0] comp, // *** NO LONGER USED input [4:0] din, output reg [DAC_BITS-1:0] dout = 0 ); // Make a lookup table with this LOG computation which defines the DAC's LSB SNR. // 20*log(1/(2^DAC_BITS-1)) //localparam real DAC_LSB_DB [8:12] = '{ -48.1308,-54.1684,-60.1975,-66.2224,-72.2451 } ; localparam int DAC_LSB_DB [8:12] = '{48,54,60,66,72} ; // Select either the user set volume attenuation or, // automatically select from the DAC_LSB_DB lookup table -15db // so that the minimum volume bits actually increment at volumes 0,1,2,3... // without repeats. IE: More DAC bits, the better the dynamic range. localparam int VOL_ATT = (VOL_ATT_DB==0) ? -(DAC_LSB_DB[DAC_BITS]-15) : VOL_ATT_DB ; localparam real VOL_factor = VOL_ATT/31 ; // factor the decibel range over the 5bit volume range. // Volume attenuation to linear amplitude formula with -infinity/basement mute correction. `define atten_db(x) ( (10**(((31-x)*VOL_factor)/20) *(2**DAC_BITS-1)) ) `define gain_fix ( (2**DAC_BITS-1) / (`atten_db(31) - `atten_db(0)) ) `define dac_out(z) ( (`atten_db(z) - `atten_db(0)) * `gain_fix ) // Convert the 'real' floating point number into an integer table for Quartus compatibility. integer dlut [0:31] ; initial for (int i=0;i<32;i++) dlut[i] = ( `dac_out(i) ); generate initial begin $warning("******************************************************"); $warning("*** BrianHG's BHG_jt49_exp.v dlut table generator. ***"); $warning("*********************************************************************"); $warning("*** dlut[0:31]='{%d,%d,%d,%d,%d,%d,%d,%d, ***",12'(dlut[ 0]),12'(dlut[ 1]),12'(dlut[ 2]),12'(dlut[ 3]),12'(dlut[ 4]),12'(dlut[ 5]),12'(dlut[ 6]),12'(dlut[ 7])); $warning("*** %d,%d,%d,%d,%d,%d,%d,%d, ***",12'(dlut[ 8]),12'(dlut[ 9]),12'(dlut[10]),12'(dlut[11]),12'(dlut[12]),12'(dlut[13]),12'(dlut[14]),12'(dlut[15])); $warning("*** %d,%d,%d,%d,%d,%d,%d,%d, ***",12'(dlut[16]),12'(dlut[17]),12'(dlut[18]),12'(dlut[19]),12'(dlut[20]),12'(dlut[21]),12'(dlut[22]),12'(dlut[23])); $warning("*** %d,%d,%d,%d,%d,%d,%d,%d} ***",12'(dlut[24]),12'(dlut[25]),12'(dlut[26]),12'(dlut[27]),12'(dlut[28]),12'(dlut[29]),12'(dlut[30]),12'(dlut[31])); $warning("*********************************************************************"); end endgenerate // Clock the look-up table. always @(posedge clk) dout <= (DAC_BITS)'( dlut[din] ); endmodule
Lines 28,29,30 are where the floating point calculation takes place.
The portion ' 10**(((31-x)*VOL_factor)/20) ' is an exponent which is a fraction, so fixed justification tricks wont work.
I would like this table to be calculated depending on user parameter inputs.
Is there anything I can do?