YosysHQ / nextpnr

nextpnr portable FPGA place and route tool
ISC License
1.29k stars 242 forks source link

No option named X for enum EBR3.PDPSC16K_MODE.DATA_WIDTH_R in tile CIB_R29C11:EBR_9 #1254

Closed slagernate closed 10 months ago

slagernate commented 10 months ago

Using Amaranth 0.4 (w/ Yosys 0.35) with prjoxide 0.1 and nextpnr 0.6-152 (these are all latest AFAIK) but getting the following:

Info: Program finished normally.
thread 'main' panicked at 'No option named X for enum EBR3.PDPSC16K_MODE.DATA_WIDTH_R in tile CIB_R29C11:EBR_9.
Valid options are: X1, X18, X2, X32, X36, X4, X9
Please make sure Oxide and nextpnr are up to date and input source code is meaningful. If they are, consider reporting this as an issue.', prjoxide/src/chip.rs:415:75

While a manual fix of the 'X' option in Amaranth's generated Verilog allows for a successful build, the EBR does not appear to behave normally.

Can make an MRE at some point.

slagernate commented 10 months ago

Here is the EBR instantiation from yosys.debug.v:

PDPSC16K #(
    .ASYNC_RST_RELEASE("ASYNC"),
    .CSDECODE_R("111"),
    .CSDECODE_W("111"),
    .DATA_WIDTH_R("X         4"),
    .DATA_WIDTH_W("X         4"),
    .ECC("DISABLED"),
    .GSR("DISABLED"),
    .INITVAL_00("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_01("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_02("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_03("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_04("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_05("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_06("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_07("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_08("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_09("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_0A("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_0B("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_0C("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_0D("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_0E("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_0F("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_10("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_11("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_12("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_13("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_14("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_15("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_16("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_17("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_18("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_19("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_1A("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_1B("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_1C("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_1D("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_1E("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_1F("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_20("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_21("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_22("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_23("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_24("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_25("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_26("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_27("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_28("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_29("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_2A("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_2B("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_2C("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_2D("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_2E("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_2F("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_30("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_31("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_32("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_33("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_34("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_35("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_36("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_37("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_38("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_39("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_3A("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_3B("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_3C("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_3D("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_3E("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .INITVAL_3F("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000"),
    .OUTREG("BYPASSED"),
    .RESETMODE("ASYNC")
  ) \U$$0.U$$0.U$$0.storage.0.0  (
    .ADR({ \U$$0.U$$0.U$$0.consume , \pin_ft_oe_n_0.ft_oe_n_0__o , \pin_ft_oe_n_0.ft_oe_n_0__o  }),
    .ADW({ \U$$0.U$$0.U$$0.produce , \pin_ft_oe_n_0.ft_oe_n_0__o , \pin_ft_oe_n_0.ft_oe_n_0__o  }),
    .CER(\U$$0.U$$0.U$$0.storage_r_en ),
    .CEW(\U$$0.U$$0.U$$0.storage_w_en ),
    .CLK(\U$$0.U$$0.U$$0.ft_d_clk_0__i ),
    .CSR({ \pin_ft_oe_n_0.ft_oe_n_0__o , \pin_ft_oe_n_0.ft_oe_n_0__o , \pin_ft_oe_n_0.ft_oe_n_0__o  }),
    .CSW({ \pin_ft_oe_n_0.ft_oe_n_0__o , \pin_ft_oe_n_0.ft_oe_n_0__o , \pin_ft_oe_n_0.ft_oe_n_0__o  }),
    .DI({ \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$1.en$8 , \U$$0.U$$0.U$$0_w_data [3:0] }),
    .DO({ \U$$0.U$$0.U$$0.storage.0.0_DO [35:4], \U$$0.U$$0.U$$0.storage_r_data [3:0] }),
    .RST(\U$$0.U$$1.en$8 )
  );

The error originates from .DATA_WIDTH_R("X 4"), where a few spaces are inserted (to recap, this can compile if the spaces are manually removed, yet the behaviour appears to be incorrect, reading out zeros all or if not most of the time).

Making an MRE for the Nexus Crosslink-NX eval board now.

slagernate commented 10 months ago

And here is example amaranth which reproduces the panic above (albeit the memory behaves as expected on the crosslink-nx eval board): Note: using a Lattice Vendor platform and a eval board definition file

import itertools
import os
from amaranth import *
from amaranth.lib.fifo import *
from amaranth.build import *
​
​
from amaranth_boards.boards.lifcl_evn import LIFCLEVNPlatform
​
class DebugModule(Elaboratable):
​
    def __init__(self):
​
        self.fifo = SyncFIFOBuffered(width=32, depth=4096)
        self.data_o = Signal(12)
​
    def elaborate(self, platform):
        m = Module()
        m.submodules += self.fifo
​
        clk_div = Signal(24)
        counter = Signal(32)
        buf = Signal(32)
​
        m.d.sync += clk_div.eq(clk_div + 1)
​
        with m.If(clk_div == 0 & self.fifo.r_rdy):
            m.d.sync += self.fifo.r_en.eq(1)
​
        with m.If(self.fifo.r_en):
            m.d.sync += buf.eq(self.fifo.r_data)
            m.d.sync += self.fifo.r_en.eq(0)
​
        with m.If(self.fifo.w_rdy):
            m.d.sync += self.fifo.w_data.eq(counter)
            m.d.sync += self.fifo.w_en.eq(1)
            m.d.sync += counter.eq(counter + 1)
        with m.Else():
            m.d.sync += self.fifo.w_en.eq(0)
​
        for i in range(8):
            m.d.comb += self.data_o[i].eq(buf[4*i:(4*i)+4].any())
​
        def get_all_resources(name):
            resources = []
            for number in itertools.count():
                try:
                    resources.append(platform.request(name, number))
                except ResourceError:
                    break
            return resources

        leds = [res.o for res in get_all_resources("led")]
​
        m.d.comb += Cat(leds).eq(self.data_o)
        print(len(leds))
​
        return m

​
if __name__ == "__main__":
    os.environ["AMARANTH_synth_opts"] = "-vm yosys.debug.v"
​
    platform = LIFCLEVNPlatform(toolchain="Oxide")
    platform.build(DebugModule(), do_program=False)
gatecat commented 10 months ago

See https://github.com/YosysHQ/yosys/pull/4048 - I haven't yet tested it on hardware, but at least this fixes the build failure.

slagernate commented 10 months ago

No issues in hardware on my side.