aboutsummaryrefslogtreecommitdiffstats
path: root/icetime
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2015-10-19 17:02:56 +0200
committerClifford Wolf <clifford@clifford.at>2015-10-19 17:02:56 +0200
commit1f4e4d7724e91fe0ee11cdce7b7eace2b307f0cf (patch)
treea434c98b7bdee889a0dc377a65ffb9332d45c186 /icetime
parentf1e096480ac704ee1845b129ad7baadea78742fc (diff)
downloadicestorm-1f4e4d7724e91fe0ee11cdce7b7eace2b307f0cf.tar.gz
icestorm-1f4e4d7724e91fe0ee11cdce7b7eace2b307f0cf.tar.bz2
icestorm-1f4e4d7724e91fe0ee11cdce7b7eace2b307f0cf.zip
Started work on icetime
Diffstat (limited to 'icetime')
-rw-r--r--icetime/.gitignore3
-rw-r--r--icetime/Makefile25
-rw-r--r--icetime/icetime.cc225
3 files changed, 253 insertions, 0 deletions
diff --git a/icetime/.gitignore b/icetime/.gitignore
new file mode 100644
index 0000000..a28ed80
--- /dev/null
+++ b/icetime/.gitignore
@@ -0,0 +1,3 @@
+icetime
+*.d
+*.o
diff --git a/icetime/Makefile b/icetime/Makefile
new file mode 100644
index 0000000..aead84a
--- /dev/null
+++ b/icetime/Makefile
@@ -0,0 +1,25 @@
+# CXX = clang
+CXX ?= clang
+LDLIBS = -lm -lstdc++
+CXXFLAGS = -MD -O0 -ggdb -Wall -std=c++11 -I/usr/local/include
+CC = $(CXX)
+DESTDIR = /usr/local
+
+all: icetime
+
+icetime: icetime.o
+
+install: all
+ cp icetime $(DESTDIR)/bin/icetime
+
+uninstall:
+ rm -f $(DESTDIR)/bin/icetime
+
+clean:
+ rm -f icetime
+ rm -f *.o *.d
+
+-include *.d
+
+.PHONY: all install uninstall clean
+
diff --git a/icetime/icetime.cc b/icetime/icetime.cc
new file mode 100644
index 0000000..61a63ed
--- /dev/null
+++ b/icetime/icetime.cc
@@ -0,0 +1,225 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+
+FILE *fin, *fout;
+
+std::string config_device;
+std::vector<std::vector<std::string>> config_tile_type;
+std::vector<std::vector<std::vector<std::vector<bool>>>> config_bits;
+
+struct net_segment_name
+{
+ int tile_x, tile_y;
+ std::string segment_name;
+
+ net_segment_name(int x, int y, std::string n) :
+ tile_x(x), tile_y(y), segment_name(n) { }
+
+ bool operator<(const net_segment_name &other) const {
+ if (tile_x != other.tile_x)
+ return tile_x < other.tile_x;
+ if (tile_y != other.tile_y)
+ return tile_y < other.tile_y;
+ return segment_name < other.segment_name;
+ }
+};
+
+std::map<net_segment_name, int> segment_to_net;
+std::vector<std::set<net_segment_name>> net_to_segments;
+std::map<int, std::set<int>> net_buffers, net_rbuffers, net_routing;
+std::set<int> used_nets;
+
+void read_chipdb()
+{
+ char buffer[1024];
+ snprintf(buffer, 1024, "/usr/local/share/icebox/chipdb-%s.txt", config_device.c_str());
+
+ FILE *fdb = fopen(buffer, "r");
+ if (fdb == nullptr) {
+ perror("Can't open chipdb file");
+ exit(1);
+ }
+
+
+ std::string mode;
+ int current_net = -1;
+ std::string thiscfg;
+
+ while (fgets(buffer, 1024, fdb))
+ {
+ if (buffer[0] == '#')
+ continue;
+
+ const char *tok = strtok(buffer, " \t\r\n");
+ if (tok == nullptr)
+ continue;
+
+ if (tok[0] == '.')
+ {
+ mode = tok;
+
+ if (mode == ".net")
+ {
+ current_net = atoi(strtok(nullptr, " \t\r\n"));
+ if (current_net >= int(net_to_segments.size()))
+ net_to_segments.resize(current_net+1);
+ }
+
+ if (mode == ".buffer" || mode == ".routing")
+ {
+ int tile_x = atoi(strtok(nullptr, " \t\r\n"));
+ int tile_y = atoi(strtok(nullptr, " \t\r\n"));
+ current_net = atoi(strtok(nullptr, " \t\r\n"));
+
+ thiscfg = "";
+ while ((tok = strtok(nullptr, " \t\r\n")) != nullptr) {
+ int bit_row, bit_col, rc;
+ rc = sscanf(tok, "B%d[%d]", &bit_row, &bit_col);
+ assert(rc == 2);
+ thiscfg.push_back(config_bits[tile_x][tile_y][bit_row][bit_col] ? '1' : '0');
+ }
+ }
+
+ continue;
+ }
+
+ if (mode == ".net") {
+ int tile_x = atoi(tok);
+ int tile_y = atoi(strtok(nullptr, " \t\r\n"));
+ std::string segment_name = strtok(nullptr, " \t\r\n");
+ net_segment_name seg(tile_x, tile_y, segment_name);
+ segment_to_net[seg] = current_net;
+ net_to_segments[current_net].insert(seg);
+ }
+
+ if (mode == ".buffer" && !strcmp(tok, thiscfg.c_str())) {
+ int other_net = atoi(strtok(nullptr, " \t\r\n"));
+ net_rbuffers[current_net].insert(other_net);
+ net_buffers[other_net].insert(current_net);
+ used_nets.insert(current_net);
+ used_nets.insert(other_net);
+ }
+
+ if (mode == ".routing" && !strcmp(tok, thiscfg.c_str())) {
+ int other_net = atoi(strtok(nullptr, " \t\r\n"));
+ net_routing[current_net].insert(other_net);
+ net_routing[other_net].insert(current_net);
+ used_nets.insert(current_net);
+ used_nets.insert(other_net);
+ }
+ }
+
+ fclose(fdb);
+}
+
+void read_config()
+{
+ char buffer[128];
+ int tile_x, tile_y, line_nr = -1;
+
+ while (fgets(buffer, 128, fin))
+ {
+ if (buffer[0] == '.')
+ {
+ line_nr = -1;
+ const char *tok = strtok(buffer, " \t\r\n");
+
+ if (!strcmp(tok, ".device"))
+ {
+ config_device = strtok(nullptr, " \t\r\n");
+ } else
+ if (!strcmp(tok, ".io_tile") || !strcmp(tok, ".logic_tile") ||
+ !strcmp(tok, ".ramb_tile") || !strcmp(tok, ".ramt_tile"))
+ {
+ line_nr = 0;
+ tile_x = atoi(strtok(nullptr, " \t\r\n"));
+ tile_y = atoi(strtok(nullptr, " \t\r\n"));
+
+ if (tile_x >= int(config_tile_type.size())) {
+ config_tile_type.resize(tile_x+1);
+ config_bits.resize(tile_x+1);
+ }
+
+ if (tile_y >= int(config_tile_type.at(tile_x).size())) {
+ config_tile_type.at(tile_x).resize(tile_y+1);
+ config_bits.at(tile_x).resize(tile_y+1);
+ }
+
+ if (!strcmp(tok, ".io_tile"))
+ config_tile_type.at(tile_x).at(tile_y) = "io";
+ if (!strcmp(tok, ".logic_tile"))
+ config_tile_type.at(tile_x).at(tile_y) = "logic";
+ if (!strcmp(tok, ".ramb_tile"))
+ config_tile_type.at(tile_x).at(tile_y) = "ramb";
+ if (!strcmp(tok, ".ramt_tile"))
+ config_tile_type.at(tile_x).at(tile_y) = "ramt";
+ }
+ } else
+ if (line_nr >= 0)
+ {
+ assert(int(config_bits.at(tile_x).at(tile_y).size()) == line_nr);
+ config_bits.at(tile_x).at(tile_y).resize(line_nr+1);
+ for (int i = 0; buffer[i] == '0' || buffer[i] == '1'; i++)
+ config_bits.at(tile_x).at(tile_y).at(line_nr).push_back(buffer[i] == '1');
+ line_nr++;
+ }
+ }
+}
+
+void help(const char *cmd)
+{
+ printf("\n");
+ printf("Usage: %s [options] input.txt [output.v]\n", cmd);
+ printf("\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ while ((opt = getopt(argc, argv, "")) != -1)
+ {
+ switch (opt)
+ {
+ default:
+ help(argv[0]);
+ }
+ }
+
+ if (optind+1 == argc) {
+ fin = fopen(argv[optind], "r");
+ if (fin == nullptr) {
+ perror("Can't open input file");
+ exit(1);
+ }
+ fout = stdout;
+ } else
+ if (optind+2 == argc) {
+ fin = fopen(argv[optind], "r");
+ if (fin == nullptr) {
+ perror("Can't open input file");
+ exit(1);
+ }
+ fout = fopen(argv[optind+1], "w");
+ if (fout == nullptr) {
+ perror("Can't open output file");
+ exit(1);
+ }
+ } else
+ help(argv[0]);
+
+ printf("// Reading input .txt file..\n");
+ read_config();
+
+ printf("// Reading chipdb file..\n");
+ read_chipdb();
+
+ return 0;
+}