当前位置:网站首页>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
边栏推荐
- Visualization of operation and maintenance monitoring data - let the data speak [Huahui data]
- M3608升压ic芯片High Efficiency 2.6A Boost DC/DC Convertor
- Decision tree learning notes
- 文件编译过程
- AB打包有的Shader没有触发IPreprocessShaders的回调
- EasyCVR智能边缘网关硬件如何设置通电自启动?
- UIButton实现左文字右图片
- Redis HyperLogLog 是什么?这些场景使用让我枪出如龙一笑破苍穹
- SQL教程之6种鲜为人知的 SQL 技术,可帮助您每月节省 100 小时
- 用户态热补丁原理与应用
猜你喜欢

同步升压 DC/DC 转换器FS3400同步SOT23-6小电流500MA升压ic

FANUC机器人进行全部备份和镜像备份以及加载备份文件的具体操作(图文)

Adum1401arwz-rl adenault digital signal isolation module

Fanuc robot carries out all backup, image backup and specific operations of loading backup files (picture and text)

File compilation process

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

用户态热补丁原理与应用

History of the Great Game

数据路:三人行,必有我师!

Post Gartner webinar "nine questions on digital transformation"
随机推荐
Server body 17: simple understanding of memory mapping and shared memory
pfSense配置TINC站點至站點隧道教程
SQL 面试题:2022 年最热门的 15 个问题
互联网协议入门详解--五层模型
Book list given by Wu Jun to college students
Random forest learning notes
EasyCVR智能边缘网关硬件如何设置通电自启动?
MySQl学习(从入门到精通 1.2)
Idea has this class but can't find it
How does the easycvr intelligent edge gateway hardware set power on self start?
What noteworthy technologies of gold: the importance of fund management
[专利与论文-19]:江苏省南京市2022年电子信息申报通知(中、高级)
C端添加Traceid的最终的方案
#夏日挑战赛# 用OpenHarmony eTS 实现一个Huawei app标准布局
什么是GCaMP6f?钙离子成像技术。
History of the Great Game
起飞,年薪40万+
【CTF】攻防世界 MISC
It is said that the price of the iPhone 14 will rise; TikTok US user data is transferred to Oracle, and bytes cannot be accessed; Seatunnel 2.1.2 releases geek headlines
Intersection du vecteur et du plan