diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/techmap/.gitignore | 1 | ||||
-rw-r--r-- | tests/techmap/mem_simple_4x1_cells.v | 13 | ||||
-rw-r--r-- | tests/techmap/mem_simple_4x1_map.v | 129 | ||||
-rw-r--r-- | tests/techmap/mem_simple_4x1_runtest.sh | 17 | ||||
-rw-r--r-- | tests/techmap/mem_simple_4x1_tb.v | 29 | ||||
-rw-r--r-- | tests/techmap/mem_simple_4x1_uut.v | 15 | ||||
-rwxr-xr-x | tests/techmap/run-test.sh | 10 |
7 files changed, 214 insertions, 0 deletions
diff --git a/tests/techmap/.gitignore b/tests/techmap/.gitignore new file mode 100644 index 000000000..397b4a762 --- /dev/null +++ b/tests/techmap/.gitignore @@ -0,0 +1 @@ +*.log diff --git a/tests/techmap/mem_simple_4x1_cells.v b/tests/techmap/mem_simple_4x1_cells.v new file mode 100644 index 000000000..7ecdd2dee --- /dev/null +++ b/tests/techmap/mem_simple_4x1_cells.v @@ -0,0 +1,13 @@ +module MEM4X1 (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN); + input CLK, WR_DATA, WR_EN; + input [3:0] RD_ADDR, WR_ADDR; + output reg RD_DATA; + + reg [15:0] memory; + + always @(posedge CLK) begin + if (WR_EN) + memory[WR_ADDR] <= WR_DATA; + RD_DATA <= memory[RD_ADDR]; + end +endmodule diff --git a/tests/techmap/mem_simple_4x1_map.v b/tests/techmap/mem_simple_4x1_map.v new file mode 100644 index 000000000..d207cc1bc --- /dev/null +++ b/tests/techmap/mem_simple_4x1_map.v @@ -0,0 +1,129 @@ + +module \$mem (RD_CLK, RD_ADDR, RD_DATA, WR_CLK, WR_EN, WR_ADDR, WR_DATA); + parameter MEMID = ""; + parameter SIZE = 256; + parameter OFFSET = 0; + parameter ABITS = 8; + parameter WIDTH = 8; + + parameter RD_PORTS = 1; + parameter RD_CLK_ENABLE = 1'b1; + parameter RD_CLK_POLARITY = 1'b1; + parameter RD_TRANSPARENT = 1'b1; + + parameter WR_PORTS = 1; + parameter WR_CLK_ENABLE = 1'b1; + parameter WR_CLK_POLARITY = 1'b1; + + input [RD_PORTS-1:0] RD_CLK; + input [RD_PORTS*ABITS-1:0] RD_ADDR; + output reg [RD_PORTS*WIDTH-1:0] RD_DATA; + + input [WR_PORTS-1:0] WR_CLK, WR_EN; + input [WR_PORTS*ABITS-1:0] WR_ADDR; + input [WR_PORTS*WIDTH-1:0] WR_DATA; + + wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + + parameter _TECHMAP_CONNMAP_RD_CLK_ = 0; + parameter _TECHMAP_CONNMAP_WR_CLK_ = 0; + + reg _TECHMAP_FAIL_; + initial begin + _TECHMAP_FAIL_ <= 0; + + // only map cells with only one read and one write port + if (RD_PORTS > 1 || WR_PORTS > 1) + _TECHMAP_FAIL_ <= 1; + + // we expect positive read clock and non-transparent reads + if (RD_TRANSPARENT || !RD_CLK_ENABLE || !RD_CLK_POLARITY) + _TECHMAP_FAIL_ <= 1; + + // we expect positive write clock + if (!WR_CLK_ENABLE || !WR_CLK_POLARITY) + _TECHMAP_FAIL_ <= 1; + + // read and write must be in same clock domain + if (_TECHMAP_CONNMAP_RD_CLK_ != _TECHMAP_CONNMAP_WR_CLK_) + _TECHMAP_FAIL_ <= 1; + + // we don't do small memories or memories with offsets + if (OFFSET != 0 || ABITS < 4 || SIZE < 16) + _TECHMAP_FAIL_ <= 1; + end + + genvar i; + generate + for (i = 0; i < WIDTH; i=i+1) begin:slice + mem_4x1_generator #( + .ABITS(ABITS), + .SIZE(SIZE) + ) bit_slice ( + .CLK(RD_CLK), + .RD_ADDR(RD_ADDR), + .RD_DATA(RD_DATA[i]), + .WR_ADDR(WR_ADDR), + .WR_DATA(WR_DATA[i]), + .WR_EN(WR_EN) + ); + end + endgenerate +endmodule + +module mem_4x1_generator (CLK, RD_ADDR, RD_DATA, WR_ADDR, WR_DATA, WR_EN); + parameter ABITS = 4; + parameter SIZE = 16; + + input CLK, WR_DATA, WR_EN; + input [ABITS-1:0] RD_ADDR, WR_ADDR; + output RD_DATA; + + wire [1023:0] _TECHMAP_DO_ = "proc; clean"; + + generate + if (ABITS > 4) begin + wire high_rd_data, low_rd_data; + if (SIZE > 2**(ABITS-1)) begin + mem_4x1_generator #( + .ABITS(ABITS-1), + .SIZE(SIZE - 2**(ABITS-1)) + ) part_high ( + .CLK(CLK), + .RD_ADDR(RD_ADDR[ABITS-2:0]), + .RD_DATA(high_rd_data), + .WR_ADDR(WR_ADDR[ABITS-2:0]), + .WR_DATA(WR_DATA), + .WR_EN(WR_EN && WR_ADDR[ABITS-1]) + ); + end else begin + assign high_rd_data = 1'bx; + end + mem_4x1_generator #( + .ABITS(ABITS-1), + .SIZE(SIZE > 2**(ABITS-1) ? 2**(ABITS-1) : SIZE) + ) part_low ( + .CLK(CLK), + .RD_ADDR(RD_ADDR[ABITS-2:0]), + .RD_DATA(low_rd_data), + .WR_ADDR(WR_ADDR[ABITS-2:0]), + .WR_DATA(WR_DATA), + .WR_EN(WR_EN && !WR_ADDR[ABITS-1]) + ); + reg delayed_abit; + always @(posedge CLK) + delayed_abit <= RD_ADDR[ABITS-1]; + assign RD_DATA = delayed_abit ? high_rd_data : low_rd_data; + end else begin + MEM4X1 _TECHMAP_REPLACE_ ( + .CLK(CLK), + .RD_ADDR(RD_ADDR), + .RD_DATA(RD_DATA), + .WR_ADDR(WR_ADDR), + .WR_DATA(WR_DATA), + .WR_EN(WR_EN) + ); + end + endgenerate +endmodule + diff --git a/tests/techmap/mem_simple_4x1_runtest.sh b/tests/techmap/mem_simple_4x1_runtest.sh new file mode 100644 index 000000000..8285875b8 --- /dev/null +++ b/tests/techmap/mem_simple_4x1_runtest.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -ev + +yosys -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v + +iverilog -o mem_simple_4x1_gold_tb mem_simple_4x1_tb.v mem_simple_4x1_uut.v +iverilog -o mem_simple_4x1_gate_tb mem_simple_4x1_tb.v mem_simple_4x1_synth.v mem_simple_4x1_cells.v + +./mem_simple_4x1_gold_tb > mem_simple_4x1_gold_tb.out +./mem_simple_4x1_gate_tb > mem_simple_4x1_gate_tb.out + +diff -u mem_simple_4x1_gold_tb.out mem_simple_4x1_gate_tb.out +rm -f mem_simple_4x1_synth.v mem_simple_4x1_tb.vcd +rm -f mem_simple_4x1_{gold,gate}_tb{,.out} +: OK + diff --git a/tests/techmap/mem_simple_4x1_tb.v b/tests/techmap/mem_simple_4x1_tb.v new file mode 100644 index 000000000..532626960 --- /dev/null +++ b/tests/techmap/mem_simple_4x1_tb.v @@ -0,0 +1,29 @@ +module tb; + +reg clk, rst; +wire [7:0] out; +wire [4:0] counter; + +uut uut (clk, rst, out, counter); + +initial begin + #5 clk <= 0; + repeat (100) #5 clk <= ~clk; + #5 $finish; +end + +initial begin + rst <= 1; + repeat (2) @(posedge clk); + rst <= 0; +end + +always @(posedge clk) + $display("%d %d %d", rst, out, counter); + +initial begin + $dumpfile("mem_simple_4x1_tb.vcd"); + $dumpvars(0, uut); +end + +endmodule diff --git a/tests/techmap/mem_simple_4x1_uut.v b/tests/techmap/mem_simple_4x1_uut.v new file mode 100644 index 000000000..8d4614595 --- /dev/null +++ b/tests/techmap/mem_simple_4x1_uut.v @@ -0,0 +1,15 @@ +module uut (clk, rst, out, counter); + +input clk, rst; +output reg [7:0] out; +output reg [4:0] counter; + +reg [7:0] memory [0:19]; + +always @(posedge clk) begin + counter <= rst || counter == 19 ? 0 : counter+1; + memory[counter] <= counter; + out <= memory[counter]; +end + +endmodule diff --git a/tests/techmap/run-test.sh b/tests/techmap/run-test.sh new file mode 100755 index 000000000..e2fc11e52 --- /dev/null +++ b/tests/techmap/run-test.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +for x in *_runtest.sh; do + echo "Running $x.." + if ! bash $x &> ${x%.sh}.log; then + tail ${x%.sh}.log + echo ERROR + exit 1 + fi +done |