目录
说明
文字说明来自"AMBA® AXI™ and ACE™ ProtocolSpecification",百度直接可以搜到。
代码源自Xilinx的AXI IP,获取方法如下:
选择create and package new IP.
Interface Mode 选择 Master,Interface Type 选择 Full, Date Width自行设定,这里选择32.
选择edit IP.
本文整理了master的部分代码,后续有时间会整理master部分剩下的代码和slave的代码,因为学习协议去看文档非常枯燥,还是与代码结合比较有效,当做一个学习笔记。
1. AXI 的时钟与复位
1.1 时钟
Each AXI component uses a single clock signal, ACLK. All input signals are sampled on the rising edge of ACLK.
All output signal changes must occur after the rising edge of ACLK.
代码:
// Global Clock Signal.
input wire M_AXI_ACLK,
1.2 复位
The AXI protocol uses a single active LOW reset signal, ARESETn. The reset signal can be asserted
asynchronously, but deassertion must be synchronous with a rising edge of ACLK.
引脚定义:
master:
// Global Reset Singal. This Signal is Active Low
input wire M_AXI_ARESETN,
复位的作用引脚为:
a master interface must drive ARVALID, AWVALID, and WVALID LOW
2. 五个通道
如图所示:
2.1 Write Address Channel
相关信号:
signal | source | description |
---|---|---|
AWVALID | master | Write address valid. This signal indicates that the channel is signaling valid write address and control information. |
AWREADY | slave | Write address valid. This signal indicates that the channel is signaling valid write address and control information. |
AWADDR | master | Write address. The write address gives the address of the first transfer in a write burst transaction. |
代码:
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )
begin
axi_awvalid <= 1'b0;
end
// If previously not valid , start next transaction
else if (~axi_awvalid && start_single_burst_write)
begin
axi_awvalid <= 1'b1;
end
/* Once asserted, VALIDs cannot be deasserted, so axi_awvalid
must wait until transaction is accepted */
else if (M_AXI_AWREADY && axi_awvalid)
begin
axi_awvalid <= 1'b0;
end
else
axi_awvalid <= axi_awvalid;
end
这一段代码即为握手过程:
Once VALID is asserted it must remain asserted until the handshake occurs, at a rising clock edge at which VALID and READY are both asserted.
代码:
// Next address after AWREADY indicates previous address acceptance
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
begin
axi_awaddr <= 'b0;
end
else if (M_AXI_AWREADY && axi_awvalid)
begin
axi_awaddr <= axi_awaddr + burst_size_bytes;
end
else
axi_awaddr <= axi_awaddr;
end
这里init_txn_pulse是初始标志,将axi_awvalid清零和axi_awaddr地址归到起始。
如前面所说,AWADDR是每次burst传输的首地址,因此每次加一个burst_size_bytes。
burst_size_bytes定义为:
assign burst_size_bytes = C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8;
即长度×宽度/8(字节),这里涉及到突发传输的长度宽度,可以看3.1。
2.2 Write Data Channel
相关信号:
signal | source | description |
---|---|---|
WVALID | master | Write valid. This signal indicates that valid write data and strobes are available. |
WREADY | slave | Write ready. This signal indicates that the slave can accept the write data. |
WLAST | master | Write last. This signal indicates the last transfer in a write burst. |
WDATA | master | Write data. |
代码:
// WVALID logic, similar to the axi_awvalid always block above
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )
begin
axi_wvalid <= 1'b0;
end
// If previously not valid, start next transaction
else if (~axi_wvalid && start_single_burst_write)
begin
axi_wvalid <= 1'b1;
end
/* If WREADY and too many writes, throttle WVALID
Once asserted, VALIDs cannot be deasserted, so WVALID
must wait until burst is complete with WLAST */
else if (M_AXI_WREADY & axi_wvalid&& axi_wlast)
axi_wvalid <= 1'b0;
else
axi_wvalid <= axi_wvalid;
end
这一段和上面的握手过程类似,不同的是WVALID需要在axi_wlast为1时清零。
代码:
//WLAST generation on the MSB of a counter underflow
// WVALID logic, similar to the axi_awvalid always block above
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )
begin
axi_wlast <= 1'b0;
end
// axi_wlast is asserted when the write index
// count reaches the penultimate count to synchronize
// with the last write data
else if (((write_index == C_M_AXI_BURST_LEN-2 && C_M_AXI_BURST_LEN >= 2) && M_AXI_WREADY & axi_wvalid) || (C_M_AXI_BURST_LEN == 1 ))
begin
axi_wlast <= 1'b1;
end
// Deassrt axi_wlast when the last write data has been
// accepted by the slave with a valid response
else if (M_AXI_WREADY & axi_wvalid)
axi_wlast <= 1'b0;
else if (axi_wlast && C_M_AXI_BURST_LEN == 1)
axi_wlast <= 1'b0;
else
axi_wlast <= axi_wlast;
end
C_M_AXI_BURST_LEN为burst的长度,在长度大于等于2时,write_index为C_M_AXI_BURST_LEN-2时wlast置1,如果长度为1则直接置1。在最后一个数据被接收后wlast清零。
代码,write_index:
/* Burst length counter. Uses extra counter register bit to indicate terminal
count to reduce decode logic */
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 || start_single_burst_write == 1'b1)
begin
write_index <= 0;
end
else if (wnext && (write_index != C_M_AXI_BURST_LEN-1))
begin
write_index <= write_index + 1;
end
else
write_index <= write_index;
end
代码,write data,这里给出的是简单的每次增加1的data
/* Write Data Generator
Data pattern is only a simple incrementing count from 0 for each burst */
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
axi_wdata <= 'b1;
//else if (wnext && axi_wlast)
// axi_wdata <= 'b0;
else if (wnext)
axi_wdata <= axi_wdata + 1;
else
axi_wdata <= axi_wdata;
end
2.3 Write Response (B) Channel
相关信号:
signal | source | description |
---|---|---|
BVALID | slave | Write response valid. This signal indicates that the channel is signaling a valid write response. |
BREADY | master | Response ready. This signal indicates that the master can accept a write response. |
代码:
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )
begin
axi_bready <= 1'b0;
end
// accept/acknowledge bresp with axi_bready by the master
// when M_AXI_BVALID is asserted by slave
else if (M_AXI_BVALID && ~axi_bready)
begin
axi_bready <= 1'b1;
end
// deassert after one clock cycle
else if (axi_bready)
begin
axi_bready <= 1'b0;
end
// retain the previous value
else
axi_bready <= axi_bready;
end
这是握手过程,是上面两段握手的反过程,valid由slave发送,ready由master发送。ready仅发送一个时钟。
2.4 Read Address Channel
signal | source | description |
---|---|---|
ARVALID | master | Read address valid. This signal indicates that the channel is signaling valid read address and control information. |
ARREADY | salve | Read address ready. This signal indicates that the slave is ready to accept an address and associated control signals. |
ARADDR | master | Read address. The read address gives the address of the first transfer in a read burst transaction. |
握手机制代码:
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )
begin
axi_arvalid <= 1'b0;
end
// If previously not valid , start next transaction
else if (~axi_arvalid && start_single_burst_read)
begin
axi_arvalid <= 1'b1;
end
else if (M_AXI_ARREADY && axi_arvalid)
begin
axi_arvalid <= 1'b0;
end
else
axi_arvalid <= axi_arvalid;
end
地址增加代码,这里和写地址十分类似:
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
begin
axi_araddr <= 'b0;
end
else if (M_AXI_ARREADY && axi_arvalid)
begin
axi_araddr <= axi_araddr + burst_size_bytes;
end
else
axi_araddr <= axi_araddr;
end
2.5 Read Data (and Response) Channel
signal | source | description |
---|---|---|
RLAST | slave | Read last. This signal indicates the last transfer in a read burst. |
RVALID | salve | Read valid. This signal indicates that the channel is signaling the required read data. |
RREADY | master | Read ready. This signal indicates that the master can accept the read data and response information. |
握手机制代码:
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 )
begin
axi_rready <= 1'b0;
end
// accept/acknowledge rdata/rresp with axi_rready by the master
// when M_AXI_RVALID is asserted by slave
else if (M_AXI_RVALID)
begin
if (M_AXI_RLAST && axi_rready)
begin
axi_rready <= 1'b0;
end
else
begin
axi_rready <= 1'b1;
end
end
// retain the previous value
end
3 突发传输机制
3.1 突发传输长度和宽度
相关信号:
signal | source | description |
---|---|---|
AWLEN | master | Burst length. The burst length gives the exact number of transfers in a burst. This information determines the number of data transfers associated with the address. |
AWSIZE | master | Burst size. This signal indicates the size of each transfer in the burst. |
ARLEN | master | 同AWLEN |
ARSIZE | master | 同ARSIZE |
引脚定义(master):
output wire [7 : 0] M_AXI_AWLEN,
output wire [2 : 0] M_AXI_AWSIZE,
output wire [7 : 0] M_AXI_ARLEN,
output wire [2 : 0] M_AXI_ARSIZE,
assign M_AXI_ARLEN = C_M_AXI_BURST_LEN - 1;
assign M_AXI_ARSIZE = clogb2((C_M_AXI_DATA_WIDTH/8)-1);
assign M_AXI_AWLEN = C_M_AXI_BURST_LEN - 1;
assign M_AXI_AWSIZE = clogb2((C_M_AXI_DATA_WIDTH/8)-1);
ARLEN/AWLEN:
The burst length for AXI4 is defined as,
Burst_Length = AxLEN[7:0] + 1, to accommodate the extended burst length of the INCR burst type in AXI4.
ARSIZE/AWSIZE如下表所示:
都与代码是一致的。
C_M_AXI_DATA_WIDTH定义与之前定义的width是一致的:
parameter integer C_M_AXI_DATA_WIDTH = 32,
一次传输的字节数:
assign burst_size_bytes = C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8;
读数据通道的突发传输长度计数:
突发传输方式计数:
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 || start_single_burst_read)
begin
read_index <= 0;
end
else if (rnext && (read_index != C_M_AXI_BURST_LEN-1))
begin
read_index <= read_index + 1;
end
else
read_index <= read_index;
end
3.2 突发传输类型
相关信号:
signal | source | description |
---|---|---|
ARBURST | master | Burst type. The burst type and the size information determine how the address for each transfer within the burst is calculated. |
AWBURST | master | 同ARBURST |
引脚定义(master):
output wire [1 : 0] M_AXI_AWBURST,
output wire [1 : 0] M_AXI_ARBURST
不同的ARBURST/AWBURST对应的突发传输类型如下表,具体的机制需要分析slave的代码 (slave的代码后续有时间也会整理)。
同时突发传输长度也与突发传输类型有关,突发传输长度的规定:
AXI4 extends burst length support for the INCR burst type to 1 to 256 transfers. Support for all other burst types in AXI4 remains at 1 to 16 transfers.