From 86d93849c89867e006cdf366fa7177ff8a2877c3 Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Fri, 20 Dec 2024 11:03:10 +0100 Subject: [PATCH] Add IN1->RAM_O2 propagation --- himbaechel/uarch/gatemate/bitstream.cc | 28 +++++++++++- himbaechel/uarch/gatemate/extra_data.h | 8 +++- himbaechel/uarch/gatemate/gatemate.cc | 35 +++++++++++++++ himbaechel/uarch/gatemate/gen/arch_gen.py | 55 ++++++++++++----------- 4 files changed, 96 insertions(+), 30 deletions(-) diff --git a/himbaechel/uarch/gatemate/bitstream.cc b/himbaechel/uarch/gatemate/bitstream.cc index 2b0762ba..03abfb93 100644 --- a/himbaechel/uarch/gatemate/bitstream.cc +++ b/himbaechel/uarch/gatemate/bitstream.cc @@ -21,6 +21,7 @@ #include "config.h" #include "gatemate.h" +#include #define HIMBAECHEL_CONSTIDS "uarch/gatemate/constids.inc" #include "himbaechel_constids.h" @@ -88,6 +89,15 @@ struct BitstreamBackend return loc; } + int getInTileIndex(Context *ctx, int tile) + { + int x0, y0; + tile_xy(ctx->chip_info, tile, x0, y0); + x0 -= 2 - 1; + y0 -= 2 - 1; + return (x0 % 2) * 2 + (y0 % 2) + 1; + } + void write_bitstream() { ChipConfig cc; @@ -112,6 +122,14 @@ struct BitstreamBackend cc.tiles[loc].add_word(stringf("GPIO.%s", p.first.c_str(ctx)), p.second.as_bits()); } break; + case id_CPE.index: + { + int x = getInTileIndex(ctx,cell.second.get()->bel.tile); + for (auto &p : params) { + cc.tiles[loc].add_word(stringf("CPE%d.%s", x, p.first.c_str(ctx)), p.second.as_bits()); + } + } + break; default: break; } @@ -127,10 +145,16 @@ struct BitstreamBackend PipId pip = w.second.pip; const auto extra_data = *reinterpret_cast( chip_pip_info(ctx->chip_info, pip).extra_data.get()); - if (extra_data.name != 0) { + if (extra_data.type == PipExtra::PIP_EXTRA_MUX) { IdString name = IdString(extra_data.name); CfgLoc loc = getConfigLoc(ctx, pip.tile); - cc.tiles[loc].add_word(name.c_str(ctx), int_to_bitvector(extra_data.value, extra_data.bits)); + std::string word = name.c_str(ctx); + int x = getInTileIndex(ctx,pip.tile); + if (boost::starts_with(word, "IM.")) + boost::replace_all(word, "IM.", stringf("IM%d.",x)); + if (boost::starts_with(word, "IOES.")) + boost::replace_all(word, "IOES.", "IOES1."); + cc.tiles[loc].add_word(word, int_to_bitvector(extra_data.value, extra_data.bits)); } } } diff --git a/himbaechel/uarch/gatemate/extra_data.h b/himbaechel/uarch/gatemate/extra_data.h index 3d0ad9bd..8834f8de 100644 --- a/himbaechel/uarch/gatemate/extra_data.h +++ b/himbaechel/uarch/gatemate/extra_data.h @@ -29,9 +29,15 @@ NPNR_PACKED_STRUCT(struct GateMatePipExtraDataPOD { uint8_t bits; uint8_t value; uint8_t invert; - uint8_t dummy; + uint8_t type; }); +enum PipExtra +{ + PIP_EXTRA_MUX = 1, + PIP_EXTRA_CPE = 2, +}; + NEXTPNR_NAMESPACE_END #endif diff --git a/himbaechel/uarch/gatemate/gatemate.cc b/himbaechel/uarch/gatemate/gatemate.cc index e0585475..b1608843 100644 --- a/himbaechel/uarch/gatemate/gatemate.cc +++ b/himbaechel/uarch/gatemate/gatemate.cc @@ -18,6 +18,7 @@ */ #include "gatemate.h" +#include "design_utils.h" #define GEN_INIT_CONSTIDS #define HIMBAECHEL_CONSTIDS "uarch/gatemate/constids.inc" @@ -50,6 +51,40 @@ delay_t GateMateImpl::estimateDelay(WireId src, WireId dst) const void GateMateImpl::postRoute() { + ctx->assignArchInfo(); + log_break(); + log_info("Resources spent on routing:\n"); + for (auto &net : ctx->nets) { + NetInfo *ni = net.second.get(); + for (auto &w : ni->wires) { + if (w.second.pip != PipId()) { + const auto extra_data = *reinterpret_cast( + chip_pip_info(ctx->chip_info, w.second.pip).extra_data.get()); + if (!extra_data.name) + continue; + if (extra_data.type == PipExtra::PIP_EXTRA_CPE) { + IdStringList id = ctx->getPipName(w.second.pip); + BelId bel = ctx->getBelByName(IdStringList::concat(id[0], ctx->id("CPE"))); + IdString type = ctx->getBelType(bel); + if (!ctx->getBoundBelCell(bel)) { + CellInfo *cell = ctx->createCell(ctx->id(ctx->nameOfBel(bel)), type); + ctx->bindBel(bel, cell, PlaceStrength::STRENGTH_FIXED); + cell->params[id_INIT_L00] = Property(5,4); //"0101"); + cell->params[id_INIT_L01] = Property(15,4); //Property("1111"); + cell->params[id_INIT_L02] = Property(15,4); //Property("1111"); + cell->params[id_INIT_L03] = Property(15,4); //Property("1111"); + cell->params[id_INIT_L10] = Property(8,4); //Property("1000"); + cell->params[id_INIT_L20] = Property(12,4); //Property("1100"); + cell->params[ctx->id("O2")] = Property(3,2); + cell->params[id_RAM_O2] = Property(1,1); + } + } + } + } + } + + print_utilisation(ctx); + const ArchArgs &args = ctx->args; if (args.options.count("out")) { write_bitstream(args.device, args.options.at("out")); diff --git a/himbaechel/uarch/gatemate/gen/arch_gen.py b/himbaechel/uarch/gatemate/gen/arch_gen.py index 5d7f0cdf..ce2722df 100644 --- a/himbaechel/uarch/gatemate/gen/arch_gen.py +++ b/himbaechel/uarch/gatemate/gen/arch_gen.py @@ -24,6 +24,8 @@ import argparse sys.path.append(path.join(path.dirname(__file__), "../../..")) from himbaechel_dbgen.chip import * +PIP_EXTRA_MUX = 1 +PIP_EXTRA_CPE = 2 parser = argparse.ArgumentParser() parser.add_argument("--lib", help="Project Peppercorn python database script path", type=str, required=True) @@ -37,6 +39,7 @@ import die @dataclass class PipExtraData(BBAStruct): + pip_type: int name: IdString bits: int = 0 value: int = 0 @@ -49,7 +52,7 @@ class PipExtraData(BBAStruct): bba.u8(self.bits) bba.u8(self.value) bba.u8(self.invert) - bba.u8(0) # dummy + bba.u8(self.pip_type) def set_timings(ch): speed = "DEFAULT" @@ -75,12 +78,10 @@ def main(): tt.add_bel_pin(bel, pin.name, f"{prim.name}.{pin.name}", pin.dir) for mux in die.get_mux_connections_for_type(type_name): pp = tt.create_pip(mux.src, mux.dst) - pp.extra_data = PipExtraData(ch.strs.id(mux.name), mux.bits, mux.value, mux.invert) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX, ch.strs.id(mux.name), mux.bits, mux.value, mux.invert) if "CPE" in type_name: - tt.create_pip("CPE.IN1", "CPE.OUT1") - tt.create_pip("CPE.IN1", "CPE.OUT2") - tt.create_pip("CPE.IN1", "CPE.RAM_O1") - tt.create_pip("CPE.IN1", "CPE.RAM_O2") + pp = tt.create_pip("CPE.IN1", "CPE.RAM_O2") + pp.extra_data = PipExtraData(PIP_EXTRA_CPE,ch.strs.id("RAM_O2")) if "GPIO" in type_name: tt.create_wire("GPIO.OUT_D1", "WIRE_INTERNAL") tt.create_wire("GPIO.OUT_D2", "WIRE_INTERNAL") @@ -90,43 +91,43 @@ def main(): tt.create_wire("GPIO.CLK_INT","WIRE_INTERNAL") pp = tt.create_pip("GPIO.OUT1", "GPIO.OUT_D1") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT1_4"), 1, 0, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT1_4"), 1, 0, False) pp = tt.create_pip("GPIO.OUT4", "GPIO.OUT_D1") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT1_4"), 1, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT1_4"), 1, 1, False) pp = tt.create_pip("GPIO.OUT2", "GPIO.OUT_D2") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT2_3"), 1, 0, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT2_3"), 1, 0, False) pp = tt.create_pip("GPIO.OUT3", "GPIO.OUT_D2") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT2_3"), 1, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT2_3"), 1, 1, False) pp = tt.create_pip("GPIO.OUT_D1","GPIO.DO") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT23_14_SEL"), 1, 0, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT23_14_SEL"), 1, 0, False) pp = tt.create_pip("GPIO.OUT_D2","GPIO.DO") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT23_14_SEL"), 1, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT23_14_SEL"), 1, 1, False) pp = tt.create_pip("GPIO.OUT2","GPIO.OE") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OE_SIGNAL"), 2, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OE_SIGNAL"), 2, 1, False) pp = tt.create_pip("GPIO.OUT3","GPIO.OE") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OE_SIGNAL"), 2, 2, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OE_SIGNAL"), 2, 2, False) pp = tt.create_pip("GPIO.OUT4","GPIO.OE") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OE_SIGNAL"), 2, 3, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OE_SIGNAL"), 2, 3, False) pp = tt.create_pip("GPIO.OUT4", "GPIO.CLK_INT") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.CLK_1_4"), 1, 0, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.CLK_1_4"), 1, 0, False) pp = tt.create_pip("GPIO.OUT1", "GPIO.CLK_INT") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.CLK_1_4"), 1, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.CLK_1_4"), 1, 1, False) pp = tt.create_pip("GPIO.CLK_INT", "GPIO.OUT_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.SEL_OUT_CLOCK"), 1, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.SEL_OUT_CLOCK"), 1, 1, False) pp = tt.create_pip("GPIO.CLOCK1", "GPIO.OUT_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT_CLOCK"), 2, 0, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT_CLOCK"), 2, 0, False) pp = tt.create_pip("GPIO.CLOCK2", "GPIO.OUT_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT_CLOCK"), 2, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT_CLOCK"), 2, 1, False) pp = tt.create_pip("GPIO.CLOCK3", "GPIO.OUT_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT_CLOCK"), 2, 2, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT_CLOCK"), 2, 2, False) pp = tt.create_pip("GPIO.CLOCK4", "GPIO.OUT_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.OUT_CLOCK"), 2, 3, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.OUT_CLOCK"), 2, 3, False) tt.create_wire("GPIO.IN_D1", "WIRE_INTERNAL") @@ -136,15 +137,15 @@ def main(): tt.create_wire("GPIO.IN_CLK","WIRE_INTERNAL") pp = tt.create_pip("GPIO.CLK_INT", "GPIO.IN_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.SEL_IN_CLOCK"), 1, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.SEL_IN_CLOCK"), 1, 1, False) pp = tt.create_pip("GPIO.CLOCK1", "GPIO.IN_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.IN_CLOCK"), 2, 0, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.IN_CLOCK"), 2, 0, False) pp = tt.create_pip("GPIO.CLOCK2", "GPIO.IN_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.IN_CLOCK"), 2, 1, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.IN_CLOCK"), 2, 1, False) pp = tt.create_pip("GPIO.CLOCK3", "GPIO.IN_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.IN_CLOCK"), 2, 2, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.IN_CLOCK"), 2, 2, False) pp = tt.create_pip("GPIO.CLOCK4", "GPIO.IN_CLK") - pp.extra_data = PipExtraData(ch.strs.id("GPIO.IN_CLOCK"), 2, 3, False) + pp.extra_data = PipExtraData(PIP_EXTRA_MUX,ch.strs.id("GPIO.IN_CLOCK"), 2, 3, False) tt.create_pip("GPIO.DI", "GPIO.IN1")