diff options
author | Patrick Urban <patrick.urban@web.de> | 2021-11-10 16:18:13 +0100 |
---|---|---|
committer | Marcelina KoĆcielnicka <mwk@0x04.net> | 2021-11-13 21:53:25 +0100 |
commit | 0d871b6c49b326315436fd8cdbd50b8d90a2990f (patch) | |
tree | 74c5f86eebfcee99f1485027d5092cfb16a2b60d /techlibs | |
parent | 285ec0547b19a48c6b52050ee715940f1635994a (diff) | |
download | yosys-0d871b6c49b326315436fd8cdbd50b8d90a2990f.tar.gz yosys-0d871b6c49b326315436fd8cdbd50b8d90a2990f.tar.bz2 yosys-0d871b6c49b326315436fd8cdbd50b8d90a2990f.zip |
synth_gatemate: Add block RAM cascade support
* add simulation model for block RAM cascade in 40K mode
* limit 20K_SDP and 40K_SDP to 40 and 80 bits (the only useful configurations)
Diffstat (limited to 'techlibs')
-rw-r--r-- | techlibs/gatemate/brams_map.v | 34 | ||||
-rw-r--r-- | techlibs/gatemate/cells_sim.v | 174 |
2 files changed, 96 insertions, 112 deletions
diff --git a/techlibs/gatemate/brams_map.v b/techlibs/gatemate/brams_map.v index b7f0ff73e..2e5e1a5cc 100644 --- a/techlibs/gatemate/brams_map.v +++ b/techlibs/gatemate/brams_map.v @@ -50,19 +50,13 @@ module \$__CC_BRAM_20K_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1 wire [15:0] ADDRA = {A1ADDR, 7'b0};
wire [15:0] ADDRB = {B1ADDR, 7'b0};
- localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 2) ? 256 : 320;
+ localparam INIT_CHUNK_SIZE = 320;
function [319:0] permute_init;
input [INIT_CHUNK_SIZE-1:0] chunk;
integer i;
begin
- if (CFG_DBITS <= 2) begin
- for (i = 0; i < 64; i = i + 1) begin
- permute_init[i * 5 +: 5] = {1'b0, chunk[i * 4 +: 4]};
- end
- end else begin
- permute_init = chunk;
- end
+ permute_init = chunk;
end
endfunction
@@ -133,19 +127,13 @@ module \$__CC_BRAM_40K_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1 wire [15:0] ADDRA = {A1ADDR, 7'b0};
wire [15:0] ADDRB = {B1ADDR, 7'b0};
- localparam INIT_CHUNK_SIZE = (CFG_DBITS <= 2) ? 256 : 320;
+ localparam INIT_CHUNK_SIZE = 320;
function [319:0] permute_init;
input [INIT_CHUNK_SIZE-1:0] chunk;
integer i;
begin
- if (CFG_DBITS <= 2) begin
- for (i = 0; i < 64; i = i + 1) begin
- permute_init[i * 5 +: 5] = {1'b0, chunk[i * 4 +: 4]};
- end
- end else begin
- permute_init = chunk;
- end
+ permute_init = chunk;
end
endfunction
@@ -173,7 +161,7 @@ module \$__CC_BRAM_40K_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1 .B_ECC_2B_ERR(B_ECC_2B_ERR),
.A_CLK(CLK2),
.B_CLK(CLK3),
- .A_EN(|A1EN),
+ .A_EN(1'b1),
.B_EN(B1EN),
.A_WE(|A1EN),
.B_WE(1'b0),
@@ -440,7 +428,7 @@ module \$__CC_BRAM_CASCADE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1 wire A_CAS, B_CAS;
// unconnected signals
- wire [39:0] A_UP_DO, A_LO_DO, B_LO_DO;
+ wire [39:0] A_UP_DO;
wire A_ECC_1B_ERR, B_ECC_1B_ERR, A_ECC_2B_ERR, B_ECC_2B_ERR;
localparam INIT_CHUNK_SIZE = 256;
@@ -462,7 +450,7 @@ module \$__CC_BRAM_CASCADE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1 `undef INIT_UPPER
.LOC("UNPLACED"),
.CAS("UPPER"),
- .A_RD_WIDTH(0), .B_RD_WIDTH(CFG_DBITS),
+ .A_RD_WIDTH(CFG_DBITS), .B_RD_WIDTH(0),
.A_WR_WIDTH(CFG_DBITS), .B_WR_WIDTH(0),
.RAM_MODE("TDP"),
.A_WR_MODE("NO_CHANGE"), .B_WR_MODE("NO_CHANGE"),
@@ -474,8 +462,8 @@ module \$__CC_BRAM_CASCADE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1 ) upper_cell (
.A_CI(A_CAS),
.B_CI(B_CAS),
- .A_DO(A_UP_DO),
- .B_DO(B1DATA),
+ .A_DO(B1DATA),
+ .B_DO(A_UP_DO),
.A_ECC_1B_ERR(A_ECC_1B_ERR),
.B_ECC_1B_ERR(B_ECC_1B_ERR),
.A_ECC_2B_ERR(A_ECC_2B_ERR),
@@ -500,7 +488,7 @@ module \$__CC_BRAM_CASCADE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1 `undef INIT_LOWER
.LOC("UNPLACED"),
.CAS("LOWER"),
- .A_RD_WIDTH(0), .B_RD_WIDTH(CFG_DBITS),
+ .A_RD_WIDTH(CFG_DBITS), .B_RD_WIDTH(0),
.A_WR_WIDTH(CFG_DBITS), .B_WR_WIDTH(0),
.RAM_MODE("TDP"),
.A_WR_MODE("NO_CHANGE"), .B_WR_MODE("NO_CHANGE"),
@@ -510,7 +498,7 @@ module \$__CC_BRAM_CASCADE (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1 .A_DO_REG(1'b0), .B_DO_REG(1'b0),
.A_ECC_EN(1'b0), .B_ECC_EN(1'b0)
) lower_cell (
- .A_CI(1'b1),
+ .A_CI(),
.B_CI(),
.A_CO(A_CAS),
.B_CO(B_CAS),
diff --git a/techlibs/gatemate/cells_sim.v b/techlibs/gatemate/cells_sim.v index 90b795d9d..1c7e40680 100644 --- a/techlibs/gatemate/cells_sim.v +++ b/techlibs/gatemate/cells_sim.v @@ -666,41 +666,11 @@ module CC_BRAM_20K ( generate
if (RAM_MODE == "SDP") begin
// Port A (write)
- if (A_WR_WIDTH <= 1) begin
- assign addra = A_ADDR[15:7] + (A_ADDR[15:7]/4);
- end
- else if (A_WR_WIDTH <= 2) begin
- assign addra = A_ADDR[15:7]*2 + (A_ADDR[15:7]/2);
- end
- else if (A_WR_WIDTH <= 5) begin
- assign addra = A_ADDR[15:7]*5;
- end
- else if (A_WR_WIDTH <= 10) begin
- assign addra = A_ADDR[15:7]*10;
- end
- else if (A_WR_WIDTH <= 20) begin
- assign addra = A_ADDR[15:7]*20;
- end
- else if (A_WR_WIDTH <= 40) begin
+ if (A_WR_WIDTH == 40) begin
assign addra = A_ADDR[15:7]*40;
end
// Port B (read)
- if (B_RD_WIDTH <= 1) begin
- assign addrb = B_ADDR[15:7] + (B_ADDR[15:7]/4);
- end
- else if (B_RD_WIDTH <= 2) begin
- assign addrb = B_ADDR[15:7]*2 + (B_ADDR[15:7]/2);
- end
- else if (B_RD_WIDTH <= 5) begin
- assign addrb = B_ADDR[15:7]*5;
- end
- else if (B_RD_WIDTH <= 10) begin
- assign addrb = B_ADDR[15:7]*10;
- end
- else if (B_RD_WIDTH <= 20) begin
- assign addrb = B_ADDR[15:7]*20;
- end
- else if (B_RD_WIDTH <= 40) begin
+ if (B_RD_WIDTH == 40) begin
assign addrb = B_ADDR[15:7]*40;
end
end
@@ -849,8 +819,8 @@ module CC_BRAM_40K ( output B_ECC_1B_ERR,
output A_ECC_2B_ERR,
output B_ECC_2B_ERR,
- output A_CO,
- output B_CO,
+ output reg A_CO = 0,
+ output reg B_CO = 0,
(* clkbuf_sink *)
input A_CLK,
(* clkbuf_sink *)
@@ -1065,6 +1035,14 @@ module CC_BRAM_40K ( $display("ERROR: Port B width of 80 bits is only supported in SDP mode.");
$finish();
end
+ if (((CAS == "UPPER") || (CAS == "LOWER")) && (WIDTH_MODE_A > 1)) begin
+ $display("ERROR: Port A cascade mode only supported in 1 bit mode.");
+ $finish();
+ end
+ if (((CAS == "UPPER") || (CAS == "LOWER")) && (WIDTH_MODE_B > 1)) begin
+ $display("ERROR: Port B cascade mode only supported in 1 bit mode.");
+ $finish();
+ end
if ((WIDTH_MODE_A != 80) && (WIDTH_MODE_A != 40) && (WIDTH_MODE_A != 20) && (WIDTH_MODE_A != 10) &&
(WIDTH_MODE_A != 5) && (WIDTH_MODE_A != 2) && (WIDTH_MODE_A != 1) && (WIDTH_MODE_A != 0)) begin
$display("ERROR: Illegal %s Port A width configuration %d.", RAM_MODE, WIDTH_MODE_A);
@@ -1075,10 +1053,6 @@ 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();
@@ -1235,47 +1209,11 @@ module CC_BRAM_40K ( generate
if (RAM_MODE == "SDP") begin
// Port A (write)
- if (A_WR_WIDTH <= 1) begin
- assign addra = A_ADDR[15:7] + (A_ADDR[15:7]/4);
- end
- else if (A_WR_WIDTH <= 2) begin
- assign addra = A_ADDR[15:7]*2 + (A_ADDR[15:7]/2);
- end
- else if (A_WR_WIDTH <= 5) begin
- assign addra = A_ADDR[15:7]*5;
- end
- else if (A_WR_WIDTH <= 10) begin
- assign addra = A_ADDR[15:7]*10;
- end
- else if (A_WR_WIDTH <= 20) begin
- assign addra = A_ADDR[15:7]*20;
- end
- else if (A_WR_WIDTH <= 40) begin
- assign addra = A_ADDR[15:7]*40;
- end
- else if (A_WR_WIDTH <= 80) begin
+ if (A_WR_WIDTH == 80) begin
assign addra = A_ADDR[15:7]*80;
end
// Port B (read)
- if (B_RD_WIDTH <= 1) begin
- assign addrb = B_ADDR[15:7] + (B_ADDR[15:7]/4);
- end
- else if (B_RD_WIDTH <= 2) begin
- assign addrb = B_ADDR[15:7]*2 + (B_ADDR[15:7]/2);
- end
- else if (B_RD_WIDTH <= 5) begin
- assign addrb = B_ADDR[15:7]*5;
- end
- else if (B_RD_WIDTH <= 10) begin
- assign addrb = B_ADDR[15:7]*10;
- end
- else if (B_RD_WIDTH <= 20) begin
- assign addrb = B_ADDR[15:7]*20;
- end
- else if (B_RD_WIDTH <= 40) begin
- assign addrb = B_ADDR[15:7]*40;
- end
- else if (B_RD_WIDTH <= 80) begin
+ if (B_RD_WIDTH == 80) begin
assign addrb = B_ADDR[15:7]*80;
end
end
@@ -1354,22 +1292,66 @@ module CC_BRAM_40K ( end
end
else if (RAM_MODE == "TDP") begin
+ // {A,B}_ADDR[0]=0 selects lower, {A,B}_ADDR[0]=1 selects upper cascade memory
+ wire upper_sel_a = ((CAS == "UPPER") && (A_ADDR[0] == 1));
+ wire lower_sel_a = ((CAS == "LOWER") && (A_ADDR[0] == 0));
+ wire upper_sel_b = ((CAS == "UPPER") && (B_ADDR[0] == 1));
+ wire lower_sel_b = ((CAS == "LOWER") && (B_ADDR[0] == 0));
+
+ reg dumm;
+
+ // Cascade output port A
+ always @(*)
+ begin
+ if ((A_WR_MODE == "NO_CHANGE") && lower_sel_a) begin
+ A_CO = memory[addra];
+ end
+ else if ((A_WR_MODE == "WRITE_THROUGH") && lower_sel_a) begin
+ A_CO = ((wea && A_BM[0]) ? (A_DI[0]) : (memory[addra]));
+ end
+ end
+
+ // Cascade output port B
+ always @(*)
+ begin
+ if ((B_WR_MODE == "NO_CHANGE") && lower_sel_b) begin
+ B_CO = memory[addrb];
+ end
+ else if ((B_WR_MODE == "WRITE_THROUGH") && lower_sel_b) begin
+ B_CO = ((web && B_BM[0]) ? (B_DI[0]) : (memory[addrb]));
+ end
+ end
+
// TDP port A
always @(posedge clka)
begin
for (i=0; i < WIDTH_MODE_A; i=i+1) begin
- if (ena && wea && A_BM[i]) memory[addra+i] <= A_DI[i];
+ if (upper_sel_a || lower_sel_a || (CAS == "NONE")) begin
+ if (ena && wea && A_BM[i])
+ memory[addra+i] <= A_DI[i];
+ end
if (A_WR_MODE == "NO_CHANGE") begin
- if (ena && !wea) A_DO_out[i] <= memory[addra+i];
+ if (ena && !wea) begin
+ if (CAS == "UPPER") begin
+ A_DO_out[i] <= ((A_ADDR[0] == 1) ? (memory[addra+i]) : (A_CI));
+ end
+ else if (CAS == "NONE") begin
+ A_DO_out[i] <= memory[addra+i];
+ end
+ end
end
else if (A_WR_MODE == "WRITE_THROUGH") begin
if (ena) begin
- if (wea && A_BM[i]) begin
- A_DO_out[i] <= A_DI[i];
+ if (CAS == "UPPER") begin
+ if (A_ADDR[0] == 1) begin
+ A_DO_out[i] <= ((wea && A_BM[i]) ? (A_DI[i]) : (memory[addra+i]));
+ end else begin
+ A_DO_out[i] <= A_CI;
+ end
end
- else begin
- A_DO_out[i] <= memory[addra+i];
+ else if (CAS == "NONE") begin
+ A_DO_out[i] <= ((wea && A_BM[i]) ? (A_DI[i]) : (memory[addra+i]));
end
end
end
@@ -1379,18 +1361,32 @@ module CC_BRAM_40K ( always @(posedge clkb)
begin
for (i=0; i < WIDTH_MODE_B; i=i+1) begin
- if (enb && web && B_BM[i]) memory[addrb+i] <= B_DI[i];
+ if (upper_sel_b || lower_sel_b || (CAS == "NONE")) begin
+ if (enb && web && B_BM[i])
+ memory[addrb+i] <= B_DI[i];
+ end
if (B_WR_MODE == "NO_CHANGE") begin
- if (enb && !web) B_DO_out[i] <= memory[addrb+i];
+ if (enb && !web) begin
+ if (CAS == "UPPER") begin
+ B_DO_out[i] <= ((B_ADDR[0] == 1) ? (memory[addrb+i]) : (B_CI));
+ end
+ else if (CAS == "NONE") begin
+ B_DO_out[i] <= memory[addrb+i];
+ end
+ end
end
else if (B_WR_MODE == "WRITE_THROUGH") begin
if (enb) begin
- if (web && B_BM[i]) begin
- B_DO_out[i] <= B_DI[i];
+ if (CAS == "UPPER") begin
+ if (B_ADDR[0] == 1) begin
+ B_DO_out[i] <= ((web && B_BM[i]) ? (B_DI[i]) : (memory[addrb+i]));
+ end else begin
+ B_DO_out[i] <= B_CI;
+ end
end
- else begin
- B_DO_out[i] <= memory[addrb+i];
+ else if (CAS == "NONE") begin
+ B_DO_out[i] <= ((web && B_BM[i]) ? (B_DI[i]) : (memory[addrb+i]));
end
end
end
@@ -1419,5 +1415,5 @@ module CC_BRAM_40K ( else begin
assign B_DO = B_DO_out;
end
- endgenerate
+ endgenerate
endmodule
|