aboutsummaryrefslogtreecommitdiffstats
path: root/icebram
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2016-05-12 00:48:37 +0200
committerClifford Wolf <clifford@clifford.at>2016-05-12 00:48:37 +0200
commit0e1417249c832afabb3c81eb707d39efe94955df (patch)
tree6c0d282c6170018a44e118bb3269272302517b99 /icebram
parent66e35e36dcebd3d0e68fea0b3148a50d7f966a63 (diff)
downloadicestorm-0e1417249c832afabb3c81eb707d39efe94955df.tar.gz
icestorm-0e1417249c832afabb3c81eb707d39efe94955df.tar.bz2
icestorm-0e1417249c832afabb3c81eb707d39efe94955df.zip
Added icebram skeleton
Diffstat (limited to 'icebram')
-rw-r--r--icebram/.gitignore3
-rw-r--r--icebram/Makefile33
-rw-r--r--icebram/icebram.cc165
-rw-r--r--icebram/rundemo.sh7
4 files changed, 202 insertions, 6 deletions
diff --git a/icebram/.gitignore b/icebram/.gitignore
index 3569a03..10fbc8a 100644
--- a/icebram/.gitignore
+++ b/icebram/.gitignore
@@ -8,3 +8,6 @@ demo_dat1.hex
demo_new.asc
demo_new.v
demo_tb.v
+icebram
+icebram.d
+icebram.o
diff --git a/icebram/Makefile b/icebram/Makefile
new file mode 100644
index 0000000..827fe7c
--- /dev/null
+++ b/icebram/Makefile
@@ -0,0 +1,33 @@
+include ../config.mk
+LDLIBS = -lm -lstdc++
+CXXFLAGS = -MD -O0 -ggdb -Wall -std=c++11 -I/usr/local/include
+
+ifeq ($(STATIC),1)
+LDFLAGS += -static
+endif
+
+all: icebram$(EXE)
+
+icebram$(EXE): icebram.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LDLIBS)
+
+test: icebram
+ bash rundemo.sh
+
+install: all
+ mkdir -p $(DESTDIR)$(PREFIX)/bin
+ cp icebram $(DESTDIR)$(PREFIX)/bin/icebram
+
+uninstall:
+ rm -f $(DESTDIR)$(PREFIX)/bin/icebram
+
+clean:
+ rm -f icebram
+ rm -f icebram.exe
+ rm -f demo.* demo_*.*
+ rm -f *.o *.d
+
+-include *.d
+
+.PHONY: all test install uninstall clean
+
diff --git a/icebram/icebram.cc b/icebram/icebram.cc
new file mode 100644
index 0000000..a4cb415
--- /dev/null
+++ b/icebram/icebram.cc
@@ -0,0 +1,165 @@
+//
+// Copyright (C) 2016 Clifford Wolf <clifford@clifford.at>
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <map>
+#include <vector>
+#include <string>
+#include <fstream>
+#include <iostream>
+
+using std::map;
+using std::vector;
+using std::string;
+using std::ifstream;
+using std::getline;
+
+void parse_hexfile_line(const char *filename, int linenr, vector<vector<bool>> &hexfile, string &line)
+{
+ vector<int> digits;
+
+ for (char c : line) {
+ if ('0' <= c && c <= '9')
+ digits.push_back(c - '0');
+ else if ('a' <= c && c <= 'f')
+ digits.push_back(10 + c - 'a');
+ else if ('A' <= c && c <= 'F')
+ digits.push_back(10 + c - 'A');
+ else goto error;
+ }
+
+ hexfile.push_back(vector<bool>(digits.size() * 4));
+
+ for (int i = 0; i < digits.size() * 4; i++)
+ if ((digits.at(digits.size() - i/4 -1) & (1 << (i%4))) != 0)
+ hexfile.back().at(i) = true;
+
+ return;
+
+error:
+ fprintf(stderr, "Can't parse line %d of %s: %s\n", linenr, filename, line.c_str());
+ exit(1);
+}
+
+void help(const char *cmd)
+{
+ printf("\n");
+ printf("Usage: %s [options] from_hexfile to_hexfile \n", cmd);
+ printf("\n");
+ // printf(" -S\n");
+ // printf(" Disable SIMPLE feedback path mode\n");
+ // printf("\n");
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ while ((opt = getopt(argc, argv, "")) != -1)
+ {
+ switch (opt)
+ {
+ // case 'i':
+ // f_pllin = atof(optarg);
+ // break;
+ default:
+ help(argv[0]);
+ }
+ }
+
+ if (optind+2 != argc)
+ help(argv[0]);
+
+ const char *from_hexfile_n = argv[optind];
+ ifstream from_hexfile_f(from_hexfile_n);
+ vector<vector<bool>> from_hexfile;
+
+ const char *to_hexfile_n = argv[optind+1];
+ ifstream to_hexfile_f(to_hexfile_n);
+ vector<vector<bool>> to_hexfile;
+
+ string line;
+
+ for (int i = 1; getline(from_hexfile_f, line); i++)
+ parse_hexfile_line(from_hexfile_n, i, from_hexfile, line);
+
+ for (int i = 1; getline(to_hexfile_f, line); i++)
+ parse_hexfile_line(to_hexfile_n, i, to_hexfile, line);
+
+ if (from_hexfile.size() != to_hexfile.size()) {
+ fprintf(stderr, "Hexfiles have different number of words! (%d vs. %d)\n", int(from_hexfile.size()), int(to_hexfile.size()));
+ exit(1);
+ }
+
+ if (from_hexfile.size() % 256 != 0) {
+ fprintf(stderr, "Hexfile number of words (%d) is not divisible by 256!\n", int(from_hexfile.size()));
+ exit(1);
+ }
+
+ for (size_t i = 1; i < from_hexfile.size(); i++)
+ if (from_hexfile.at(i-1).size() != from_hexfile.at(i).size()) {
+ fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i), from_hexfile_n);
+ exit(1);
+ }
+
+ for (size_t i = 1; i < to_hexfile.size(); i++)
+ if (to_hexfile.at(i-1).size() != to_hexfile.at(i).size()) {
+ fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i+1), to_hexfile_n);
+ exit(1);
+ }
+
+ vector<string> ascfile_lines;
+ map<string, vector<vector<bool>>> ascfile_hexdata;
+
+ for (int i = 1; getline(std::cin, line); i++)
+ {
+ next_asc_stmt:
+ ascfile_lines.push_back(line);
+
+ if (line.substr(0, 9) == ".ram_data")
+ {
+ auto &hexdata = ascfile_hexdata[line];
+
+ for (; getline(std::cin, line); i++) {
+ if (line.substr(0, 1) == ".")
+ goto next_asc_stmt;
+ parse_hexfile_line("stdin", i, hexdata, line);
+ }
+ }
+ }
+
+ // FIXME: Do the actual thing
+
+ for (size_t i = 0; i < ascfile_lines.size(); i++) {
+ auto &line = ascfile_lines.at(i);
+ std::cout << line << std::endl;
+ if (ascfile_hexdata.count(line)) {
+ for (auto &word : ascfile_hexdata.at(line)) {
+ for (int k = word.size()-4; k >= 0; k -= 4) {
+ int digit = (word[k+3] ? 8 : 0) + (word[k+2] ? 4 : 0) + (word[k+1] ? 2 : 0) + (word[k] ? 1 : 0);
+ std::cout << "0123456789abcdef"[digit];
+ }
+ std::cout << std::endl;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/icebram/rundemo.sh b/icebram/rundemo.sh
index 9358447..b2e7ecd 100644
--- a/icebram/rundemo.sh
+++ b/icebram/rundemo.sh
@@ -5,12 +5,7 @@ python3 makedemo.py
yosys -p 'synth_ice40 -blif demo.blif' demo.v
arachne-pnr -d 8k -w demo.pcf -o demo.asc demo.blif
-if true; then
- cp demo.asc demo_new.asc
- cp demo_dat0.hex demo_dat1.hex
-else
- ./icebram -o demo_new.asc demo.asc demo_dat0.hex demo_dat1.hex
-fi
+./icebram demo_dat0.hex demo_dat1.hex < demo.asc > demo_new.asc
icebox_vlog -n demo -p demo.pcf -c demo_new.asc > demo_new.v
iverilog -o demo.vvp demo_tb.v demo_new.v $( yosys-config --datdir/ice40/cells_sim.v )