作者:绿杨,来源:安谋科技学堂
本篇将带大家认识一下使用SystemVerilog描述的代码示例中的AHB总线信号接口以及工作时序。
Advanced Microcontroller Bus Architecture, 即AMBA,是ARM公司提出的总线规范,被很多SoC设计所采用,常用的实现有AHB(Advanced High-Performance Bus)和APB(Advanced Peripheral Bus)。AHB用于高性能系统,APB用于低速外设。以下代码实例使用的是SystemVerilog描述。
一. AHB总线信号接口
包括AHB主设备,AHB从设备,AHB仲裁器等。
interface ahb_msr_intf #(
parameter AW = 32,
DW = 32
) (
input logic HCLK,
input logic HRESETn
);
logic HGRANT;
logic HREADY;
HRESP_e HRESP;
logic [DW-1:0] HRDATA;
logic HBUSREQ;
logic HLOCK;
HTRANS_e HTRANS;
logic [AW-1:0] HADDR;
logic HWRITE;
HSIZE_e HSIZE;
HBURST_e HBURST;
HPROT_e HPROT;
logic [DW-1:0] HWDATA;
modport m (
input HGRANT, HREADY, HRESP, HRDATA,
output HBUSREQ, HLOCK, HTRANS, HADDR, HWRITE, HSIZE, HBURST, HPROT, HWDATA
);
modport s (
input HBUSREQ, HLOCK, HTRANS, HADDR, HWRITE, HSIZE, HBURST, HPROT, HWDATA,
output HGRANT, HREADY, HRESP, HRDATA
);
endinterface: ahb_msr_intf
以上为AHB主设备接口。
interface ahb_slv_intf #(
parameter AW = 32,
DW = 32
) (
input logic HCLK,
input logic HRESETn
);
logic HSEL;
logic [AW-1:0] HADDR;
HTRANS_e HTRANS;
HSIZE_e HSIZE;
HBURST_e HBURST;
logic HWRITE;
HPROT_e HPROT;
logic [DW-1:0] HWDATA;
logic HREADY;
HRESP_e HRESP;
logic [DW-1:0] HRDATA;
modport m (
input HREADY, HRESP, HRDATA,
output HSEL, HADDR, HTRANS, HSIZE, HBURST, HWRITE, HPROT, HWDATA
);
modport s (
input HSEL, HADDR, HTRANS, HSIZE, HBURST, HWRITE, HPROT, HWDATA,
output HREADY, HRESP, HRDATA
);
endinterface: ahb_slv_intf
以上为AHB从设备接口。下面对信号进行一一说明。
HCLK 总线时钟。
HRESETn 总线复位信号,低电平有效。
HADDR 地址总线,字节为单位。
HTRANS[1:0] 传输类型,具体如下:
typedef enum logic [1:0] {
HTRANS_IDLE = 2'b00,
HTRANS_BUSY = 2'b01,
HTRANS_NONSEQ = 2'b10,
HTRANS_SEQ = 2'b11
} HTRANS_e;
HWRITE 为高表示写传输,为低表示读传输。
HSIZE 传输大小,可能的取值定义如下:
typedef enum logic [2:0] {
HSIZE_BYTE = 3'b000, // 8bit
HSIZE_HALFWORD = 3'b001, // 16bit
HSIZE_WORD = 3'b010, // 32bit
HSIZE_DWORD = 3'b011, // 64bit
HSIZE_QWORD = 3'b100, // 128bit
HSIZE_OWORD = 3'b101, // 256bit
HSIZE_HWORD = 3'b110, // 512bit
HSIZE_TWORD = 3'b111 // 1024bit
} HSIZE_e;
HBURST 突发传输类型,突发传输模式可以为增量传输或者回环传输。
printf("hello typedef enum logic [2:0] {
HBURST_SINGLE = 3'b000,
HBURST_INCR = 3'b001,
HBURST_WRAP4 = 3'b010,
HBURST_INCR4 = 3'b011,
HBURST_WRAP8 = 3'b100,
HBURST_INCR8 = 3'b101,
HBURST_WRAP16 = 3'b110,
HBURST_INCR16 = 3'b111
} HBURST_e;
world!");
HPROT 提供总线访问的附加信息并且主要是打算给那些希望执行某种保护级别的模块使用的。
这个信号指示当前传输是否为预取指或者数据传输,同时也表示传输是保护模式访问还是用户模式访问。对带存储器管理单元的总线主机而言这些信号也用来指示当前传输是高速缓存的(cache)还是缓冲的(buffer)。定义如下:
// cacheable | bufferable | privileged | data
// not-cacheable | not-bufferable | user | opcode
typedef enum logic [3:0] {
HPROT_NNUO = 4'b0000,
HPROT_NNUD = 4'b0001,
HPROT_NNPO = 4'b0010,
HPROT_NNPD = 4'b0011,
HPROT_NBUO = 4'b0100,
HPROT_NBUD = 4'b0101,
HPROT_NBPO = 4'b0110,
HPROT_NBPD = 4'b0111,
HPROT_CNUO = 4'b1000,
HPROT_CNUD = 4'b1001,
HPROT_CNPO = 4'b1010,
HPROT_CNPD = 4'b1011,
HPROT_CBUO = 4'b1100,
HPROT_CBUD = 4'b1101,
HPROT_CBPO = 4'b1110,
HPROT_CBPD = 4'b1111
} HPROT_e;
HWDATA 写数据。
HSELx 从机选择。
HRDATA 读数据。
HREADY 为高时表示总线传输完成。
HRESP 传输相应信号,表征传输状态,定义如下:
typedef enum logic [1:0] {
HRESP_OKAY = 2'b00,
HRESP_ERROR = 2'b01,
HRESP_RETRY = 2'b10,
HRESP_SPLIT = 2'b11
} HRESP_e;
HSPLITx 16位信号,指示仲裁器总线主设备应该被允许重试一个分块传输,每一位对应一个总线主机。
以下信号与仲裁器相关:
HBUSREQx 总线主设备x请求申请总线控制权。最多16个主设备。
HLOCKx 总线锁定请求,其他主设备无法或者仲裁器授权。
HGRANTx 表示当前主设备为优先级最高的主设备。
HMASTER 仲裁器信号表示正在执行传输或支持分块传输的从设备进行传输的主设备号。
HMASTLOCK 主设备正在执行一个锁定顺序的传输。
AHB 互联矩阵:
module ahb_matrix # (
parameter WIDTH = 32,
NMSR = 4,
NSLV = 16
) (
input logic HCLK,
input logic HRESETn,
ahb_msr_intf.s ahbmv[NMSR],
ahb_slv_intf.m ahbsv[NSLV]
);
localparam NMSRV = $clog2(NMSR),
NSLVV = $clog2(NSLV);
logic HBUSREQx[NMSR];
logic HGRANTx[NMSR];
logic HREADY;
HRESP_e HRESP;
logic [WIDTH-1:0] HRDATA;
logic HSEL[NSLV];
logic [31:0] HADDR;
logic HWRITE;
HTRANS_e HTRANS;
HSIZE_e HSIZE;
HBURST_e HBURST;
HPROT_e HPROT;
logic [WIDTH-1:0] HWDATA;
logic [NMSRV-1:0] HMASTER, HMASTERd;
logic [NSLVV-1:0] HSLAVE, HSLAVEd;
logic errslv;
genvar i;
struct {
logic [WIDTH-1:0] HADDR [NMSR];
logic HWRITE [NMSR];
HTRANS_e HTRANS [NMSR];
HSIZE_e HSIZE [NMSR];
HBURST_e HBURST [NMSR];
HPROT_e HPROT [NMSR];
logic [WIDTH-1:0] HWDATA [NMSR];
} ahbmd;
struct {
logic [WIDTH-1:0] HRDATA [NSLV];
logic HREADY [NSLV];
HRESP_e HRESP [NSLV];
} ahbsd;
generate
for (i = 0; i < NSLV; i++) begin: ahbsv_loop
assign ahbsv[i].HSEL = HSEL[i];
assign ahbsv[i].HADDR = HADDR;
assign ahbsv[i].HWRITE = HWRITE;
assign ahbsv[i].HTRANS = HTRANS;
assign ahbsv[i].HSIZE = HSIZE;
assign ahbsv[i].HBURST = HBURST;
assign ahbsv[i].HPROT = HPROT;
assign ahbsv[i].HWDATA = HWDATA;
end
endgenerate
generate
for (i = 0; i < NMSR; i++) begin: ahbmv_loop
assign HBUSREQx[i] = ahbmv[i].HBUSREQ;
assign ahbmv[i].HGRANT = HGRANTx[i];
assign ahbmv[i].HREADY = HREADY;
assign ahbmv[i].HRESP = HRESP;
assign ahbmv[i].HRDATA = HRDATA;
end
endgenerate
generate
for (i = 0; i < NMSR; i++) begin: ahbmd_loop
assign ahbmd.HADDR[i] = ahbmv[i].HADDR;
assign ahbmd.HWRITE[i] = ahbmv[i].HWRITE;
assign ahbmd.HTRANS[i] = ahbmv[i].HTRANS;
assign ahbmd.HSIZE[i] = ahbmv[i].HSIZE;
assign ahbmd.HBURST[i] = ahbmv[i].HBURST;
assign ahbmd.HPROT[i] = ahbmv[i].HPROT;
assign ahbmd.HWDATA[i] = ahbmv[i].HWDATA;
end
endgenerate
assign HADDR = ahbmd.HADDR[HMASTER];
assign HWRITE = ahbmd.HWRITE[HMASTER];
assign HTRANS = ahbmd.HTRANS[HMASTER];
assign HSIZE = ahbmd.HSIZE[HMASTER];
assign HBURST = ahbmd.HBURST[HMASTER];
assign HPROT = ahbmd.HPROT[HMASTER];
assign HWDATA = ahbmd.HWDATA[HMASTERd];
generate
for (i = 0; i < NSLV; i++) begin: ahbsd_loop
assign ahbsd.HRDATA[i] = ahbsv[i].HRDATA;
assign ahbsd.HREADY[i] = ahbsv[i].HREADY;
assign ahbsd.HRESP[i] = ahbsv[i].HRESP;
end
endgenerate
assign HRDATA = ahbsd.HRDATA[HSLAVEd];
assign HREADY = errslv ? 1'b1 : ahbsd.HREADY[HSLAVEd];
assign HRESP = errslv ? HRESP_OKAY : ahbsd.HRESP[HSLAVEd];
always_ff @(posedge HCLK or negedge HRESETn) begin
if (!HRESETn)
HSLAVEd <= '0;
else if (HREADY)
HSLAVEd <= HSLAVE;
end
ahb_arbiter #(
.NMSR (NMSR)
) ahb_arbiter (
.HCLK (HCLK),
.HRESETn (HRESETn),
.HBUSREQx (HBUSREQx),
.HTRANS (HTRANS),
.HBURST (HBURST),
.HRESP (HRESP),
.HREADY (HREADY),
.HMASTER (HMASTER),
.HMASTERd (HMASTERd),
.HGRANTx (HGRANTx)
);
ahb_decoder #(
.NSLV (NSLV)
) ahb_decoder (
.HADDR (HADDR),
.HSEL (HSEL),
.HSLAVE (HSLAVE),
.errslv (errslv)
);
endmodule: ahb_matrix
二. AHB总线工作时序
无须多言,看图。
基本传输模式
多重传输
使用传输类型
增量突发传输
回环突发传输
未定义长度的增量突发传输