--- /dev/null
+
+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
+