diff options
-rw-r--r-- | icebox/icebox.py | 1 | ||||
-rw-r--r-- | iceprog/iceprog.c | 6 | ||||
-rw-r--r-- | icetime/icetime.cc | 43 |
3 files changed, 41 insertions, 9 deletions
diff --git a/icebox/icebox.py b/icebox/icebox.py index a7631a2..ef5478b 100644 --- a/icebox/icebox.py +++ b/icebox/icebox.py @@ -1719,7 +1719,6 @@ noplls_db = { "8k-cm81:4k": [ "8k_1" ], "1k-qn48": [ "1k" ], "1k-cb81": [ "1k" ], - "1k-cb121": [ "1k" ], "1k-vq100": [ "1k" ], "384-qn32": [ "384" ], } diff --git a/iceprog/iceprog.c b/iceprog/iceprog.c index 20b05a4..f80a432 100644 --- a/iceprog/iceprog.c +++ b/iceprog/iceprog.c @@ -967,7 +967,7 @@ int main(int argc, char **argv) if (rc <= 0) break; fprintf(stderr, " \r"); - fprintf(stderr, "addr 0x%06X %3ld%%\r", rw_offset + addr, addr / (file_size / 100)); + fprintf(stderr, "addr 0x%06X %3ld%%\r", rw_offset + addr, 100 * addr / file_size); flash_write_enable(); flash_prog(rw_offset + addr, buffer, rc); flash_wait(); @@ -989,7 +989,7 @@ int main(int argc, char **argv) for (int addr = 0; addr < read_size; addr += 256) { uint8_t buffer[256]; fprintf(stderr, " \r"); - fprintf(stderr, "addr 0x%06X %3d%%\r", rw_offset + addr, addr / (read_size / 100)); + fprintf(stderr, "addr 0x%06X %3d%%\r", rw_offset + addr, 100 * addr / read_size); flash_read(rw_offset + addr, buffer, 256); fwrite(buffer, read_size - addr > 256 ? 256 : read_size - addr, 1, f); } @@ -1003,7 +1003,7 @@ int main(int argc, char **argv) if (rc <= 0) break; fprintf(stderr, " \r"); - fprintf(stderr, "addr 0x%06X %3ld%%\r", rw_offset + addr, addr / (file_size / 100)); + fprintf(stderr, "addr 0x%06X %3ld%%\r", rw_offset + addr, 100 * addr / file_size); flash_read(rw_offset + addr, buffer_flash, rc); if (memcmp(buffer_file, buffer_flash, rc)) { fprintf(stderr, "Found difference between flash and file!\n"); diff --git a/icetime/icetime.cc b/icetime/icetime.cc index 065705a..fef65d2 100644 --- a/icetime/icetime.cc +++ b/icetime/icetime.cc @@ -59,6 +59,7 @@ std::set<std::tuple<int, int, int>> extra_bits; std::set<std::string> io_names; std::map<int, std::string> net_symbols; +std::map<std::string, unsigned> lc_lut_in_mask; bool get_config_bit(int tile_x, int tile_y, int bit_row, int bit_col) { @@ -846,6 +847,15 @@ struct TimingAnalysis } if (driver_type == "LogicCell40" && (driver_port == "ltout" || driver_port == "lcout")) { + unsigned mask = lc_lut_in_mask.at(driver_cell); + if (inport == "in0" && ((mask & 0x1) == 0)) + continue; + if (inport == "in1" && ((mask & 0x2) == 0)) + continue; + if (inport == "in2" && ((mask & 0x4) == 0)) + continue; + if (inport == "in3" && ((mask & 0x8) == 0)) + continue; if (inport == "carryin") continue; } @@ -1231,14 +1241,37 @@ std::string make_lc40(int x, int y, int z) for (int i = 0; i < 20; i++) lcbits[i] = get_config_bit(x, y, lcbits_pos[i].first, lcbits_pos[i].second) ? '1' : '0'; + static const std::vector<int> lut_perm = { + 4, 14, 15, 5, 6, 16, 17, 7, 3, 13, 12, 2, 1, 11, 10, 0, + }; + + unsigned lut_init = 0; + for (unsigned i = 0; i < lut_perm.size(); i++) + if (lcbits[lut_perm[i]] == '1') + lut_init |= (1U << i); + // FIXME: fill in the '0' netlist_cell_params[cell]["C_ON"] = stringf("1'b%c", lcbits[8]); netlist_cell_params[cell]["SEQ_MODE"] = stringf("4'b%c%c%c%c", lcbits[9], '0', '0', '0'); - netlist_cell_params[cell]["LUT_INIT"] = stringf("16'b%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", - lcbits[0], lcbits[10], lcbits[11], lcbits[1], - lcbits[2], lcbits[12], lcbits[13], lcbits[3], - lcbits[7], lcbits[17], lcbits[16], lcbits[6], - lcbits[5], lcbits[15], lcbits[14], lcbits[4]); + + std::string init = "16'b"; + for (int i = 15; i >= 0; i--) + init += ((lut_init >> i) & 0x1) ? '1' : '0'; + + netlist_cell_params[cell]["LUT_INIT"] = init; + + // Find which LUT inputs are "don't care" in the function, to avoid false paths for bits + // only affecting the carry. + lc_lut_in_mask[cell] = 0; + for (unsigned k = 0; k < 4; k++) { + for (unsigned i = 0; i < 16; i++) { + // If toggling the LUT input makes a difference it's not a don't care + if (((lut_init >> i) & 0x1U) != ((lut_init >> (i ^ (1U << k))) & 0x1U)) { + lc_lut_in_mask[cell] |= (1 << k); + break; + } + } + } if (lcbits[8] == '1') { |