diff options
-rw-r--r-- | common/pywrappers.h | 33 | ||||
-rw-r--r-- | generic/arch_pybindings.cc | 9 | ||||
-rw-r--r-- | generic/examples/.gitignore | 1 | ||||
-rw-r--r-- | generic/examples/README.md | 11 | ||||
-rw-r--r-- | generic/examples/blinky.v (renamed from generic/synth/blink.v) | 0 | ||||
-rw-r--r-- | generic/examples/report.py | 13 | ||||
-rwxr-xr-x | generic/examples/simple.sh | 4 | ||||
-rw-r--r-- | generic/examples/simple.v | 15 | ||||
-rw-r--r-- | generic/main.cc | 2 | ||||
-rw-r--r-- | generic/pack.cc | 2 | ||||
-rw-r--r-- | generic/synth/synth_generic.tcl | 2 |
11 files changed, 66 insertions, 26 deletions
diff --git a/common/pywrappers.h b/common/pywrappers.h index b9ed807d..1d970985 100644 --- a/common/pywrappers.h +++ b/common/pywrappers.h @@ -155,11 +155,15 @@ template <typename Class, typename FuncT, FuncT fn, typename rv_conv> struct fn_ using class_type = typename WrapIfNotContext<Class>::maybe_wrapped_t; using conv_result_type = typename rv_conv::ret_type; - static conv_result_type wrapped_fn(class_type &cls) + static object wrapped_fn(class_type &cls) { Context *ctx = get_ctx<Class>(cls); Class &base = get_base<Class>(cls); - return rv_conv()(ctx, (base.*fn)()); + try { + return object(rv_conv()(ctx, (base.*fn)())); + } catch (bad_wrap &) { + return object(); + } } template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); } @@ -172,11 +176,15 @@ template <typename Class, typename FuncT, FuncT fn, typename rv_conv, typename a using conv_result_type = typename rv_conv::ret_type; using conv_arg1_type = typename arg1_conv::arg_type; - static conv_result_type wrapped_fn(class_type &cls, conv_arg1_type arg1) + static object wrapped_fn(class_type &cls, conv_arg1_type arg1) { Context *ctx = get_ctx<Class>(cls); Class &base = get_base<Class>(cls); - return rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1))); + try { + return object(rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1)))); + } catch (bad_wrap &) { + return object(); + } } template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); } @@ -191,11 +199,15 @@ struct fn_wrapper_2a using conv_arg1_type = typename arg1_conv::arg_type; using conv_arg2_type = typename arg2_conv::arg_type; - static conv_result_type wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2) + static object wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2) { Context *ctx = get_ctx<Class>(cls); Class &base = get_base<Class>(cls); - return rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1), arg2_conv()(ctx, arg2))); + try { + return object(rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1), arg2_conv()(ctx, arg2)))); + } catch (bad_wrap &) { + return object(); + } } template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); } @@ -212,11 +224,16 @@ struct fn_wrapper_3a using conv_arg2_type = typename arg2_conv::arg_type; using conv_arg3_type = typename arg3_conv::arg_type; - static conv_result_type wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2, conv_arg3_type arg3) + static object wrapped_fn(class_type &cls, conv_arg1_type arg1, conv_arg2_type arg2, conv_arg3_type arg3) { Context *ctx = get_ctx<Class>(cls); Class &base = get_base<Class>(cls); - return rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1), arg2_conv()(ctx, arg2), arg3_conv()(ctx, arg3))); + try { + return object( + rv_conv()(ctx, (base.*fn)(arg1_conv()(ctx, arg1), arg2_conv()(ctx, arg2), arg3_conv()(ctx, arg3)))); + } catch (bad_wrap &) { + return object(); + } } template <typename WrapCls> static void def_wrap(WrapCls cls_, const char *name) { cls_.def(name, wrapped_fn); } diff --git a/generic/arch_pybindings.cc b/generic/arch_pybindings.cc index 950e7e34..f4e7c564 100644 --- a/generic/arch_pybindings.cc +++ b/generic/arch_pybindings.cc @@ -26,6 +26,14 @@ #include "pywrappers.h" NEXTPNR_NAMESPACE_BEGIN +namespace PythonConversion { +template <> struct string_converter<const IdString &> +{ + const IdString &from_str(Context *ctx, std::string name) { NPNR_ASSERT_FALSE("unsupported"); } + + std::string to_str(Context *ctx, const IdString &id) { return id.str(ctx); } +}; +} // namespace PythonConversion void arch_wrap_python() { @@ -190,6 +198,7 @@ void arch_wrap_python() WRAP_MAP_UPTR(CellMap, "IdCellMap"); WRAP_MAP_UPTR(NetMap, "IdNetMap"); + WRAP_VECTOR(const std::vector<IdString>, conv_to_str<IdString>); } NEXTPNR_NAMESPACE_END diff --git a/generic/examples/.gitignore b/generic/examples/.gitignore new file mode 100644 index 00000000..83d79a7d --- /dev/null +++ b/generic/examples/.gitignore @@ -0,0 +1 @@ +blinky.txt diff --git a/generic/examples/README.md b/generic/examples/README.md new file mode 100644 index 00000000..5eb0ea72 --- /dev/null +++ b/generic/examples/README.md @@ -0,0 +1,11 @@ +# Generic Architecture Example + +This contains a simple, artificial, example of the nextpnr generic API. + + - simple.py procedurally generates a simple FPGA architecture with IO at the edges, + logic slices in all other tiles, and interconnect only between adjacent tiles + + - report.py stores design information after place-and-route to blinky.txt in place + of real bitstream generation + + - Run blinky.sh to build an example design on the FPGA above
\ No newline at end of file diff --git a/generic/synth/blink.v b/generic/examples/blinky.v index b7cb1b86..b7cb1b86 100644 --- a/generic/synth/blink.v +++ b/generic/examples/blinky.v diff --git a/generic/examples/report.py b/generic/examples/report.py new file mode 100644 index 00000000..c43367fa --- /dev/null +++ b/generic/examples/report.py @@ -0,0 +1,13 @@ +with open("blinky.txt", "w") as f: + for nname, net in ctx.nets: + print("# Net %s" % nname, file=f) + # FIXME: Pip ordering + for wire, pip in net.wires: + if pip.pip != "": + print("%s" % pip.pip, file=f) + print("", file=f) + for cname, cell in ctx.cells: + print("# Cell %s at %s" % (cname, cell.bel), file=f) + for param, val in cell.params: + print("%s.%s %s" % (cell.bel, param, val), file=f) + print("", file=f)
\ No newline at end of file diff --git a/generic/examples/simple.sh b/generic/examples/simple.sh new file mode 100755 index 00000000..ed800639 --- /dev/null +++ b/generic/examples/simple.sh @@ -0,0 +1,4 @@ +#!/usr/bin/bash +set -ex +yosys -p "tcl ../synth/synth_generic.tcl 4 blinky.json" blinky.v +../../nextpnr-generic --pre-pack simple.py --json blinky.json --post-route report.py
\ No newline at end of file diff --git a/generic/examples/simple.v b/generic/examples/simple.v deleted file mode 100644 index 6d337101..00000000 --- a/generic/examples/simple.v +++ /dev/null @@ -1,15 +0,0 @@ -(* blackbox *) -module SLICE_LUT4( - input I0, I1, I2, I3, - input CLK, - output Q -); -parameter INIT = 16'h0000; -parameter FF_USED = 1'b0; -endmodule - -module top(input a, output q); - -SLICE_LUT4 sl_i(.I0(a), .Q(q)); - -endmodule
\ No newline at end of file diff --git a/generic/main.cc b/generic/main.cc index 08b0b348..c203f35c 100644 --- a/generic/main.cc +++ b/generic/main.cc @@ -49,7 +49,7 @@ po::options_description GenericCommandHandler::getArchOptions() return specific; } -void GenericCommandHandler::customBitstream(Context *ctx) { log_error("Here is when bitstream gets created"); } +void GenericCommandHandler::customBitstream(Context *ctx) {} std::unique_ptr<Context> GenericCommandHandler::createContext() { diff --git a/generic/pack.cc b/generic/pack.cc index 4d4a76a8..26ae9182 100644 --- a/generic/pack.cc +++ b/generic/pack.cc @@ -252,7 +252,7 @@ static void pack_io(Context *ctx) } else { // Create a GENERIC_IOB buffer std::unique_ptr<CellInfo> ice_cell = - create_generic_cell(ctx, ctx->id("GENERIC_IOB"), ci->name.str(ctx) + "$sb_io"); + create_generic_cell(ctx, ctx->id("GENERIC_IOB"), ci->name.str(ctx) + "$iob"); nxio_to_iob(ctx, ci, ice_cell.get(), packed_cells); new_cells.push_back(std::move(ice_cell)); iob = new_cells.back().get(); diff --git a/generic/synth/synth_generic.tcl b/generic/synth/synth_generic.tcl index c5950788..e5d88e0d 100644 --- a/generic/synth/synth_generic.tcl +++ b/generic/synth/synth_generic.tcl @@ -14,7 +14,7 @@ yosys memory_map yosys opt -full yosys techmap -map +/techmap.v yosys opt -fast -yosys abc -lut $LUT_K +yosys abc -lut $LUT_K -dress yosys clean yosys techmap -D LUT_K=$LUT_K -map [file dirname [file normalize $argv0]]/cells_map.v yosys clean |