libtrellis: Adding more misc and IO bels
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 56d81b9..da6f71f 100644 --- a/libtrellis/src/Bels.cpp +++ b/libtrellis/src/Bels.cpp
@@ -511,8 +511,105 @@ 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;