From 9374ef29bf24c6a9223e7b6742e3debd66a66bf9 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 13 Jun 2018 14:01:42 +0200 Subject: Fixing implementation of constants Signed-off-by: David Shah --- ice40/icebreaker.pcf | 5 +++++ ice40/icebreaker.v | 9 +++++++-- ice40/pack.cc | 46 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 52 insertions(+), 8 deletions(-) (limited to 'ice40') diff --git a/ice40/icebreaker.pcf b/ice40/icebreaker.pcf index 4564c84e..bc4a2974 100644 --- a/ice40/icebreaker.pcf +++ b/ice40/icebreaker.pcf @@ -3,7 +3,12 @@ set_io led2 25 set_io led3 21 set_io led4 23 set_io led5 26 +set_io ledr 11 +set_io ledg 37 + set_io clki 35 set_io btn1 20 set_io btn2 19 set_io btn3 18 +set_io btn_n 10 + diff --git a/ice40/icebreaker.v b/ice40/icebreaker.v index 2ad2397d..1c8c0863 100644 --- a/ice40/icebreaker.v +++ b/ice40/icebreaker.v @@ -3,11 +3,15 @@ module icebreaker ( input btn1, input btn2, input btn3, + input btn_n, + output led1, output led2, output led3, output led4, - output led5 + output led5, + output ledr, + output ledg, ); wire clk; SB_GB clk_gb(.USER_SIGNAL_TO_GLOBAL_BUFFER(clki), .GLOBAL_BUFFER_OUTPUT(clk)); @@ -22,5 +26,6 @@ module icebreaker ( outcnt <= counter >> LOG2DELAY; end assign {led1, led2, led3, led4, led5} = outcnt ^ (outcnt >> 1); - //assign {led1, led2, led3, led4, led5} = {!btn1, btn2, btn3, btn2, btn1}; + + assign {ledr, ledg} = ~(!btn_n + btn1 + btn2 + btn3); endmodule diff --git a/ice40/pack.cc b/ice40/pack.cc index 72dcadea..49c95ad6 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -110,28 +110,62 @@ static void pack_nonlut_ffs(Design *design) } } +// Merge a net into a constant net +static void set_net_constant(NetInfo *orig, NetInfo *constnet, bool constval) +{ + orig->driver.cell = nullptr; + for (auto user : orig->users) { + if (user.cell != nullptr) { + CellInfo *uc = user.cell; + log_info("%s user %s\n", orig->name.c_str(), uc->name.c_str()); + if (is_lut(uc) && (user.port.str().at(0) == 'I') && !constval) { + uc->ports[user.port].net = nullptr; + } else { + uc->ports[user.port].net = constnet; + constnet->users.push_back(user); + } + } + } + orig->users.clear(); +} + // Pack constants (simple implementation) static void pack_constants(Design *design) { CellInfo *gnd_cell = create_ice_cell(design, "ICESTORM_LC", "$PACKER_GND"); - gnd_cell->attrs["LUT_INIT"] = "0"; + gnd_cell->params["LUT_INIT"] = "0"; + NetInfo *gnd_net = new NetInfo; + gnd_net->name = "$PACKER_GND_NET"; + gnd_net->driver.cell = gnd_cell; + gnd_net->driver.port = "O"; CellInfo *vcc_cell = create_ice_cell(design, "ICESTORM_LC", "$PACKER_VCC"); - vcc_cell->attrs["LUT_INIT"] = "1"; + vcc_cell->params["LUT_INIT"] = "1"; + NetInfo *vcc_net = new NetInfo; + vcc_net->name = "$PACKER_VCC_NET"; + vcc_net->driver.cell = vcc_cell; + vcc_net->driver.port = "O"; + + std::vector dead_nets; for (auto net : design->nets) { NetInfo *ni = net.second; if (ni->driver.cell != nullptr && ni->driver.cell->type == "GND") { - ni->driver.cell = gnd_cell; - ni->driver.port = "O"; + set_net_constant(ni, gnd_net, false); design->cells[gnd_cell->name] = gnd_cell; + design->nets[gnd_net->name] = gnd_net; + dead_nets.push_back(net.first); } else if (ni->driver.cell != nullptr && ni->driver.cell->type == "VCC") { - ni->driver.cell = vcc_cell; - ni->driver.port = "O"; + set_net_constant(ni, vcc_net, true); design->cells[vcc_cell->name] = vcc_cell; + design->nets[vcc_net->name] = vcc_net; + dead_nets.push_back(net.first); } } + + for (auto dn : dead_nets) + design->nets.erase(dn); } static bool is_nextpnr_iob(CellInfo *cell) -- cgit v1.2.3