3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-09-02 00:00:44 +00:00

synth_gatemate: Revise block RAM read modes and initialization

* enable mixed read-width / write-width ports in SDP mode
* fix NO_CHANGE and WRITE_THROUGH behavior during read access
* remove redundant zero-initialization
* set A/B_WE bit during map (gatemate_bramopt pass could be removed later)
* differentiate "upper" and "lower" initialization for cascade mode
This commit is contained in:
Patrick Urban 2021-10-11 10:19:29 +02:00 committed by Marcelina Kościelnicka
parent 3f4ccdf2f5
commit 4bee908ae8
3 changed files with 230 additions and 71 deletions

View file

@ -758,41 +758,41 @@ module CC_BRAM_20K (
generate
if (RAM_MODE == "SDP") begin
// Port A (write)
if (WIDTH_MODE_A <= 1) begin
if (A_WR_WIDTH <= 1) begin
assign addra = A_ADDR[15:7] + (A_ADDR[15:7]/4);
end
if (WIDTH_MODE_A <= 2) begin
else if (A_WR_WIDTH <= 2) begin
assign addra = A_ADDR[15:7]*2 + (A_ADDR[15:7]/2);
end
else if (WIDTH_MODE_A <= 5) begin
else if (A_WR_WIDTH <= 5) begin
assign addra = A_ADDR[15:7]*5;
end
else if (WIDTH_MODE_A <= 10) begin
else if (A_WR_WIDTH <= 10) begin
assign addra = A_ADDR[15:7]*10;
end
else if (WIDTH_MODE_A <= 20) begin
else if (A_WR_WIDTH <= 20) begin
assign addra = A_ADDR[15:7]*20;
end
else if (WIDTH_MODE_A <= 40) begin
else if (A_WR_WIDTH <= 40) begin
assign addra = A_ADDR[15:7]*40;
end
// Port B (read)
if (WIDTH_MODE_B <= 1) begin
if (B_RD_WIDTH <= 1) begin
assign addrb = B_ADDR[15:7] + (B_ADDR[15:7]/4);
end
else if (WIDTH_MODE_B <= 2) begin
else if (B_RD_WIDTH <= 2) begin
assign addrb = B_ADDR[15:7]*2 + (B_ADDR[15:7]/2);
end
else if (WIDTH_MODE_B <= 5) begin
else if (B_RD_WIDTH <= 5) begin
assign addrb = B_ADDR[15:7]*5;
end
else if (WIDTH_MODE_B <= 10) begin
else if (B_RD_WIDTH <= 10) begin
assign addrb = B_ADDR[15:7]*10;
end
else if (WIDTH_MODE_B <= 20) begin
else if (B_RD_WIDTH <= 20) begin
assign addrb = B_ADDR[15:7]*20;
end
else if (WIDTH_MODE_B <= 40) begin
else if (B_RD_WIDTH <= 40) begin
assign addrb = B_ADDR[15:7]*40;
end
end
@ -841,7 +841,7 @@ module CC_BRAM_20K (
// SDP write port
always @(posedge clka)
begin
for (k=0; k < WIDTH_MODE_A; k=k+1) begin
for (k=0; k < A_WR_WIDTH; k=k+1) begin
if (k < 20) begin
if (ena && wea && A_BM[k]) memory[addra+k] <= A_DI[k];
end
@ -853,12 +853,13 @@ module CC_BRAM_20K (
// SDP read port
always @(posedge clkb)
begin
for (k=0; k < WIDTH_MODE_B; k=k+1) begin
// "NO_CHANGE" only
for (k=0; k < B_RD_WIDTH; k=k+1) begin
if (k < 20) begin
if (enb) A_DO_out[k] <= memory[addrb+k];
if (enb && !wea) A_DO_out[k] <= memory[addrb+k];
end
else begin // use both ports
if (enb) B_DO_out[k-20] <= memory[addrb+k];
if (enb && !wea) B_DO_out[k-20] <= memory[addrb+k];
end
end
end
@ -871,10 +872,17 @@ module CC_BRAM_20K (
if (ena && wea && A_BM[i]) memory[addra+i] <= A_DI[i];
if (A_WR_MODE == "NO_CHANGE") begin
if (ena) A_DO_out[i] <= memory[addra+i];
if (ena && !wea) A_DO_out[i] <= memory[addra+i];
end
else if (A_WR_MODE == "WRITE_THROUGH") begin
if (ena) A_DO_out[i] <= A_DI[i];
if (ena) begin
if (wea && A_BM[i]) begin
A_DO_out[i] <= A_DI[i];
end
else begin
A_DO_out[i] <= memory[addra+i];
end
end
end
end
end
@ -885,10 +893,17 @@ module CC_BRAM_20K (
if (enb && web && B_BM[i]) memory[addrb+i] <= B_DI[i];
if (B_WR_MODE == "NO_CHANGE") begin
if (enb) B_DO_out[i] <= memory[addrb+i];
if (enb && !web) B_DO_out[i] <= memory[addrb+i];
end
else if (B_WR_MODE == "WRITE_THROUGH") begin
if (enb) B_DO_out[i] <= B_DI[i];
if (enb) begin
if (web && B_BM[i]) begin
B_DO_out[i] <= B_DI[i];
end
else begin
B_DO_out[i] <= memory[addrb+i];
end
end
end
end
end
@ -1152,6 +1167,10 @@ module CC_BRAM_40K (
$display("ERROR: Illegal %s Port B width configuration %d.", RAM_MODE, WIDTH_MODE_B);
$finish();
end
if (CAS != "NONE") begin
$display("WARNING: Cascade simulation model not yet supported.");
$finish();
end
if ((CAS != "NONE") && ((WIDTH_MODE_A > 1) || (WIDTH_MODE_B > 1))) begin
$display("ERROR: Cascade feature only supported in 1 bit data width mode.");
$finish();
@ -1308,47 +1327,47 @@ module CC_BRAM_40K (
generate
if (RAM_MODE == "SDP") begin
// Port A (write)
if (WIDTH_MODE_A <= 1) begin
if (A_WR_WIDTH <= 1) begin
assign addra = A_ADDR[15:7] + (A_ADDR[15:7]/4);
end
if (WIDTH_MODE_A <= 2) begin
else if (A_WR_WIDTH <= 2) begin
assign addra = A_ADDR[15:7]*2 + (A_ADDR[15:7]/2);
end
else if (WIDTH_MODE_A <= 5) begin
else if (A_WR_WIDTH <= 5) begin
assign addra = A_ADDR[15:7]*5;
end
else if (WIDTH_MODE_A <= 10) begin
else if (A_WR_WIDTH <= 10) begin
assign addra = A_ADDR[15:7]*10;
end
else if (WIDTH_MODE_A <= 20) begin
else if (A_WR_WIDTH <= 20) begin
assign addra = A_ADDR[15:7]*20;
end
else if (WIDTH_MODE_A <= 40) begin
else if (A_WR_WIDTH <= 40) begin
assign addra = A_ADDR[15:7]*40;
end
else if (WIDTH_MODE_A <= 80) begin
else if (A_WR_WIDTH <= 80) begin
assign addra = A_ADDR[15:7]*80;
end
// Port B (read)
if (WIDTH_MODE_B <= 1) begin
if (B_RD_WIDTH <= 1) begin
assign addrb = B_ADDR[15:7] + (B_ADDR[15:7]/4);
end
else if (WIDTH_MODE_B <= 2) begin
else if (B_RD_WIDTH <= 2) begin
assign addrb = B_ADDR[15:7]*2 + (B_ADDR[15:7]/2);
end
else if (WIDTH_MODE_B <= 5) begin
else if (B_RD_WIDTH <= 5) begin
assign addrb = B_ADDR[15:7]*5;
end
else if (WIDTH_MODE_B <= 10) begin
else if (B_RD_WIDTH <= 10) begin
assign addrb = B_ADDR[15:7]*10;
end
else if (WIDTH_MODE_B <= 20) begin
else if (B_RD_WIDTH <= 20) begin
assign addrb = B_ADDR[15:7]*20;
end
else if (WIDTH_MODE_B <= 40) begin
else if (B_RD_WIDTH <= 40) begin
assign addrb = B_ADDR[15:7]*40;
end
else if (WIDTH_MODE_B <= 80) begin
else if (B_RD_WIDTH <= 80) begin
assign addrb = B_ADDR[15:7]*80;
end
end
@ -1403,7 +1422,7 @@ module CC_BRAM_40K (
// SDP write port
always @(posedge clka)
begin
for (k=0; k < WIDTH_MODE_A; k=k+1) begin
for (k=0; k < A_WR_WIDTH; k=k+1) begin
if (k < 40) begin
if (ena && wea && A_BM[k]) memory[addra+k] <= A_DI[k];
end
@ -1415,12 +1434,13 @@ module CC_BRAM_40K (
// SDP read port
always @(posedge clkb)
begin
for (k=0; k < WIDTH_MODE_B; k=k+1) begin
// "NO_CHANGE" only
for (k=0; k < B_RD_WIDTH; k=k+1) begin
if (k < 40) begin
if (enb) A_DO_out[k] <= memory[addrb+k];
if (enb && !wea) A_DO_out[k] <= memory[addrb+k];
end
else begin // use both ports
if (enb) B_DO_out[k-40] <= memory[addrb+k];
if (enb && !wea) B_DO_out[k-40] <= memory[addrb+k];
end
end
end
@ -1433,10 +1453,17 @@ module CC_BRAM_40K (
if (ena && wea && A_BM[i]) memory[addra+i] <= A_DI[i];
if (A_WR_MODE == "NO_CHANGE") begin
if (ena) A_DO_out[i] <= memory[addra+i];
if (ena && !wea) A_DO_out[i] <= memory[addra+i];
end
else if (A_WR_MODE == "WRITE_THROUGH") begin
if (ena) A_DO_out[i] <= A_DI[i];
if (ena) begin
if (wea && A_BM[i]) begin
A_DO_out[i] <= A_DI[i];
end
else begin
A_DO_out[i] <= memory[addra+i];
end
end
end
end
end
@ -1447,10 +1474,17 @@ module CC_BRAM_40K (
if (enb && web && B_BM[i]) memory[addrb+i] <= B_DI[i];
if (B_WR_MODE == "NO_CHANGE") begin
if (enb) B_DO_out[i] <= memory[addrb+i];
if (enb && !web) B_DO_out[i] <= memory[addrb+i];
end
else if (B_WR_MODE == "WRITE_THROUGH") begin
if (enb) B_DO_out[i] <= B_DI[i];
if (enb) begin
if (web && B_BM[i]) begin
B_DO_out[i] <= B_DI[i];
end
else begin
B_DO_out[i] <= memory[addrb+i];
end
end
end
end
end