From 6edc11de4de20aa5194f5cf3705a320b1891a2d6 Mon Sep 17 00:00:00 2001 From: Alessandro Comodi Date: Mon, 5 Jul 2021 13:34:34 +0200 Subject: [PATCH] interchange: tests: add obuftds test Signed-off-by: Alessandro Comodi --- .../examples/tests/CMakeLists.txt | 1 + .../examples/tests/obuftds/CMakeLists.txt | 7 ++++ .../examples/tests/obuftds/basys3.xdc | 9 +++++ .../examples/tests/obuftds/obuftds.v | 37 +++++++++++++++++++ .../examples/tests/obuftds/run.tcl | 14 +++++++ fpga_interchange/macros.cc | 12 ++++++ 6 files changed, 80 insertions(+) create mode 100644 fpga_interchange/examples/tests/obuftds/CMakeLists.txt create mode 100644 fpga_interchange/examples/tests/obuftds/basys3.xdc create mode 100644 fpga_interchange/examples/tests/obuftds/obuftds.v create mode 100644 fpga_interchange/examples/tests/obuftds/run.tcl diff --git a/fpga_interchange/examples/tests/CMakeLists.txt b/fpga_interchange/examples/tests/CMakeLists.txt index 1d3dd72f..f8a52a41 100644 --- a/fpga_interchange/examples/tests/CMakeLists.txt +++ b/fpga_interchange/examples/tests/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(ff) add_subdirectory(lut) add_subdirectory(lut_nexus) add_subdirectory(lutram) +add_subdirectory(obuftds) add_subdirectory(ram_nexus) diff --git a/fpga_interchange/examples/tests/obuftds/CMakeLists.txt b/fpga_interchange/examples/tests/obuftds/CMakeLists.txt new file mode 100644 index 00000000..0313c9bb --- /dev/null +++ b/fpga_interchange/examples/tests/obuftds/CMakeLists.txt @@ -0,0 +1,7 @@ +add_interchange_group_test( + name obuftds + family ${family} + board_list basys3 + tcl run.tcl + sources obuftds.v +) diff --git a/fpga_interchange/examples/tests/obuftds/basys3.xdc b/fpga_interchange/examples/tests/obuftds/basys3.xdc new file mode 100644 index 00000000..4b777233 --- /dev/null +++ b/fpga_interchange/examples/tests/obuftds/basys3.xdc @@ -0,0 +1,9 @@ +set_property PACKAGE_PIN V2 [get_ports sw[8] ] +set_property PACKAGE_PIN T3 [get_ports sw[9] ] +set_property PACKAGE_PIN T2 [get_ports sw[10]] +set_property PACKAGE_PIN R3 [get_ports sw[11]] + +set_property PACKAGE_PIN U19 [get_ports diff_p[0]] +set_property PACKAGE_PIN V19 [get_ports diff_n[0]] +set_property PACKAGE_PIN V13 [get_ports diff_p[1]] +set_property PACKAGE_PIN V14 [get_ports diff_n[1]] diff --git a/fpga_interchange/examples/tests/obuftds/obuftds.v b/fpga_interchange/examples/tests/obuftds/obuftds.v new file mode 100644 index 00000000..d4e9a603 --- /dev/null +++ b/fpga_interchange/examples/tests/obuftds/obuftds.v @@ -0,0 +1,37 @@ +module top( + input wire [11:8] sw, + + output wire [1:0] diff_p, + output wire [1:0] diff_n +); + +wire [1:0] buf_i; +wire [1:0] buf_t; + +OBUFTDS # ( + .IOSTANDARD("DIFF_SSTL135"), + .SLEW("FAST") +) obuftds_0 ( + .I(buf_i[0]), + .T(buf_t[0]), + .O(diff_p[0]), + .OB(diff_n[0]) +); + +OBUFTDS # ( + .IOSTANDARD("DIFF_SSTL135"), + .SLEW("FAST") +) obuftds_1 ( + .I(buf_i[1]), + .T(buf_t[1]), + .O(diff_p[1]), + .OB(diff_n[1]) +); + +assign buf_i[0] = sw[ 8]; +assign buf_t[0] = sw[ 9]; +assign buf_i[1] = sw[10]; +assign buf_t[1] = sw[11]; + +endmodule + diff --git a/fpga_interchange/examples/tests/obuftds/run.tcl b/fpga_interchange/examples/tests/obuftds/run.tcl new file mode 100644 index 00000000..b8d0df72 --- /dev/null +++ b/fpga_interchange/examples/tests/obuftds/run.tcl @@ -0,0 +1,14 @@ +yosys -import + +read_verilog $::env(SOURCES) + +synth_xilinx -nolutram -nowidelut -nosrl -nocarry -nodsp + +# opt_expr -undriven makes sure all nets are driven, if only by the $undef +# net. +opt_expr -undriven +opt_clean + +setundef -zero -params + +write_json $::env(OUT_JSON) diff --git a/fpga_interchange/macros.cc b/fpga_interchange/macros.cc index 42c8e1ba..762615c1 100644 --- a/fpga_interchange/macros.cc +++ b/fpga_interchange/macros.cc @@ -58,14 +58,24 @@ void Arch::expand_macros() std::vector next_cells; + bool first_iter = false; do { // Expand cells for (auto cell : cells) { // TODO: consult exception map const MacroExpansionPOD *exp = lookup_macro_rules(chip_info, cell->type); + + // Block infinite expansion loop due to a macro being expanded in the same primitive. + // E.g.: OBUFTDS expands into the following cells, with an infinite loop being generated: + // - 2 OBUFTDS + // - 1 INV + if (exp && first_iter) + continue; + const MacroPOD *macro = lookup_macro(chip_info, exp ? IdString(exp->macro_name) : cell->type); if (macro == nullptr) continue; + // Get the ultimate root of this macro expansion IdString parent = (cell->macro_parent == IdString()) ? cell->name : cell->macro_parent; // Create child instances @@ -158,6 +168,8 @@ void Arch::expand_macros() // The next iteration only needs to look at cells created in this iteration std::swap(next_cells, cells); next_cells.clear(); + + first_iter = true; } while (!cells.empty()); // Do this at the end, otherwise we might add cells that are later destroyed for (auto &cell : ctx->cells)