当前位置:网站首页>AHB2Standard_handshake_bridge 设计
AHB2Standard_handshake_bridge 设计
2022-06-11 19:27:00 【Starry丶】
1. 功能描述
AHB协议毕竟与FIFO、RAM等读写协议不一样,而AHB是SoC系统片内常用的高速接口,所以就需要将AHB的时序转化为标准的握手时序,此处研究AHB到标准握手的桥接器,实现接口转化。
例如下图

是的,AHB2HANDSHAKE桥是作为AHB slave呈现的,由此可以得出桥接器的输入输出
2. 参数描述
| Group | Signal | Direction | Width(bits) | Description |
|---|---|---|---|---|
| AHB slave | hrstn | input | 1 | 复位信号 |
| hclk | input | 1 | 时钟 | |
| haddr | input | HADDR_WIDTH | 用于访问内部寄存器的地址 | |
| hburst | input | 3 | burst传输格式 | |
| hsize | input | 3 | 数据传输有效位 | |
| htrans | input | 2 | 传输状态 | |
| hwrite | input | 1 | 1表示写,0表示读 | |
| hsel | input | 1 | 选通 | |
| hwdata | input | HDATA_WIDTH | 写数据 | |
| hrdata | output | HDATA_WIDTH | 读出的数据 | |
| hreadyout | output | 1 | 准备标志 | |
| hresp | output | 1 | 反馈当前传输是否存在错误 | |
| Standard Handshake | waddr | output | HADDR_WIDTH | 写地址 |
| wdata | output | HDATA_WIDTH | 写数据 | |
| wr_en | output | 1 | 写使能 | |
| wready | input | 1 | 写准备 | |
| raddr | output | HADDR_WIDTH | 读地址 | |
| rdata | input | HDATA_WIDTH | 读数据 | |
| rdata_val | input | 1 | 读数据有效 | |
| rd_en | output | 1 | 读使能 | |
| rready | input | 1 | 读准备 |
之后是参数描述
| Parameter | Units | Description |
|---|---|---|
| HADDR_WIDTH | bit | 地址位宽 |
| HDATA_WIDTH | bit | 写入or读出的数据位宽 |
| ACCESS_ADDR1、ACCESS_ADDR2、ACCESS_ADDR3、ACCESS_ADDR4 | bit | 可访问地址 |
3. 逻辑设计

从上图可以看出,AHB2HANDSHAKE模块是作为AHB slave出现的,所以要从AHB Slave角度进行设计。
依然是按照状态机的思路。如果是状态机的思路,AHB协议中HTRANS有四种状态、HBURST有八种状态,我们使用哪一个呢?还是自己写状态机?
可选择思路是基于HTRANS的IDLE、BUSY、NONSEQ和SEQ四种状态进行设计,毕竟burst传输属于NONSEQ或SEQ状态。
3.1. HTRANS没法用
哈哈哈我根据HTRANS的四种状态设计了半天发现作为AHB slave压根就没法用状态机。
先看看下面这几张波形图,从AHB Slave的角度思考一下


上图中揭示了AHB比较膈应的地方,就是一次访问地址和数据是分两拍进行的,当然这也是实现流水的基础。这就导致了第二拍传数据的时候,地址可以发生变化。
所以如果对一个地址的访问需要两拍,注意这两拍中address phase与data phase可不在同一个HTRANS,data phase甚至会跨越多个HTRANS状态。
换句话说就是,HTRANS这个状态机不能决定hwdata和hrdata信号的变化规律。
这个与平时的状态机设计不同,平时设计的思路是整个模块被分成好几个状态,该模块的每个信号会根据不同状态变化规律不一。
但是AHB协议中HADDR会根据HTRANS的取值来决定是否有效,而HWDATA和HRDATA的变化并不会参照HTRANS这个状态。
但是作为AHB Slave不必关心有没有跨HTRANS、HTRANS某个状态是否要延迟,这个是AHB Master要做的事情。作为slave,只需要将数据正确写入或正确读出即可
那么如何对AHB到标准握手时序桥进行设计呢?还是状态机,不过我们采用最原始的状态机:读和写

3.2. IDLE
该状态下当然是啥都不干啦,当检测到AHB master要进行传输时,即htrans为NONSEQ时,检测hwrite判断转入WRITE还是READ,如下图

于是状态机重写为

3.3. 写
该状态下实现写,当标准握手时序下写完成该状态结束。
注意是标准握手时序,所以需要将地址和数据在时序上对齐。
怎么实现呢?时序图在IDLE已经展现了,如下图带反压的WRITE

即便是burst写也可以

而WRITE下一个状态,则根据WRITE结束的那一拍htrans的值,状态机如下

关于那个BUSY作一下说明。AHB master在进入BUSY时会给出下一个传输的控制信号,但是在下一次传输真正来临时控制信号还会保持不变,所以在AHB slave检测到
wr_en && hready && (htrans == BUSY)时依旧可以转换为IDLE状态
3.4. 读
该状态下实现读,当确定读出数据了该状态结束。
同样要求rd_en与rdata时序对齐,如果与写类似,将haddr打拍成raddr,那么在data phase第一拍必然不会读出数据,最快也要第二拍。
也就是说,必然会反压一拍,如下图带延迟的情况。

由此状态机更新为

3.5. 代码
module ahb2standard_handshake_bridge#(
parameter HADDR_WIDTH = 32,
parameter HDATA_WIDTH = 32
parameter ACCESS_ADDR1 = 32'h0000_0000_0000_0010,
parameter ACCESS_ADDR2 = 32'h0000_0000_0000_0014,
parameter ACCESS_ADDR3 = 32'h0000_0000_0000_0018,
parameter ACCESS_ADDR4 = 32'h0000_0000_0000_001C
)(
input hrstn,
input hclk,
input [HADDR_WIDTH-1:0] haddr,
input [2:0] hburst,
input [2:0] hsize,
input [1:0] htrans,
input hwrite,
input hsel,
input [HDATA_WIDTH-1:0] hwdata,
output [HDATA_WIDTH-1:0] hrdata,
output hready,
output hresp,
output [HADDR_WIDTH-1:0] waddr,
output [HDATA_WIDTH-1:0] wdata,
output wr_en,
input wready,
output [HADDR_WIDTH-1:0] raddr,
input [HDATA_WIDTH-1:0] rdata,
input rdata_val,
output rd_en,
input rready
);
localparam IDLE = 2'b00;
localparam WRITE = 2'b01;
localparam READ = 2'b11;
reg [1:0] cur_state;
reg [1:0] nxt_state;
reg [HADDR_WIDTH-1:0] waddr_r;
reg [HADDR_WIDTH-1:0] raddr_r;
reg hready_r;
reg wr_en_r;
reg rd_en_r;
reg hresp_r;
[email protected](posedge hclk or negedge hrstn) begin
if(!hrstn)
cur_state <= IDLE;
else
cur_state <= nxt_state;
end
[email protected](*) begin
case(cur_state)
IDLE:
if(htrans[1]) begin
if(hwrite)
nxt_state = WRITE;
else
nxt_state = READ;
end
else
nxt_state = IDLE;
WRITE:
if(wr_en && hready) begin
if(!htrans[1])
nxt_state = IDLE;
else if(!hwrite)
nxt_state = READ;
else
nxt_state = WRITE;
end
else
nxt_state = WRITE;
READ:
if(rdata_val) begin
if(!htrans[1])
nxt_state = IDLE;
else if(hwrite)
nxt_state = WRITE;
else
nxt_state = READ;
end
else
nxt_state = READ;
default:
nxt_state = IDLE;
endcase
end
assign wdata = hwdata[(8 << hsize)-1:0];
[email protected](*) begin
case(cur_state)
IDLE:
hready_r = 1'b0;
WRITE:
hready_r = wready;
READ:
hready_r = rdata_val;
default:
hready_r = 1'b0;
endcase
end
assign hready = hready_r;
[email protected](posedge hclk or negedge hrstn) begin
if(!hrstn)
waddr_r <= 'd0;
else if(cur_state == IDLE) begin
if(htrans[1] && hwrite)
waddr_r <= haddr;
end
else if(cur_state == WRITE) begin
if(wr_en && hready && htrans[1] && hwrite)
waddr_r <= haddr;
end
else if(cur_state == READ) begin
if(rdata_val && htrans[1] && hwrite)
waddr_r <= haddr;
end
end
assign waddr = waddr_r;
[email protected](posedge hclk or negedge hrstn) begin
if(!hrstn)
wr_en_r <= 1'b0;
else if(cur_state == IDLE) begin
if(htrans[1] && hwrite)
wr_en_r <= 1'b1;
end
else if(cur_state == WRITE) begin
if(!hready)
wr_en_r <= wr_en_r;
else if(htrans[1]) begin
if(hwrite)
wr_en_r <= 1'b1;
else
wr_en_r <= 1'b0;
end
else
wr_en_r <= 1'b0;
end
else if(cur_state == READ) begin
if(rdata_val && htrans[1] && hwrite)
wr_en_r <= 1'b1;
end
end
assign wr_en = wr_en_r;
assign hrdata = rdata[(8 << hsize)-1:0];
[email protected](posedge hclk or negedge hrstn) begin
if(!hrstn)
raddr_r <= 'd0;
else if(cur_state == IDLE) begin
if(htrans[1] && !hwrite)
raddr_r <= haddr;
end
else if(cur_state == WRITE) begin
if(wr_en && hready && htrans[1] && !hwrite)
raddr_r <= haddr;
end
else if(cur_state == READ) begin
if(rdata_val && htrans[1] && !hwrite)
raddr_r <= haddr;
end
end
assign raddr = raddr_r;
[email protected](posedge hclk or negedge hrstn) begin
if(!hrstn)
rd_en_r <= 1'b0;
else if(cur_state == IDLE) begin
if(htrans[1] && !hwrite)
rd_en_r <= 1'b1;
end
else if(cur_state == WRITE) begin
if(wr_en && hready && htrans[1] && !hwrite)
rd_en_r <= 1'b1;
end
else if(cur_state == READ) begin
if(!rready)
rd_en_r <= rd_en_r;
else if(!rdata_val)
rd_en_r <= 1'b0;
else if(htrans[1]) begin
if(hwrite)
rd_en_r <= 1'b0;
else
rd_en_r <= 1'b1;
end
else
rd_en_r <= 1'b0;
end
else
rd_en_r <= 1'b0;
end
assign rd_en = rd_en_r;
[email protected](*) begin
if(cur_state == WRITE && wr_en && hready) begin
if(waddr != ACCESS_ADDR1
&& waddr != ACCESS_ADDR2
&& waddr != ACCESS_ADDR3
&& waddr != ACCESS_ADDR4)
hresp_r = 1'b1;
end
else if(cur_state == READ && rdata_val) begin
if(raddr != ACCESS_ADDR1
&& raddr != ACCESS_ADDR2
&& raddr != ACCESS_ADDR3
&& raddr != ACCESS_ADDR4)
hresp_r = 1'b1;
end
else
hresp_r = 1'b0;
end
assign hresp = hresp_r;
endmodule
边栏推荐
- pstack和dmesg
- Picture bed: picgo+ Tencent cloud +typera
- 【 aide 】 comment puis - je faire en sorte que les messages sélectionnés ci - dessous puissent être affichés après l'ouverture de l'article Wechat public number dans un navigateur externe?
- Key contents that wwdc22 developers need to pay attention to
- Detailed explanation of iSCSI (IV) -- actual configuration of iSCSI server
- LDPC 7 - simple example of decoding
- Use canvas to add text watermark to the page
- 构建Web应用程序
- The Economist: WTO MC12 restarts the digital economy and becomes the core engine of global economic recovery and growth
- Software requirements engineering review
猜你喜欢

postman配置中文
![[signal denoising] speech adaptive denoising based on nonlinear filter with matlab code](/img/fd/07cee3c51ac44ca40f730dd487aa20.png)
[signal denoising] speech adaptive denoising based on nonlinear filter with matlab code

The Economist: WTO MC12 restarts the digital economy and becomes the core engine of global economic recovery and growth

Introduction to go language (VI) -- loop statement

Gmail: how do I recall an outgoing message?

Detailed explanation of iSCSI (IV) -- actual configuration of iSCSI server

Programmers have changed dramatically in 10 years. Everything has changed, but it seems that nothing has changed

Activate function formulas, derivatives, image notes

Raki's notes on reading paper: learning fast, learning slow: a general continuous learning method

疫情下远程办公沟通心得|社区征文
随机推荐
Hyper parameter optimization of deep neural networks using Bayesian Optimization
An adaptive chat site - anonymous online chat room PHP source code
疫情下远程办公沟通心得|社区征文
The Economist: WTO MC12 restarts the digital economy and becomes the core engine of global economic recovery and growth
Gmail: how do I recall an outgoing message?
Neural network and deep learning-2-simple example of machine learning pytorch
Hospital intelligent infusion management system source code hospital source code
On Workflow selection
Operator new and placement new
What started mongodb? What are the application scenarios?
leetcode:66. add one-tenth
PIL pilot image processing [1] - installation and creation
Use canvas to add text watermark to the page
更换目标检测的backbone(以Faster RCNN为例)
SLAM APP
High concurrency architecture design
556. 下一个更大元素 III-(31. 下一个排列)-两次遍历
ASEMI的MOS管25N120在不同应用场景的表现
On the translation of rich text storage database format
Performance of MOS transistor 25n120 of asemi in different application scenarios