YosysHQ / apicula

Project Apicula 🐝: bitstream documentation for Gowin FPGAs
MIT License
496 stars 67 forks source link

MULT36x36 not working, but MULT18x18 is working! - DSP Primitive #242

Closed bjoernskau closed 7 months ago

bjoernskau commented 7 months ago

Hey apicula team

We are using the new DSP Primitives making a FIR filter using the MULT36x36 and some other blocks.

We found some problems with the MULT36x36, while representing a signed A or B input:

            wire [71:0] mult_1c;

            MULT36X36 uut(
            .DOUT   (mult_1c), 
            .A      (36'hFFFFFFFFFB),//-5
            .B      (36'h0000000005),// 5
            .ASIGN  (1'b1), 
            .BSIGN  (1'b1), 
            .CE     (1'b1), 
            .CLK    (clk), 
            .RESET  (!btn1_reset)
            );
            defparam uut.AREG=1'b1;
            defparam uut.BREG=1'b1;
            defparam uut.OUT0_REG=1'b1;
            defparam uut.OUT1_REG=1'b1;
            defparam uut.PIPE_REG=1'b0;
            defparam uut.ASIGN_REG=1'b1;
            defparam uut.BSIGN_REG=1'b1;
            defparam uut.MULT_RESET_MODE="SYNC";

Here I get the result:

FF FF FF FF FF FF EB FF E7 (hex)
111111111111111111111111111111111111111111111111111010111111111111100111 (bin)
-1310745 (dec)

So there is something wrong with the MULT36x36 bit 19 and 21, they should be 1 (these bits change when doing other signed multiplications)

On the other hand, the MULT18x18 works perfectly fine!

            wire [17:0] soa;
            wire [17:0] sob;
            wire [35:0] dout;

            MULT18X18 uut(
                    .DOUT   (dout), 
                    .SOA    (soa),
                    .SOB    (sob),
                    .A      (18'hFFFFB),//-5
                    .B      (18'h00005),// 5
                    .SIA    (18'b0),
                    .SIB    (18'b0),
                    .ASIGN  (1'b1),
                    .BSIGN  (1'b1),
                    .ASEL   (1'b0),
                    .BSEL   (1'b0),
                    .CE     (1'b1),
                    .CLK    (clk),
                    .RESET  (!btn1_reset)

                    );
                    defparam uut.AREG=1'b1;
                    defparam uut.BREG=1'b1;
                    defparam uut.OUT_REG=1'b1;
                    defparam uut.PIPE_REG=1'b0;
                    defparam uut.ASIGN_REG=1'b1;
                    defparam uut.BSIGN_REG=1'b1;
                    defparam uut.SOA_REG=1'b0;
                    defparam uut.MULT_RESET_MODE="SYNC";

Here I get the result:

 F FF FF FF E7 (hex)
111111111111111111111111111111100111 (bin)
-25 (dec)

And this is correct!

So there must be a problem in the MULT36x36 macro. Hope one of you guys can help solve the issue. Thank you in advance!

yrabbit commented 7 months ago

Great! Only real application can reveal all errors. I'll look at this multiplier and these tricky bits.

bjoernskau commented 7 months ago

I just cloned your mult36x36-fix branch and it works now! Thank you for the fast response, and fix!