一文详解AHB-Lite协议

频道:保险市场 日期: 浏览:66000

一、AHB-Lite协议介绍

AHB(Advanced High-performance Bus)高速总线,接高速master设备,APB(Advanced Peripheral Bus)外设总线,用来接低速slave,AHB主要用于高性能模块(如CPUDMADSP等)之间的连接一个master可以有多个slave,AHB和APB之间通过一个AHB2APB桥转接。这里是实现一个AHB-Lite协议,相较于AHB-APB总线协议,AHB-Lite只有单主机,且没有HBUSREQ和HGRANT信号,同时从设备信号接口也简单许多。

二、系统框架介绍

9f1966ba-800e-11f0-a18e-92fbcf53809c.png

主设备Master0利用AHB-Lite总线协议通过AHB Bridge访问四个APB从设备Slave0、Slave、Slave2和Slave3。每个从设备的地址空间如下:

Slave0: 0x0000_0000 ~ 0x0000_00ff;

Slave1: 0x0000_0100 ~ 0x0000_01ff;

Slave2: 0x0000_0200 ~ 0x0000_02ff;

Slave3: 0x0000_0300 ~ 0x0000_03ff;

令从设备地址空间的下边界为其地址的基址,假设每个从设备中有可访问APB寄存器16个,位宽均为32比特,16个寄存器的访问地址计算方式为 基址 +寄存器编号左移2位(byte 偏移)

主设备接口的数据读写采用AHB-Lite总线协议,并遵循如下时序规范:

从设备读写遵循APB时序规范:

9f404f46-800e-11f0-a18e-92fbcf53809c.png

三、代码设计

模块里包含Master 、Slave、Bridge设计

代码如下:

//-------------------------

//File Name:AHB_APB.v

//Designer:Liang Genyuan

//-------------------------

module AHB_APB(

HCLK,

HRESETn,

HWRITE,

HADDR,

HWDATAin,

HRDATA,

PRDATAin,

PWDATA

);

input HCLK;

input HRESETn;

input HWRITE;

input [31:0] HADDR;

input [31:0] HWDATAin;

input [31:0] PRDATAin;

output[31:0] HRDATA;

output[31:0] PWDATA;

reg PCLK;

wire PRESETn;

wire PWRITE;

reg PSEL;

reg PENABLE;

wire[31:0] PADDR;

reg[31:0] PWDATA;

reg[31:0] PRDATA;

reg[31:0] HWDATA;

reg[31:0] HRDATA;

reg PSELS0;

reg PSELS1;

reg PSELS2;

reg PSELS3;

reg[31:0] HADDR_Reg;

reg HWRITE_Reg;

reg[3:0] HSEL_Reg;

reg[31:0] HWDATA_Reg;

reg[31:0] PRDATA_Reg;

reg HREADY;

reg [3:0] state_c ;

reg [3:0] state_n ;

parameter IDLE = 4'b0000 ;

parameter SETUP = 4'b0001;

parameter ENABLE = 4'b0010 ;

//PCLK二分频

always @(posedge HCLK) begin

if(!HRESETn)begin

PCLK<=0;

end

else if(HCLK==1'b1)begin

PCLK<=~PCLK;

end

end

//slave选择

`define S0BASE 4'b0000

`define S1BASE 4'b0001

`define S2BASE 4'b0010

`define S3BASE 4'b0011

wire[3:0] HSEL;

assign HSEL = HADDR[11:8];

always @(*)begin

if(!HRESETn) begin

PSELS0 = 1'b0;

PSELS1 = 1'b0;

PSELS2 = 1'b0;

PSELS3 = 1'b0;

end

case (HSEL)

`S0BASE :

PSELS0 = 1'b1;

`S1BASE :

PSELS1 = 1'b1;

`S2BASE :

PSELS2 = 1'b1;

`S3BASE :

PSELS3 = 1'b1;

endcase

end

//slave读写

wire[5:0] reg_num;

reg [3:0] PSELx;

assign reg_num= PADDR[7:2];

assign PRESETn=HRESETn;

assign PADDR=HADDR_Reg;

assign PWRITE=HWRITE_Reg;

always @(posedge PCLK or negedge PRESETn) begin

if(!PRESETn)begin

PWDATA<=0;

PRDATA<=0;

end

else if(PWRITE)begin

if((state_c==SETUP)||(state_c==ENABLE))begin

PWDATA<=HWDATA_Reg;

end

else begin

PWDATA<=0;

end

end

else if(!PWRITE)begin

PRDATA<=PRDATAin;

end

else begin

PRDATA<=0;

end

end

//APB bridge状态机

wire idle2setup_start ;

wire setup2enable_start;

wire enable2idle_start ;

always@(posedge HCLK or negedge HRESETn)begin

if(!HRESETn)begin

PSELx<=0;

end

else if(state_c!=IDLE)begin

PSELx<=HSEL_Reg;

end

end

always @(posedge PCLK or negedge PRESETn) begin

if (!PRESETn) begin

state_c <= IDLE ;

end

else begin

state_c <= state_n;

end

end

always @(*) begin

case(state_c)

IDLE :begin

if(idle2setup_start)

state_n = SETUP ;

else

state_n = state_c ;

end

SETUP :begin

if(setup2enable_start)

state_n = ENABLE ;

else

state_n = state_c ;

end

ENABLE :begin

if(enable2idle_start)

state_n = IDLE ;

else

state_n = state_c ;

end

default : state_n = IDLE ;

endcase

end

always@(posedge PCLK or negedge PRESETn)begin

if(PRESETn==1'b0)begin

PENABLE<=0;

PSEL<=0;

end

else if(state_c==SETUP)begin

PSEL<=1;

PENABLE<=0;

end

else if(state_c==ENABLE)begin

PSEL<=1;

PENABLE<=1;

end

else begin

PSEL<=0;

PENABLE<=0;

end

end

assign idle2setup_start = (state_c==IDLE)&&(HADDR!=32'b0) ;

assign setup2enable_start = state_c==SETUP ;

assign enable2idle_start = state_c==ENABLE ;

//桥寄存

always @ (negedge HRESETn or posedge HCLK) begin

if (!HRESETn)

begin

HADDR_Reg <= {32{1'b0}};

HWRITE_Reg <= 1'b0;

end

else

if (HREADY)begin

HADDR_Reg <= HADDR;

HWRITE_Reg <= HWRITE;

end

end

always @(posedge HCLK or negedge HRESETn)begin

if(HRESETn==1'b0)begin

HSEL_Reg<=0;

end

else if(HREADY)begin

HSEL_Reg<=HSEL;

end

end

always @(posedge HCLK or negedge HRESETn)begin

if(HRESETn==1'b0)begin

HWDATA_Reg<=0;

PRDATA_Reg<=0;

end

else if(HWRITE==1)begin

HWDATA_Reg<=HWDATA;

end

else begin

PRDATA_Reg<=PRDATA;

end

end

//master

//HREADY控制

always @(posedge PCLK or negedge PRESETn)begin

if(!PRESETn)begin

HREADY<=0;

end

else if((state_c==IDLE)&&(HWDATA==0))begin

HREADY<=1;

end

else if(state_c==SETUP)begin

HREADY<=0;

end

end

always @(posedge HCLK or negedge HRESETn)begin

if(HRESETn==1'b0)begin

HWDATA<=32'b0;

HRDATA<=32'b0;

end

else if(HWRITE==0)begin

HRDATA<=PRDATA_Reg;

end

else if(HWRITE==1)begin

HWDATA<=HWDATAin;

end

end

endmodule

四、仿真测试

分别对读写时序进行两组测试:

1、写时序

a、

HADDR=32’b0000_0000_0000_0000_0000_0001_0000_0000

HWDATAin=32’b0000_0000_0000_0000_0000_0001_0000_0001

PSELx=1,reg_num=0

即选中了第一个从设备中第一个寄存器

b、

HADDR=32’b0000_0000_0000_0000_0000_0011_0000_1000;

HWDATAin=32’b0000_0000_0000_0000_0000_1111_0000_1111;

9f6c0334-800e-11f0-a18e-92fbcf53809c.png

PSELx=3,reg_num=2

即选中了第三个从设备中第三个寄存器

2、读时序

a、

HADDR=32’b0000_0000_0000_0000_0000_0011_0000_1000

PRDATAin=32’b00000_0000_0000_0000_0000_1111_0000_1111

9f765546-800e-11f0-a18e-92fbcf53809c.png

PSELx=3 reg_num=2

即第三个从设备第三个寄存器

b、

HADDR=32’b0000_0000_0000_0000_0000_0100_0000_1100

PRDATAin=32’b00000_0000_0000_0000_0000_1110_0000_1110

9f8a0ae6-800e-11f0-a18e-92fbcf53809c.png

PSELx=4 reg_num=3

即第四个从设备第四个寄存器

原文链接:

https://blog.csdn.net/yueqiu693/article/details/119849052

  • 随机文章
  • 热门文章
  • 热评文章