aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2019-01-17 14:38:37 +0100
committerClifford Wolf <clifford@clifford.at>2019-01-17 14:38:37 +0100
commitdb5765b443c26b5b2dc3ac56d5a448fc8b861d43 (patch)
tree1d618cc08ef5a17d11feee182604f527848a1ad6
parent9b277fc21ea455a0e0ca9b7acde039e90ddb380d (diff)
downloadyosys-db5765b443c26b5b2dc3ac56d5a448fc8b861d43.tar.gz
yosys-db5765b443c26b5b2dc3ac56d5a448fc8b861d43.tar.bz2
yosys-db5765b443c26b5b2dc3ac56d5a448fc8b861d43.zip
Add SF2 IO buffer insertion
Signed-off-by: Clifford Wolf <clifford@clifford.at>
-rw-r--r--examples/igloo2/example.v3
-rw-r--r--examples/igloo2/libero.tcl2
-rw-r--r--techlibs/sf2/Makefile.inc1
-rw-r--r--techlibs/sf2/cells_sim.v21
-rw-r--r--techlibs/sf2/sf2_iobs.cc130
-rw-r--r--techlibs/sf2/synth_sf2.cc17
6 files changed, 171 insertions, 3 deletions
diff --git a/examples/igloo2/example.v b/examples/igloo2/example.v
index 0e336e557..1a1967d5a 100644
--- a/examples/igloo2/example.v
+++ b/examples/igloo2/example.v
@@ -1,5 +1,6 @@
module example (
input clk,
+ input EN,
output LED1,
output LED2,
output LED3,
@@ -14,7 +15,7 @@ module example (
reg [BITS-1:0] outcnt;
always @(posedge clk) begin
- counter <= counter + 1;
+ counter <= counter + EN;
outcnt <= counter >> LOG2DELAY;
end
diff --git a/examples/igloo2/libero.tcl b/examples/igloo2/libero.tcl
index b2090f402..952342a4c 100644
--- a/examples/igloo2/libero.tcl
+++ b/examples/igloo2/libero.tcl
@@ -5,7 +5,7 @@ file delete -force proj
new_project \
-name example \
-location proj \
- -block_mode 1 \
+ -block_mode 0 \
-hdl "VERILOG" \
-family IGLOO2 \
-die PA4MGL500 \
diff --git a/techlibs/sf2/Makefile.inc b/techlibs/sf2/Makefile.inc
index cade49f37..cc3054ace 100644
--- a/techlibs/sf2/Makefile.inc
+++ b/techlibs/sf2/Makefile.inc
@@ -1,5 +1,6 @@
OBJS += techlibs/sf2/synth_sf2.o
+OBJS += techlibs/sf2/sf2_iobs.o
$(eval $(call add_share_file,share/sf2,techlibs/sf2/arith_map.v))
$(eval $(call add_share_file,share/sf2,techlibs/sf2/cells_map.v))
diff --git a/techlibs/sf2/cells_sim.v b/techlibs/sf2/cells_sim.v
index b03b2c750..f967068af 100644
--- a/techlibs/sf2/cells_sim.v
+++ b/techlibs/sf2/cells_sim.v
@@ -73,3 +73,24 @@ module CFG4 (
parameter [15:0] INIT = 16'h0;
assign Y = INIT >> {D, C, B, A};
endmodule
+
+module CLKBUF (
+ input PAD,
+ output Y
+);
+ assign Y = PAD;
+endmodule
+
+module INBUF (
+ input PAD,
+ output Y
+);
+ assign Y = PAD;
+endmodule
+
+module OUTBUF (
+ input D,
+ output PAD
+);
+ assign PAD = D;
+endmodule
diff --git a/techlibs/sf2/sf2_iobs.cc b/techlibs/sf2/sf2_iobs.cc
new file mode 100644
index 000000000..27141430c
--- /dev/null
+++ b/techlibs/sf2/sf2_iobs.cc
@@ -0,0 +1,130 @@
+/*
+ * yosys -- Yosys Open SYnthesis Suite
+ *
+ * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+struct Sf2IobsPass : public Pass {
+ Sf2IobsPass() : Pass("sf2_iobs", "SF2: insert IO buffers") { }
+ void help() YS_OVERRIDE
+ {
+ // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+ log("\n");
+ log(" sf2_iobs [options] [selection]\n");
+ log("\n");
+ log("Add SF2 I/O buffers to top module IOs as needed.\n");
+ log("\n");
+ }
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ {
+ log_header(design, "Executing sf2_iobs pass (insert IO buffers).\n");
+
+ size_t argidx;
+ for (argidx = 1; argidx < args.size(); argidx++)
+ {
+ // if (args[argidx] == "-singleton") {
+ // singleton_mode = true;
+ // continue;
+ // }
+ break;
+ }
+ extra_args(args, argidx, design);
+
+ Module *module = design->top_module();
+
+ if (module == nullptr)
+ log_cmd_error("No top module found.\n");
+
+ SigMap sigmap(module);
+
+ pool<SigBit> clk_bits;
+ pool<SigBit> handled_io_bits;
+ dict<SigBit, SigBit> rewrite_bits;
+ vector<pair<Cell*, SigBit>> pad_bits;
+
+ for (auto cell : module->cells())
+ {
+ if (cell->type == "\\SLE") {
+ for (auto bit : sigmap(cell->getPort("\\CLK")))
+ clk_bits.insert(bit);
+ }
+ if (cell->type.in("\\INBUF", "\\OUTBUF", "\\CLKBUF")) {
+ for (auto bit : sigmap(cell->getPort("\\PAD")))
+ handled_io_bits.insert(bit);
+ }
+ }
+
+ for (auto wire : vector<Wire*>(module->wires()))
+ {
+ if (!wire->port_input && !wire->port_output)
+ continue;
+
+ for (int index = 0; index < GetSize(wire); index++)
+ {
+ SigBit bit(wire, index);
+ SigBit canonical_bit = sigmap(bit);
+
+ if (handled_io_bits.count(canonical_bit))
+ continue;
+
+ if (wire->port_input && wire->port_output)
+ log_error("Failed to add buffer for inout port bit %s.\n", log_signal(bit));
+
+ IdString buf_type, buf_port;
+
+ if (wire->port_output) {
+ buf_type = "\\OUTBUF";
+ buf_port = "\\D";
+ } else if (clk_bits.count(canonical_bit)) {
+ buf_type = "\\CLKBUF";
+ buf_port = "\\Y";
+ } else {
+ buf_type = "\\INBUF";
+ buf_port = "\\Y";
+ }
+
+ Cell *c = module->addCell(NEW_ID, buf_type);
+ SigBit new_bit = module->addWire(NEW_ID);
+ c->setPort(buf_port, new_bit);
+ pad_bits.push_back(make_pair(c, bit));
+ rewrite_bits[canonical_bit] = new_bit;
+
+ log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit));
+ }
+ }
+
+ auto rewrite_function = [&](SigSpec &s) {
+ for (auto &bit : s) {
+ SigBit canonical_bit = sigmap(bit);
+ if (rewrite_bits.count(canonical_bit))
+ bit = rewrite_bits.at(canonical_bit);
+ }
+ };
+
+ module->rewrite_sigspecs(rewrite_function);
+
+ for (auto &it : pad_bits)
+ it.first->setPort("\\PAD", it.second);
+ }
+} Sf2IobsPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/techlibs/sf2/synth_sf2.cc b/techlibs/sf2/synth_sf2.cc
index 6828a4298..bdc20456d 100644
--- a/techlibs/sf2/synth_sf2.cc
+++ b/techlibs/sf2/synth_sf2.cc
@@ -60,6 +60,9 @@ struct SynthSf2Pass : public ScriptPass
log(" -noflatten\n");
log(" do not flatten design before synthesis\n");
log("\n");
+ log(" -noiobs\n");
+ log(" run synthesis in \"block mode\", i.e. do not insert IO buffers\n");
+ log("\n");
log(" -retime\n");
log(" run 'abc' with -dff option\n");
log("\n");
@@ -70,7 +73,7 @@ struct SynthSf2Pass : public ScriptPass
}
string top_opt, edif_file, vlog_file, json_file;
- bool flatten, retime;
+ bool flatten, retime, iobs;
void clear_flags() YS_OVERRIDE
{
@@ -80,6 +83,7 @@ struct SynthSf2Pass : public ScriptPass
json_file = "";
flatten = true;
retime = false;
+ iobs = true;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@@ -122,6 +126,10 @@ struct SynthSf2Pass : public ScriptPass
retime = true;
continue;
}
+ if (args[argidx] == "-noiobs") {
+ iobs = false;
+ continue;
+ }
break;
}
extra_args(args, argidx, design);
@@ -191,6 +199,13 @@ struct SynthSf2Pass : public ScriptPass
run("clean");
}
+ if (check_label("map_iobs"))
+ {
+ if (iobs || help_mode)
+ run("sf2_iobs", "(unless -noiobs)");
+ run("clean");
+ }
+
if (check_label("check"))
{
run("hierarchy -check");