Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

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

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

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.

    Cheers,

    Alex
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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