diff options
| author | David Shah <dave@ds0.me> | 2020-10-13 14:15:29 +0100 | 
|---|---|---|
| committer | David Shah <dave@ds0.me> | 2020-11-30 08:45:27 +0000 | 
| commit | da1e3c8612e9b63c91340142a9bf4529ac5f056a (patch) | |
| tree | 8cc15a6349d0da11ef3d9bcea15f58b8657071f7 | |
| parent | 1bb509897c77b7a8931f10b84dc1de98668c04bd (diff) | |
| download | nextpnr-da1e3c8612e9b63c91340142a9bf4529ac5f056a.tar.gz nextpnr-da1e3c8612e9b63c91340142a9bf4529ac5f056a.tar.bz2 nextpnr-da1e3c8612e9b63c91340142a9bf4529ac5f056a.zip | |
nexus: Add constant/inversion packing
Signed-off-by: David Shah <dave@ds0.me>
| -rw-r--r-- | nexus/arch.h | 12 | ||||
| -rw-r--r-- | nexus/fasm.cc | 47 | ||||
| -rw-r--r-- | nexus/pack.cc | 28 | ||||
| -rw-r--r-- | nexus/pins.cc | 8 | 
4 files changed, 78 insertions, 17 deletions
| diff --git a/nexus/arch.h b/nexus/arch.h index 4da60706..d5481bac 100644 --- a/nexus/arch.h +++ b/nexus/arch.h @@ -783,19 +783,21 @@ enum CellPinStyle      PINGLB_MASK = 0x100, -    PINBIT_GATED = 0x1000, // pin must be enabled in bitstream if used -    PINBIT_1 = 0x2000,     // pin has an explicit bit that must be set if tied to 1 +    PINBIT_GATED = 0x1000,  // pin must be enabled in bitstream if used +    PINBIT_1 = 0x2000,      // pin has an explicit bit that must be set if tied to 1 +    PINBIT_CIBMUX = 0x4000, // pin's CIBMUX must be floating for pin to be 1      PINSTYLE_NONE = 0x0000, // default -    PINSTYLE_CIB = 0x0012,  // 'CIB' signal, floats high but explicitly zeroed if not used +    PINSTYLE_CIB = 0x4012,  // 'CIB' signal, floats high but explicitly zeroed if not used      PINSTYLE_CLK = 0x0107,  // CLK type signal, invertible and defaults to disconnected      PINSTYLE_CE = 0x0027,   // CE type signal, invertible and defaults to enabled      PINSTYLE_LSR = 0x0017,  // LSR type signal, invertible and defaults to not reset      PINSTYLE_DEDI = 0x0000, // dedicated signals, leave alone -    PINSTYLE_PU = 0x0022,   // signals that float high and default high +    PINSTYLE_PU = 0x4022,   // signals that float high and default high +    PINSTYLE_T = 0x4027,    // PIO 'T' signal      PINSTYLE_INV_PD = 0x0017, // invertible, pull down by default -    PINSTYLE_INV_PU = 0x0027, // invertible, pull up by default +    PINSTYLE_INV_PU = 0x4027, // invertible, pull up by default      PINSTYLE_IOL_CE = 0x2027, // CE type signal, with explicit 'const-1' config bit      PINSTYLE_GATE = 0x1011,   // gated signal that defaults to 0 diff --git a/nexus/fasm.cc b/nexus/fasm.cc index 50b41e06..3029f4dc 100644 --- a/nexus/fasm.cc +++ b/nexus/fasm.cc @@ -170,7 +170,7 @@ struct NexusFasmWriter          std::string tile = tile_name(pip.tile, tile_by_type_and_loc(pip.tile, pd.tile_type));          std::string source_wire = escape_name(ctx->pip_src_wire_name(pip).str(ctx));          std::string dest_wire = escape_name(ctx->pip_dst_wire_name(pip).str(ctx)); -        write_bit(stringf("%s.PIP.%s.%s", tile.c_str(), dest_wire.c_str(), source_wire.c_str())); +        out << stringf("%s.PIP.%s.%s", tile.c_str(), dest_wire.c_str(), source_wire.c_str()) << std::endl;      }      // Write out all the pips corresponding to a net      void write_net(const NetInfo *net) @@ -184,6 +184,25 @@ struct NexusFasmWriter              write_pip(p);          blank();      } +    // Find the CIBMUX output for a signal +    WireId find_cibmux(const CellInfo *cell, IdString pin) +    { +        WireId cursor = ctx->getBelPinWire(cell->bel, pin); +        if (cursor == WireId()) +            return WireId(); +        for (int i = 0; i < 10; i++) { +            std::string cursor_name = IdString(ctx->wire_data(cursor).name).str(ctx); +            if (cursor_name.find("JCIBMUXOUT") == 0) { +                return cursor; +            } +            for (PipId pip : ctx->getPipsUphill(cursor)) +                if (ctx->checkPipAvail(pip)) { +                    cursor = ctx->getPipSrcWire(pip); +                    break; +                } +        } +        return WireId(); +    }      // Write out the mux config for a cell      void write_cell_muxes(const CellInfo *cell)      { @@ -206,8 +225,26 @@ struct NexusFasmWriter              // Pins that must be explictly set to 1 rather than just left floating              if ((pin_style & PINBIT_1) && (pin_mux == PINMUX_1))                  write_bit(stringf("%sMUX.1", ctx->nameOf(port.first))); +            // Handle CIB muxes - these must be set such that floating pins really are floating to VCC and not connected +            // to another CIB signal +            if ((pin_style & PINBIT_CIBMUX) && port.second.net == nullptr) { +                WireId cibmuxout = find_cibmux(cell, port.first); +                if (cibmuxout != WireId()) { +                    write_comment(stringf("CIBMUX for unused pin %s", ctx->nameOf(port.first))); +                    bool found = false; +                    for (PipId pip : ctx->getPipsUphill(cibmuxout)) { +                        if (ctx->checkPipAvail(pip) && ctx->checkWireAvail(ctx->getPipSrcWire(pip))) { +                            write_pip(pip); +                            found = true; +                            break; +                        } +                    } +                    NPNR_ASSERT(found); +                } +            }          }      } +      // Write config for an OXIDE_COMB cell      void write_comb(const CellInfo *cell)      { @@ -244,10 +281,7 @@ struct NexusFasmWriter          pop();          write_enum(cell, "REGDDR");          write_enum(cell, "SRMODE"); -        write_enum(cell, "CLKMUX"); -        write_enum(cell, "CEMUX"); -        write_enum(cell, "LSRMUX"); -        write_enum(cell, "GSR"); +        write_cell_muxes(cell);          pop(2);      }      // Write config for an SEIO33_CORE cell @@ -267,6 +301,7 @@ struct NexusFasmWriter          const char *iodir = is_input ? "INPUT" : (is_output ? "OUTPUT" : "BIDIR");          write_bit(stringf("BASE_TYPE.%s_%s", iodir, str_or_default(cell->attrs, id_IO_TYPE, "LVCMOS33").c_str()));          write_ioattr(cell, "PULLMODE", "NONE"); +        write_cell_muxes(cell);          pop(2);      }      // Write config for an SEIO18_CORE cell @@ -287,6 +322,7 @@ struct NexusFasmWriter          const char *iodir = is_input ? "INPUT" : (is_output ? "OUTPUT" : "BIDIR");          write_bit(stringf("BASE_TYPE.%s_%s", iodir, str_or_default(cell->attrs, id_IO_TYPE, "LVCMOS18H").c_str()));          write_ioattr(cell, "PULLMODE", "NONE"); +        write_cell_muxes(cell);          pop(3);      }      // Write config for an OSC_CORE cell @@ -302,6 +338,7 @@ struct NexusFasmWriter          write_enum(cell, "LF_OUTPUT_EN");          write_enum(cell, "DEBUG_N", "DISABLED");          write_int_vector(stringf("HF_CLK_DIV[7:0]"), ctx->parse_lattice_param(cell, id_HF_CLK_DIV, 8, 0).intval, 8); +        write_cell_muxes(cell);          pop(2);      }      // Write out FASM for the whole design diff --git a/nexus/pack.cc b/nexus/pack.cc index b9472ed1..e9b4336d 100644 --- a/nexus/pack.cc +++ b/nexus/pack.cc @@ -321,7 +321,12 @@ struct NexusPacker      {          NetInfo *net = get_net_or_empty(cell, port);          if (net == nullptr || net->driver.cell == nullptr) { -            // Pin is disconnected, return its default value +            // Pin is disconnected +            // If a mux value exists already, honour it +            CellPinMux exist_mux = ctx->get_cell_pinmux(cell, port); +            if (exist_mux != PINMUX_SIG) +                return exist_mux; +            // Otherwise, look up the default value and use that              CellPinStyle pin_style = ctx->get_cell_pin_style(cell, port);              if ((pin_style & PINDEF_MASK) == PINDEF_0)                  return PINMUX_0; @@ -434,7 +439,7 @@ struct NexusPacker              if (req_mux == PINMUX_INV) {                  // Pin is inverted. If there is a hard inverter; then use it -                if ((pin_style & PINOPT_MASK) == PINOPT_INV) { +                if (pin_style & PINOPT_INV) {                      uninvert_port(cell, port_name);                      ctx->set_cell_pinmux(cell, port_name, PINMUX_INV);                  } @@ -624,13 +629,30 @@ struct NexusPacker          }      } +    void pack_constants() +    { +        // Make sure we have high and low nets available +        get_const_net(id_VHI); +        get_const_net(id_VLO); +        // Iterate through cells +        for (auto cell : sorted(ctx->cells)) { +            CellInfo *ci = cell.second; +            // Skip certain cells at this point +            if (ci->type != id_LUT4 && ci->type != id_INV && ci->type != id_VHI && ci->type != id_VLO) +                process_inv_constants(cell.second); +        } +        // Remove superfluous inverters and constant drivers +        trim_design(); +    } +      explicit NexusPacker(Context *ctx) : ctx(ctx) {}      void operator()()      { +        pack_io();          pack_ffs(); +        pack_constants();          pack_luts(); -        pack_io();      }  }; diff --git a/nexus/pins.cc b/nexus/pins.cc index 33015add..f9ddd5f5 100644 --- a/nexus/pins.cc +++ b/nexus/pins.cc @@ -48,15 +48,15 @@ static const std::unordered_map<IdString, Arch::CellPinsData> base_cell_pin_data           }},          {id_SEIO18_CORE,           { -                 {id_T, PINSTYLE_CE}, +                 {id_T, PINSTYLE_T},                   {id_B, PINSTYLE_DEDI}, -                 {{}, PINSTYLE_INV_PU}, +                 {{}, PINSTYLE_PU},           }},          {id_SEIO33_CORE,           { -                 {id_T, PINSTYLE_CE}, +                 {id_T, PINSTYLE_T},                   {id_B, PINSTYLE_DEDI}, -                 {{}, PINSTYLE_INV_PU}, +                 {{}, PINSTYLE_PU},           }},          {id_OXIDE_EBR, {{id_CLKA, PINSTYLE_CLK},    {id_CLKB, PINSTYLE_CLK},    {id_CEA, PINSTYLE_CE},                          {id_CEB, PINSTYLE_CE},      {id_CSA0, PINSTYLE_PU},     {id_CSA1, PINSTYLE_PU}, | 
