aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--icebram/.gitignore10
-rw-r--r--icebram/makedemo.py69
-rw-r--r--icebram/rundemo.sh17
3 files changed, 96 insertions, 0 deletions
diff --git a/icebram/.gitignore b/icebram/.gitignore
new file mode 100644
index 0000000..3569a03
--- /dev/null
+++ b/icebram/.gitignore
@@ -0,0 +1,10 @@
+demo.asc
+demo.blif
+demo.pcf
+demo.v
+demo.vvp
+demo_dat0.hex
+demo_dat1.hex
+demo_new.asc
+demo_new.v
+demo_tb.v
diff --git a/icebram/makedemo.py b/icebram/makedemo.py
new file mode 100644
index 0000000..bcec93f
--- /dev/null
+++ b/icebram/makedemo.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+
+import numpy as np
+
+while True:
+ bram_width = 4 * np.random.randint(1, 9)
+ bram_depth = 256 * np.random.randint(1, 9)
+ numrports = np.random.randint(1, 5)
+ if bram_width * bram_depth * numrports < 16*4096: break
+
+with open("demo.v", "wt") as f:
+ print("module demo (", file=f)
+ for i in range(numrports):
+ print(" input [%d:0] raddr%d," % (np.ceil(np.log2(bram_depth))-1, i), file=f)
+ print(" output reg [%d:0] rdata%d," % (bram_width-1, i), file=f)
+ print(" input [%d:0] waddr," % (np.ceil(np.log2(bram_depth))-1), file=f)
+ print(" input [%d:0] wdata," % (bram_width-1), file=f)
+ print(" input wen, clk", file=f)
+ print(");", file=f)
+ print(" reg [%d:0] memory [0:%d];" % (bram_width-1, bram_depth-1), file=f)
+ print(" initial $readmemh(\"demo_dat0.hex\", memory);", file=f)
+ for i in range(numrports):
+ print(" always @(posedge clk) rdata%d <= memory[raddr%d];" % (i, i), file=f)
+ print(" always @(posedge clk) if (wen) memory[waddr] <= wdata;", file=f)
+ print("endmodule", file=f)
+
+with open("demo_tb.v", "wt") as f:
+ print("module demo_tb;", file=f)
+ print(" reg clk = 0;", file=f)
+ print(" always #5 clk = ~clk;", file=f)
+ print(" integer i, errcnt = 0;", file=f)
+ print(" reg [%d:0] addr;" % (np.ceil(np.log2(bram_depth))-1), file=f)
+ for i in range(numrports):
+ print(" wire [%d:0] rdata%d;" % (bram_width-1, i), file=f)
+ print(" reg [%d:0] refmem [0:%d];" % (bram_width-1, bram_depth-1), file=f)
+ print(" initial $readmemh(\"demo_dat1.hex\", refmem);", file=f)
+ print(" demo uut (", file=f)
+ for i in range(numrports):
+ print(" .raddr%d(addr+%d'd%d)," % (i, np.ceil(np.log2(bram_depth)), i), file=f)
+ print(" .rdata%d(rdata%d)," % (i, i), file=f)
+ print(" .wen(1'b0),", file=f)
+ print(" .clk(clk)", file=f)
+ print(" );", file=f)
+ print(" initial begin", file=f)
+ print(" repeat (10) @(negedge clk);", file=f)
+ print(" for (i = 0; i < %d; i = i + %d) begin" % (bram_depth, numrports), file=f)
+ print(" addr <= i;", file=f)
+ print(" @(posedge clk);", file=f)
+ print(" @(negedge clk);", file=f)
+ for i in range(numrports):
+ print(" if (i+%d < %d && refmem[i+%d] !== rdata%d) begin errcnt = errcnt+1; " % (i, bram_depth, i, i) +
+ "$display(\"ERROR @%%x: %%0%dx != %%0%dx\", i+%d, refmem[i+%d], rdata%d); end" % (bram_width/4, bram_width/4, i, i, i), file=f)
+ print(" end", file=f)
+ print(" if (errcnt == 0)", file=f)
+ print(" $display(\"All tests OK.\");", file=f)
+ print(" else", file=f)
+ print(" $display(\"Found %1d ERROR(s).\", errcnt);", file=f)
+ print(" $finish;", file=f)
+ print(" end", file=f)
+ print("endmodule", file=f)
+
+with open("demo_dat0.hex", "wt") as f:
+ for i in range(bram_depth):
+ print("%0*x" % (bram_width//4, np.random.randint(1 << bram_width)), file=f)
+
+with open("demo_dat1.hex", "wt") as f:
+ for i in range(bram_depth):
+ print("%0*x" % (bram_width//4, np.random.randint(1 << bram_width)), file=f)
+
diff --git a/icebram/rundemo.sh b/icebram/rundemo.sh
new file mode 100644
index 0000000..9358447
--- /dev/null
+++ b/icebram/rundemo.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -ex
+
+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
+
+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 )
+vvp -N demo.vvp