Skip to content

New IR causes DSP inference issues with Quartus #1148

Closed
@tpwrules

Description

@tpwrules

The following design (within the Details) infers 2 DSP blocks: Info (21062): Implemented 2 DSP elements.

from amaranth import *
from amaranth.lib import wiring
from amaranth.lib.wiring import In, Out

from amaranth_boards.de10_nano import DE10NanoPlatform

class DSPMACBlock(wiring.Component):
    # using signed 18x18->36 mode
    # https://www.intel.com/content/www/us/en/docs/programmable/683375/current/independent-multiplier-mode.html

    mul_a: In(signed(18)) # A input is 18 bits
    mul_b: In(signed(18)) # B input is 18 bits
    result: Out(signed(36)) # result is len(A)+len(B)

    def elaborate(self, platform):
        m = Module()

        m.d.sync += self.result.eq(self.mul_a * self.mul_b)

        return m

class Top(Elaboratable):
    def elaborate(self, platform):
        m = Module()

        m.submodules.mac = mac = DSPMACBlock()
        m.d.comb += [
            mac.mul_a.eq(Mux(platform.request("switch", 0).i, -1, 0)), # use all bits
            mac.mul_b.eq(Mux(platform.request("switch", 1).i, -1, 0)),
            platform.request("led", 0).o.eq(mac.result[-1])
        ]

        return m

if __name__ == "__main__":
    DE10NanoPlatform().build(Top())

Given that this is a supported DSP mode, I would expect this to infer only 1 block. This worked properly with the old IR. If I make both operands of the * signed by modifying line 107 of the generated Verilog (assign \$1 = ...) then correctly 1 block is inferred.

Not sure if there's any difference in functionality between the two scenarios.

Versions:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions