设为首页 加入收藏

TOP

「数字IC设计项目」 —— AHB SRAM控制器设计 & March C-算法内建自测试的实现(六)
2023-07-23 13:25:06 】 浏览:267
Tags:数字 计项目 AHB SRAM March
BIST_en ), .oBIST_done (BIST_done_5 ), .oBIST_fail (BIST_fail_5 ) ); sram_bist u_bank1_sram6 ( // Function Mode IO .iSRAM_CLK (iHCLK ), .iSRAM_CSN (iSRAM_CSN_BANK1[2]), .iSRAM_WEN (iSRAM_WEN_BANK1 ), .iSRAM_ADDR (iSRAM_ADDR ), //13 bits SRAM ADDR .iSRAM_WDATA(iSRAM_WDATA[23:16]), .oSRAM_RDATA(oSRAM6_q ), // Test Mode IO .iBIST_en (iBIST_en ), .oBIST_done (BIST_done_6 ), .oBIST_fail (BIST_fail_6 ) ); sram_bist u_bank1_sram7 ( // Function Mode IO .iSRAM_CLK (iHCLK ), .iSRAM_CSN (iSRAM_CSN_BANK1[3]), .iSRAM_WEN (iSRAM_WEN_BANK1 ), .iSRAM_ADDR (iSRAM_ADDR ), //13 bits SRAM ADDR .iSRAM_WDATA(iSRAM_WDATA[31:24]), .oSRAM_RDATA(oSRAM7_q ), // Test Mode IO .iBIST_en (iBIST_en ), .oBIST_done (BIST_done_7 ), .oBIST_fail (BIST_fail_7 ) ); endmodule

1.6 SRAM读写功能的仿真验证

在完成RTL设计后,我们编写了Testbench,
并在Vivado平台上进行了简单的读写仿真验证,波形如下:

分析一下Testbench具体对SRAM发起了什么操作:

首先,T1-T7进行了六次写操作,将6个数据依次写入SRAM的0x0000,0x0004,0x0008,0x8000,0x8004,0x8008六个地址当中

其中前三个地址对应Bank0,后三个地址对应Bank1,

因此在T2-T4期间 SRAM_CSN_BANK0 和 SRAM_WEN_BANK0 被拉高,

在T5-T7期间 SRAM_CSN_BANK1 和 SRAM_WEN_BANK1 被拉高,

从上图中可以看出,T7除了是Data 6的写数据周期,也是Data 1 读地址周期,

但是由于SRAM端口上,该周期需要执行写Data 6的操作。

于是发生了地址冲突,无法在该周期同时进行读Data 1

因此,在T8并没有返回Data 1的读数据,HREADY被拉低,

随后,在T9-T14,总线上HRDATA依次拿到了六个SRAM读数据,读出的data与T1-T7写入的data完全一致,证明了以上SRAM控制器的设计逻辑是正确的

1.7 支持半字/字节读写

细心的读者们可能发现上述设计仅考虑了读SRAM按字进行读写的情况,

也就是每次读写都是32位的。

实际上,AHB协议同样支持我们以16位/8位的方式对SRAM进行访问,由HSIZE[2:0]控制,具体对应关系如下:

HSIZE[2:0] = 3'b000:按BYTE读写
HSIZE[2:0] = 3'b001:按Half Word读写
HSIZE[2:0] = 3'b010:按Word读写

支持半字/字节读写使得CSN信号的生成变得更为复杂,

基于上述设计,读者们可以思考一下如何实现该功能,

以下给出参考设计:

// SRAM Bank CSN
  wire [3:0] SRAM_CSN_BANK0_write;
  wire [3:0] SRAM_CSN_BANK0_read ;
  wire [3:0] SRAM_CSN_BANK1_write;
  wire [3:0] SRAM_CSN_BANK1_read ;

  always @(*) begin
    case( {iHADDR[15],iHSIZE} )
      //选中BANK0,HSIZE = Word
      4'b0010:begin
        SRAM_CSN_BANK0_read <= 4'b1111;
        SRAM_CSN_BANK0_read <= 4'b0000;
      end
      //选中BANK1,HSIZE = Word
      4'b1010:begin
        SRAM_CSN_BANK0_read <= 4'b0000;
        SRAM_CSN_BANK1_read <= 4'b1111;
      end
      //选中BANK0,HSIZE = Half Word
      4'b0001:begin
        if(iHADDR[1]) begin
          SRAM_CSN_BANK0_read <= 4'b1100;
          SRAM_CSN_BANK1_read <= 4'b0000;
        end else begin
          SRAM_CSN_BANK0_read <= 4'b0011;
          SRAM_CSN_BANK1_read <= 4'b0000;
        end   
      end
      //选中BANK1,HSIZE = Half Word
      4'b1001:begin
        if(iHADDR[1]) begin
          SRAM_CSN_BANK0_read <= 4'b0000;
          SRAM_CSN_BANK1_read <= 4'b1100;
        end else begin
          SRAM_CSN_BANK0_read <= 4'b0000;
          SRAM_CSN_BANK1_read <= 4'b0011;
        end   
      end
      //选中BANK0,HSIZE = BYTE
      4'b0000:begin
        case (iHADDR[1:0])
          2'b00: begin
            SRAM_CSN_BANK0_read <= 4'b0001;
            SRAM_CSN_BANK1_read <= 4'b0000;
          end
          2'b01: begin
            SRAM_CSN_BANK0_read <= 4'b0010;
            SRAM_CSN_BANK1_read <= 4'b0000;
          end
          2'b10: begin
            SRAM_CSN_BANK0_read <= 4'b0100;
            SRAM_CSN_BANK1_read <= 4'b0000;
          end
          2'b11: begin
            SRAM_CSN_BANK0_read <= 4'b1000;
            SRAM_CSN_BANK1_read <= 4'b0000;
          end
        endcase  
      end
      //选中BANK1,HSIZE = BYTE
      4'b1000:begin
        case (iHADDR[1:0])
          2'b00: begin
            SRAM_CSN_BANK0_read <= 4'b0000;
            SRAM_CSN_BANK1_read <= 4'b0001;
          end
          2'b01: begin
            SRAM_CSN_BANK0_read <= 4'b0000;
            SRAM_CSN_BANK1_read <= 4'b0010;
          end
          2'b10: begin
            SRAM_CSN_BANK0_read <= 4'b0000;
            SRAM_CSN_BANK1_read <= 4'b0100;
          end
          2'b11: begin
            SRAM_CSN_BANK0_read <
首页 上一页 3 4 5 6 7 8 9 下一页 尾页 6/11/11
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【牛客】7 计数器&存储器&综合 下一篇推排序 Verilog实现原理

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目