当前位置:网站首页>AXI_ Bus_ Matrix_ 4x4 design - logic design
AXI_ Bus_ Matrix_ 4x4 design - logic design
2022-06-21 21:04:00 【Starry and】
Catalog
Think well before you write code
1. decoder
The idea of decoder is very simple , take AXI Information exchange is divided into reading and writing .
Write control AW The channel depends on AWADDR The height of 2bit, namely AWSEL Coming film selection Slave. Writing data W Channels also depend on AWADDR The height of 2bit, Because only in this way can the matched write control and write data be correctly sent to a certain Slave. Write feedback B The same goes for channels .
This involves AXI Master over there AW、W and B How the three channels work together .
for example AXI Master Need to be Slave0、Slave1 and Slave2 Write data . that Master You can give me shillings AWSEL by 0 And Slave0 After the write interaction is completed , Re order AWSEL by 1 And Slave1 Write interaction .
Of course AXI Master You can also order separately AWSEL by 0、1、2 take AW The channels are distributed to Slave0、Slave1、Slave2, Re order AWSEL by 0、1、2 take W The channels are distributed to Slave0、Slave1、Slave2, At last, I will make AWSEL by 0、1、2 Will wait for each Slave Of B Channel feedback
Empathy , Read control AR The channel depends on ARSEL, Read feedback R Channels also depend on ARSEL.
1.1. Code
The code is as follows
module decoder#(
parameter RID_WIDTH = 8,
parameter RDATA_WIDTH = 16,
parameter BID_WIDTH = 8
)(
input arstn,
input aclk,
//AW CHANNEL
input [1:0] awsel,
input awvalid,
output awready,
output [3:0] awvalid_slv,
input [3:0] awready_slv,
//W CHANNEL
input wvalid,
output wready,
output [3:0] wvalid_slv,
input [3:0] wready_slv,
//AR CHANNEL
input [1:0] arsel,
input arvalid,
output arready,
output [3:0] arvalid_slv,
input [3:0] arready_slv,
//R CHANNEL
output [RID_WIDTH-1:0] rid,
output [RDATA_WIDTH-1:0] rdata,
output [1:0] rresp,
output rlast,
output rvalid,
input rready,
input [RID_WIDTH*4-1:0] rid_slv,
input [RDATA_WIDTH*4-1:0] rdata_slv,
input [2*4-1:0] rresp_slv,
input [1*4-1:0] rlast_slv,
input [3:0] rvalid_slv,
output [3:0] rready_slv,
//B CHANNEL
output [BID_WIDTH-1:0] bid,
output [1:0] bresp,
output bvalid,
input bready,
input [BID_WIDTH*4-1:0] bid_slv,
input [2*4-1:0] bresp_slv,
input [3:0] bvalid_slv,
output [3:0] bready_slv
);
reg awready_r;
reg wready_r;
reg arready_r;
reg [RID_WIDTH-1:0] rid_r;
reg [RDATA_WIDTH-1:0] rdata_r;
reg [1:0] rresp_r;
reg rlast_r;
reg rvalid_r;
reg [BID_WIDTH-1:0] bid_r;
reg [1:0] bresp_r;
reg bvalid_r;
//AW CHANNEL
[email protected](*) begin
case(awsel)
2'b00:
awready_r = awready_slv[0];
2'b01:
awready_r = awready_slv[1];
2'b10:
awready_r = awready_slv[2];
2'b11:
awready_r = awready_slv[3];
default:
awready_r = 1'b0;
endcase
end
assign awready = awready_r;
assign awvalid_slv = awvalid << awsel;
//W CHANNEL
[email protected](*) begin
case(awsel)
2'b00:
wready_r = wready_slv[0];
2'b01:
wready_r = wready_slv[1];
2'b10:
wready_r = wready_slv[2];
2'b11:
wready_r = wready_slv[3];
default:
wready_r = 1'b0;
endcase
end
assign wready = wready_r;
assign wvalid_slv = wvalid << awsel;
//AR CHANNEL
[email protected](*) begin
case(arsel)
2'b00:
arready_r = arready_slv[0];
2'b01:
arready_r = arready_slv[1];
2'b10:
arready_r = arready_slv[2];
2'b11:
arready_r = arready_slv[3];
default:
arready_r = 1'b0;
endcase
end
assign arready = arready_r;
assign arvalid_slv = arvalid << arsel;
//R CHANNEL
[email protected](*) begin
case(arsel)
2'b00:
rid_r = rid_slv[RID_WIDTH-1:0];
2'b01:
rid_r = rid_slv[RID_WIDTH*2-1:RID_WIDTH];
2'b10:
rid_r = rid_slv[RID_WIDTH*3-1:RID_WIDTH*2];
2'b11:
rid_r = rid_slv[RID_WIDTH*4-1:RID_WIDTH*3];
default:
rid_r = 'd0;
endcase
end
assign rid = rid_r;
[email protected](*) begin
case(arsel)
2'b00:
rdata_r = rdata_slv[RDATA_WIDTH-1:0];
2'b01:
rdata_r = rdata_slv[RDATA_WIDTH*2-1:RDATA_WIDTH];
2'b10:
rdata_r = rdata_slv[RDATA_WIDTH*3-1:RDATA_WIDTH*2];
2'b11:
rdata_r = rdata_slv[RDATA_WIDTH*4-1:RDATA_WIDTH*3];
default:
rdata_r = 'd0;
endcase
end
assign rdata = rdata_r;
[email protected](*) begin
case(arsel)
2'b00:
rresp_r = rresp_slv[1:0];
2'b01:
rresp_r = rresp_slv[3:2];
2'b10:
rresp_r = rresp_slv[5:4];
2'b11:
rresp_r = rresp_slv[7:6];
default:
rresp_r = 'd0;
endcase
end
assign rresp = rresp_r;
[email protected](*) begin
case(arsel)
2'b00:
rlast_r = rlast_slv[0];
2'b01:
rlast_r = rlast_slv[1];
2'b10:
rlast_r = rlast_slv[2];
2'b11:
rlast_r = rlast_slv[3];
default:
rlast_r = 'd0;
endcase
end
assign rlast = rlast_r;
[email protected](*) begin
case(arsel)
2'b00:
rvalid_r = rvalid_slv[0];
2'b01:
rvalid_r = rvalid_slv[1];
2'b10:
rvalid_r = rvalid_slv[2];
2'b11:
rvalid_r = rvalid_slv[3];
default:
rvalid_r = 'd0;
endcase
end
assign rvalid = rvalid_r;
assign rready_slv = rready << arsel;
//B CHANNEL
[email protected](*) begin
case(awsel)
2'b00:
bid_r = bid_slv[BID_WIDTH-1:0];
2'b01:
bid_r = bid_slv[BID_WIDTH*2-1:BID_WIDTH];
2'b10:
bid_r = bid_slv[BID_WIDTH*3-1:BID_WIDTH*2];
2'b11:
bid_r = bid_slv[BID_WIDTH*4-1:BID_WIDTH*3];
default:
bid_r = 'd0;
endcase
end
assign bid = bid_r;
[email protected](*) begin
case(awsel)
2'b00:
bresp_r = bresp_slv[1:0];
2'b01:
bresp_r = bresp_slv[3:2];
2'b10:
bresp_r = bresp_slv[5:4];
2'b11:
bresp_r = bresp_slv[7:6];
default:
bresp_r = 'd0;
endcase
end
assign bresp = bresp_r;
[email protected](*) begin
case(awsel)
2'b00:
bvalid_r = bvalid_slv[0];
2'b01:
bvalid_r = bvalid_slv[1];
2'b10:
bvalid_r = bvalid_slv[2];
2'b11:
bvalid_r = bvalid_slv[3];
default:
bvalid_r = 'd0;
endcase
end
assign bvalid = bvalid_r;
assign bready_slv = bready << awsel;
endmodule
2. axi_round_robin_arbiter
Here we implement the arbiter based on the polling policy
Classic polling arbitration IP Input only req、 The output is only grant, But for the AXI for , Is divided into 5 Channels interact with each other . So and decoder similar ,5 Each channel considers polling arbitration .
however AXI There is synergy between channels in the protocol , Use here AXI4, that AW The receiving order of the channel must be the same as W The order of channel data collection is consistent , This is because there is no wid so AXI Slave I don't know from W The tunnel FIFO Where did the data read out in come from . So for AXI Write in words , Need to put AW Channels and W The channels are combined into one module to consider .
for example AW Channel input awid The order is 0、1、2, that W The input data of the channel must also be 0、1、2.
and B The passage can follow AW、W Come apart , It has bid, And AW、W There is no absolute order of collection .
AR and R There is no absolute order , Separable design .
2.1. AW、W passageway polling
Based on the state machine , The idea is to receive a package AW Channel data , Record its len, And then according to len and awid Receive corresponding AXI Master Of W Channel data , Guarantee AW Channels and W The channel sequence is consistent .

How does the weight change ? What we are thinking about here is that every AW、W The channel completes one-time data collection , The weight changes once . Make sure AW Acceptance and W Reception must come from the same AXI Master
WAIT_AW
● State variable selection MAX_PRIO_BITx
Based on the classical polling arbitration algorithm , Select the state with the highest weight bit That's all right. .
● according to req Output grant
This is actually no problem ,req In fact, it's all about AXI Master Of awvalid Composed of many bit data , and grant Is the result of arbitration .
● State transition conditions : The handshake is complete
The state transition condition of the original algorithm is req When something changes, it shifts , stay AXI In this environment, it becomes these Master Of awvalid When a change occurs, the state changes , This is the river ?
First , Such a setting can run through . But personally, I don't think it's very good , Because shaking hands doesn't mean awvalid Once the gate is cleared, it is finished , It also needs to be awready Handshake only when the signal is high , So my idea is Complete a handshake transfer state , Here's the picture

although req Changes have taken place in the middle , But the condition of state transition is the same as Master0 The condition is not transferred until the handshake is completed .
Be careful AW A channel is simply a one-time transmission of multiple control messages , No burst,awready&awvalid One effective clap can complete the handshake .
module axi_round_robin_arbiter_aw #(
parameter AWID_WIDTH = 8,
parameter AWADDR_WIDTH = 16,
parameter MAX_PRIO_INITIAL_INDEX = 0
)(
input aclk,
input arstn,
input [AWID_WIDTH*4-1:0] awid_mst,
input [AWADDR_WIDTH*4-1:0] awaddr_mst,
input [8*4-1:0] awlen_mst,
input [3*4-1:0] awsize_mst,
input [2*4-1:0] awburst_mst,
input [1*4-1:0] awvalid_mst,
output [1*4-1:0] awready_mst,
output [AWID_WIDTH-1:0] awid,
output [AWADDR_WIDTH-1:0] awaddr,
output [8-1:0] awlen,
output [3-1:0] awsize,
output [2-1:0] awburst,
output awvalid,
input awready,
);
reg [AWID_WIDTH-1:0] awid_r;
reg [AWADDR_WIDTH-1:0] awaddr_r;
reg [8-1:0] awlen_r;
reg [3-1:0] awsize_r;
reg [2-1:0] awburst_r;
reg awvalid_r;
reg [1*4-1:0] awready_mst_r;
reg [4-1:0] cur_state;
reg [4-1:0] nxt_state;
wire [4-1:0] grant;
wire handshake_done;
wire [4-1:0] inital_state;
wire [4:0] res1;
wire [4:0] res2;
assign inital_state = {
{
(4-MAX_PRIO_INITIAL_INDEX-1){
1'b0}},1'b1,{
MAX_PRIO_INITIAL_INDEX{
1'b0}}};
assign handshake_done = (|awvalid_mst) && awready;
[email protected](posedge aclk or negedge arstn) begin
if(!arstn)
cur_state <= inital_state;
else
cur_state <= nxt_state;
end
[email protected](*) begin
if(!handshake_done)
nxt_state = cur_state;
else if(grant[3])
nxt_state = 'b1;
else
nxt_state = grant << 1;
end
assign res1 = {
1'b0,~awvalid_mst} + {
1'b0,cur_state};
assign res2 = res1[4] + res1;
assign grant = awvalid_mst & res2;
//-----------------chip select--------------------------
[email protected](*) begin
case(grant)
4'b0001:
awid_r = awid_mst[AWID_WIDTH-1:0];
4'b0010:
awid_r = awid_mst[AWID_WIDTH*2-1:AWID_WIDTH];
4'b0100:
awid_r = awid_mst[AWID_WIDTH*3-1:AWID_WIDTH*2];
4'b1000:
awid_r = awid_mst[AWID_WIDTH*4-1:AWID_WIDTH*3];
default:
awid_r = 'd0;
endcase
end
assign awid = awid_r;
[email protected](*) begin
case(grant)
4'b0001:
awaddr_r = awaddr_mst[AWADDR_WIDTH-1:0];
4'b0010:
awaddr_r = awaddr_mst[AWADDR_WIDTH*2-1:AWADDR_WIDTH];
4'b0100:
awaddr_r = awaddr_mst[AWADDR_WIDTH*3-1:AWADDR_WIDTH*2];
4'b1000:
awaddr_r = awaddr_mst[AWADDR_WIDTH*4-1:AWADDR_WIDTH*3];
default:
awaddr_r = 'd0;
endcase
end
assign awaddr = awaddr_r;
[email protected](*) begin
case(grant)
4'b0001:
awlen_r = awlen_mst[8-1:0];
4'b0010:
awlen_r = awlen_mst[8*2-1:8];
4'b0100:
awlen_r = awlen_mst[8*3-1:8*2];
4'b1000:
awlen_r = awlen_mst[8*4-1:8*3];
default:
awlen_r = 'd0;
endcase
end
assign awlen = awlen_r;
[email protected](*) begin
case(grant)
4'b0001:
awsize_r = awsize_mst[3-1:0];
4'b0010:
awsize_r = awsize_mst[3*2-1:3];
4'b0100:
awsize_r = awsize_mst[3*3-1:3*2];
4'b1000:
awsize_r = awsize_mst[3*4-1:3*3];
default:
awsize_r = 'd0;
endcase
end
assign awsize = awsize_r;
[email protected](*) begin
case(grant)
4'b0001:
awburst_r = awburst_mst[2-1:0];
4'b0010:
awburst_r = awburst_mst[2*2-1:2];
4'b0100:
awburst_r = awburst_mst[2*3-1:2*2];
4'b1000:
awburst_r = awburst_mst[2*4-1:2*3];
default:
awburst_r = 'd0;
endcase
end
assign awburst = awburst_r;
[email protected](*) begin
case(grant)
4'b0001:
awvalid_r = awvalid_mst[1-1:0];
4'b0010:
awvalid_r = awvalid_mst[1*2-1:1];
4'b0100:
awvalid_r = awvalid_mst[1*3-1:1*2];
4'b1000:
awvalid_r = awvalid_mst[1*4-1:1*3];
default:
awvalid_r = 'd0;
endcase
end
assign awvalid = awvalid_r;
[email protected](*) begin
case(grant)
4'b0001:
awready_mst_r = awready << 1;
4'b0010:
awready_mst_r = awready << 2;
4'b0100:
awready_mst_r = awready << 3;
4'b1000:
awready_mst_r = awready << 4;
default:
awready_mst_r = 'd0;
endcase
end
assign awready_mst = awready_mst_r;
endmodule
WAIT_W
2.2. AR passageway
2.3. B passageway arbiter
2.4. R passageway arbiter
边栏推荐
- 什么是GCaMP6f?钙离子成像技术。
- 全局负载均衡实现原理
- Quartus II 18.0软件安装包和安装教程
- Alibaba cloud ack one and ACK cloud native AI suite have been newly released to meet the needs of the end of the computing era
- Kubernetes-23: explain how to make CPU manager more flexible
- Decision tree learning notes
- The final scheme of adding traceid at the C end
- LN2220 2A过流5V1A高效率升压IC芯片 DC/DC 电压调整器
- Adum1401arwz-rl adenault digital signal isolation module
- What are the applications of 4.3-inch touch screen intelligent network central control host
猜你喜欢

Harbor high availability cluster design and deployment (practice + video), based on offline installation

【CTF】攻防世界 MISC

Jingdong 39 year old "graduate" found a new job within a week after being laid off, with a salary increase of 20%!

延长 洁鲜生密实袋,给食材上一把“安全锁”

String类型转换成List<Integer>

Check information on the Internet after the college entrance examination, and pay attention to prevent websites without SSL certificates

Quartus II 18.0软件安装包和安装教程

Show you how to distinguish several kinds of parallelism
![[parallel and distributed computing] 10B_ MapReduce GFS Implementation](/img/f9/3ce3c129d08f4e291f87217aae8fe2.png)
[parallel and distributed computing] 10B_ MapReduce GFS Implementation

Quartus II 18.0 software installation package and installation tutorial
随机推荐
行业首家!极氪APP获中国网络安全审查技术与认证中心权威认证
Unity analog flashlight light source detector, AI attack range detection area, object detection in visual cone, fan-shaped area detection, circular area detection, cone area detection
Henkel database custom operator '! ~~'
TX9118 同步升压IC
In May, I just came back from the Ali software testing post. I worked for Alibaba P7 at 3+1, with an annual salary of 28*15
QX2308高效 PFM 同步升压 DC/DC 变换器
Quartus II 18.0软件安装包和安装教程
Introduction to high performance intranet DNS system
volatile
LeeCode70 爬楼梯
TC3608H高效率 1.2MHz DC-DC 升压器 IC
The difference between break and continue
最详细整理STL之vector基础
C端添加Traceid的最终的方案
The Summer Challenge realizes a standard layout of Huawei app with openharmony ETS
【并行与分布式计算】10b_MapReduce GFS Implementation
#夏日挑战赛# 用OpenHarmony eTS 实现一个Huawei app标准布局
The second round of layoffs in a large factory is coming, and the routine is full
Pfsense configurer le tutoriel de tunnel de site à site Tinc
Harbor high availability cluster design and deployment (practice + video), based on offline installation