本篇文章给大家讲解AHB2APB同步桥(或者叫转接桥)的设计。转接桥在SoC设计中属于比较重要的一环,因为SoC通常使用多种不同的总线协议,这些不同的总线协议之间想要完成通信,就需要转接桥的帮助。
Bridge,顾名思义,桥梁,用于完成两者之间的通信。本篇文章的转接桥是AHB高性能总线到APB总线桥接器,主要完成以下的功能:
- Bridge是APB总线中唯一主机;
- APB的时钟和AHB的时钟是同步时钟;APB的时钟和AHB时钟的分频关系由PCLKEN信号决定;
- 该模块支持输入输出数据寄存或者不寄存,由模块参数控制;
- 该同步桥支持APB总线字节选通信号,保护控制信号;
- 该同步桥支持APB模块的使能信号;
- 该同步桥只支持一个APB从设备,所以只有一个PSEL;
1、转接桥接口、时序
其接口如下图所示,可以看到其完成了AHB协议到APB协议的转换,并且是单对单的,即连接一个AHB主设备、一个APB从设备。
接下来我们看一下设计思路:
首先是第一种情况,输入输出数据不寄存且不产生错误的情况下。这种情况下其实和之前讲的APB状态机基本是一样的。大家想想看,AHB的通信和APB实际上本来就是差不多的,不过AHB可以支持流水,APB不支持流水。此外AHB可以突发传输,APB不可以突发传输。对于突发上述模块直接没有相应接口,对于输入是流水的情况,实际上会反压前级,只能按照APB的方式进行传输。因此转接桥和APB协议的状态机一样,总共可以分为三个状态:
- IDLE:空闲状态;外设总线默认在此状态;
- ST_APB_TRNF:传输建立状态;在此状态,将PSEL置为1,并保持到ST_APB_TRANF2状态(即对应setup phase)
- ST_APB_TRNF2:传输状态;在此状态。传输完成时,需要将PENABLE置为1;
其状态机如下图所示:
其状态转换的条件如下所示:
- 路径1:当收到AHB的传输请求,apb_select为1,状态从IDLE跳到ST_APB_TRNF,其中apb_select代表着APB Bridge is selected。在状态跳转的这个周期,还需要采样控制信号,用代码注释的话来说,就是Capture transfer information at the end of AHB address phase
- 路径2:当在APB时钟的上升沿(PCLKEN有效的时候),将PENABLE置为1;(如果PCLK和HCLK时钟相同的话,则直接跳就行)。
- 路径3:完成一次传输后,如果紧跟着下一次传输,状态应该从ST_APB_TRNF2跳回ST_APB_TRNF。
- 路径4:如果完成一次传输后,如果后面没有传输,状态从ST_APB_TRNF2跳到ST_IDLE。
接下来我们考虑第二种情况,即输入输出数据需要寄存。同时也没有发生错误。(其实大部分情况下都是这种传输方式,因为APB那边很有可能不能够接收数据,因此就需要先将控制信号寄存好)这种情况下,需要增加两个状态,即输入数据需要寄存,输出数据也需要寄存,总共可以分为以下五种状态:
- IDLE:空闲状态;外设总线默认在此状态;
- ST_APB_WAIT:传输等待状态,等待输入数据寄存1拍;
- ST_APB_TRNF:传输建立状态,在此状态,将PSEL置为1,并且保持到ST_APB_TRNF2状态;
- ST_APB_TRNF2:传输状态;在此状态,传输完成的时候,将PENABLE置为1;
- ST_APB_ENDOK:传输结束状态;因为输出寄存1拍,所以传输完成最后1拍需要继续保持传输状态,给出传输信号。
其状态机如下所示:
最后我们考虑第三种情况,即传输错误的情况。因为这种情况下需要通知AHB主机那边,而AHB的错误响应本身就有两拍,因此这种情况下又需要两个状态,用来准备错误异常处理。这里直接贴图:
2、转接桥代码讲解:
完整的代码链接
接下来的讲解只会挑重点讲解:
首先是参数,这里指定位宽为16bit,对读数据进行缓存,不对写数据进行缓存。
module cmsdk_ahb_to_apb #( // Parameter to define address width // 16 = 2^16 = 64KB APB address space parameter ADDRWIDTH = 16, parameter REGISTER_RDATA = 1, parameter REGISTER_WDATA = 0)
接下来我们看一下状态机,这里和我们前面的讲解一致。
localparam [ST_BITS-1:0] ST_IDLE = 3'b000; // Idle waiting for transaction localparam [ST_BITS-1:0] ST_APB_WAIT = 3'b001; // Wait APB transfer localparam [ST_BITS-1:0] ST_APB_TRNF = 3'b010; // Start APB transfer localparam [ST_BITS-1:0] ST_APB_TRNF2 = 3'b011; // Second APB transfer cycle localparam [ST_BITS-1:0] ST_APB_ENDOK = 3'b100; // Ending cycle for OKAY localparam [ST_BITS-1:0] ST_APB_ERR1 = 3'b101; // First cycle for Error response localparam [ST_BITS-1:0] ST_APB_ERR2 = 3'b110; // Second cycle for Error response localparam [ST_BITS-1:0] ST_ILLEGAL = 3'b111; // Illegal state
然后我们看关键的控制信号:
reg_rdata_cfg和reg_wdata_cfg代表读数据或者写数据是否需要寄存;
apb_select代表APB bridge select信号,当HSEL拉高,代表AHB主机要发送数据了,HREADY为高代表没有Slave有未完成的传输,可以采样控制信号,而HTRANS[1]为高代表为NONSEQ或者SEQ传输。
在select信号有效的时候,代表要开始数据传输了,这个时候需要把控制信号给锁存下(注意锁存的都是控制信号,没有锁存wdata,这一拍对应addr cycle)。
// Configuration signal assign reg_rdata_cfg = (REGISTER_RDATA==0) ? 1'b0 : 1'b1; assign reg_wdata_cfg = (REGISTER_WDATA==0) ? 1'b0 : 1'b1; // Generate APB bridge select assign apb_select = HSEL & HTRANS[1] & HREADY; // Generate APB transfer ended assign apb_tran_end = (state_reg==3'b011) & PREADY; // Sample control signals always @(posedge HCLK or negedge HRESETn) begin if (~HRESETn) begin addr_reg <= {(ADDRWIDTH-2){1'b0}}; wr_reg <= 1'b0; pprot_reg <= {2{1'b0}}; pstrb_reg <= {4{1'b0}}; end else if (apb_select) // Capture transfer information at the end of AHB address phase begin addr_reg <= HADDR[ADDRWIDTH-1:2]; wr_reg <= HWRITE; pprot_reg <= pprot_nxt; pstrb_reg <= pstrb_nxt; end end
然后我们看一下输出信号是怎么赋值的,我们可以看到。PADDR、PWRITE、PPROT和PSTRB这些控制信号,都是寄存的数据。而PWDATA是直接来自于HWDATA(不使用写数据锁存的方式)。然后PSEL和PENABLE由当前状态决定。
// Connect outputs to top level assign PADDR = {addr_reg, 2'b00}; // from sample register assign PWRITE = wr_reg; // from sample register // From sample register or from HWDATA directly assign PWDATA = (reg_wdata_cfg) ? rwdata_reg : HWDATA; assign PSEL = (state_reg==ST_APB_TRNF) | (state_reg==ST_APB_TRNF2); assign PENABLE = (state_reg==ST_APB_TRNF2); assign PPROT = {pprot_reg[1], 1'b0, pprot_reg[0]}; assign PSTRB = pstrb_reg[3:0];
综上,就完成了AHB2APB转接桥的设计,实际上很简单。因为AHB和APB本身是很像的。这种状态机的转换方式相对效率较低,需要多个周期才能完成。但是可以有效反压,避免丢数据。大家可以仔细研究一下。
欢迎和我一起学习AMBA总线,完整的专栏在这里: