aboutsummaryrefslogtreecommitdiffstats
path: root/icetime
diff options
context:
space:
mode:
Diffstat (limited to 'icetime')
-rw-r--r--icetime/icetime.cc66
1 files changed, 47 insertions, 19 deletions
diff --git a/icetime/icetime.cc b/icetime/icetime.cc
index 6c1e136..9d3a5cf 100644
--- a/icetime/icetime.cc
+++ b/icetime/icetime.cc
@@ -852,38 +852,66 @@ void make_seg_cell(int net, const net_segment_t &seg)
return;
}
- if (seg.name == "io_global/inclk" || seg.name == "io_global/outclk")
+ if (seg.name == "io_global/inclk" || seg.name == "io_global/outclk" || seg.name == "io_global/cen")
{
- for (int i = 0; i < 2; i++)
+ for (int z = 0; z < 2; z++)
{
- if (seg.name == "io_global/inclk")
- {
- std::tuple<int, int, std::string> din0_key(seg.x, seg.y, stringf("io_%d/D_IN_%d", i, 0));
- std::tuple<int, int, std::string> din1_key(seg.x, seg.y, stringf("io_%d/D_IN_%d", i, 1));
+ std::string pintype;
+ std::pair<int, int> bitpos;
- if (x_y_name_net.count(din0_key) == 0 && x_y_name_net.count(din1_key) == 0)
- continue;
+ for (int i = 0; i < 6; i++) {
+ bitpos = io_tile_bits[stringf("IOB_%d.PINTYPE_%d", z, 5-i)][0];
+ pintype.push_back(config_bits[seg.x][seg.y][bitpos.first][bitpos.second] ? '1' : '0');
}
- if (seg.name == "io_global/outclk")
- {
- std::tuple<int, int, std::string> dout0_key(seg.x, seg.y, stringf("io_%d/D_OUT_%d", i, 0));
- std::tuple<int, int, std::string> dout1_key(seg.x, seg.y, stringf("io_%d/D_OUT_%d", i, 1));
+ bool use_inclk = false;
+ bool use_outclk = false;
+
+ if (pintype[5-0] == '0')
+ use_inclk = true;
+
+ if (pintype[5-5] == '1' && pintype[5-4] == '1')
+ use_outclk = true;
- if (x_y_name_net.count(dout0_key) == 0 && x_y_name_net.count(dout1_key) == 0)
- continue;
+ if (pintype[5-5] == '1' || pintype[5-4] == '1') {
+ if (pintype[5-2] == '1' || pintype[5-3] == '0')
+ use_outclk = true;
}
- auto cell = make_seg_pre_io(seg.x, seg.y, i);
+ std::tuple<int, int, std::string> din0_key(seg.x, seg.y, stringf("io_%d/D_IN_%d", z, 0));
+ std::tuple<int, int, std::string> din1_key(seg.x, seg.y, stringf("io_%d/D_IN_%d", z, 1));
+
+ if (x_y_name_net.count(din0_key) == 0 && x_y_name_net.count(din1_key) == 0)
+ use_inclk = false;
+
+ std::tuple<int, int, std::string> dout0_key(seg.x, seg.y, stringf("io_%d/D_OUT_%d", z, 0));
+ std::tuple<int, int, std::string> dout1_key(seg.x, seg.y, stringf("io_%d/D_OUT_%d", z, 1));
+
+ if (x_y_name_net.count(dout0_key) == 0 && x_y_name_net.count(dout1_key) == 0)
+ use_outclk = false;
- if (seg.name == "io_global/inclk")
+ if (!use_inclk && !use_outclk)
+ continue;
+
+ auto cell = make_seg_pre_io(seg.x, seg.y, z);
+
+ if (seg.name == "io_global/inclk" && use_inclk) {
netlist_cells[cell]["INPUTCLK"] = net_name(seg.net);
+ make_inmux(seg.x, seg.y, seg.net, "ClkMux");
+ }
- if (seg.name == "io_global/outclk")
+ if (seg.name == "io_global/outclk" && use_outclk) {
netlist_cells[cell]["OUTPUTCLK"] = net_name(seg.net);
+ make_inmux(seg.x, seg.y, seg.net, "ClkMux");
+ }
- if (netlist_cells[cell]["CLOCKENABLE"] == "")
- netlist_cells[cell]["CLOCKENABLE"] = "vcc";
+ if (seg.name == "io_global/cen") {
+ netlist_cells[cell]["CLOCKENABLE"] = net_name(seg.net);
+ make_inmux(seg.x, seg.y, seg.net, "CEMux");
+ } else {
+ if (netlist_cells[cell]["CLOCKENABLE"] == "")
+ netlist_cells[cell]["CLOCKENABLE"] = "vcc";
+ }
}
}
}