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; input [WR_PORTS*WIDTH-1:0] 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; parameter _TECHMAP_BITS_CONNMAP_ = 0; parameter _TECHMAP_CONNMAP_WR_EN_ = 0; reg _TECHMAP_FAIL_; integer k; 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; // only one global write enable bit is supported for (k = 1; k < WR_PORTS*WIDTH; k = k+1) if (_TECHMAP_CONNMAP_WR_EN_[0 +: _TECHMAP_BITS_CONNMAP_] != _TECHMAP_CONNMAP_WR_EN_[k*_TECHMAP_BITS_CONNMAP_ +: _TECHMAP_BITS_CONNMAP_]) _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[0]) ); 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