utput [3:0] oSRAM_CSN_BANK1,
output [12:0] oSRAM_ADDR,
output [31:0] oSRAM_WDATA
);
/*————————————————————————————————————————————————————————————————————————*\
/ AHB Signal Register \
\*————————————————————————————————————————————————————————————————————————*/
reg iHSEL_r ;
reg iHWRITE_r ;
reg iHWRITE_2r;
reg [2:0] iHBURST_r ;
reg [1:0] iHTRANS_r ;
reg [2:0] iHSIZE_r ;
reg [31:0] iHWDATA_r ;
reg [15:0] iHADDR_r ;
reg [15:0] iHADDR_2r ;
always@( posedge iHCLK) begin
if(!iHRESETn) begin
iHSEL_r <= 1'b0;
iHWRITE_r <= 1'b0;
iHWRITE_2r <= 1'b0;
iHBURST_r <= 3'b0;
iHTRANS_r <= 2'b0;
iHSIZE_r <= 3'b0;
iHWDATA_r <= 32'b0;
iHADDR_r <= 16'b0;
iHADDR_2r <= 16'b0;
end
else begin
iHSEL_r <= iHSEL;
iHWRITE_r <= iHWRITE;
iHWRITE_2r <= iHWRITE_r;
iHBURST_r <= iHBURST;
iHTRANS_r <= iHTRANS;
iHSIZE_r <= iHSIZE;
iHWDATA_r <= iHWDATA;
iHADDR_r <= iHADDR;
iHADDR_2r <= iHADDR_r;
end
end
/*————————————————————————————————————————————————————————————————————————*\
/ AHB BUS → Interface → SRAM Core \
\*————————————————————————————————————————————————————————————————————————*/
// SRAM Write Enable
assign oSRAM_WEN_BANK0 = ( iHWRITE_r == 1'b1 && iHADDR_r[15] == 1'b0) ? 1'b1 : 1'b0;
assign oSRAM_WEN_BANK1 = ( iHWRITE_r == 1'b1 && iHADDR_r[15] == 1'b1) ? 1'b1 : 1'b0;
// SRAM Bank CSN select for read ↓ select for write ↓
assign oSRAM_CSN_BANK0 = ( iHADDR_r[15] == 1'b0 || (iHADDR[15] == 1'b0 && iHWRITE == 1'b0) ) ? 4'b1111 : 4'b0000;
assign oSRAM_CSN_BANK1 = ( iHADDR_r[15] == 1'b1 || (iHADDR[15] == 1'b1 && iHWRITE == 1'b0) ) ? 4'b1111 : 4'b0000;
// SRAM Addr
wire [12:0] SRAM_WRITE_ADDR;
wire [12:0] SRAM_READ_ADDR;
assign SRAM_WRITE_ADDR = iHADDR_r[14:2]; // WRITE:addr have to wait a T , sent together with data to SRAM_CORE
assign SRAM_READ_ADDR = iHADDR [14:2]; // READ :addr send to MEM at once
assign oSRAM_ADDR = (iHWRITE_r == 1'b1) ? SRAM_WRITE_ADDR : SRAM_READ_ADDR;
// SRAM Write Data
assign oSRAM_WDATA = iHWDATA;
/*————————————————————————————————————————————————————————————————————————*\
/ AHB BUS ← Interface ← SRAM Core \
\*————————————————————————————————————————————————————————————————————————*/
// response to AHB MASTER
assign oHREADY = (iHSEL_r == 1'b1 && (iHWRITE_r == 1'b1 || iHWRITE_2r == 1'b0)) ? 1'b1 : 1'b0 ;
assign oHRESP = (iHSEL_r == 1'b1) ? 2'b00 : 2'b00; //OKAY = 2'b00
// sram read data
assign oHRDATA = (iHSEL_r == 1'b1 && iHWRITE_r == 1'b0 && iHADDR_r[15] == 1'b0) ? {iSRAM3_q, iSRAM2_q, iSRAM1_q, iSRAM0_q}:
(iHSEL_r == 1'b1 && iHWRITE_r == 1'b0 && iHADDR_r[15] == 1'b1) ? {iSRAM7_q, iSRAM6_q, iSRAM5_q, iSRAM4_q}:
32'bz;
endmodule
1.5 sram_core
接下来是顶层模块下的sram_core,主要内容是将sram_bist模块进行了8次例化,
因此,sram_core实际上是将这8个SRAM拼成了一个16k×32的SRAM,
sram_core的地址共15位,地址范围为0x0000-0xFFFFF,
其中,Bank0对应0x0000-0x7FFFF;Bank1对应0x8000~0xFFFFF,
而每个sram_bist端口上的地址为sram_core上的地址右移两位得到,共13位,地址范围为0x0000~0x1FFF,
除此之外,sram_core将每个8k×8 SRAM的内建自测试的输出结果BIST_done_x,BIST_fail_x(x=0~7)进行了逻辑与/或以得到整块sram_core存储体的DFT测试结果,
在执行SRAM数据读写功能的时候,sram_bist可以看做8k×8的单端口SRAM。
sram_core模块的RTL代码如下:
module sram_core (
// From AHB
input iHCLK ,
input iHRESETn,
// From sram_interface
input iSRAM_WEN_BANK0,
input iSRAM_WEN_BANK1,
input [12:0] iSRAM_ADDR ,
input [3: