1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > AHB-SRAM简单设计之总线控制单元 ahb_slave_if.v

AHB-SRAM简单设计之总线控制单元 ahb_slave_if.v

时间:2023-12-02 05:35:57

相关推荐

AHB-SRAM简单设计之总线控制单元 ahb_slave_if.v

前言

这部分的代码在最后,本来打算刚开始就直接上代码,可是200多行,有点占篇幅。我们就先分析下这部分!

推荐一篇硕士论文,可以自行搜索下载,或点击免费下载:基于AHB总线SRAM控制器 的设计及优化.caj。

AHB总线控制单元 ahb_slave_if.v

就这么说,市面上arm公司的架构比较受众,最基本的就是AMBA协议。芯片设计公司要把东西(ram、sram、uart等等)按照协议集联起来,所以要考虑的就是如何把他们连接到AMBA里面去!所以就产生了与模块对应的控制单元。

在这里有点迷惑:下面这部分是论文里的,也是参考博客中完全复现的部分!

这部分提到的sram控制器,不是AHB总线控制单元的部分吗?顶层模块只是将两个子模块例化连接起来就行了!难道他们是将这部分单独放了一个模块,然后例化在了ahb_slave_if.v中?

SRAM 的工作原理很简单,SRAM 控制单元根据接受到的总线控制信号,将这些信号处理转化为 SRAM 存储器可以识别的信号,发送到 SRAM 存储器;之后,将经过地址译码的物理地址传送到存储器的地址总线,并将数据路径处理的数据送到SRAM 存储器的数据总线。最后,SRAM 存储器进行相应的读写访问。如果是写操作,SRAM 控制单元的任务就完成了,SRAM 存储器已将数据信息按照要求写入。如果是读操作,SRAM 控制单元需要接收返回的读数据,将其送到数据路径,由数据路径将信息传输给 AHB 总线,最终实现总线对 SRAM 的读操作。

这里设计的SRAM控制器的作用就是实现SRAM存储器与AHB总线的数据信息交换

声明:下面分析的这部分照搬前言提到的硕士论文 !!!!!!!!

/*选用单周期读写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) beginif(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

ahb_slave_if.v

module ahb_slave_if(//input signalsinput hclk,input hresetn,input hsel,input hwrite,input hready,input[2:0] hsize,input [1:0] htrans,input [2:0] hburst, // hard code -> parameterinput [31:0] hwdata,input [31:0] haddr,//output signalsoutputhready_resp,output [1:0]hresp,output [31:0]hrdata,//sram outputinput [7:0] sram_q0, // 8bitsinput [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,outputsram_w_en,// 0:write, 1:readoutput [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 signalsreg 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 enablewire sram_write; //sram write enable signal from AHB buswire sram_read; //sram read enable signal from AHB buswire [15:0] sram_addr;//sram address from AHB buswire [31:0] sram_data_out; //data read from sram and send to AHB busparameterIDLE = 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 Cycleassign 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--0xffffassign sram_addr = haddr_r [15:0];//64K 8*8Kassign 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 bank1assign 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) beginif(hsize_sel == 2'b10)//32bitsram_csn = 4'b0;else if(hsize_sel == 2'b01) begin//16bitif(haddr_sel[1] == 1'b0) //little-endiansram_csn = 4'b1100;elsesram_csn = 4'b0011;endelse if(hsize_sel == 2'b00) begin//8bitcase(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 signalsalways@(posedge hclk , negedge hresetn) beginif(!hresetn) beginhwrite_r <= 1'b0 ;hsize_r <= 3'b0 ; hburst_r <= 3'b0 ;htrans_r <= 2'b0 ;haddr_r <= 32'b0 ;endelse if(hsel && hready) begin //hsel要片选,否则信号一直在翻转,可能会功能错误,并且功耗大hwrite_r <= hwrite ;//写SRAM时,把控制信号寄存。因为写操作时,要把地址打一拍,和数据对齐hsize_r <= hsize ; // hburst_r <= hburst ;//AHB中master会把burst传输所有地址传递过来,AXI只传递起始地址。此处用处不大。减少一个REGhtrans_r <= htrans ;haddr_r <= haddr ;end else beginhwrite_r <= 1'b0 ;hsize_r <= 3'b0 ; hburst_r <= 3'b0 ;htrans_r <= 2'b0 ;haddr_r <= 32'b0 ;endendendmodule

后记

这是AHB-SRAM项目中,总线控制单元ahb_slave_if.v的所有文件,如果需要跳转到查看此项目的架构,请点击跳转

AHB-SRAM简单设计之架构图解

笔者是小白,自学输出过程中,难免有错误,请大家指正!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。