From ddfc535df766a8d6091e6c043b74bb6a40c8d2b7 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jul 2018 20:04:49 +0200 Subject: Add ArchNetInfo and ArchCellInfo Signed-off-by: Clifford Wolf --- ecp5/archdefs.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ecp5') diff --git a/ecp5/archdefs.h b/ecp5/archdefs.h index 84a431fd..df1add44 100644 --- a/ecp5/archdefs.h +++ b/ecp5/archdefs.h @@ -129,6 +129,9 @@ struct DecalId } }; +struct ArchNetInfo { }; +struct ArchCellInfo { }; + NEXTPNR_NAMESPACE_END namespace std { -- cgit v1.2.3 From edf7bd09cf2a27fa1ada1a1e34cbe47c4bf0d48a Mon Sep 17 00:00:00 2001 From: David Shah Date: Tue, 17 Jul 2018 21:51:24 +0200 Subject: ecp5: Function to handle constant LUT inputs Signed-off-by: David Shah --- ecp5/pack.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'ecp5') diff --git a/ecp5/pack.cc b/ecp5/pack.cc index 1900eded..c0427d46 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -359,6 +359,32 @@ class Ecp5Packer flush_cells(); } + void set_lut_input_constant(CellInfo *cell, IdString input, bool value) + { + int index = std::string("ABCD").find(input.str(ctx)); + int init = int_or_default(cell->params, ctx->id("INIT")); + int new_init = 0; + for (int i = 0; i < 16; i++) { + if (((i >> index) & 0x1) != value) { + int other_i = (i & (~(1 << index))) | (value << index); + if ((init >> other_i) & 0x1) + new_init |= (1 << i); + } else { + if ((init >> i) & 0x1) + new_init |= (1 << i); + } + } + cell->params[ctx->id("INIT")] = std::to_string(init); + NetInfo *innet = cell->ports.at(input).net; + if (innet != nullptr) { + innet->users.erase( + std::remove_if(innet->users.begin(), innet->users.end(), + [cell, input](PortRef port) { return port.cell == cell && port.port == input; }), + innet->users.end()); + } + cell->ports.at(input).net = nullptr; + } + public: void pack() { -- cgit v1.2.3 From f138368e343d0d69b6e1f74d44e13d7097999de6 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 18 Jul 2018 09:35:40 +0200 Subject: ecp5: Add simple constant packer Signed-off-by: David Shah --- ecp5/archdefs.h | 8 ++++-- ecp5/cells.cc | 8 ++++++ ecp5/pack.cc | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) (limited to 'ecp5') diff --git a/ecp5/archdefs.h b/ecp5/archdefs.h index df1add44..941607ba 100644 --- a/ecp5/archdefs.h +++ b/ecp5/archdefs.h @@ -129,8 +129,12 @@ struct DecalId } }; -struct ArchNetInfo { }; -struct ArchCellInfo { }; +struct ArchNetInfo +{ +}; +struct ArchCellInfo +{ +}; NEXTPNR_NAMESPACE_END diff --git a/ecp5/cells.cc b/ecp5/cells.cc index 59504735..22e6a8dc 100644 --- a/ecp5/cells.cc +++ b/ecp5/cells.cc @@ -116,6 +116,14 @@ std::unique_ptr create_ecp5_cell(Context *ctx, IdString type, std::str add_port(ctx, new_cell.get(), "I", PORT_IN); add_port(ctx, new_cell.get(), "T", PORT_IN); add_port(ctx, new_cell.get(), "O", PORT_OUT); + } else if (type == ctx->id("LUT4")) { + new_cell->params[ctx->id("INIT")] = "0"; + + add_port(ctx, new_cell.get(), "A", PORT_IN); + add_port(ctx, new_cell.get(), "B", PORT_IN); + add_port(ctx, new_cell.get(), "C", PORT_IN); + add_port(ctx, new_cell.get(), "D", PORT_IN); + add_port(ctx, new_cell.get(), "Z", PORT_OUT); } else { log_error("unable to create ECP5 cell of type %s", type.c_str(ctx)); } diff --git a/ecp5/pack.cc b/ecp5/pack.cc index c0427d46..47f22e55 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -385,10 +385,94 @@ class Ecp5Packer cell->ports.at(input).net = nullptr; } + // Merge a net into a constant net + void set_net_constant(const Context *ctx, NetInfo *orig, NetInfo *constnet, bool constval) + { + orig->driver.cell = nullptr; + for (auto user : orig->users) { + if (user.cell != nullptr) { + CellInfo *uc = user.cell; + if (ctx->verbose) + log_info("%s user %s\n", orig->name.c_str(ctx), uc->name.c_str(ctx)); + if (is_lut(ctx, uc)) { + set_lut_input_constant(uc, user.port, constval); + } else if (is_ff(ctx, uc) && user.port == ctx->id("CE")) { + uc->params[ctx->id("CEMUX")] = constval ? "1" : "0"; + uc->ports[user.port].net = nullptr; + } else if (is_ff(ctx, uc) && user.port == ctx->id("LSR") && + ((!constval && str_or_default(uc->params, ctx->id("LSRMUX"), "LSR") == "LSR") || + (constval && str_or_default(uc->params, ctx->id("LSRMUX"), "LSR") == "INV"))) { + 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) + void pack_constants() + { + log_info("Packing constants..\n"); + + std::unique_ptr gnd_cell = create_ecp5_cell(ctx, ctx->id("LUT4"), "$PACKER_GND"); + gnd_cell->params[ctx->id("LUT_INIT")] = "0"; + std::unique_ptr gnd_net = std::unique_ptr(new NetInfo); + gnd_net->name = ctx->id("$PACKER_GND_NET"); + gnd_net->driver.cell = gnd_cell.get(); + gnd_net->driver.port = ctx->id("Z"); + gnd_cell->ports.at(ctx->id("Z")).net = gnd_net.get(); + + std::unique_ptr vcc_cell = create_ecp5_cell(ctx, ctx->id("LUT4"), "$PACKER_VCC"); + vcc_cell->params[ctx->id("LUT_INIT")] = "65535"; + std::unique_ptr vcc_net = std::unique_ptr(new NetInfo); + vcc_net->name = ctx->id("$PACKER_VCC_NET"); + vcc_net->driver.cell = vcc_cell.get(); + vcc_net->driver.port = ctx->id("Z"); + vcc_cell->ports.at(ctx->id("Z")).net = vcc_net.get(); + + std::vector dead_nets; + + bool gnd_used = false, vcc_used = false; + + for (auto net : sorted(ctx->nets)) { + NetInfo *ni = net.second; + if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("GND")) { + IdString drv_cell = ni->driver.cell->name; + set_net_constant(ctx, ni, gnd_net.get(), false); + gnd_used = true; + dead_nets.push_back(net.first); + ctx->cells.erase(drv_cell); + } else if (ni->driver.cell != nullptr && ni->driver.cell->type == ctx->id("VCC")) { + IdString drv_cell = ni->driver.cell->name; + set_net_constant(ctx, ni, vcc_net.get(), true); + vcc_used = true; + dead_nets.push_back(net.first); + ctx->cells.erase(drv_cell); + } + } + + if (gnd_used) { + ctx->cells[gnd_cell->name] = std::move(gnd_cell); + ctx->nets[gnd_net->name] = std::move(gnd_net); + } + if (vcc_used) { + ctx->cells[vcc_cell->name] = std::move(vcc_cell); + ctx->nets[vcc_net->name] = std::move(vcc_net); + } + + for (auto dn : dead_nets) { + ctx->nets.erase(dn); + } + } + public: void pack() { pack_io(); + pack_constants(); find_lutff_pairs(); pack_lut5s(); pair_luts(); -- cgit v1.2.3 From 74cbaa5b83518d1743ae0a8fd335e7be1afb4f54 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 18 Jul 2018 09:52:53 +0200 Subject: ecp5: Simple packer working Signed-off-by: David Shah --- ecp5/cells.cc | 2 +- ecp5/pack.cc | 36 +++++++++++++++++++++++------------- ecp5/synth/blinky.v | 4 ++-- ecp5/synth/counter.v | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 ecp5/synth/counter.v (limited to 'ecp5') diff --git a/ecp5/cells.cc b/ecp5/cells.cc index 22e6a8dc..e3532f36 100644 --- a/ecp5/cells.cc +++ b/ecp5/cells.cc @@ -177,7 +177,7 @@ void ff_to_slice(Context *ctx, CellInfo *ff, CellInfo *lc, int index, bool drive void lut_to_slice(Context *ctx, CellInfo *lut, CellInfo *lc, int index) { - lc->params[ctx->id("LUT" + std::to_string(index) + "_INITVAL")] = str_or_default(lc->params, ctx->id("INIT"), "0"); + lc->params[ctx->id("LUT" + std::to_string(index) + "_INITVAL")] = str_or_default(lut->params, ctx->id("INIT"), "0"); replace_port(lut, ctx->id("A"), lc, ctx->id("A" + std::to_string(index))); replace_port(lut, ctx->id("B"), lc, ctx->id("B" + std::to_string(index))); replace_port(lut, ctx->id("C"), lc, ctx->id("C" + std::to_string(index))); diff --git a/ecp5/pack.cc b/ecp5/pack.cc index 47f22e55..da5b3ec5 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -71,6 +71,15 @@ class Ecp5Packer } } + const NetInfo *net_or_nullptr(CellInfo *cell, IdString port) + { + auto fnd = cell->ports.find(port); + if (fnd == cell->ports.end()) + return nullptr; + else + return fnd->second.net; + } + // Return whether two FFs can be packed together in the same slice bool can_pack_ffs(CellInfo *ff0, CellInfo *ff1) { @@ -88,11 +97,11 @@ class Ecp5Packer if (str_or_default(ff0->params, ctx->id("CLKMUX"), "CLK") != str_or_default(ff1->params, ctx->id("CLKMUX"), "CLK")) return false; - if (ff0->ports.at(ctx->id("CLK")).net != ff1->ports.at(ctx->id("CLK")).net) + if (net_or_nullptr(ff0, ctx->id("CLK")) != net_or_nullptr(ff1, ctx->id("CLK"))) return false; - if (ff0->ports.at(ctx->id("CE")).net != ff1->ports.at(ctx->id("CE")).net) + if (net_or_nullptr(ff0, ctx->id("CE")) != net_or_nullptr(ff1, ctx->id("CE"))) return false; - if (ff0->ports.at(ctx->id("LSR")).net != ff1->ports.at(ctx->id("LSR")).net) + if (net_or_nullptr(ff0, ctx->id("LSR")) != net_or_nullptr(ff1, ctx->id("LSR"))) return false; return true; } @@ -275,6 +284,8 @@ class Ecp5Packer ff_to_slice(ctx, ff, packed.get(), 0, true); packed_cells.insert(ff->name); sliceUsage[packed->name].ff0_used = true; + lutffPairs.erase(ci->name); + fflutPairs.erase(ff->name); } new_cells.push_back(std::move(packed)); @@ -304,10 +315,14 @@ class Ecp5Packer if (ff0 != lutffPairs.end()) { ff_to_slice(ctx, ctx->cells.at(ff0->second).get(), slice.get(), 0, true); packed_cells.insert(ff0->second); + lutffPairs.erase(lut0->name); + fflutPairs.erase(ff0->second); } if (ff1 != lutffPairs.end()) { ff_to_slice(ctx, ctx->cells.at(ff1->second).get(), slice.get(), 1, true); packed_cells.insert(ff1->second); + lutffPairs.erase(lut1->name); + fflutPairs.erase(ff1->second); } new_cells.push_back(std::move(slice)); @@ -333,6 +348,8 @@ class Ecp5Packer if (ff != lutffPairs.end()) { ff_to_slice(ctx, ctx->cells.at(ff->second).get(), slice.get(), 0, true); packed_cells.insert(ff->second); + lutffPairs.erase(ci->name); + fflutPairs.erase(ff->second); } new_cells.push_back(std::move(slice)); @@ -374,14 +391,7 @@ class Ecp5Packer new_init |= (1 << i); } } - cell->params[ctx->id("INIT")] = std::to_string(init); - NetInfo *innet = cell->ports.at(input).net; - if (innet != nullptr) { - innet->users.erase( - std::remove_if(innet->users.begin(), innet->users.end(), - [cell, input](PortRef port) { return port.cell == cell && port.port == input; }), - innet->users.end()); - } + cell->params[ctx->id("INIT")] = std::to_string(new_init); cell->ports.at(input).net = nullptr; } @@ -418,7 +428,7 @@ class Ecp5Packer log_info("Packing constants..\n"); std::unique_ptr gnd_cell = create_ecp5_cell(ctx, ctx->id("LUT4"), "$PACKER_GND"); - gnd_cell->params[ctx->id("LUT_INIT")] = "0"; + gnd_cell->params[ctx->id("INIT")] = "0"; std::unique_ptr gnd_net = std::unique_ptr(new NetInfo); gnd_net->name = ctx->id("$PACKER_GND_NET"); gnd_net->driver.cell = gnd_cell.get(); @@ -426,7 +436,7 @@ class Ecp5Packer gnd_cell->ports.at(ctx->id("Z")).net = gnd_net.get(); std::unique_ptr vcc_cell = create_ecp5_cell(ctx, ctx->id("LUT4"), "$PACKER_VCC"); - vcc_cell->params[ctx->id("LUT_INIT")] = "65535"; + vcc_cell->params[ctx->id("INIT")] = "65535"; std::unique_ptr vcc_net = std::unique_ptr(new NetInfo); vcc_net->name = ctx->id("$PACKER_VCC_NET"); vcc_net->driver.cell = vcc_cell.get(); diff --git a/ecp5/synth/blinky.v b/ecp5/synth/blinky.v index ac7c6ea3..a8f556b2 100644 --- a/ecp5/synth/blinky.v +++ b/ecp5/synth/blinky.v @@ -1,4 +1,4 @@ -module top(input clk_pin, input btn_pin, output [3:0] led_pin, output gpio0_pin); +module top(input clk_pin, input btn_pin, output [7:0] led_pin, output gpio0_pin); wire clk; wire [7:0] led; @@ -72,6 +72,6 @@ module top(input clk_pin, input btn_pin, output [3:0] led_pin, output gpio0_pin) assign led = led_reg; // Tie GPIO0, keep board from rebooting - TRELLIS_SLICE #(.MODE("LOGIC"), .LUT0_INITVAL(16'hFFFF)) vcc (.F0(gpio0)); + assign gpio0 = 1'b1; endmodule diff --git a/ecp5/synth/counter.v b/ecp5/synth/counter.v new file mode 100644 index 00000000..f2a4b812 --- /dev/null +++ b/ecp5/synth/counter.v @@ -0,0 +1,52 @@ +module top(input clk_pin, input btn_pin, output [7:0] led_pin, output gpio0_pin); + + wire clk; + wire [7:0] led; + wire btn; + wire gpio0; + + (* BEL="X0/Y35/PIOA" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("INPUT")) clk_buf (.B(clk_pin), .O(clk)); + + (* BEL="X4/Y71/PIOA" *) (* IO_TYPE="LVCMOS33" *) (* keep *) + TRELLIS_IO #(.DIR("INPUT")) btn_buf (.B(btn_pin), .O(btn)); + + (* BEL="X0/Y23/PIOC" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_0 (.B(led_pin[0]), .I(led[0])); + (* BEL="X0/Y23/PIOD" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_1 (.B(led_pin[1]), .I(led[1])); + (* BEL="X0/Y26/PIOA" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_2 (.B(led_pin[2]), .I(led[2])); + (* BEL="X0/Y26/PIOC" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_3 (.B(led_pin[3]), .I(led[3])); + + (* BEL="X0/Y26/PIOB" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_4 (.B(led_pin[4]), .I(led[4])); + (* BEL="X0/Y32/PIOD" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_5 (.B(led_pin[5]), .I(led[5])); + (* BEL="X0/Y26/PIOD" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_6 (.B(led_pin[6]), .I(led[6])); + (* BEL="X0/Y29/PIOD" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_7 (.B(led_pin[7]), .I(led[7])); + + + (* BEL="X0/Y62/PIOD" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) gpio0_buf (.B(gpio0_pin), .I(gpio0)); + + localparam ctr_width = 30; + localparam ctr_max = 2**ctr_width - 1; + reg [ctr_width-1:0] ctr = 0; + reg [9:0] pwm_ctr = 0; + reg dir = 0; + + always@(posedge clk) begin + ctr <= ctr + 1'b1; + end + + + assign led = ctr[ctr_width-1:ctr_width-8]; + + // Tie GPIO0, keep board from rebooting + assign gpio0 = 1'b1; + +endmodule -- cgit v1.2.3 From 5393841c669775eab5a5e5fde9be2bab3ec67879 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 18 Jul 2018 15:34:22 +0200 Subject: ecp5: Adding PIO data to chipdb Signed-off-by: David Shah --- ecp5/arch.h | 23 +++++++++++++++ ecp5/trellis_import.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) (limited to 'ecp5') diff --git a/ecp5/arch.h b/ecp5/arch.h index 4bb71b47..5158fe5c 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -96,13 +96,36 @@ NPNR_PACKED_STRUCT(struct LocationTypePOD { RelPtr pip_data; }); +NPNR_PACKED_STRUCT(struct PIOInfoPOD { + Location abs_loc; + int32_t bel_index; + RelPtr function_name; + int16_t bank; + int16_t padding; +}); + +NPNR_PACKED_STRUCT(struct PackagePinPOD { + RelPtr name; + Location abs_loc; + int32_t bel_index; +}); + +NPNR_PACKED_STRUCT(struct PackageInfoPOD { + RelPtr name; + int32_t num_pins; + RelPtr pin_data; +}); + NPNR_PACKED_STRUCT(struct ChipInfoPOD { int32_t width, height; int32_t num_tiles; int32_t num_location_types; + int32_t num_packages, num_pios; RelPtr locations; RelPtr location_type; RelPtr> tiletype_names; + RelPtr package_info; + RelPtr pio_info; }); #if defined(_MSC_VER) diff --git a/ecp5/trellis_import.py b/ecp5/trellis_import.py index 2bc32169..af5386e7 100755 --- a/ecp5/trellis_import.py +++ b/ecp5/trellis_import.py @@ -2,6 +2,8 @@ import pytrellis import database import argparse +import json +from os import path location_types = dict() type_at_location = dict() @@ -319,6 +321,49 @@ bel_types = { "PIO": 2 } +def get_bel_index(ddrg, loc, name): + loctype = ddrg.locationTypes[ddrg.typeAtLocation[loc]] + idx = 0 + for bel in loctype.bels: + if ddrg.to_str(bel.name) == name: + return idx + idx += 1 + assert loc.y == max_row # Only missing IO should be special pins at bottom of device + return None + + +packages = {} +pindata = [] + +def process_pio_db(ddrg, device): + piofile = path.join(database.get_db_root(), "ECP5", dev_names[device], "iodb.json") + with open(piofile, 'r') as f: + piodb = json.load(f) + for pkgname, pkgdata in sorted(piodb["packages"].items()): + pins = [] + for name, pinloc in sorted(pkgdata.items()): + x = pinloc["col"] + y = pinloc["row"] + loc = pytrellis.Location(x, y) + pio = "PIO" + pinloc["pio"] + bel_idx = get_bel_index(ddrg, loc, pio) + if bel_idx is not None: + pins.append((name, loc, bel_idx)) + packages[pkgname] = pins + for metaitem in piodb["pio_metadata"]: + x = metaitem["col"] + y = metaitem["row"] + loc = pytrellis.Location(x, y) + pio = "PIO" + metaitem["pio"] + bank = metaitem["bank"] + if "function" in metaitem: + pinfunc = metaitem["function"] + else: + pinfunc = None + bel_idx = get_bel_index(ddrg, loc, pio) + if bel_idx is not None: + pindata.append((loc, bel_idx, bank, pinfunc)) + def write_database(dev_name, ddrg, endianness): def write_loc(loc, sym_name): @@ -409,6 +454,32 @@ def write_database(dev_name, ddrg, endianness): for y in range(0, max_row+1): for x in range(0, max_col+1): bba.u32(loctypes.index(ddrg.typeAtLocation[pytrellis.Location(x, y)]), "loctype") + for package, pkgdata in sorted(packages.items()): + bba.l("package_data_%s" % package, "PackagePinPOD") + for pin in pkgdata: + name, loc, bel_idx = pin + bba.s(name, "name") + write_loc(loc, "abs_loc") + bba.u32(bel_idx, "bel_index") + + bba.l("package_data", "PackageInfoPOD") + for package, pkgdata in sorted(packages.items()): + bba.s(package, "name") + bba.u32(len(pkgdata), "num_pins") + bba.r("package_data_%s" % package, "pin_data") + + bba.l("pio_info", "PIOInfoPOD") + for pin in pindata: + loc, bel_idx, bank, func = pin + write_loc(loc, "abs_loc") + bba.u32(bel_idx, "bel_index") + if func is not None: + bba.s(func, "function_name") + else: + bba.r(None, "function_name") + bba.u16(bank, "bank") + bba.u16(0, "padding") + bba.l("tiletype_names", "RelPtr") for tt in tiletype_names: @@ -419,9 +490,15 @@ def write_database(dev_name, ddrg, endianness): bba.u32(max_row + 1, "height") bba.u32((max_col + 1) * (max_row + 1), "num_tiles") bba.u32(len(location_types), "num_location_types") + bba.u32(len(packages), "num_packages") + bba.u32(len(pindata), "num_pios") + bba.r("locations", "locations") bba.r("location_types", "location_type") bba.r("tiletype_names", "tiletype_names") + bba.r("package_data", "package_info") + bba.r("pio_info", "pio_info") + bba.finalize() return bba @@ -451,6 +528,7 @@ def main(): ddrg = pytrellis.make_dedup_chipdb(chip) max_row = chip.get_max_row() max_col = chip.get_max_col() + process_pio_db(ddrg, args.device) print("{} unique location types".format(len(ddrg.locationTypes))) bba = write_database(args.device, ddrg, "le") -- cgit v1.2.3 From c80934f953a9aa185aec0f3e9b9a23296c6e682b Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 18 Jul 2018 16:01:53 +0200 Subject: ecp5: Add support for pin name constraints using 'LOC' attributes Signed-off-by: David Shah --- ecp5/arch.cc | 33 +++++++++++++++++++++++++++++++-- ecp5/arch.h | 1 + ecp5/main.cc | 8 ++++++-- ecp5/pack.cc | 15 +++++++++++++++ ecp5/synth/blinky.v | 22 +++++++++++----------- 5 files changed, 64 insertions(+), 15 deletions(-) (limited to 'ecp5') diff --git a/ecp5/arch.cc b/ecp5/arch.cc index 0ffede3b..1510a27f 100644 --- a/ecp5/arch.cc +++ b/ecp5/arch.cc @@ -118,6 +118,16 @@ Arch::Arch(ArchArgs args) : args(args) log_error("Unsupported ECP5 chip type.\n"); } #endif + package_info = nullptr; + for (int i = 0; i < chip_info->num_packages; i++) { + if (args.package == chip_info->package_info[i].name.get()) { + package_info = &(chip_info->package_info[i]); + break; + } + } + + if (!package_info) + log_error("Unsupported package '%s' for '%s'.\n", args.package.c_str(), getChipName().c_str()); id_trellis_slice = id("TRELLIS_SLICE"); id_clk = id("CLK"); @@ -282,9 +292,28 @@ IdString Arch::getPipName(PipId pip) const // ----------------------------------------------------------------------- -BelId Arch::getPackagePinBel(const std::string &pin) const { return BelId(); } +BelId Arch::getPackagePinBel(const std::string &pin) const +{ + for (int i = 0; i < package_info->num_pins; i++) { + if (package_info->pin_data[i].name.get() == pin) { + BelId bel; + bel.location = package_info->pin_data[i].abs_loc; + bel.index = package_info->pin_data[i].bel_index; + return bel; + } + } + return BelId(); +} -std::string Arch::getBelPackagePin(BelId bel) const { return ""; } +std::string Arch::getBelPackagePin(BelId bel) const +{ + for (int i = 0; i < package_info->num_pins; i++) { + if (package_info->pin_data[i].abs_loc == bel.location && package_info->pin_data[i].bel_index == bel.index) { + return package_info->pin_data[i].name.get(); + } + } + return ""; +} // ----------------------------------------------------------------------- void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const diff --git a/ecp5/arch.h b/ecp5/arch.h index 5158fe5c..944aedea 100644 --- a/ecp5/arch.h +++ b/ecp5/arch.h @@ -363,6 +363,7 @@ struct ArchArgs struct Arch : BaseCtx { const ChipInfoPOD *chip_info; + const PackageInfoPOD *package_info; mutable std::unordered_map bel_by_name; mutable std::unordered_map wire_by_name; diff --git a/ecp5/main.cc b/ecp5/main.cc index 7521b88c..5a4a900a 100644 --- a/ecp5/main.cc +++ b/ecp5/main.cc @@ -68,6 +68,8 @@ int main(int argc, char *argv[]) options.add_options()("45k", "set device type to LFE5U-45F"); options.add_options()("85k", "set device type to LFE5U-85F"); + options.add_options()("package", po::value(), "select device package (defaults to CABGA381)"); + options.add_options()("json", po::value(), "JSON design file to ingest"); options.add_options()("seed", po::value(), "seed value for random number generator"); @@ -123,8 +125,10 @@ int main(int argc, char *argv[]) args.type = ArchArgs::LFE5U_45F; if (vm.count("85k")) args.type = ArchArgs::LFE5U_85F; - - args.package = "CABGA381"; + if (vm.count("package")) + args.package = vm["package"].as(); + else + args.package = "CABGA381"; args.speed = 6; std::unique_ptr ctx = std::unique_ptr(new Context(args)); diff --git a/ecp5/pack.cc b/ecp5/pack.cc index da5b3ec5..11cc2647 100644 --- a/ecp5/pack.cc +++ b/ecp5/pack.cc @@ -232,8 +232,23 @@ class Ecp5Packer } else { log_error("TRELLIS_IO required on all top level IOs...\n"); } + packed_cells.insert(ci->name); std::copy(ci->attrs.begin(), ci->attrs.end(), std::inserter(trio->attrs, trio->attrs.begin())); + + auto loc_attr = trio->attrs.find(ctx->id("LOC")); + if (loc_attr != trio->attrs.end()) { + std::string pin = loc_attr->second; + BelId pinBel = ctx->getPackagePinBel(pin); + if (pinBel == BelId()) { + log_error("IO pin '%s' constrained to pin '%s', which does not exist for package '%s'.\n", + trio->name.c_str(ctx), pin.c_str(), ctx->args.package.c_str()); + } else { + log_info("pin '%s' constrained to Bel '%s'.\n", trio->name.c_str(ctx), + ctx->getBelName(pinBel).c_str(ctx)); + } + trio->attrs[ctx->id("BEL")] = ctx->getBelName(pinBel).str(ctx); + } } } flush_cells(); diff --git a/ecp5/synth/blinky.v b/ecp5/synth/blinky.v index a8f556b2..36ec7ae3 100644 --- a/ecp5/synth/blinky.v +++ b/ecp5/synth/blinky.v @@ -5,32 +5,32 @@ module top(input clk_pin, input btn_pin, output [7:0] led_pin, output gpio0_pin) wire btn; wire gpio0; - (* BEL="X0/Y35/PIOA" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="G2" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("INPUT")) clk_buf (.B(clk_pin), .O(clk)); - (* BEL="X4/Y71/PIOA" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="R1" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("INPUT")) btn_buf (.B(btn_pin), .O(btn)); - (* BEL="X0/Y23/PIOC" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="B2" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) led_buf_0 (.B(led_pin[0]), .I(led[0])); - (* BEL="X0/Y23/PIOD" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="C2" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) led_buf_1 (.B(led_pin[1]), .I(led[1])); - (* BEL="X0/Y26/PIOA" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="C1" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) led_buf_2 (.B(led_pin[2]), .I(led[2])); - (* BEL="X0/Y26/PIOC" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="D2" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) led_buf_3 (.B(led_pin[3]), .I(led[3])); - (* BEL="X0/Y26/PIOB" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="D1" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) led_buf_4 (.B(led_pin[4]), .I(led[4])); - (* BEL="X0/Y32/PIOD" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="E2" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) led_buf_5 (.B(led_pin[5]), .I(led[5])); - (* BEL="X0/Y26/PIOD" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="E1" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) led_buf_6 (.B(led_pin[6]), .I(led[6])); - (* BEL="X0/Y29/PIOD" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="H3" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) led_buf_7 (.B(led_pin[7]), .I(led[7])); - (* BEL="X0/Y62/PIOD" *) (* IO_TYPE="LVCMOS33" *) + (* LOC="L2" *) (* IO_TYPE="LVCMOS33" *) TRELLIS_IO #(.DIR("OUTPUT")) gpio0_buf (.B(gpio0_pin), .I(gpio0)); localparam ctr_width = 24; -- cgit v1.2.3 From 50bf32665d0d7b7054df3ce1f36aad783eaaaa83 Mon Sep 17 00:00:00 2001 From: David Shah Date: Wed, 18 Jul 2018 16:31:55 +0200 Subject: ecp5: Tidying up examples Signed-off-by: David Shah --- ecp5/synth/blinky.v | 78 ++++++++++++++++++++++----------------------- ecp5/synth/blinky.ys | 9 +----- ecp5/synth/blinky_nopack.ys | 2 -- ecp5/synth/cells.v | 49 ---------------------------- ecp5/synth/counter.v | 52 ------------------------------ ecp5/synth/simple_map.v | 68 --------------------------------------- ecp5/synth/ulx3s.v | 18 ----------- ecp5/synth/ulx3s.ys | 9 ------ ecp5/synth/wire.v | 11 ------- ecp5/synth/wire.ys | 9 ------ 10 files changed, 40 insertions(+), 265 deletions(-) delete mode 100644 ecp5/synth/blinky_nopack.ys delete mode 100644 ecp5/synth/cells.v delete mode 100644 ecp5/synth/counter.v delete mode 100644 ecp5/synth/simple_map.v delete mode 100644 ecp5/synth/ulx3s.v delete mode 100644 ecp5/synth/ulx3s.ys delete mode 100644 ecp5/synth/wire.v delete mode 100644 ecp5/synth/wire.ys (limited to 'ecp5') diff --git a/ecp5/synth/blinky.v b/ecp5/synth/blinky.v index 36ec7ae3..9c6b187b 100644 --- a/ecp5/synth/blinky.v +++ b/ecp5/synth/blinky.v @@ -1,46 +1,46 @@ module top(input clk_pin, input btn_pin, output [7:0] led_pin, output gpio0_pin); - wire clk; - wire [7:0] led; + wire clk; + wire [7:0] led; wire btn; wire gpio0; - (* LOC="G2" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("INPUT")) clk_buf (.B(clk_pin), .O(clk)); + (* LOC="G2" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("INPUT")) clk_buf (.B(clk_pin), .O(clk)); - (* LOC="R1" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("INPUT")) btn_buf (.B(btn_pin), .O(btn)); + (* LOC="R1" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("INPUT")) btn_buf (.B(btn_pin), .O(btn)); - (* LOC="B2" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_0 (.B(led_pin[0]), .I(led[0])); - (* LOC="C2" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_1 (.B(led_pin[1]), .I(led[1])); - (* LOC="C1" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_2 (.B(led_pin[2]), .I(led[2])); + (* LOC="B2" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_0 (.B(led_pin[0]), .I(led[0])); + (* LOC="C2" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_1 (.B(led_pin[1]), .I(led[1])); + (* LOC="C1" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_2 (.B(led_pin[2]), .I(led[2])); (* LOC="D2" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_3 (.B(led_pin[3]), .I(led[3])); + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_3 (.B(led_pin[3]), .I(led[3])); - (* LOC="D1" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_4 (.B(led_pin[4]), .I(led[4])); - (* LOC="E2" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_5 (.B(led_pin[5]), .I(led[5])); - (* LOC="E1" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_6 (.B(led_pin[6]), .I(led[6])); + (* LOC="D1" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_4 (.B(led_pin[4]), .I(led[4])); + (* LOC="E2" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_5 (.B(led_pin[5]), .I(led[5])); + (* LOC="E1" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_6 (.B(led_pin[6]), .I(led[6])); (* LOC="H3" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_7 (.B(led_pin[7]), .I(led[7])); + TRELLIS_IO #(.DIR("OUTPUT")) led_buf_7 (.B(led_pin[7]), .I(led[7])); - (* LOC="L2" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) gpio0_buf (.B(gpio0_pin), .I(gpio0)); + (* LOC="L2" *) (* IO_TYPE="LVCMOS33" *) + TRELLIS_IO #(.DIR("OUTPUT")) gpio0_buf (.B(gpio0_pin), .I(gpio0)); localparam ctr_width = 24; localparam ctr_max = 2**ctr_width - 1; - reg [ctr_width-1:0] ctr = 0; - reg [9:0] pwm_ctr = 0; + reg [ctr_width-1:0] ctr = 0; + reg [9:0] pwm_ctr = 0; reg dir = 0; - always@(posedge clk) begin - ctr <= btn ? ctr : (dir ? ctr - 1'b1 : ctr + 1'b1); + always@(posedge clk) begin + ctr <= btn ? ctr : (dir ? ctr - 1'b1 : ctr + 1'b1); if (ctr[ctr_width-1 : ctr_width-3] == 0 && dir == 1) dir <= 1'b0; else if (ctr[ctr_width-1 : ctr_width-3] == 7 && dir == 0) @@ -54,19 +54,19 @@ module top(input clk_pin, input btn_pin, output [7:0] led_pin, output gpio0_pin) genvar i; generate - for (i = 0; i < 8; i=i+1) begin - always @ (posedge clk) begin - if (ctr[ctr_width-1 : ctr_width-3] == i) - brightness[i] <= bright_max; - else if (ctr[ctr_width-1 : ctr_width-3] == (i - 1)) - brightness[i] <= ctr[ctr_width-4:ctr_width-13]; - else if (ctr[ctr_width-1 : ctr_width-3] == (i + 1)) - brightness[i] <= bright_max - ctr[ctr_width-4:ctr_width-13]; - else - brightness[i] <= 0; - led_reg[i] <= pwm_ctr < brightness[i]; - end - end + for (i = 0; i < 8; i=i+1) begin + always @ (posedge clk) begin + if (ctr[ctr_width-1 : ctr_width-3] == i) + brightness[i] <= bright_max; + else if (ctr[ctr_width-1 : ctr_width-3] == (i - 1)) + brightness[i] <= ctr[ctr_width-4:ctr_width-13]; + else if (ctr[ctr_width-1 : ctr_width-3] == (i + 1)) + brightness[i] <= bright_max - ctr[ctr_width-4:ctr_width-13]; + else + brightness[i] <= 0; + led_reg[i] <= pwm_ctr < brightness[i]; + end + end endgenerate assign led = led_reg; diff --git a/ecp5/synth/blinky.ys b/ecp5/synth/blinky.ys index c0b74636..fb359380 100644 --- a/ecp5/synth/blinky.ys +++ b/ecp5/synth/blinky.ys @@ -1,9 +1,2 @@ read_verilog blinky.v -read_verilog -lib cells.v -synth -top top -abc -lut 4 -techmap -map simple_map.v -splitnets -opt_clean -stat -write_json blinky.json +synth_ecp5 -noccu2 -nomux -nodram -json blinky.json diff --git a/ecp5/synth/blinky_nopack.ys b/ecp5/synth/blinky_nopack.ys deleted file mode 100644 index fb359380..00000000 --- a/ecp5/synth/blinky_nopack.ys +++ /dev/null @@ -1,2 +0,0 @@ -read_verilog blinky.v -synth_ecp5 -noccu2 -nomux -nodram -json blinky.json diff --git a/ecp5/synth/cells.v b/ecp5/synth/cells.v deleted file mode 100644 index 353b8ada..00000000 --- a/ecp5/synth/cells.v +++ /dev/null @@ -1,49 +0,0 @@ -(* blackbox *) -module TRELLIS_SLICE( - input A0, B0, C0, D0, - input A1, B1, C1, D1, - input M0, M1, - input FCI, FXA, FXB, - - input CLK, LSR, CE, - input DI0, DI1, - - input WD0, WD1, - input WAD0, WAD1, WAD2, WAD3, - input WRE, WCK, - - output F0, Q0, - output F1, Q1, - output FCO, OFX0, OFX1, - - output WDO0, WDO1, WDO2, WDO3, - output WADO0, WADO1, WADO2, WADO3 -); - -parameter MODE = "LOGIC"; -parameter GSR = "ENABLED"; -parameter SRMODE = "LSR_OVER_CE"; -parameter CEMUX = "1"; -parameter CLKMUX = "CLK"; -parameter LSRMUX = "LSR"; -parameter LUT0_INITVAL = 16'h0000; -parameter LUT1_INITVAL = 16'h0000; -parameter REG0_SD = "0"; -parameter REG1_SD = "0"; -parameter REG0_REGSET = "RESET"; -parameter REG1_REGSET = "RESET"; -parameter CCU2_INJECT1_0 = "NO"; -parameter CCU2_INJECT1_1 = "NO"; - -endmodule - -(* blackbox *) (* keep *) -module TRELLIS_IO( - inout B, - input I, - input T, - output O, -); -parameter DIR = "INPUT"; - -endmodule diff --git a/ecp5/synth/counter.v b/ecp5/synth/counter.v deleted file mode 100644 index f2a4b812..00000000 --- a/ecp5/synth/counter.v +++ /dev/null @@ -1,52 +0,0 @@ -module top(input clk_pin, input btn_pin, output [7:0] led_pin, output gpio0_pin); - - wire clk; - wire [7:0] led; - wire btn; - wire gpio0; - - (* BEL="X0/Y35/PIOA" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("INPUT")) clk_buf (.B(clk_pin), .O(clk)); - - (* BEL="X4/Y71/PIOA" *) (* IO_TYPE="LVCMOS33" *) (* keep *) - TRELLIS_IO #(.DIR("INPUT")) btn_buf (.B(btn_pin), .O(btn)); - - (* BEL="X0/Y23/PIOC" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_0 (.B(led_pin[0]), .I(led[0])); - (* BEL="X0/Y23/PIOD" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_1 (.B(led_pin[1]), .I(led[1])); - (* BEL="X0/Y26/PIOA" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_2 (.B(led_pin[2]), .I(led[2])); - (* BEL="X0/Y26/PIOC" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_3 (.B(led_pin[3]), .I(led[3])); - - (* BEL="X0/Y26/PIOB" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_4 (.B(led_pin[4]), .I(led[4])); - (* BEL="X0/Y32/PIOD" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_5 (.B(led_pin[5]), .I(led[5])); - (* BEL="X0/Y26/PIOD" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_6 (.B(led_pin[6]), .I(led[6])); - (* BEL="X0/Y29/PIOD" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf_7 (.B(led_pin[7]), .I(led[7])); - - - (* BEL="X0/Y62/PIOD" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) gpio0_buf (.B(gpio0_pin), .I(gpio0)); - - localparam ctr_width = 30; - localparam ctr_max = 2**ctr_width - 1; - reg [ctr_width-1:0] ctr = 0; - reg [9:0] pwm_ctr = 0; - reg dir = 0; - - always@(posedge clk) begin - ctr <= ctr + 1'b1; - end - - - assign led = ctr[ctr_width-1:ctr_width-8]; - - // Tie GPIO0, keep board from rebooting - assign gpio0 = 1'b1; - -endmodule diff --git a/ecp5/synth/simple_map.v b/ecp5/synth/simple_map.v deleted file mode 100644 index 550fa92c..00000000 --- a/ecp5/synth/simple_map.v +++ /dev/null @@ -1,68 +0,0 @@ -module \$_DFF_P_ (input D, C, output Q); - TRELLIS_SLICE #( - .MODE("LOGIC"), - .CLKMUX("CLK"), - .CEMUX("1"), - .REG0_SD("0"), - .REG0_REGSET("RESET"), - .SRMODE("LSR_OVER_CE"), - .GSR("DISABLED") - ) _TECHMAP_REPLACE_ ( - .CLK(C), - .M0(D), - .Q0(Q) - ); -endmodule - -module \$lut (A, Y); - parameter WIDTH = 0; - parameter LUT = 0; - - input [WIDTH-1:0] A; - output Y; - - generate - if (WIDTH == 1) begin - TRELLIS_SLICE #( - .MODE("LOGIC"), - .LUT0_INITVAL({8{LUT[1:0]}}) - ) _TECHMAP_REPLACE_ ( - .A0(A[0]), - .F0(Y) - ); - end - if (WIDTH == 2) begin - TRELLIS_SLICE #( - .MODE("LOGIC"), - .LUT0_INITVAL({4{LUT[3:0]}}) - ) _TECHMAP_REPLACE_ ( - .A0(A[0]), - .B0(A[1]), - .F0(Y) - ); - end - if (WIDTH == 3) begin - TRELLIS_SLICE #( - .MODE("LOGIC"), - .LUT0_INITVAL({2{LUT[7:0]}}) - ) _TECHMAP_REPLACE_ ( - .A0(A[0]), - .B0(A[1]), - .C0(A[2]), - .F0(Y) - ); - end - if (WIDTH == 4) begin - TRELLIS_SLICE #( - .MODE("LOGIC"), - .LUT0_INITVAL(LUT) - ) _TECHMAP_REPLACE_ ( - .A0(A[0]), - .B0(A[1]), - .C0(A[2]), - .D0(A[3]), - .F0(Y) - ); - end - endgenerate -endmodule diff --git a/ecp5/synth/ulx3s.v b/ecp5/synth/ulx3s.v deleted file mode 100644 index 08f6e65b..00000000 --- a/ecp5/synth/ulx3s.v +++ /dev/null @@ -1,18 +0,0 @@ -module top(input a_pin, output led_pin, output led2_pin, output gpio0_pin); - - wire a; - wire led, led2; - wire gpio0; - (* BEL="X4/Y71/PIOA" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("INPUT")) a_buf (.B(a_pin), .O(a)); - (* BEL="X0/Y23/PIOC" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led_buf (.B(led_pin), .I(led)); - (* BEL="X0/Y26/PIOA" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) led2_buf (.B(led2_pin), .I(led2)); - (* BEL="X0/Y62/PIOD" *) (* IO_TYPE="LVCMOS33" *) - TRELLIS_IO #(.DIR("OUTPUT")) gpio0_buf (.B(gpio0_pin), .I(gpio0)); - assign led = a; - assign led2 = !a; - - TRELLIS_SLICE #(.MODE("LOGIC"), .LUT0_INITVAL(16'hFFFF)) vcc (.F0(gpio0)); -endmodule diff --git a/ecp5/synth/ulx3s.ys b/ecp5/synth/ulx3s.ys deleted file mode 100644 index d741c985..00000000 --- a/ecp5/synth/ulx3s.ys +++ /dev/null @@ -1,9 +0,0 @@ -read_verilog ulx3s.v -read_verilog -lib cells.v -synth -top top -abc -lut 4 -techmap -map simple_map.v -splitnets -opt_clean -stat -write_json ulx3s.json diff --git a/ecp5/synth/wire.v b/ecp5/synth/wire.v deleted file mode 100644 index 2af68ed2..00000000 --- a/ecp5/synth/wire.v +++ /dev/null @@ -1,11 +0,0 @@ -module top(input a_pin, output [3:0] led_pin); - - wire a; - wire [3:0] led; - - TRELLIS_IO #(.DIR("INPUT")) a_buf (.B(a_pin), .O(a)); - TRELLIS_IO #(.DIR("OUTPUT")) led_buf [3:0] (.B(led_pin), .I(led)); - - //assign led[0] = !a; - always @(posedge a) led[0] <= !led[0]; -endmodule diff --git a/ecp5/synth/wire.ys b/ecp5/synth/wire.ys deleted file mode 100644 index f916588b..00000000 --- a/ecp5/synth/wire.ys +++ /dev/null @@ -1,9 +0,0 @@ -read_verilog wire.v -read_verilog -lib cells.v -synth -top top -abc -lut 4 -techmap -map simple_map.v -splitnets -opt_clean -stat -write_json wire.json -- cgit v1.2.3