Added tests/techmap/mem_simple_4x1
authorClifford Wolf <clifford@clifford.at>
Fri, 21 Feb 2014 11:06:40 +0000 (12:06 +0100)
committerClifford Wolf <clifford@clifford.at>
Fri, 21 Feb 2014 11:06:40 +0000 (12:06 +0100)
Makefile
tests/techmap/.gitignore [new file with mode: 0644]
tests/techmap/mem_simple_4x1_cells.v [new file with mode: 0644]
tests/techmap/mem_simple_4x1_map.v [new file with mode: 0644]
tests/techmap/mem_simple_4x1_runtest.sh [new file with mode: 0644]
tests/techmap/mem_simple_4x1_tb.v [new file with mode: 0644]
tests/techmap/mem_simple_4x1_uut.v [new file with mode: 0644]
tests/techmap/run-test.sh [new file with mode: 0755]

index 730a5355b8d1dcfefa540939b2924b34c8d6378f..85b45577d44c3b0279e46005ed9833ab9f824e7d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -138,6 +138,7 @@ test: yosys
        cd tests/simple && bash run-test.sh
        cd tests/hana && bash run-test.sh
        cd tests/asicworld && bash run-test.sh
+       cd tests/techmap && bash run-test.sh
        cd tests/sat && bash run-test.sh
 
 install: $(TARGETS) $(EXTRA_TARGETS)
diff --git a/tests/techmap/.gitignore b/tests/techmap/.gitignore
new file mode 100644 (file)
index 0000000..397b4a7
--- /dev/null
@@ -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 (file)
index 0000000..7ecdd2d
--- /dev/null
@@ -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 (file)
index 0000000..d207cc1
--- /dev/null
@@ -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 (file)
index 0000000..8285875
--- /dev/null
@@ -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 (file)
index 0000000..5326269
--- /dev/null
@@ -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 (file)
index 0000000..8d46145
--- /dev/null
@@ -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 (executable)
index 0000000..e2fc11e
--- /dev/null
@@ -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