AHB-SRAMC Design
SRAM集成,顶层模块尽量不要写交互逻辑
module ahb_slave_if(
input hclk,
input hrestn,
input hwrite,
input hsel,
input hready,
input [2:0] hsize,
input [1:0] htrans,
input [2:0] hburst,
input [31:0] haddr
input [31:0] hwdata,
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;
onput hready_resp,
onput [1:0] hresp,
onput [31:0] hrdata,
output sram_w_en,
output [3:0] bank0_csn,
output [3:0] bank1_csn,
output [31:0] sram_wdata,
output [12:0] sram_addr_out
);
// 定义一些内部信号
wire [1:0] haddr_sel;
wire [1:0] hsize_sel;
wire bank_sel; // bank选择信号,拉高选择bank0,拉低选择bank1
wire sram_csn_en; // sram选择信号
wire sram_read;
wire sram_write; // sram读写信号
wire [15:0] sram_addr;
wire [31:0] sram_data_out;
parameter IDLE = 2'b00,
BUSY = 2'b01,
NONSEQ = 2'b10,
SEQ = 2'b11;
assign hready_resp = 1'b1;
assign hresp = 2'b00;
// 从sram中读取的数据
hrdata = sram_data_out;
// 根据bank_sel进行选择bank中的mem读取,bank_sel == 1 选择bank0,bank_sel == 0选择bank1
assign sram_data_out = bank_sel ? {sram_q7,sram_q6,sram_q5,sram_q4}:
{sram_q3,sram_q2,sram_q1,sram_q0};
assign sram_write = hwrite && ((htrans_r == NONSEQ) || (htrans_r == SEQ));
assign sram_read = (!hwrite) && ((htrans_r == NONSEQ) || (htrans_r == SEQ));
// 产生写信号,低有效
assign sram_w_en = !sram_write;
assign sram_addr = haddr[15:0];
assign sram_addr_out = sram_addr[14:2];
// 写或读的时候进行片选
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;
assign haddr_sel = sram_addr[1:0];
assign hsize_sel = hszie_r[1:0];
assign sram_wdata = hwdata;
always @(hsize_sel or haddr_sel)
begin
if(hsize_sel == 2‘b10)
sram_csn = 4’b0;
else if(haddr_sel == 2'b01)
begin
if(!haddr_sel[1] = 1'b0)
sram_csn = 4'b1100;
else
sram_csn = 4'b0011;
end
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总线控制信号进行打拍处理
always@(posedge hclk or negedge hrestn)
begin
if(!hrestn) 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
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
- 将ahb总线地址和控制信号进行打拍
- 定义parameter(htrans状态和hsize)