add template_sram_tp/sp_assmbly

This commit is contained in:
leeyunlong 2025-06-20 08:43:27 +08:00
parent b4f2c518f5
commit e779dfcd54
3 changed files with 423 additions and 8 deletions

View File

@ -0,0 +1,177 @@
module ${SramWrapName} #(
parameter WIDTH = ${Width},
parameter DEPTH = ${Depth},
parameter IN_PIPE = 0,
parameter OUT_PIPE = 1
)(
input wire CLK,
input wire CEB,
input wire WEB,
input wire [$clog2(DEPTH)-1:0] A,
input wire [WIDTH-1:0] D,
input wire [WIDTH-1:0] BWEB,
input wire SD,
input wire [1:0] RTSEL,
input wire [1:0] WTSEL,
output wire [WIDTH-1:0] Q
);
localparam ADDR_WIDTH = $clog2(DEPTH);
wire sram_ceb;
wire sram_web;
wire [WIDTH-1:0] sram_bweb;
wire [ADDR_WIDTH-1:0] sram_addr;
wire [WIDTH-1:0] sram_rdata;
wire [WIDTH-1:0] sram_wdata;
localparam ASSEMBLY_WIDTH_NUMS = ${AssemblyWidth};
localparam ASSEMBLY_DEPTH_NUMS = ${AssemblyDepth};
localparam COMPILE_DEPTH = ${CompileDepth};
localparam COMPILE_WIDTH = ${CompileWidth};
localparam ADDR_COMPILE_WIDTH = $clog2(COMPILE_DEPTH);
`ifdef USE_N12_TSMC_SRAM
wire[ASSEMBLY_DEPTH_NUMS - 1:] sram_ceb_sub;
wire[WIDTH - 1:0] sram_rdata_sub[ASSEMBLY_DEPTH_NUMS - 1:0];
wire [ADDR_WIDTH -1:ADDR_COMPILE_WIDTH] sram_sel = sram_addr[ADDR_WIDTH -1:ADDR_COMPILE_WIDTH];
assign sram_rdata = sram_rdata_sub[sram_sel];
genvar gv_row;
genvar gv_col;
generate
for(gv_row=0; gv_row<ASSEMBLY_DEPTH_NUMS; gv_row=gv_row+1) begin: GEN_ASSEMBLY_SRAM_row
//== Judge Chip enable
sram_ceb_sub[gv_row] = ((sram_ceb==1'b0) && (sram_addr[ADDR_WIDTH -1:ADDR_COMPILE_WIDTH]==gv_row)) ? 1'b0 : 1'b1; // CEB for each row
for(gv_col=0; gv_col<ASSEMBLY_WIDTH_NUMS; gv_col=gv_col+1) begin: GEN_ASSEMBLY_SRAM_col
//== SRAM Instance
if(DEPTH==${Depth} && WIDTH==${Width}) begin : GEN_${Depth}x${Width}_SRAM
${ReferenceName} U_${ReferenceName} (
.CLK (CLK ),
.CEB (sram_ceb_sub[gv_row] ),
.WEB (sram_web ),
.A (sram_addr[ADDR_COMPILE_WIDTH-1:0] ),
.D (sram_wdata[gv_col*(WIDTH/ASSEMBLY_WIDTH_NUMS) +: COMPILE_WIDTH] ),
.BWEB (sram_bweb[gv_col*(WIDTH/ASSEMBLY_WIDTH_NUMS) +: COMPILE_WIDTH] ),
.Q (sram_rdata_sub[gv_row][gv_col*(WIDTH/ASSEMBLY_WIDTH_NUMS) +: COMPILE_WIDTH]),
.SLP (1'b0 ),
.DSLP (1'b0 ),
.SD (SD ),
.RTSEL (RTSEL ),
.WTSEL (WTSEL ),
.FADIO (9'b0 ),
.REDENIO (1'b0 ),
.PUDELAY ( )
);
end
else begin : ILLEGAL_SRAM_SIZE
$display("Error: Unsupported SRAM size %d x %d for TSMC N12 SRAM", WIDTH, DEPTH);
end
end
end
endgenerate
`elsif USE_N12_SNPS_SRAM
`elsif USE_N7_TSMC_SRAM
`elsif USE_N7_SNPS_SRAM
`else
reg [WIDTH-1:0] ram [DEPTH-1:0];
reg [WIDTH-1:0] rdata_ff;
integer i;
always @(posedge CLK) begin
if (CEB == 1'b0) begin
if (WEB == 1'b0) begin // write
for (i = 0; i < WIDTH; i = i + 1) begin
if (BWEB[i] == 1'b0) ram[A][i] <= D[i];
end
end
else begin // read
rdata_ff <= ram[A];
end
end
end
assign sram_rdata = rdata_ff;
`endif
// Input PIPE
generate
if(IN_PIPE==1) begin : GEN_IN_PIPE_1
reg ceb_ff;
reg web_ff;
reg [WIDTH-1:0] bweb_ff;
reg [ADDR_WIDTH-1:0] a_ff;
reg [WIDTH-1:0] d_ff;
always @(posedge CLK) begin
if(CEB==1'b0) begin
ceb_ff <= 1'b0;
web_ff <= WEB;
bweb_ff <= BWEB;
a_ff <= A;
d_ff <= D;
end
else begin
ceb_ff <= 1'b1;
end
end
assign sram_ceb = ceb_ff;
assign sram_web = web_ff;
assign sram_bweb = bweb_ff;
assign sram_addr = a_ff;
assign sram_wdata = d_ff;
end
else begin : GEN_IN_PIPE_0
assign sram_ceb = CEB;
assign sram_web = WEB;
assign sram_bweb = BWEB;
assign sram_addr = A;
assign sram_wdata = D;
end
endgenerate
// Output PIPE
generate
if(OUT_PIPE==1) begin : GEN_OUT_PIPE_1
reg sram_ren_ff;
reg [WIDTH-1:0] sram_rdata_ff;
always @(posedge CLK) begin
if(CEB==1'b0 && WEB==1'b1) begin
sram_ren_ff <= 1'b1; // flag indicating read operation
end
else begin
sram_ren_ff <= 1'b0;
end
end
always @(posedge CLK) begin
if(sram_ren_ff==1'b1) begin
sram_rdata_ff <= sram_rdata; // latch read data
end
else begin
sram_rdata_ff <= sram_rdata_ff;
end
end
assign Q = sram_rdata_ff; // output latched data
end
else begin : GEN_OUT_PIPE_0
assign Q = sram_rdata; // direct output
end
endgenerate
endmodule

View File

@ -39,14 +39,14 @@ module ${SramWrapName} #(
localparam MTSEL_VAL = 2'b01;
${ReferenceName} U_${ReferenceName} (
.CLK (CLK),
.WEB (sram_web),
.AA (sram_waddr),
.D (sram_wdata[0 +: WIDTH/3]),
.BWEB (sram_bweb[0 +: WIDTH/3]),
.REB (sram_reb),
.AB (sram_raddr),
.Q (sram_rdata[0 +: WIDTH/3]),
.CLK (CLK ),
.WEB (sram_web ),
.AA (sram_waddr ),
.D (sram_wdata ),
.BWEB (sram_bweb ),
.REB (sram_reb ),
.AB (sram_raddr ),
.Q (sram_rdata ),
//.BIST (1'b0),
//.WEBM (1'b0),
//.AMA ({ADDR_WIDTH{1'b0}}),

View File

@ -0,0 +1,238 @@
module ${SramWrapName} #(
parameter WIDTH = ${Width},
parameter DEPTH = ${Depth},
parameter IN_PIPE = 0,
parameter OUT_PIPE = 1
)(
input wire CLK, // Write/Read Clock, Sync type SRAM
input wire WEB, // Write Enable, Active-low
input wire [$clog2(DEPTH)-1:0] AA, // Write Address
input wire [WIDTH-1:0] D, // Write Data
input wire [WIDTH-1:0] BWEB, // Bit mask Write Enable, Active-low
input wire REB, // Read Enable, Active-low
input wire [$clog2(DEPTH)-1:0] AB, // Read Address
input wire SD,
input wire [1:0] RTSEL,
input wire [1:0] WTSEL,
input wire [1:0] MTSEL,
output wire [WIDTH-1:0] Q // Read Data Output
);
localparam ADDR_WIDTH = $clog2(DEPTH);
wire sram_web;
wire [ADDR_WIDTH-1:0] sram_waddr;
wire [WIDTH-1:0] sram_wdata;
wire [WIDTH-1:0] sram_bweb;
wire sram_reb;
wire [ADDR_WIDTH-1:0] sram_raddr;
wire [WIDTH-1:0] sram_rdata;
localparam ASSEMBLY_WIDTH_NUMS = ${AssemblyWidth};
localparam ASSEMBLY_DEPTH_NUMS = ${AssemblyDepth};
localparam COMPILE_DEPTH = ${CompileDepth};
localparam COMPILE_WIDTH = ${CompileWidth};
localparam ADDR_COMPILE_WIDTH = $clog2(COMPILE_DEPTH);
`ifdef USE_N12_TSMC_SRAM
wire[ASSEMBLY_DEPTH_NUMS - 1:0] sram_web_sub;
wire[ASSEMBLY_DEPTH_NUMS - 1:0] sram_reb_sub;
wire[WIDTH - 1:0] sram_wdata_sub[ASSEMBLY_DEPTH_NUMS - 1:0];
wire [ADDR_WIDTH -1:ADDR_COMPILE_WIDTH] sram_sel = sram_raddr[ADDR_WIDTH -1:ADDR_COMPILE_WIDTH];
assign sram_rdata = sram_rdata_sub[sram_sel];
genvar gv_row;
genvar gv_col;
generate
for (gv_row=0;gv_row<ASSEMBLY_DEPTH_NUMS;gv_row=gv_row+1 ) begin:gen_sram_row
assign sram_web_sub[gv_row] = (WEB==1'b0 && AA[ADDR_WIDTH -1:ADDR_COMPILE_WIDTH]==gv_row) ? 1'b0 : 1'b1;
assign sram_reb_sub[gv_row] = (REB==1'b0 && AB[ADDR_WIDTH -1:ADDR_COMPILE_WIDTH]==gv_row) ? 1'b0 : 1'b1;
for (gv_col=0;gv_col<ASSEMBLY_WIDTH_NUMS;gv_col=gv_col+1) begin:gen_sram_col
//== SRAM Instance
if(DEPTH==${Depth} && WIDTH==${Width}) begin : GEN_${Depth}X${Width}_SRAM
${ReferenceName} U_${ReferenceName} (
.CLK (CLK ),
.WEB (sram_web_sub[gv_row] ),
.AA (sram_waddr[ADDR_COMPILE_WIDTH-1:0] ),
.D (sram_wdata[gv_col*(WIDTH/ASSEMBLY_WIDTH_NUMS) +: COMPILE_WIDTH] ),
.BWEB (sram_bweb[gv_col*(WIDTH/ASSEMBLY_WIDTH_NUMS) +: COMPILE_WIDTH] ),
.REB (sram_reb_sub[gv_row] ),
.AB (sram_raddr[ADDR_COMPILE_WIDTH-1:0] ),
.Q (sram_rdata_sub[gv_row][gv_col*(WIDTH/ASSEMBLY_WIDTH_NUMS) +: COMPILE_WIDTH]),
//.BIST (1'b0),
//.WEBM (1'b0),
//.AMA ({ADDR_WIDTH{1'b0}}),
//.DM (0)
//.BWEBM (0),
//.REBM (1'b0),
//.AMB ({ADDR_WIDTH{1'b0}}),
.RTSEL (RTSEL),
.WTSEL (WTSEL),
.MTSEL (MTSEL),
.SLP (1'b0),
.DSLP (1'b0),
.SD (SD),
.PUDELAY (),
.FADIO (9'd0),
.REDENIO (1'b0)
);
end
else begin : ILLEAGAL_SIZE_SRAM
//$display("\tERROR %m : Illegal SRAM size. %t\n", $realtime);
end
end
end
if(DEPTH==${Depth} && WIDTH==${Width}) begin : GEN_${Depth}X${Width}_SRAM
localparam RTSEL_VAL = 2'b01;
localparam WTSEL_VAL = 2'b01;
localparam MTSEL_VAL = 2'b01;
${ReferenceName} U_${ReferenceName} (
.CLK (CLK ),
.WEB (sram_web ),
.AA (sram_waddr ),
.D (sram_wdata ),
.BWEB (sram_bweb ),
.REB (sram_reb ),
.AB (sram_raddr ),
.Q (sram_rdata ),
//.BIST (1'b0),
//.WEBM (1'b0),
//.AMA ({ADDR_WIDTH{1'b0}}),
//.DM (0)
//.BWEBM (0),
//.REBM (1'b0),
//.AMB ({ADDR_WIDTH{1'b0}}),
.RTSEL (RTSEL),
.WTSEL (WTSEL),
.MTSEL (MTSEL),
.SLP (1'b0),
.DSLP (1'b0),
.SD (SD),
.PUDELAY ( ),
.FADIO (9'd0),
.REDENIO (1'b0)
);
end
else begin : ILLEAGAL_SIZE_SRAM
//$display("\tERROR %m : Illegal SRAM size. %t\n", $realtime);
end
endgenerate
`elsif USE_N12_SNPS_SRAM
`elsif USE_N7_TSMC_SRAM
`elsif USE_N7_SNPS_SRAM
`else
reg [WIDTH-1:0] ram [DEPTH-1:0];
reg [WIDTH-1:0] rdata_ff;
integer i;
always @(posedge CLK) begin
if (WEB == 1'b0) begin // write
for (i = 0; i < WIDTH; i = i + 1) begin
if (BWEB[i] == 1'b0)
ram[AA][i] <= D[i];
end
end
end
// 读操作
always @(posedge CLK) begin
if (REB == 1'b0) begin // read
rdata_ff <= ram[AB];
end
end
assign sram_rdata = rdata_ff;
`endif
// Input PIPE
generate
if(IN_PIPE==1) begin : GEN_IN_PIPE_1
reg web_ff;
reg [WIDTH-1:0] bweb_ff;
reg [ADDR_WIDTH-1:0] aa_ff;
reg [ADDR_WIDTH-1:0] ab_ff;
reg [WIDTH-1:0] d_ff;
reg reb_ff;
always @(posedge CLK) begin
if(WEB==1'b0) begin
web_ff <= 1'b0;
bweb_ff <= BWEB;
aa_ff <= AA;
d_ff <= D;
end
else begin
web_ff <= 1'b1;
end
end
always @(posedge CLK) begin
if(REB==1'b0) begin
reb_ff <= 1'b0;
ab_ff <= AB;
end
else begin
reb_ff <= 1'b1;
end
end
assign sram_web = web_ff;
assign sram_waddr = aa_ff;
assign sram_wdata = d_ff;
assign sram_bweb = bweb_ff;
assign sram_reb = reb_ff;
assign sram_raddr = ab_ff;
end
else begin : GEN_IN_PIPE_0
assign sram_web = WEB;
assign sram_waddr = AA;
assign sram_wdata = D;
assign sram_bweb = BWEB;
assign sram_reb = REB;
assign sram_raddr = AB;
end
endgenerate
generate
if(OUT_PIPE==1) begin : GEN_OUT_PIPE_1
reg sram_ren_ff;
reg [WIDTH-1:0] sram_rdata_ff;
always @(posedge CLK) begin
if(REB == 1'b0) begin
sram_ren_ff <= 1'b1;
end
else begin
sram_ren_ff <= 1'b0;
end
end
always @(posedge CLK) begin
if(sram_ren_ff == 1'b1) begin
sram_rdata_ff <= sram_rdata;
end
else begin
sram_rdata_ff <= sram_rdata_ff; // 保持上一个值
end
end
assign Q = sram_rdata_ff;
end
else begin : GEN_OUT_PIPE_0
assign Q = sram_rdata;
end
endgenerate
endmodule