基于AHB的SRAM设计

基于AHB的SRAM设计

一、描述

  1. 作为系统的缓存;
  2. SRAM存储体由MeMery complier生成;
  3. 项目完成SRAM控制器的设计;
  4. SRAM作为AHB Slave的形式存在;

二、特性

  1. 支持8位,16位和32位的SRAM数据读写操作;
  2. 支持SRAM的单周期读写;
  3. 支持低功耗工作;
  4. 支持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 signals
    input 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 mode
    input wire            dft_en,
    input wire            bist_en,

    //output signals
    output 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_csn
    wire       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 srams
    wire [31:0] sram_wdata;

    //sram data output data which selected and read by AHB bus
    wire [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 signals
            hclk,
            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 signals
            hready_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)
begin
    if(hsize_sel == 2'b10)
        sram_csn = 4'b0;
    // 01为传输16bit数据,将两块sram绑定,通过haddr_sel[1]来判断选择低两块还是高两块,低电平有效
    else if(hsize_sel == 2'b01)
    begin
        if(haddr_sel[1] == 1'b0)
            sram_csn = 4'b1100;
        else
            sram_csn = 4'b0011;
    end

  	// 00传输8bit数据,再根据haddr_sel来判断选择bank中的哪个cs,低电平有效
    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

//------------------------------------------------- 
//sequential portion
//------------------------------------------------- 
//tmp the ahb address and control signals
always @(posedge hclk or negedge hresetn)
begin
    if(!hresetn)
    begin
        hwrite_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)
    begin
        hwrite_r <= hwrite;
        hsize_r <= hsize;
        hburst_r <= hburst;
        htrans_r <= htrans;
        haddr_r <= haddr;
    end
    
    else
    begin
        hwrite_r <= 1'b0;
        hsize_r <= 3'b0;
        hburst_r <= 3'b0;
        htrans_r <= 2'b0;
        haddr_r <= 32'b0;
    end
end
endmodule

五、总结

  1. 支持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

  2. 支持低功耗工作
    将64k分成8块8k,由4片组成一个bank-bank0,bank1。根据不同的地址,选择一块或者多块SRAM,未被选中的SRAM处于low-power standby状态。

  3. 支持单周期读写
    一个周期读,一个周期写
    AHB总线数据传输具有地址周期和数据周期,AHB的地址信号和控制信号发送完毕后,下一个周期才发送数据,而SRAM的写时序是同时输入地址和数据的,所以要对ahb的地址和控制信号进行打拍处理。

  • 12
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值