本项目中的SRAM控制器具有较低的功耗和较小的面积,其一端连接AHB总线,另一端连接大小为64K的SRAM存储器,该存储器为单端口。本项目的SRAM控制器的作用就是实现SRAM存储器与AHB总线的数据信息交换。其组成结构示意图如图所示:
SRAM控制器设计大体可以划分为以下的模块: ①SRAM控制单元、②SRAM存储单元(内嵌MBIST电路)、③AHB总线控制单元(含AHB总线的接口模块、地址路径和数据路径)。三大模块的详细代码参见后续篇文章。本项目的设计核心是 AHB总线控制单元和SRAM控制单元。AHB总线控制单元直接接受来自外部的访问请求,并把这些信息转化为外部对SRAM存储器的数据存取请求。SRAM控制单元直接与存储器相连接,主要的功能是将控制信号和地址信号及数据信号进行转化,并将其发送给SRAM存储器,进行实际的数据存取。地址路径可以分为地址译码路径和地址通路两部分;数据路径可以分为写数据通路和读数据通路。
总线的控制单元是总线与SRAM控制器连接的接口,所有AHB总线传输过来的数据信号都必须经过总线控制单元的转换处理,否则,数据信号就不能被传送到SRAM控制器,就不能很好的实现SRAM控制器与总线之间的数据传输。这里的总线控制单元在设计称为slave interface。总线控制单元的接口图如图所示:
图中左侧的数据信号为AHB总线传输到总线控制单元的信号,包括地址和数据信号。图中右侧为控制单元反馈给AHB总线的信号。这些信号都是与AHB总线兼容的。当HSEL信号有效时,总线控制单元与 SRAM存储器控制单元之间可以进行信息传输,实现对SRAM存储器的读写操作。
总线控制单元的主要作用就是接收来自AHB总线的地址和数据信息等,将这些总线访问的指令信息处理后送到其他单元:将读写地址信息传送到地址路径,将写数据送到数据路径,同时接收数据路径返回的读数据。
SRAM控制单元直接控制SRAM存储器进行存取操作,因此,SRAM 控制单元与SRAM存储器连接的接口信号也很重要。SRAM存储控制单元和SRAM存储器的信号接口图如下所示:
SRAM的工作原理很简单,SRAM控制单元根据接收到的总线控制信号,将这些信号处理转化为SRAM存储器可以识别的信号,发送到 SRAM存储器;之后,将经过地址译码的物理地址传送到存储器的地址总线,并将数据路径处理的数据送到SRAM存储器的数据总线。最后,SRAM存储器进行相应的读写访问。如果是写操作,SRAM 控制单元的任务就完成了,SRAM 存储器已将数据信息按照要求写入。如果是读操作,SRAM控制单元需要接收返回的读数据,将其送到数据路径,由数据路径将信息传输给AHB总线,最终实现总线对SRAM
的读操作。
在本项目中,将SRAM控制单元作为顶层,模块名为sramc_top.v,调用总线控制单元,模块名为ahb_slave_if.v和SRAM存储器,模块名为sram_core.v。
由于要实现SRAM存储器和AHB总线之间的数据传输,就要有地址路径和数据路径两个重要的组成单元。
地址路径的主要功能就是提供访问地址信息,在本项目中,地址路径的作用就是接受AHB总线的读写访问地址,并将这些信息传送到 SRAM控制单元。当SRAM存储器处于无法访问状态时,地址路径会将地址信息暂时存放,直到对SRAM实现读写访问时,地址路径才会继续有效。地址路径有两个部分组成:地址译码单元和地址通路。
地址译码单元的主要任务就是将读写地址编译成SRAM存储器可以识别的地址。地址通路是在地址译码单元的基础上,实现对读写地址的缓冲,这是由SRAM存储器的读写基本传输特性和猝发传输特点所决定。
数据路径的作用就是实现AHB总线对SRAM存储器的正确访问。在项目中,数据路径的功能就是实现写数据通路和读数据通路。
写数据通路就是从系统内其他主设备向从设备写入数据必经的通道,它的作用是可以暂时存放数据信息。当有写操作要求时,SRAM控制器检查写数据通路是否有空。间,如果有就写入待写数据,如果没有空间,那么等待下一个周期。写数据通路使用FIFO来实现。
读数据通路和写输入通路相对应,数据从SRAM存储器返回到AHB总线也需要经过读数据通路。当AHB总线处于BUSY状态时,不能接受从SRAM存储器传输的数据时,就可以将这些数据暂时存放在读数据通路当中,当AHB总线处于IDLE时,这些数据传输到总线上面进行处理。也就是说读数据通路其实也扮演着数据缓冲的作用。在设计中,和写数据通路一样,也常使用FIFO实现。
上面介绍了整体的设计思路,SRAM控制器设计框图,如下两幅图所示。将SRAM存储单元部分设计分为上下两个bank(block),bank0包括 sram_bist0、sram_bist1、sram_bist2、sram_bist3四个部分,地址范围是0到32;bank1包括sram_bist4、sram_bist5、sram_bist6、sram_bist7四个部分,地址范围是32到64。
这种 设计方法的优势在于在运行的时候,如果选中bank0,那么下面的芯片都没有片选中,因此,bank1中的存储单元处于闲置状态,bank1的内存功耗很低。同时,每个bank又分成4片(AHB支持 8/16/32位操作)。比如,在 0 到 32 位的空间,我们只取一个8位的操作,只选中4片中的一片,剩下的3片功耗都很低。在整个设计系统中,8片SRAM只有一片被选中工作,其余的都未被选中,未被选中的SRAM功耗很低,片选中的功耗与没被选中的功耗会相差数十倍甚至上百倍,这样将会很大程度降低了功耗。
从图中可以看出,总线控制单元端口主要是控制信号和数据信号等。这一个模块的主要作用就是将总线的信号转化为SRAM控制单元可以识别的物理信号,进而实现读写操作的功能。总线控制单元的内部结构如下图所示:
总线控制单元模块是设计中的重点模块,这一部分核心的代码在第三部分有详细的展示。由于SRAM存储单元采用的8K*8的设计方式,且每个block中包含4块SRAM存储单元。因此,每个block的位宽为32 位,且AHB总线也支持32位的操作,在写数据时可以直接赋值,其中,片选信号是由高位译码产生的。
根据上面的结构框图,对电路进行设计。 顶层模块包含总线模块和存储单元模块。其中,存储单元模块由8个子模块构成,每个子模块由一个SRAM存储单元和bist结构组成。
下面简单介绍一下总线模块的部分代码,实现的主要功能就是AHB 总线与SRAM存储单元的数据传输。这一部分也说明了存储单元是如何进行片选的,正是由于采用了片选结构,电路整体功耗才比较低。
/*选用单周期读写SRAM且SRAM一直处于“OK”状态*/
assign hready_resp =1’b1;
assign hresp =2’b00;
/*数据从SRAM传输到AHB总线 */
assign hrdata = sram_data_out
/* 根据AHB总线协议,只有当TRANS信号为NONSEQ或者SEQ时,数据读写才有效,因此,需要保证SRAM读写时,TRANS信号有效。SRAM进行写操时,hwrite信号为高;SRAM进行读操作时,hwrite信号为低 */
assign sram_write = ((htrans_r == NONSEQ) || (htrans_r == SEQ)) && hwrite_r;
assign sram_read = ((htrans_r == NONSEQ) || (htrans_r == SEQ)) && (!hwrite_r);
/*写使能信号低有效*/
assign sram_w_en = !sram_write;
/*只有当SRAM进行读写操作时,片选使能信号才为高电平,主要是节省功耗*/
assign sram_csn_en = (sram_write || sram_read);
/*当片选信号为1时,选中bank0;当片选信号为0时,选中bank1*/
assign sram_data_out = (bank_sel) ? {
sram_q3, sram_q2, sram_q1, sram_q0} :
{
sram_q7, sram_q6, sram_q5, sram_q4} ;
/*这一部分片选操作时,低32K空间选择bank0,在高32K空间选择bank1*/
assign bank_sel = (sram_csn_en && (sram_addr[15] == 1'b0)) ? 1'b1 : 1'b0;
assign bank0_csn= (sram_csn_en && (sram_addr[15] == 1'b0)) ? sram_csn : 4'b1111;
assign bank1_csn= (sram_csn_en && (sram_addr[15] == 1'b1)) ? sram_csn : 4'b1111;
/*数据从AHB总线写入SRAM */
assign sram_wdata = hwdata;
/*每个bank有4片SRAM,每一片SRAM有一个片选信号 */
always@(hsize_sel or haddr_sel)
begin
if(hsize_sel == 2'b10)
sram_csn = 4'b0;
/*一次片选两片SRAM */
else if(hsize_sel == 2'b01)
begin
if(haddr_sel[1] == 1'b0)
sram_csn = 4'b1100;
else
sram_csn = 4'b0011;
end
/*选择一片SRAM,具体到4片中的某一片*/
else if(hsize_sel == 2'b00)
begin
case(haddr_sel)
2'b00 : sram_csn = 4'b1110;
2'b01 : sram_csn = 4'b1101;
2'b10 : sram_csn = 4'b1011;
2'b11 : sram_csn = 4'b0111;
default : sram_csn = 4'b1111;
endcase
end
else
sram_csn = 4'b1111;
end
上面部分代码是与结构框图相对应的片选部分,这一部分是组合逻辑部分,主要是分成两个操作:数据从SRAM传输到AHB总线和数据从 AHB总线传输到SRAM中。这一部分设计的意义在于只有一片SRAM 工作,整体功耗较小。在时序逻辑部分,片选hsel信号,避免信号不停翻转,可以有效降低功耗。
一个建议的SystemVerilog的验证平台如下,其中agent的结构注意与UVM的架构平台区分。
如何一步一步编写SystemVerilog Testbench?
SV验证平台的目录一般分三级; 以AHB_SRAMC项目为例,通常可将