mirror of https://github.com/YosysHQ/yosys.git
New $mem simlib model
This commit is contained in:
parent
bbf89c4dc6
commit
474831643c
|
@ -1518,107 +1518,48 @@ input [WR_PORTS*WIDTH-1:0] WR_EN;
|
||||||
input [WR_PORTS*ABITS-1:0] WR_ADDR;
|
input [WR_PORTS*ABITS-1:0] WR_ADDR;
|
||||||
input [WR_PORTS*WIDTH-1:0] WR_DATA;
|
input [WR_PORTS*WIDTH-1:0] WR_DATA;
|
||||||
|
|
||||||
reg [WIDTH-1:0] data [SIZE-1:0];
|
reg [WIDTH-1:0] memory [SIZE-1:0];
|
||||||
reg update_async_rd;
|
|
||||||
|
|
||||||
genvar i;
|
integer i, j;
|
||||||
generate
|
reg [WR_PORTS-1:0] LAST_WR_CLK;
|
||||||
|
reg [RD_PORTS-1:0] LAST_RD_CLK;
|
||||||
|
|
||||||
for (i = 0; i < RD_PORTS; i = i+1) begin:rd
|
function port_active;
|
||||||
if (RD_CLK_ENABLE[i] == 0) begin:rd_noclk
|
input clk_enable;
|
||||||
always @(RD_ADDR or update_async_rd)
|
input clk_polarity;
|
||||||
RD_DATA[i*WIDTH +: WIDTH] <= data[RD_ADDR[i*ABITS +: ABITS] - OFFSET];
|
input last_clk;
|
||||||
end else
|
input this_clk;
|
||||||
if (RD_TRANSPARENT[i] == 1) begin:rd_transparent
|
begin
|
||||||
reg [ABITS-1:0] addr_buf;
|
casez ({clk_enable, clk_polarity, last_clk, this_clk})
|
||||||
if (RD_CLK_POLARITY[i] == 1) begin:rd_trans_posclk
|
4'b0???: port_active = 1;
|
||||||
always @(posedge RD_CLK[i])
|
4'b1101: port_active = 1;
|
||||||
addr_buf <= RD_ADDR[i*ABITS +: ABITS];
|
4'b1010: port_active = 1;
|
||||||
end else begin:rd_trans_negclk
|
default: port_active = 0;
|
||||||
always @(negedge RD_CLK[i])
|
endcase
|
||||||
addr_buf <= RD_ADDR[i*ABITS +: ABITS];
|
end
|
||||||
end
|
endfunction
|
||||||
always @(addr_buf or update_async_rd)
|
|
||||||
RD_DATA[i*WIDTH +: WIDTH] <= data[addr_buf - OFFSET];
|
always @* begin
|
||||||
end else begin:rd_notransparent
|
for (i = 0; i < RD_PORTS; i = i+1) begin
|
||||||
if (RD_CLK_POLARITY[i] == 1) begin:rd_notrans_posclk
|
if ((!RD_TRANSPARENT[i] && RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i]))
|
||||||
always @(posedge RD_CLK[i])
|
RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET];
|
||||||
RD_DATA[i*WIDTH +: WIDTH] <= data[RD_ADDR[i*ABITS +: ABITS] - OFFSET];
|
|
||||||
end else begin:rd_notrans_negclk
|
|
||||||
always @(negedge RD_CLK[i])
|
|
||||||
RD_DATA[i*WIDTH +: WIDTH] <= data[RD_ADDR[i*ABITS +: ABITS] - OFFSET];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
for (i = 0; i < WR_PORTS; i = i+1) begin:wr
|
for (i = 0; i < WR_PORTS; i = i+1) begin
|
||||||
integer k, n;
|
if (port_active(WR_CLK_ENABLE[i], WR_CLK_POLARITY[i], LAST_WR_CLK[i], WR_CLK[i]))
|
||||||
reg found_collision, run_update;
|
for (j = 0; j < WIDTH; j = j+1)
|
||||||
if (WR_CLK_ENABLE[i] == 0) begin:wr_noclk
|
if (WR_EN[i*WIDTH+j])
|
||||||
always @(WR_ADDR or WR_DATA or WR_EN) begin
|
memory[WR_ADDR[i*ABITS +: ABITS] - OFFSET][j] = WR_DATA[i*WIDTH+j];
|
||||||
run_update = 0;
|
|
||||||
for (n = 0; n < WIDTH; n = n+1) begin
|
|
||||||
if (WR_EN[i*WIDTH + n]) begin
|
|
||||||
found_collision = 0;
|
|
||||||
for (k = i+1; k < WR_PORTS; k = k+1)
|
|
||||||
if (WR_EN[k*WIDTH + n] && WR_ADDR[i*ABITS +: ABITS] == WR_ADDR[k*ABITS +: ABITS])
|
|
||||||
found_collision = 1;
|
|
||||||
if (!found_collision) begin
|
|
||||||
data[WR_ADDR[i*ABITS +: ABITS] - OFFSET][n] <= WR_DATA[i*WIDTH + n];
|
|
||||||
run_update = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if (run_update) begin
|
|
||||||
update_async_rd <= 1;
|
|
||||||
update_async_rd <= 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end else
|
|
||||||
if (WR_CLK_POLARITY[i] == 1) begin:rd_posclk
|
|
||||||
always @(posedge WR_CLK[i]) begin
|
|
||||||
run_update = 0;
|
|
||||||
for (n = 0; n < WIDTH; n = n+1) begin
|
|
||||||
if (WR_EN[i*WIDTH + n]) begin
|
|
||||||
found_collision = 0;
|
|
||||||
for (k = i+1; k < WR_PORTS; k = k+1)
|
|
||||||
if (WR_EN[k*WIDTH + n] && WR_ADDR[i*ABITS +: ABITS] == WR_ADDR[k*ABITS +: ABITS])
|
|
||||||
found_collision = 1;
|
|
||||||
if (!found_collision) begin
|
|
||||||
data[WR_ADDR[i*ABITS +: ABITS] - OFFSET][n] <= WR_DATA[i*WIDTH + n];
|
|
||||||
run_update = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if (run_update) begin
|
|
||||||
update_async_rd <= 1;
|
|
||||||
update_async_rd <= 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end else begin:rd_negclk
|
|
||||||
always @(negedge WR_CLK[i]) begin
|
|
||||||
run_update = 0;
|
|
||||||
for (n = 0; n < WIDTH; n = n+1) begin
|
|
||||||
if (WR_EN[i*WIDTH + n]) begin
|
|
||||||
found_collision = 0;
|
|
||||||
for (k = i+1; k < WR_PORTS; k = k+1)
|
|
||||||
if (WR_EN[k*WIDTH + n] && WR_ADDR[i*ABITS +: ABITS] == WR_ADDR[k*ABITS +: ABITS])
|
|
||||||
found_collision = 1;
|
|
||||||
if (!found_collision) begin
|
|
||||||
data[WR_ADDR[i*ABITS +: ABITS] - OFFSET][n] <= WR_DATA[i*WIDTH + n];
|
|
||||||
run_update = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if (run_update) begin
|
|
||||||
update_async_rd <= 1;
|
|
||||||
update_async_rd <= 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
endgenerate
|
for (i = 0; i < RD_PORTS; i = i+1) begin
|
||||||
|
if ((RD_TRANSPARENT[i] || !RD_CLK_ENABLE[i]) && port_active(RD_CLK_ENABLE[i], RD_CLK_POLARITY[i], LAST_RD_CLK[i], RD_CLK[i]))
|
||||||
|
RD_DATA[i*WIDTH +: WIDTH] <= memory[RD_ADDR[i*ABITS +: ABITS] - OFFSET];
|
||||||
|
end
|
||||||
|
|
||||||
|
LAST_RD_CLK <= RD_CLK;
|
||||||
|
LAST_WR_CLK <= WR_CLK;
|
||||||
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue