基于AHB总线的sram控制器设计

AHB-SRAMC介绍

SRAM在整个系统中作为缓存,SRAM控制器实现SRAM存储器与AHB总线的数据信息交换,其一端连接AHB总线,另一端连接SRAM(8k*8两个bank),将AHB总线上的读写操作转换成标准的SRAM读写操作(将控制信号和地址信号及数据信号进行转化,并将其发送给相应的SRAM存储器,进行实际的数据存取)。
在这里插入图片描述
AHB-SRAMC设计规格

  • 支持8位、16位和32位的SRAM数据读写操作;
  • 支持SRAM单周期读写(直接影响Soc性能);
  • 支持在多块SRAM组成的存储器中,根据不同地址系统选择一块或者多块SRAM。未被选中的SRAM则处于 low power standby状态。(低功耗)

主要注意2个问题:

  • AHB总线传输,数据位宽有 8/16/32的传输模式,而sram不一定支持。这里采用4个sram来实现,每块sram对应一个byte。
  • AHB总线时序和sram时序的转化。AHB总线数据传输具有地址周期和数据周期,AHB的地址和控制信号发送完毕后,下一个周期才发送数据,而sram的写时序是同时输入地址和数据,所以这里对AHB的地址和控制信号做打拍处理。

具体模块设计

sramc_top是顶层模块作为SRAM的控制器,包括ahb_sram_if和sram_core 两个模块。其中ahb_sram_if 连接sram控制器到AHB总线并且生成SRAM的控制信号(SRAM的地址,读写信号,片选信号等);sram_core包含了8个sram并作为sram的顶层,并包含了DFT和BIST部分。

Top: sramc_top:作为顶层模块,连接ahb_sram_if和sram_core模块。
在这里插入图片描述

信号描述:

SignalI/OwidthsourceDescriptions
hclkinput1Clock sourceBus clock
sram_clkinput1Clock sourcesram clock
hrestninput1Reset controllerReset
hselinput1DecoderSlave selectAHB control
htranstinput[1:0]MasterTransfer type:NONSEQ, SEQ,IDLE,BUSY
hwriteinput1MasterTransfer direction
hsizeinput[2:0]MasterTransfer size
hburstinput[2:0]MasterBurst type
haddrinput[31:0]MasterAddress bus
hwdatainput[31:0]MasterWrite data bus
hreadyoutput1SlaveTransfer done
hrespoutput1SlaveTransfer response(status)
hrdataoutput[31:0]SlaveRead data bus

ahb_slave_if

ahb_slave_if模块是连接AHB总线和sram的接口模块,将AHB总线的控制信号、地址信号以及数据信号进行转化,并将其发送给相应的SRAM存储器。

信号描述

SignalI/OWidthSourceDescriptions
hclkinput1Clock sourceBus clock
hrestninput1Reset controllerReset
hselinput1DecoderSlave
htranstinput[1:0]MasterTransfer type:NONSEQ, SEQ, IDLE,BUSY
hwriteinput1MasterTransfer direction:1-write 0-read
hsizeinput[2:0]MasterTransfer size: byte (8-bit), halfword (16-bit) or word (32-bit). max :1024bit
hburstinput[2:0]MasterBurst type:SIGNAL,INCR1/4/8/16,WAPR4/8/16
haddrinpu[31:0]MasterAddress bus
hwdatainput[31:0]MasterWrite data bus
sram_q0-q7input[7:0]sramsram output data
hreadyoutput1SlaveTransfer done
hrespoutput[1:0]SlaveTransfer response(status): OKAY ,ERROR,RETRY ,SPLIT
hrdataoutput[31:0]SlaveRead data bus
sram_w_enoutput1sramwrite enable :write:0;read:1
sram_addr_outoutput[12:0]sram address
sram_wdataoutput[31:0]sram write data
bank0_csnoutput[3:0]sram bank0 select
bank1_csnoutput[3:0]sram bank1 select

Verilog实现

module ahb_slave_if(

  //input signals
  input			hclk,
  input			hresetn,
  input			hsel,
  input			hwrite,
  input			hready,
  input	[2:0]	hsize,
  input [1:0]	htrans,
  input [2:0]  	hburst,   // hard code -> parameter
  input [31:0] 	hwdata,
  input [31:0] 	haddr,
  
  //output signals
  output		  	hready_resp,
  output [1:0]	hresp,
  output [31:0]	hrdata,
  
  //sram output
  input [7:0]	 sram_q0, // 8bits
  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,
  
  //sram control signal
  output		sram_w_en,      // 0:write, 1:read
  output [12:0]	sram_addr_out,
  output [31:0] sram_wdata,     //写sram数据
  output [3:0]	bank0_csn,      //四字节可以单独写入
  output [3:0]	bank1_csn
  );

  //-------------------------------------------------------
  //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 address from AHB bus
  wire [31:0] sram_data_out; //data read from sram and send to AHB bus

  parameter     IDLE   = 2'b00,
                BUSY   = 2'b01,
		            NONSEQ = 2'b10,
		            SEQ    = 2'b11;

  //---------------------------------------------------------
  //  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; // Singal Cycle
  assign hresp  = 2'b00;     // OK
  
  //---------------------------------------------------------
  //sram data output to AHB bus
  //---------------------------------------------------------
  assign   hrdata = sram_data_out; //组合逻辑读,CPU读SRAM,地址有效则立即读

  //Choose the right data output of the two banks(bank0, bank1) according
  //to the value of bank_sel. If bank_sel = 1'b1, bank0 sleceted, or 
  //bank1 selected.
  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.
  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;

  //generate sram address
  //SRAM总寻址64K 0x0--0xffff
  assign sram_addr = haddr_r [15:0];//64K 8*8K
  assign sram_addr_out = sram_addr[14:2]; // word
  
  //Generate bank select signals by the value of sram_addr[15].
  //Each bank(32kx32) comprises of four sram block(8kx8), 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. 
  assign sram_csn_en = (sram_write || sram_read);
  //低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;

  //signals used to generating 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)//32bit
      sram_csn = 4'b0;
    else if(hsize_sel == 2'
	) begin//16bit
      if(haddr_sel[1] == 1'b0) //little-endian
        sram_csn = 4'b1100;
      else
        sram_csn = 4'b0011;
    end
    else if(hsize_sel == 2'b00) begin//8bit
      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 , 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
    else if(hsel && hready) begin //hsel要片选,否则信号一直在翻转,可能会功能错误,并且功耗大
      hwrite_r  <= hwrite ;//写SRAM时,把控制信号寄存。因为写操作时,要把地址打一拍,和数据对齐
      hsize_r   <= hsize  ;  
 //   hburst_r  <= hburst ;//AHB中master会把burst传输所有地址传递过来,AXI只传递起始地址。此处用处不大。减少一个REG
      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

sram_core

sram_core:两个bank,每个bank 4个SRAM(8Kx8)
在这里插入图片描述
sram逻辑真值表:
在这里插入图片描述

信号描述

signalI/Owidthdescription
hclkinput1AHB bus clockAHB bus signals
sram_clkinput1sram clockAHB bus signals
hreserninput1resetAHB bus signals
sram_addrinput[12:0]sram addresssram control signals form ahb_sram_if
sram_wdatainput[31:0]sram write datasram control signals form ahb_sram_if
sram_weninput1sram write enable :write:0;read:1sram control signals form ahb_sram_if
bank0_csninput[3:0]sram bank0 selectsram control signals form ahb_sram_if
bank1_csninput[3:0]sram bank1 selectsram control signals form ahb_sram_if
bist_eninput1bist enabletest model enable
dft_eninput1dft enabletest model enable
sram_q0-q7output[7:0]sram data 8bit8 sram data output into AHB bus
bist_doneoutput1bist donetest model ouput flag

verilog实现

module sram_core(
		hclk,
		sram_clk,
		hreset_n,
		
		sram_addr,
		sram_wdata,
		sram_wen,		
		bank0_csn,
		bank1_csn,
		
		dft_en,
		bist_en,
		
		sram_q0,
		sram_q1,
		sram_q2,
		sram_q3,
		sram_q4,
		sram_q5,
		sram_q6,
		sram_q7,
		
		bist_done,
		bist_fail,		

);
input hclk;
input sram_clk;
input hreset_n;
		
input [12:0] sram_addr;
input [31:0] sram_wdata;
input sram_wen;			//low :write ; high :read
input [3:0] bank0_csn;
input [3:0] bank1_csn;
		
input dft_en;
input bist_en;
		
output wire [7:0] sram_q0;
output wire [7:0] sram_q1;
output wire [7:0] sram_q2;
output wire [7:0] sram_q3;
output wire [7:0] sram_q4;
output wire [7:0] sram_q5;
output wire [7:0] sram_q6;
output wire [7:0] sram_q7;
		
output	bist_done;
output [7:0] bist_fail;

  //Every sram bist's work state and results output.
  wire bist_done0;
  wire bist_fail0;
  wire bist_done1;
  wire bist_fail1;
  wire bist_done2;
  wire bist_fail2;
  wire bist_done3;
  wire bist_fail3;
  wire bist_done4;
  wire bist_fail4;
  wire bist_done5;
  wire bist_fail5;
  wire bist_done6;
  wire bist_fail6;
  wire bist_done7;
  wire bist_fail7;

  wire bank0_bistdone;
  wire bank1_bistdone;

  wire [3:0] bank0_bistfail;
  wire [3:0] bank1_bistfail;

  //bist finishing state of bank0
  assign bank0_bistdone = (bist_done3 && bist_done2) && (bist_done1 && bist_done0);

  //bist results of bank0
  assign bank0_bistfail = {bist_fail3,bist_fail2,bist_fail1,bist_fail0};

  //bist finishing state of bank1
  assign bank1_bistdone = (bist_done7 && bist_done6) && (bist_done5 && bist_done4);

  //bist results of bank1
  assign bank1_bistfail = {bist_fail7,bist_fail6,bist_fail5,bist_fail4};

  //--------------------------------------------------------------------------
  //the 8 srams results of BIST test and the finishing state
  //--------------------------------------------------------------------------
  assign bist_done = bank0_bistdone && bank1_bistdone;
  assign bist_fail = {bank1_bistfail,bank0_bistfail} ;

  //-------------------------------------------------------------------------
  //Instance 8 srams and each provides with BIST and DFT functions. 
  //Bank0 comprises of sram0~sram3, and bank1 comprises of sram4~sram7. 
  //In each bank, the sram control signals broadcast to each sram, and data
  //written per byte into each sram in little-endian style.
  //-------------------------------------------------------------------------
  //bank0 bank1读写使能以及地址都完全相同,写入的数据也相同
		
ram_bist u_sram_bist0(
                     .hclk             (hclk),
                     .sram_clk         (sram_clk),
                     .sram_rst_n       (hreset_n),
                     .sram_csn_in      (bank0_csn[0]),
                     .sram_wen_in      (sram_wen),
                     .sram_addr_in     (sram_addr),
                     .sram_wdata_in    (sram_wdata[7:0]),
                     .bist_en          (bist_en),
	                 .dft_en           (dft_en),
                                
                     .sram_data_out    (sram_q0),
                     .bist_done        (bist_done0),
                     .bist_fail        (bist_fail0)  
                    );	

ram_bist u_sram_bist1(
                     .hclk             (hclk),
                     .sram_clk         (sram_clk),
                     .sram_rst_n       (hreset_n),
                     .sram_csn_in      (bank0_csn[1]),
                     .sram_wen_in      (sram_wen),
                     .sram_addr_in     (sram_addr),
                     .sram_wdata_in    (sram_wdata[15:8]),
                     .bist_en          (bist_en),
	                 .dft_en           (dft_en),
                                
                     .sram_data_out    (sram_q1),
                     .bist_done        (bist_done1),
                     .bist_fail        (bist_fail1)  
                    );		
					
ram_bist u_sram_bist2(
                     .hclk             (hclk),
                     .sram_clk         (sram_clk),
                     .sram_rst_n       (hreset_n),
                     .sram_csn_in      (bank0_csn[2]),
                     .sram_wen_in      (sram_wen),
                     .sram_addr_in     (sram_addr),
                     .sram_wdata_in    (sram_wdata[23:16]),
                     .bist_en          (bist_en),
	                 .dft_en           (dft_en),
                                
                     .sram_data_out    (sram_q2),
                     .bist_done        (bist_done2),
                     .bist_fail        (bist_fail2)  
                    );	
					
ram_bist u_sram_bist3(
                     .hclk             (hclk),
                     .sram_clk         (sram_clk),
                     .sram_rst_n       (hreset_n),
                     .sram_csn_in      (bank0_csn[3]),
                     .sram_wen_in      (sram_wen),
                     .sram_addr_in     (sram_addr),
                     .sram_wdata_in    (sram_wdata[31:24]),
                     .bist_en          (bist_en),
	                 .dft_en           (dft_en),
                                
                     .sram_data_out    (sram_q3),
                     .bist_done        (bist_done3),
                     .bist_fail        (bist_fail3)  
                    );
					
ram_bist u_sram_bist4(
                     .hclk             (hclk),
                     .sram_clk         (sram_clk),
                     .sram_rst_n       (hreset_n),
                     .sram_csn_in      (bank1_csn[0]),
                     .sram_wen_in      (sram_wen),
                     .sram_addr_in     (sram_addr),
                     .sram_wdata_in    (sram_wdata[7:0]),
                     .bist_en          (bist_en),
	                 .dft_en           (dft_en),
                                
                     .sram_data_out    (sram_q4),
                     .bist_done        (bist_done4),
                     .bist_fail        (bist_fail4)  
                    );	
					
ram_bist u_sram_bist5(
                     .hclk             (hclk),
                     .sram_clk         (sram_clk),
                     .sram_rst_n       (hreset_n),
                     .sram_csn_in      (bank1_csn[1]),
                     .sram_wen_in      (sram_wen),
                     .sram_addr_in     (sram_addr),
                     .sram_wdata_in    (sram_wdata[15:8]),
                     .bist_en          (bist_en),
	                 .dft_en           (dft_en),
                                
                     .sram_data_out    (sram_q5),
                     .bist_done        (bist_done5),
                     .bist_fail        (bist_fail5)  
                    );	
					
ram_bist u_sram_bist6(
                     .hclk             (hclk),
                     .sram_clk         (sram_clk),
                     .sram_rst_n       (hreset_n),
                     .sram_csn_in      (bank1_csn[2]),
                     .sram_wen_in      (sram_wen),
                     .sram_addr_in     (sram_addr),
                     .sram_wdata_in    (sram_wdata[23:16]),
                     .bist_en          (bist_en),
	                 .dft_en           (dft_en),
                                
                     .sram_data_out    (sram_q6),
                     .bist_done        (bist_done6),
                     .bist_fail        (bist_fail6)  
                    );	
					
ram_bist u_sram_bist7(
                     .hclk             (hclk),
                     .sram_clk         (sram_clk),
                     .sram_rst_n       (hreset_n),
                     .sram_csn_in      (bank1_csn[3]),
                     .sram_wen_in      (sram_wen),
                     .sram_addr_in     (sram_addr),
                     .sram_wdata_in    (sram_wdata[31:23]),
                     .bist_en          (bist_en),
	                 .dft_en           (dft_en),
                                
                     .sram_data_out    (sram_q7),
                     .bist_done        (bist_done7),
                     .bist_fail        (bist_fail7)  
                    );	
				

endmodule 

源码免积分下载(含SRAM模型)

https://download.csdn.net/download/zgezi/85053283

  • 41
    点赞
  • 445
    收藏
    觉得还不错? 一键收藏
  • 34
    评论
随着计算机系统的发展,内存的速度成为了系统性能的瓶颈之一。为了解决这一问题,SRAM(静态随机存储器)成为了一种常用的内存类型,而AHB(高级高速总线)是一种快速的总线协议。基于AHB的SRAM控制器设计与优化可以显著提高系统性能。 SRAM控制器的任务是管理SRAM芯片的读写操作。基于AHB的SRAM控制器可以通过总线传输协议来与其他设备进行通信,从而实现高速数据传输。其中,读取操作需要首先将地址和请求发送到SRAM中,然后等待SRAM返回数据。在这个过程中,控制器需要使用适当的寻址算法来定位存储位置,并根据SRAM的工作原理优化读取周期。 在设计和优化基于AHB的SRAM控制器时,需要考虑以下几个关键因素: 第一,SRAM内部结构的特点。SRAM的读取速度非常快,但它的存储密度相对较低,且需要专用硬件实现。因此,控制器需要在寻址和数据访问方面操作SRAM的内部结构。 第二,总线带宽。为了充分利用AHB总线的高速性能,控制器应使用适当的调度算法和数据传输协议,以充分利用总线带宽。 第三,芯片时序。SRAM芯片的时序和时延对读写操作的速度有重要影响。控制器应根据SRAM芯片的特性和内部结构来优化时序和时延参数。 综上所述,基于AHB的SRAM控制器设计和优化是一项复杂且重要的任务,它需要结合SRAM芯片的特性、总线带宽和时序参数进行考虑,以充分利用系统性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值