aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/coolrunner2/coolrunner2_sop.cc
diff options
context:
space:
mode:
authorUdi Finkelstein <github@udifink.com>2018-09-18 01:27:01 +0300
committerUdi Finkelstein <github@udifink.com>2018-09-18 01:27:01 +0300
commitc693f595c53e2e40840ff40b5b5ba06767582d23 (patch)
treede5e3f353f3222abca7186996e88cd9d635a964b /techlibs/coolrunner2/coolrunner2_sop.cc
parentf6fe73b31f6e6d8966ad4ddae860b4d79133cce2 (diff)
parent592a82c0ad8beb6de023aa2a131aab6472f949e8 (diff)
downloadyosys-c693f595c53e2e40840ff40b5b5ba06767582d23.tar.gz
yosys-c693f595c53e2e40840ff40b5b5ba06767582d23.tar.bz2
yosys-c693f595c53e2e40840ff40b5b5ba06767582d23.zip
Merge branch 'master' into pr_reg_wire_error
Diffstat (limited to 'techlibs/coolrunner2/coolrunner2_sop.cc')
-rw-r--r--techlibs/coolrunner2/coolrunner2_sop.cc62
1 files changed, 60 insertions, 2 deletions
diff --git a/techlibs/coolrunner2/coolrunner2_sop.cc b/techlibs/coolrunner2/coolrunner2_sop.cc
index b57214ccb..48da0d8ad 100644
--- a/techlibs/coolrunner2/coolrunner2_sop.cc
+++ b/techlibs/coolrunner2/coolrunner2_sop.cc
@@ -25,7 +25,7 @@ PRIVATE_NAMESPACE_BEGIN
struct Coolrunner2SopPass : public Pass {
Coolrunner2SopPass() : Pass("coolrunner2_sop", "break $sop cells into ANDTERM/ORTERM cells") { }
- virtual void help()
+ void help() YS_OVERRIDE
{
log("\n");
log(" coolrunner2_sop [options] [selection]\n");
@@ -33,7 +33,7 @@ struct Coolrunner2SopPass : public Pass {
log("Break $sop cells into ANDTERM/ORTERM cells.\n");
log("\n");
}
- virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
+ void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing COOLRUNNER2_SOP pass (break $sop cells into ANDTERM/ORTERM cells).\n");
extra_args(args, 1, design);
@@ -250,6 +250,64 @@ struct Coolrunner2SopPass : public Pass {
}
}
+ // In some cases we can get a FF feeding straight into an FF. This is not possible, so we need to insert
+ // some AND/XOR cells in the middle to make it actually work.
+
+ // Find all the FF outputs
+ pool<SigBit> sig_fed_by_ff;
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\FDCP" || cell->type == "\\FDCP_N" || cell->type == "\\FDDCP" ||
+ cell->type == "\\LDCP" || cell->type == "\\LDCP_N" ||
+ cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP" ||
+ cell->type == "\\FDCPE" || cell->type == "\\FDCPE_N" || cell->type == "\\FDDCPE")
+ {
+ auto output = sigmap(cell->getPort("\\Q")[0]);
+ sig_fed_by_ff.insert(output);
+ }
+ }
+
+ // Look at all the FF inputs
+ for (auto cell : module->selected_cells())
+ {
+ if (cell->type == "\\FDCP" || cell->type == "\\FDCP_N" || cell->type == "\\FDDCP" ||
+ cell->type == "\\LDCP" || cell->type == "\\LDCP_N" ||
+ cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP" ||
+ cell->type == "\\FDCPE" || cell->type == "\\FDCPE_N" || cell->type == "\\FDDCPE")
+ {
+ SigBit input;
+ if (cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP")
+ input = sigmap(cell->getPort("\\T")[0]);
+ else
+ input = sigmap(cell->getPort("\\D")[0]);
+
+ if (sig_fed_by_ff[input])
+ {
+ printf("Buffering input to \"%s\"\n", cell->name.c_str());
+
+ auto and_to_xor_wire = module->addWire(NEW_ID);
+ auto xor_to_ff_wire = module->addWire(NEW_ID);
+
+ auto and_cell = module->addCell(NEW_ID, "\\ANDTERM");
+ and_cell->setParam("\\TRUE_INP", 1);
+ and_cell->setParam("\\COMP_INP", 0);
+ and_cell->setPort("\\OUT", and_to_xor_wire);
+ and_cell->setPort("\\IN", input);
+ and_cell->setPort("\\IN_B", SigSpec());
+
+ auto xor_cell = module->addCell(NEW_ID, "\\MACROCELL_XOR");
+ xor_cell->setParam("\\INVERT_OUT", false);
+ xor_cell->setPort("\\IN_PTC", and_to_xor_wire);
+ xor_cell->setPort("\\OUT", xor_to_ff_wire);
+
+ if (cell->type == "\\FTCP" || cell->type == "\\FTCP_N" || cell->type == "\\FTDCP")
+ cell->setPort("\\T", xor_to_ff_wire);
+ else
+ cell->setPort("\\D", xor_to_ff_wire);
+ }
+ }
+ }
+
// Actually do the removal now that we aren't iterating
for (auto cell : cells_to_remove)
{