基于AHB的SRAM设计
一、描述
- 作为系统的缓存;
- SRAM存储体由MeMery complier生成;
- 项目完成SRAM控制器的设计;
- SRAM作为AHB Slave的形式存在;
二、特性
- 支持8位,16位和32位的SRAM数据读写操作;
- 支持SRAM的单周期读写;
- 支持低功耗工作;
- 支持DFT/BIST的功能;
三、基础知识介绍
AMBA:Advanced Microcontroller Bus Architecture高级微控制器总线架构。
AMBA 2.0
定义了三种总线:
AHB(Advanced High-performance Bus):高性能总线;
ASB(Advanced System Bus):高级系统总线(基本不用);
APB(Advanced Peripheral Bus):外围设备总线;
- AHB:
高速总线,高性能;
二级流水线操作;
可支持多个总线主设备(最多16个);
支持burst传输;
总线带宽:8/16/32/64/128bits;
上升沿触发操作;
对于一个新设计建议使用AHB; - APB
低速总线,低功耗;
接口简单;
再Bridge中锁存地址信号和控制信号;
适用于多种外设;
上升沿触发;
1、AHB的介绍
-
AHB的组成
AHB主设备(Master):初始化一次读/写操作;某一时刻只允许一个主设备使用总线。CPU,DMA,DSP,LCDC…
AHB从设备(Slave):响应一次读/写操作;通过地址映射来选择使用哪一个从设备;外部存储器控制器EMI,APB bridge。
AHB总裁器(Arbiter):允许某一个主设备控制总线;再AMBA协议中没有定义仲裁算法。
AHB译码器(Decoder):通过地址译码来决定选择哪一个设备。 -
AHB的基本信号
HRESETN:低电平有效。
HADDR[31:0]:32位系统地址总线。
HWDATA[31:0]:写数据总线,从主设备写到从设备。
HRADTA[31:0]:读数据总线,从从设备读到主设备。
HTRANS:指出当前传输的状态。
HSIZE:指出当前传输的大小。
HBURST:指出传输的burst类型。
HRESP:从设备发给主设备的总线传输状态。
HREADY:高代表从设备指出传输结束;低代表从设备需延长传输周期。
传输类型:HTRANS[1:0]:当前传输状态
00:IDLE --主设备占用总线,但没进行传输;两次burst传输中间主设备发IDLE。
01:BUSY --主设备占用总线,但是再burst传输过程中还没有准备好进行下一次传输;一次burst传输中间主设备发BUSY。
10:NONSEQ --表明一次单个数据的传输;或者一次burst传输的第一个数据;地址和控制信号与上一次传输无关。
11:SEQ --表明burst传输接下来的数据;地址和上一次传输的地址是相关的。
猝发传输类型HBURST:SINGLE,INCR
burst传输不可跨越1k边界。
HSEL:由AHB decoder通过地址映射给出
AHB Slave响应信号:
HREADY传输完成:HRESP传输响应(OK,ERROR,RETRY)
AHB slave短时间无法响应:HREADY拉低。
AHB slave长时间无法响应:发送RETRY信号。
地址译码:
HSELx:选择从设备,指出由主设备所选择的从设备。
由地址译码器提供的选择信号。
记:arbiter用来选择master,decoder用来选择slave
从设备响应:
所访问的从设备必须响应这次传输
从设备可能返回的响应:
- 完成这次传输
- 插入等待状态(HREADY信号)
- 发出错误信号表示这次传输失败
- 延迟传输,使得总线可用于其他传输(split)
HREADY:tranfer done
HRESP[1:0]:tranfer respone
00:OKEY (成功) -单周期响应
01:ERROR(失败) -两周期响应
10:RETRY(传输未完成;请求主设备重新开始一个传输) -两周期响应
11:SPLIT(传输未完成;请求主设备分离一次传输) -两周期响应
总线的流水特性需要从设备两个周期的响应,可以设得从设备有足够的时间处理下一次传输。
BIST:Build In Self Test 内建自测试
DFT(生产过程中):Design for Test 机台芯片测试
SRAM :英文全称是’Static RAM’,Static Random Access Memory的缩写,翻译成中文就是’静态随机存储器’。SRAM主要用于制造Cache。
四、项目
该项目分成三个模块:一个顶层模块sram_top.v;把两个内部模块实例并连接。
两个内部模块为:
- sram_slave_if.v 总线控制单元------------需要我们设计的模块
- sram_core.v 由MeMory Compilier生成
该项目为64k的sram,分成8片8k的sram,每4片组成一个bank:bank0和bank1。
1.sram_top.v
module sramc_top(//input signalsinput wire hclk,input wire sram_clk, input wire hresetn, input wire hsel, input wire hwrite, input wire hready, input wire [2:0] hsize , input wire [2:0] hburst, input wire [1:0] htrans, input wire [31:0] hwdata, input wire [31:0] haddr, //Signals for BIST and DFT test mode//When signal"dft_en" or "bist_en" is high, sram controller enters into test modeinput wire dft_en,input wire bist_en,//output signalsoutput wire hready_resp, output wire [1:0] hresp, output wire [31:0] hrdata, //When "bist_done" is high, it shows BIST test is over.output wire bist_done,//"bist_fail" shows the results of each sram funtions.There are 8 srams in this controller.output wire [7:0] bist_fail
);//Select one of the two sram blocks according to the value of sram_csnwire bank_sel ;wire [3:0] bank0_csn;wire [3:0] bank1_csn;//Each of 8 srams is 8kx8, the depth is 2^13 (8K), so the sram's address width is 13 bits. wire [12:0] sram_addr;//AHB bus data write into sramswire [31:0] sram_wdata;//sram data output data which selected and read by AHB buswire [7:0] sram_q0;wire [7:0] sram_q1;wire [7:0] sram_q2;wire [7:0] sram_q3;wire [7:0] sram_q4;wire [7:0] sram_q5;wire [7:0] sram_q6;wire [7:0] sram_q7;// Instance the two modules: // ahb_slave_if.v and sram_core.v ahb_slave_if ahb_slave_if_u(//-----------------------------------------// AHB input signals into sram controller//-----------------------------------------.hclk (hclk),.hresetn (hresetn),.hsel (hsel),.hwrite (hwrite),.hready (hready),.hsize (hsize),.htrans (htrans),.hburst (hburst),.hwdata (hwdata),.haddr (haddr),//-----------------------------------------//8 sram blcoks data output into ahb slave interface//-----------------------------------------.sram_q0 (sram_q0),.sram_q1 (sram_q1),.sram_q2 (sram_q2),.sram_q3 (sram_q3),.sram_q4 (sram_q4),.sram_q5 (sram_q5),.sram_q6 (sram_q6),.sram_q7 (sram_q7),//---------------------------------------------//AHB slave(sram controller) output signals //---------------------------------------------.hready_resp (hready_resp),.hresp (hresp),.hrdata (hrdata),//---------------------------------------------//sram control signals and sram address //---------------------------------------------.sram_w_en (sram_w_en),.sram_addr_out(sram_addr),//data write into sram.sram_wdata (sram_wdata),//choose the corresponding sram in a bank, active low.bank_sel (bank_sel ),.bank0_csn (bank0_csn),.bank1_csn (bank1_csn));sram_core sram_core_u(//AHB bus signals.hclk (hclk ),.sram_clk (sram_clk),.hresetn (hresetn ),//-------------------------------------------//sram control singals from ahb_slave_if.v//-------------------------------------------.sram_addr (sram_addr ),.sram_wdata_in(sram_wdata),.sram_wen (sram_w_en ),.bank_sel (bank_sel ),.bank0_csn (bank0_csn ),.bank1_csn (bank1_csn ),//test mode enable signals.bist_en (bist_en ),.dft_en (dft_en ),//-------------------------------------------//8 srams data output into AHB bus//-------------------------------------------.sram_q0 (sram_q0),.sram_q1 (sram_q1),.sram_q2 (sram_q2),.sram_q3 (sram_q3),.sram_q4 (sram_q4),.sram_q5 (sram_q5),.sram_q6 (sram_q6),.sram_q7 (sram_q7),//test results output when in test mode.bist_done (bist_done),.bist_fail (bist_fail));endmodule
2.ahb_slave_if.v
该模块位接口模块,将AHB master发送的存取指令转为sram的数据存取与块,片选指令。
module ahb_slave_if(//input signalshclk,hresetn,hsel,hwrite,hready,hsize,htrans,hburst,hwdata,haddr,sram_q0,sram_q1,sram_q2,sram_q3,sram_q4,sram_q5,sram_q6,sram_q7,//output signalshready_resp,hresp,hrdata,sram_w_en,sram_addr_out,sram_wdata,bank0_csn,bank1_csn
);
//-------------------------------------------------------
list of AHB signals
//-------------------------------------------------------
signals used during normal operation
input hclk;
input hresetn;//-------------------------------------------------------
signals from AHB bus used during normal operation
//-------------------------------------------------------
input hsel;
input hwrite;
input hready; //=1代表读/写有效
input [2:0] hsize; //用来设置每一次数据传输的大小
input [2:0] hburst;
input [1:0] htrans; //判断当前传输状态
input [31:0] hwdata;
inout [31:0] haddr;//signals from sram core data output(read srams)
input [7:0] sram_q0;
input [7:0] sram_q1;
input [7:0] sram_q2;
input [7:0] sram_q3;
input [7:0] sram_q4;
input [7:0] sram_q5;
input [7:0] sram_q6;
input [7:0] sram_q7;//signals tp AHB bus used during normal operation
output hready_resp;
output [1:0] hresp;
output [31:0] hrdata;//sram read or write enable signals
//when "sram_w_en" is low, it means write sram; and high, it means read sram
output sram_w_en;//choose the right srams when bank is confirmed:
//bank_csn allows the four bytes in the 32-bit width to be written independently
output [3:0] bank0_csn;
output [3:0] bank1_csn;//--------------------------------------------------------
//signals to sram core in normal operation ,it contains
//sram address and data writing into sram.
//--------------------------------------------------------
output [12:0] sram_addr_out;
output [31:0] sram_wdata;//--------------------------------------------------------
//internal registers used for temp the input ahb signals
//--------------------------------------------------------
//temperate all the AHB input signals
reg hwrite_r;
reg [2:0] hsize_r;
reg [2:0] hburst_r;
reg [1:0] htrans_r;
reg [31:0] haddr_r;
reg [3:0] sram_csn;//-------------------------------------------------
//Internal signals
//-------------------------------------------------
//"haddr_sel" and "hsize_sel" used to generate banks of
//sram: "bank0_sel" and "bank1_sel". wire [1:0] haddr_sel;
wire [1:0] hsize_sel;
wire bank_sel;
wire sram_csn_en; //sram chip select enable
wire sram_write; //sram write enable signal from AHB bus
wire sram_read; //sram read enable signal from AHB bus
wire [15:0] sram_addr; //sram addrss from AHB bus
wire [31:0] sram_data_out; //data read from sram and send to AHB bus//-------------------------------------------------
//transfer type signal encoding
//-------------------------------------------------
// 用来判断当前传输状态,对应htrans中的4种状态
parameter IDLE = 2'b00, BUSY = 2'b01,NONSEQ = 2'b10,SEQ = 2'b11;//-------------------------------------------------
//Main code
//-------------------------------------------------
//-------------------------------------------------
//combinatorial portion
//-------------------------------------------------
//assign the response and read data of the ahb slave
//In order to implement the sram function-writing or reading
//in one cycle, the value of hready_resp is always "1"
assign hready_resp = 1'b1;//响应始终设置为okay
assign hresp = 2'b00;//----------------------------------------------------
//sram data output to AHB bus
//----------------------------------------------------
assign hrdata = sram_data_out;//choose the right data output of the two banks(bank0,bank1) according
//to the value of bank_sel. If bank_sel=1'b1,bank0 selected,or bank1 selected.
//通过判断选择哪个bank,将bank中的数据输出
assign sram_data_out = bank_sel?(sram_q3,sram_q2,sram_q1,sram_q0):(sram_q7,sram_q6,sram_q5,sram_q4);//Generate sram write and read enable signals
// 对sram操作,需要将地址打拍,与数据对应,实现单周期读写
assign sram_write = ((htrants_r == NONSEQ) || (htrans_r == SEQ)) && hwrite_r;
assign sram_read = ((htrants_r == NONSEQ) || (htrans_r == SEQ)) && (!hwrite_r);
// sram的读写使能,1:读 0:写
assign sram_w_en = !sram_write;//generate sram address
assign sram_addr = haddr_r[15:0];
assign sram_addr_out = sram_addr[14:2];//generate bank select signals by the values of sram_addr[15].
//each bank(32*32) comprises of four sram block(8k*8),and
//the width of the address of the bank is 15 bits(14~0),so
//the sram_addr[15] is the minimun of the next bank. If its
//value is "1",it means the next bank is selcted.
//在 “五、总结”中介绍了不同bit的数据传输的片,块选择
assign sram_csn_en = (sram_write || sram_read);
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;//signals used to generation sram chip select signal in one bank.
assign haddr_sel = sram_addr[1:0];
assign hsize_sel = hsize_r[1:0];//----------------------------------------------------------
//data from ahb writing into sram
//----------------------------------------------------------
assign sram_wdata = hwdata;//----------------------------------------------------------
//Generate the sram chip selecting signals in one bank,
//The resluts show the AHB bus write or read how many data
//once a time: byte,halfword or word
//----------------------------------------------------------
always @(hsize_sel or haddr_sel)
beginif(hsize_sel == 2'b10)sram_csn = 4'b0;// 01为传输16bit数据,将两块sram绑定,通过haddr_sel[1]来判断选择低两块还是高两块,低电平有效else if(hsize_sel == 2'b01)beginif(haddr_sel[1] == 1'b0)sram_csn = 4'b1100;elsesram_csn = 4'b0011;end// 00传输8bit数据,再根据haddr_sel来判断选择bank中的哪个cs,低电平有效else if(hsize_sel == 2'b00)begincase(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;endcaseendelsesram_csn = 4'b1111;
end//-------------------------------------------------
//sequential portion
//-------------------------------------------------
//tmp the ahb address and control signals
always @(posedge hclk or negedge hresetn)
beginif(!hresetn)beginhwrite_r <= 1'b0;hsize_r <= 3'b0;hburst_r <= 3'b0;htrans_r <= 2'b0;haddr_r <= 32'b0;end//将控制信号和地址信号打拍,对应数据。因为数据晚一个cyle传入else if(hsel && hready)beginhwrite_r <= hwrite;hsize_r <= hsize;hburst_r <= hburst;htrans_r <= htrans;haddr_r <= haddr;endelsebeginhwrite_r <= 1'b0;hsize_r <= 3'b0;hburst_r <= 3'b0;htrans_r <= 2'b0;haddr_r <= 32'b0;end
end
endmodule
五、总结
-
支持8/16/32位的SRAM数据读写操作
通过hsize[1:0]来选择位数
00:8bit,深度为2^16,haddr的有效范围[15:0];
haddr[15]选择bank:haddr[15] == 0:bank0;haddr[15] == 1:bank1;
01:16bit,深度为2^15,haddr的有效范围[14];
将两片cs绑定
haddr[13]为cs片选:
bank0:
haddr[13] == 0:cs0,cs1
haddr[13] == 0:cs2,cs3
bank1:
haddr[13] == 0:cs4,cs5
haddr[13] == 0:cs6,cs7
10:32bit,深度为2^14,haddr有效范围[13:0]
haddr[13]为块选:
haddr[13] == 0:bank0
haddr[13] == 1:bank1 -
支持低功耗工作
将64k分成8块8k,由4片组成一个bank-bank0,bank1。根据不同的地址,选择一块或者多块SRAM,未被选中的SRAM处于low-power standby状态。 -
支持单周期读写
一个周期读,一个周期写
AHB总线数据传输具有地址周期和数据周期,AHB的地址信号和控制信号发送完毕后,下一个周期才发送数据,而SRAM的写时序是同时输入地址和数据的,所以要对ahb的地址和控制信号进行打拍处理。