work/Scripts/gen_sram_wrap/template_sram_tp_wrap.v

182 lines
5.0 KiB
Verilog

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 mem_ctrl_bus_sd,
input wire [64 -1:0] mem_ctrl_bus,
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;
wire SD = mem_ctrl_bus_sd;
wire [2 -1:0] RTSEL = mem_ctrl_bus[63:62];
wire [2 -1:0] MTSEL = mem_ctrl_bus[59:58];
wire [2 -1:0] WTSEL = mem_ctrl_bus[55:54];
`ifdef USE_N12_TSMC_SRAM
generate
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