mirror of https://github.com/YosysHQ/icestorm.git
Added icebram bitslice replacer
This commit is contained in:
parent
0e1417249c
commit
2c553baeac
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
Loading…
Reference in New Issue