diff options
-rw-r--r-- | icetime/.gitignore | 1 | ||||
-rw-r--r-- | icetime/Makefile | 11 | ||||
-rw-r--r-- | icetime/icetime.cc | 89 | ||||
-rw-r--r-- | icetime/mktest.py | 34 |
4 files changed, 130 insertions, 5 deletions
diff --git a/icetime/.gitignore b/icetime/.gitignore index a28ed80..8fee1fd 100644 --- a/icetime/.gitignore +++ b/icetime/.gitignore @@ -1,3 +1,4 @@ icetime +test[0-9]* *.d *.o diff --git a/icetime/Makefile b/icetime/Makefile index 2eef844..e93eaa2 100644 --- a/icetime/Makefile +++ b/icetime/Makefile @@ -14,8 +14,19 @@ install: all uninstall: rm -f $(DESTDIR)/bin/icetime + +# View timing netlist: +# yosys -qp 'read_verilog -lib cells.v; prep; show' test0_ref.v + +test0 test1 test2 test3 test4 test5 test6 test7 test8 test9: icetime + python3 mktest.py $@ + ./icetime -P tq144 -p $@.pcf $@.txt $@_out.v + +mktest: test0 test1 test2 test3 test4 test5 test6 test7 test8 test9 + clean: rm -f icetime + rm -f test[0-9]* rm -f *.o *.d -include *.d diff --git a/icetime/icetime.cc b/icetime/icetime.cc index 9ba91a9..479fe64 100644 --- a/icetime/icetime.cc +++ b/icetime/icetime.cc @@ -14,9 +14,12 @@ FILE *fin, *fout; -std::string config_device; +std::string config_device, selected_package; std::vector<std::vector<std::string>> config_tile_type; std::vector<std::vector<std::vector<std::vector<bool>>>> config_bits; +std::map<std::tuple<int, int, int>, std::string> pin_pos; +std::map<std::string, std::string> pin_names; +std::set<std::string> io_names; struct net_segment_t { @@ -103,6 +106,39 @@ std::string net_name(int net) return stringf("net_%d", net); } +void read_pcf(const char *filename) +{ + FILE *f = fopen(filename, "r"); + if (f == nullptr) { + perror("Can't open pcf file"); + exit(1); + } + + char buffer[128]; + + while (fgets(buffer, 128, f)) + { + if (buffer[0] == '#') + continue; + + const char *tok = strtok(buffer, " \t\r\n"); + if (tok == nullptr || strcmp(tok, "set_io")) + continue; + + std::vector<std::string> args; + while ((tok = strtok(nullptr, " \t\r\n")) != nullptr) { + if (!strcmp(tok, "--warn-no-port")) + continue; + args.push_back(tok); + } + + assert(args.size() == 2); + pin_names[args[1]] = args[0]; + } + + fclose(f); +} + void read_config() { char buffer[128]; @@ -187,6 +223,13 @@ void read_chipdb() { mode = tok; + if (mode == ".pins") + { + if (strtok(nullptr, " \t\r\n") != selected_package) + mode = ""; + continue; + } + if (mode == ".net") { current_net = atoi(strtok(nullptr, " \t\r\n")); @@ -212,6 +255,14 @@ void read_chipdb() continue; } + if (mode == ".pins") { + int pos_x = atoi(strtok(nullptr, " \t\r\n")); + int pos_y = atoi(strtok(nullptr, " \t\r\n")); + int pos_z = atoi(strtok(nullptr, " \t\r\n")); + std::tuple<int, int, int> key(pos_x, pos_y, pos_z); + pin_pos[key] = tok; + } + if (mode == ".net") { int tile_x = atoi(tok); int tile_y = atoi(strtok(nullptr, " \t\r\n")); @@ -328,15 +379,26 @@ std::string make_seg_pre_io(int x, int y, int z) netlist_cells[cell]["DIN1"] = ""; netlist_cells[cell]["DIN0"] = ""; + std::string io_name; + std::tuple<int, int, int> key(x, y, z); + + if (pin_pos.count(key)) { + io_name = pin_pos.at(key); + io_name = pin_names.count(io_name) ? pin_names.at(io_name) : "io_" + io_name; + } else { + io_name = stringf("io_%d_%d_%d", x, y, z); + } + + io_names.insert(io_name); + extra_vlog.push_back(stringf(" inout %s;\n", io_name.c_str())); extra_vlog.push_back(stringf(" wire io_pad_%d_%d_%d_din;\n", x, y, z)); extra_vlog.push_back(stringf(" wire io_pad_%d_%d_%d_dout;\n", x, y, z)); extra_vlog.push_back(stringf(" wire io_pad_%d_%d_%d_oe;\n", x, y, z)); - extra_vlog.push_back(stringf(" (* keep *) wire io_pad_%d_%d_%d_pin;\n", x, y, z)); extra_vlog.push_back(stringf(" IO_PAD io_pad_%d_%d_%d (\n", x, y, z)); extra_vlog.push_back(stringf(" .DIN(io_pad_%d_%d_%d_din),\n", x, y, z)); extra_vlog.push_back(stringf(" .DOUT(io_pad_%d_%d_%d_dout),\n", x, y, z)); extra_vlog.push_back(stringf(" .OE(io_pad_%d_%d_%d_oe),\n", x, y, z)); - extra_vlog.push_back(stringf(" .PACKAGEPIN(io_pad_%d_%d_%d_pin)\n", x, y, z)); + extra_vlog.push_back(stringf(" .PACKAGEPIN(%s)\n", io_name.c_str())); extra_vlog.push_back(stringf(" );\n")); return cell; @@ -579,16 +641,27 @@ void help(const char *cmd) printf("\n"); printf("Usage: %s [options] input.txt [output.v]\n", cmd); printf("\n"); + printf(" -p <pcf_file>\n"); + printf(" -P <chip_package>\n"); + printf(" provide this two options for correct IO pin names\n"); + printf("\n"); exit(1); } int main(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "")) != -1) + while ((opt = getopt(argc, argv, "p:P:")) != -1) { switch (opt) { + case 'p': + printf("// Reading input .pcf file..\n"); + read_pcf(optarg); + break; + case 'P': + selected_package = optarg; + break; default: help(argv[0]); } @@ -629,7 +702,13 @@ int main(int argc, char **argv) for (auto &seg : interconn_src) make_interconn(seg); - fprintf(fout, "module chip;\n"); + fprintf(fout, "module chip ("); + const char *io_sep = ""; + for (auto io : io_names) { + fprintf(fout, "%s%s", io_sep, io.c_str()); + io_sep = ", "; + } + fprintf(fout, ");\n"); for (int net : declared_nets) fprintf(fout, " (* keep *) wire net_%d;\n", net); diff --git a/icetime/mktest.py b/icetime/mktest.py new file mode 100644 index 0000000..9cd5cd6 --- /dev/null +++ b/icetime/mktest.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 + +import sys, os, shutil +import numpy as np + +pins = np.random.permutation(""" + 1 2 3 4 7 8 9 10 11 12 19 22 23 24 25 26 28 29 31 32 33 34 + 37 38 41 42 43 44 45 47 48 52 56 58 60 61 62 63 64 + 73 74 75 76 78 79 80 81 87 88 90 91 95 96 97 98 101 102 104 105 106 107 + 112 113 114 115 116 117 118 119 120 121 122 134 135 136 137 138 139 141 142 143 144 +""".split()) + +with open("%s.v" % sys.argv[1], "w") as f: + print("module top(input i0, output o0, o1, o2, o3);", file=f) + print(" assign {o0, o1, o2, o3} = {i0, i0, !i0, !i0};", file=f) + print("endmodule", file=f) + +with open("%s.pcf" % sys.argv[1], "w") as f: + print("set_io i0 %s" % pins[0], file=f) + print("set_io o0 %s" % pins[1], file=f) + print("set_io o1 %s" % pins[2], file=f) + print("set_io o2 %s" % pins[3], file=f) + print("set_io o3 %s" % pins[4], file=f) + +os.system("bash ../icefuzz/icecube.sh %s.v" % sys.argv[1]) +os.rename("%s.v" % sys.argv[1], "%s_in.v" % sys.argv[1]) +os.rename("%s.vsb" % sys.argv[1], "%s_ref.v" % sys.argv[1]) + +os.remove("%s.bin" % sys.argv[1]) +os.remove("%s.glb" % sys.argv[1]) +os.remove("%s.psb" % sys.argv[1]) +os.remove("%s.sdf" % sys.argv[1]) +shutil.rmtree("%s.tmp" % sys.argv[1]) + |