diff options
author | Clifford Wolf <clifford@clifford.at> | 2016-05-12 18:32:07 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2016-05-12 18:32:07 +0200 |
commit | 2c553baeac92026177dcf3be95cb793f1a5c973d (patch) | |
tree | 3ab656702552922b7af3d50b25ea27b55dae5ab7 /icebram | |
parent | 0e1417249c832afabb3c81eb707d39efe94955df (diff) | |
download | icestorm-2c553baeac92026177dcf3be95cb793f1a5c973d.tar.gz icestorm-2c553baeac92026177dcf3be95cb793f1a5c973d.tar.bz2 icestorm-2c553baeac92026177dcf3be95cb793f1a5c973d.zip |
Added icebram bitslice replacer
Diffstat (limited to 'icebram')
-rw-r--r-- | icebram/icebram.cc | 115 | ||||
-rw-r--r-- | icebram/makedemo.py | 4 | ||||
-rw-r--r-- | icebram/rundemo.sh | 2 |
3 files changed, 112 insertions, 9 deletions
diff --git a/icebram/icebram.cc b/icebram/icebram.cc index a4cb415..cea30f5 100644 --- a/icebram/icebram.cc +++ b/icebram/icebram.cc @@ -18,6 +18,7 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <assert.h> #include <map> #include <vector> @@ -26,6 +27,7 @@ #include <iostream> using std::map; +using std::pair; using std::vector; using std::string; using std::ifstream; @@ -63,22 +65,24 @@ 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"); + printf(" -v\n"); + printf(" verbose output\n"); + printf("\n"); exit(1); } int main(int argc, char **argv) { + bool verbose = false; + int opt; - while ((opt = getopt(argc, argv, "")) != -1) + while ((opt = getopt(argc, argv, "v")) != -1) { switch (opt) { - // case 'i': - // f_pllin = atof(optarg); - // break; + case 'v': + verbose = true; + break; default: help(argv[0]); } @@ -87,6 +91,10 @@ int main(int argc, char **argv) if (optind+2 != argc) help(argv[0]); + + // ------------------------------------------------------- + // Load from_hexfile and to_hexfile + const char *from_hexfile_n = argv[optind]; ifstream from_hexfile_f(from_hexfile_n); vector<vector<bool>> from_hexfile; @@ -125,6 +133,50 @@ int main(int argc, char **argv) exit(1); } + if (from_hexfile.size() == 0 || from_hexfile.at(0).size() == 0) { + fprintf(stderr, "Empty from/to hexfiles!\n"); + exit(1); + } + + if (verbose) + fprintf(stderr, "Loaded pattern for %d bits wide and %d words deep memory.\n", int(from_hexfile.at(0).size()), int(from_hexfile.size())); + + + // ------------------------------------------------------- + // Create bitslices from pattern data + + map<vector<bool>, pair<vector<bool>, int>> pattern; + + for (int i = 0; i < int(from_hexfile.at(0).size()); i++) + { + vector<bool> pattern_from, pattern_to; + + for (int j = 0; j < int(from_hexfile.size()); j++) + { + pattern_from.push_back(from_hexfile.at(j).at(i)); + pattern_to.push_back(to_hexfile.at(j).at(i)); + + if (pattern_from.size() == 256) { + if (pattern.count(pattern_from)) { + fprintf(stderr, "Conflicting from pattern for bit slice from_hexfile[%d:%d][%d]!\n", j, j-255, i); + exit(1); + } + pattern[pattern_from] = std::make_pair(pattern_to, 0); + pattern_from.clear(), pattern_to.clear(); + } + } + + assert(pattern_from.empty()); + assert(pattern_to.empty()); + } + + if (verbose) + fprintf(stderr, "Extracted %d bit slices from from/to hexfile data.\n", int(pattern.size())); + + + // ------------------------------------------------------- + // Read ascfile from stdin + vector<string> ascfile_lines; map<string, vector<vector<bool>>> ascfile_hexdata; @@ -145,7 +197,54 @@ int main(int argc, char **argv) } } - // FIXME: Do the actual thing + if (verbose) + fprintf(stderr, "Found %d initialized bram cells in asc file.\n", int(ascfile_hexdata.size())); + + + // ------------------------------------------------------- + // Replace bram data + + int max_replace_cnt = 0; + + for (auto &bram_it : ascfile_hexdata) + { + auto &bram_data = bram_it.second; + + for (int i = 0; i < 16; i++) + { + vector<bool> from_bitslice; + + for (int j = 0; j < 256; j++) + from_bitslice.push_back(bram_data.at(j / 16).at(16 * (j % 16) + i)); + + auto p = pattern.find(from_bitslice); + if (p != pattern.end()) + { + auto &to_bitslice = p->second.first; + + for (int j = 0; j < 256; j++) + bram_data.at(j / 16).at(16 * (j % 16) + i) = to_bitslice.at(j); + + max_replace_cnt = std::max(++p->second.second, max_replace_cnt); + } + } + } + + int min_replace_cnt = max_replace_cnt; + for (auto &it : pattern) + min_replace_cnt = std::min(min_replace_cnt, it.second.second); + + if (min_replace_cnt != max_replace_cnt) { + fprintf(stderr, "Found some bitslices up to %d times, others only %d times!\n", max_replace_cnt, min_replace_cnt); + exit(1); + } + + if (verbose) + fprintf(stderr, "Found and replaced %d instances of the memory.\n", max_replace_cnt); + + + // ------------------------------------------------------- + // Write ascfile to stdout for (size_t i = 0; i < ascfile_lines.size(); i++) { auto &line = ascfile_lines.at(i); diff --git a/icebram/makedemo.py b/icebram/makedemo.py index bcec93f..35d3653 100644 --- a/icebram/makedemo.py +++ b/icebram/makedemo.py @@ -8,6 +8,10 @@ while True: numrports = np.random.randint(1, 5) if bram_width * bram_depth * numrports < 16*4096: break +bram_width = 16 +bram_depth = 256 +numrports = 1 + with open("demo.v", "wt") as f: print("module demo (", file=f) for i in range(numrports): diff --git a/icebram/rundemo.sh b/icebram/rundemo.sh index b2e7ecd..4e90ea2 100644 --- a/icebram/rundemo.sh +++ b/icebram/rundemo.sh @@ -5,7 +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 -./icebram demo_dat0.hex demo_dat1.hex < demo.asc > demo_new.asc +./icebram -v 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 ) |