Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Need Forum Guidance? Click here

Search our FPGA Knowledge Articles here.
19348 Discussions

Is my design using 'hard' multipliers? How do I find out? How do I force it?

Honored Contributor II

I've got following (below) Verilog module.  


When I compile it i see no DSP blocks etc used in the report.  


How can I tell if it is using a hardware multiplier and if not how can I force it to use one so I can gauge that performance? 


I will attatch the full .syn.rpt. 


wbr Kusti 



/* Machine-generated using Migen */ module correlator( input e, input a, input b, input o, output reg oe, input sys_clk, input sys_rst ); reg signed counter = 8'sd255; reg product = 20'd0; reg accum_product = 26'd0; reg accum_in_a = 16'd0; reg accum_in_b = 16'd0; reg product_accum_in_a_and_b = 32'd0; reg final_result = 32'd0; always @(posedge sys_clk) begin if (($signed({1'd0, e}) & (counter < $signed({1'd0, 1'd0})))) begin counter <= 7'd65; end else begin if ((counter >= $signed({1'd0, 1'd0}))) begin counter <= (counter - $signed({1'd0, 1'd1})); end end if (($signed({1'd0, e}) | (counter >= $signed({1'd0, 1'd0})))) begin product <= (a * b); accum_product <= (accum_product + product); accum_in_a <= (accum_in_a + a); accum_in_b <= (accum_in_b + b); product_accum_in_a_and_b <= (accum_in_a * accum_in_b); end if ((counter == $signed({1'd0, 1'd0}))) begin final_result <= ((accum_product * 7'd64) - product_accum_in_a_and_b); oe <= 1'd1; end if (oe) begin oe <= 1'd0; accum_in_a <= 1'd0; accum_in_b <= 1'd0; accum_product <= 1'd0; product <= 1'd0; product_accum_in_a_and_b <= 1'd0; counter <= 1'sd1; final_result <= 1'd0; end if (sys_rst) begin oe <= 1'd0; counter <= 8'sd255; product <= 20'd0; accum_product <= 26'd0; accum_in_a <= 16'd0; accum_in_b <= 16'd0; product_accum_in_a_and_b <= 32'd0; final_result <= 32'd0; end end endmodule
0 Kudos
2 Replies
Honored Contributor II

If you infer multipliers in your code, as you have done, Quartus needs to be able to identify all the bits around the multiplier that it needs to take and fit in to a DSP block. This includes various input & output registers. 


Look at the block diagram for the DSP block. You'll see input registers that only feed the internals of the DSP block, including the multiplier. 


Your 'product' signal is the product of 'a' & 'b'. However, both 'a' & 'b' feed other logic too. So Quartus can't put those registers into the DSP block - there's no path out of the DSP block for either 'a' or 'b'. Hence it can't fit your code into a DSP block and Quartus will have created it all in logic. 


A sure way to force a multiplier into a DSP block is to infer a multiplier created via the IP catalogue. However, that way you'll have to work with the input/output registers in the IP and the 'extra' clock cycles required. 



Honored Contributor II

Thanks for the tips. I've reworked my stuff and the DSP block is now correctly inferred according to the syn report.