Merge branch 'miscbels'
diff --git a/libtrellis/include/Bels.hpp b/libtrellis/include/Bels.hpp index ad1f44c..0141c83 100644 --- a/libtrellis/include/Bels.hpp +++ b/libtrellis/include/Bels.hpp
@@ -18,6 +18,8 @@ void add_extref(RoutingGraph &graph, int x, int y); void add_pcsclkdiv(RoutingGraph &graph, int x, int y, int z); void add_iologic(RoutingGraph &graph, int x, int y, int z, bool s); +void add_misc(RoutingGraph &graph, const std::string &name, int x, int y); +void add_ioclk_bel(RoutingGraph &graph, const std::string &name, int x, int y, int i); } }
diff --git a/libtrellis/src/Bels.cpp b/libtrellis/src/Bels.cpp index 2a8154e..da6f71f 100644 --- a/libtrellis/src/Bels.cpp +++ b/libtrellis/src/Bels.cpp
@@ -446,5 +446,170 @@ graph.add_bel(bel); } +void add_misc(RoutingGraph &graph, const std::string &name, int x, int y) { + std::string postfix; + RoutingBel bel; + + auto add_input = [&](const std::string &pin, bool j = true) { + graph.add_bel_input(bel, graph.ident(pin), x, y, graph.ident(fmt((j ? "J" : "") << pin << "_" << postfix))); + }; + auto add_output = [&](const std::string &pin, bool j = true) { + graph.add_bel_output(bel, graph.ident(pin), x, y, graph.ident(fmt((j ? "J" : "") << pin << "_" << postfix))); + }; + bel.name = graph.ident(name); + bel.type = graph.ident(name); + bel.loc.x = x; + bel.loc.y = y; + + if (name == "GSR") { + postfix = "GSR"; + bel.z = 0; + add_input("GSR"); + add_input("CLK"); + } else if (name == "JTAGG") { + postfix = "JTAG"; + bel.z = 1; + add_input("TCK"); + add_input("TMS"); + add_input("TDI"); + add_input("JTDO2"); + add_input("JTDO1"); + add_output("TDO"); + add_output("JTDI"); + add_output("JTCK"); + add_output("JRTI2"); + add_output("JRTI1"); + add_output("JSHIFT"); + add_output("JUPDATE"); + add_output("JRSTN"); + add_output("JCE2"); + add_output("JCE1"); + } else if (name == "OSCG") { + postfix = "OSC"; + bel.z = 2; + graph.add_bel_output(bel, graph.ident("OSC"), 0, 0, graph.ident("G_JOSC_OSC")); + add_output("SEDSTDBY", false); + } else if (name == "SEDGA") { + postfix = "SED"; + bel.z = 3; + add_input("SEDENABLE"); + add_input("SEDSTART"); + add_input("SEDFRCERR"); + add_output("SEDDONE"); + add_output("SEDINPROG"); + add_output("SEDERR"); + add_input("SEDSTDBY", false); + } else if (name == "DTR") { + postfix = "DTR"; + bel.z = 0; + add_input("STARTPULSE"); + for (int i = 0; i < 8; i++) + add_output("DTROUT" + std::to_string(i)); + } else if (name == "USRMCLK") { + postfix = "CCLK"; + bel.z = 0; + add_input("PADDO"); + add_input("PADDT"); + add_output("PADDI"); + } else { + throw runtime_error("unknown Bel " + name); + } + graph.add_bel(bel); } + +void add_ioclk_bel(RoutingGraph &graph, const std::string &name, int x, int y, int i) { + std::string postfix; + RoutingBel bel; + + auto add_input = [&](const std::string &pin, bool j = true) { + graph.add_bel_input(bel, graph.ident(pin), x, y, graph.ident(fmt((j ? "J" : "") << pin << "_" << postfix))); + }; + auto add_output = [&](const std::string &pin, bool j = true) { + graph.add_bel_output(bel, graph.ident(pin), x, y, graph.ident(fmt((j ? "J" : "") << pin << "_" << postfix))); + }; + bel.type = graph.ident(name); + bel.loc.x = x; + bel.loc.y = y; + + if (name == "CLKDIVF") { + postfix = "CLKDIV" + std::to_string(i); + bel.name = graph.ident(postfix); + bel.z = i; + add_input("CLKI", false); + add_input("RST"); + add_input("ALIGNWD"); + add_output("CDIVX"); + } else if (name == "ECLKSYNCB") { + postfix = "ECLKSYNC" + std::to_string(i); + bel.name = graph.ident(postfix); + bel.z = 2 + i; + add_input("ECLKI", false); + add_input("STOP"); + add_output("ECLKO"); + } else if (name == "DLLDELD") { + postfix = "DLLDEL"; + bel.name = graph.ident(postfix); + bel.z = 4; + add_input("A"); + add_input("DDRDEL", false); + add_input("LOADN"); + add_input("MOVE"); + add_input("DIRECTION"); + add_output("Z", false); + add_output("CFLAG"); + } else if (name == "DDRDLL") { + postfix = "DDRDLL"; + bel.name = graph.ident(postfix); + bel.z = 0; + add_input("CLK"); + add_input("RST"); + add_input("UDDCNTLN"); + add_input("FREEZE"); + add_output("DDRDEL", false); + add_output("LOCK"); + add_output("DIVOSC"); + for (int j = 0; j < 8; j++) + add_output("DCNTL" + std::to_string(j)); + } else if (name == "DQSBUFM") { + postfix = "DQS"; + bel.name = graph.ident("DQSBUF"); + bel.z = 8; + add_input("DQSI"); + add_input("READ1"); + add_input("READ0"); + add_input("READCLKSEL2"); + add_input("READCLKSEL1"); + add_input("READCLKSEL0"); + add_input("DDRDEL", false); + add_input("ECLK", false); + add_input("SCLK"); + add_input("RST"); + for (int j = 0; j < 8; j++) + add_input("DYNDELAY" + std::to_string(j)); + add_input("PAUSE"); + add_input("RDLOADN"); + add_input("RDMOVE"); + add_input("RDDIRECTION"); + add_input("WRLOADN"); + add_input("WRMOVE"); + add_input("WRDIRECTION"); + add_output("DQSR90"); + add_output("DQSW"); + add_output("DQSW270"); + for (int j = 0; j < 3; j++) { + add_output("RDPNTR" + std::to_string(j), false); + add_output("WRPNTR" + std::to_string(j), false); + } + add_output("DATAVALID"); + add_output("BURSTDET"); + add_output("RDCFLAG"); + add_output("WRCFLAG"); + } else { + throw runtime_error("unknown Bel " + name); + } + graph.add_bel(bel); } + + +} +} \ No newline at end of file
diff --git a/libtrellis/src/Chip.cpp b/libtrellis/src/Chip.cpp index 7b08dac..52ac8c9 100644 --- a/libtrellis/src/Chip.cpp +++ b/libtrellis/src/Chip.cpp
@@ -187,6 +187,55 @@ if (tile->info.type == "BMID_0H") for (int z = 0; z < 2; z++) Bels::add_pcsclkdiv(*rg, x, y-1, z); + // Config/system Bels + if (tile->info.type == "EFB0_PICB0") { + Bels::add_misc(*rg, "GSR", x, y-1); + Bels::add_misc(*rg, "JTAGG", x, y-1); + Bels::add_misc(*rg, "OSCG", x, y-1); + Bels::add_misc(*rg, "SEDGA", x, y-1); + } + if (tile->info.type == "DTR") + Bels::add_misc(*rg, "DTR", x, y-1); + if (tile->info.type == "EFB1_PICB1") + Bels::add_misc(*rg, "USRMCLK", x-5, y); + if (tile->info.type == "ECLK_L") { + Bels::add_ioclk_bel(*rg, "CLKDIVF", x-2, y, 0); + Bels::add_ioclk_bel(*rg, "CLKDIVF", x-2, y, 1); + Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x-2, y, 0); + Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x-2, y, 1); + Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x-2, y+1, 0); + Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x-2, y+1, 1); + Bels::add_ioclk_bel(*rg, "DLLDELD", x-2, y-1, 0); + Bels::add_ioclk_bel(*rg, "DLLDELD", x-2, y, 0); + Bels::add_ioclk_bel(*rg, "DLLDELD", x-2, y+1, 0); + Bels::add_ioclk_bel(*rg, "DLLDELD", x-2, y+2, 0); + } + if (tile->info.type == "ECLK_R") { + Bels::add_ioclk_bel(*rg, "CLKDIVF", x+2, y, 0); + Bels::add_ioclk_bel(*rg, "CLKDIVF", x+2, y, 1); + Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x+2, y, 0); + Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x+2, y, 1); + Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x+2, y+1, 0); + Bels::add_ioclk_bel(*rg, "ECLKSYNCB", x+2, y+1, 1); + Bels::add_ioclk_bel(*rg, "DLLDELD", x+2, y-1, 0); + Bels::add_ioclk_bel(*rg, "DLLDELD", x+2, y, 0); + Bels::add_ioclk_bel(*rg, "DLLDELD", x+2, y+1, 0); + Bels::add_ioclk_bel(*rg, "DLLDELD", x+2, y+2, 0); + } + if (tile->info.type == "DDRDLL_UL") + Bels::add_ioclk_bel(*rg, "DDRDLL", x-2, y-10, 0); + if (tile->info.type == "DDRDLL_ULA") + Bels::add_ioclk_bel(*rg, "DDRDLL", x-2, y-13, 0); + if (tile->info.type == "DDRDLL_UR") + Bels::add_ioclk_bel(*rg, "DDRDLL", x+2, y-10, 0); + if (tile->info.type == "DDRDLL_URA") + Bels::add_ioclk_bel(*rg, "DDRDLL", x+2, y-13, 0); + if (tile->info.type == "DDRDLL_LL") + Bels::add_ioclk_bel(*rg, "DDRDLL", x-2, y+13, 0); + if (tile->info.type == "DDRDLL_LR") + Bels::add_ioclk_bel(*rg, "DDRDLL", x+2, y+13, 0); + if (tile->info.type == "PICL0_DQS2" || tile->info.type == "PICR0_DQS2") + Bels::add_ioclk_bel(*rg, "DQSBUFM", x, y, 0); } return rg;