深入理解AMBA总线(八)AHB2APB同步桥设计

简介: 深入理解AMBA总线(八)AHB2APB同步桥设计

本篇文章给大家讲解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、转接桥代码讲解:

完整的代码链接

https://link.zhihu.com/?target=https%3A//github.com/ForrestBlue/cortexm0ds/blob/master/logical/cmsdk_ahb_to_apb/verilog/cmsdk_ahb_to_apb.v

接下来的讲解只会挑重点讲解:

首先是参数,这里指定位宽为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总线,完整的专栏在这里:

https://www.zhihu.com/column/c_1663245806869291008

目录
相关文章
|
存储 网络性能优化 vr&ar
深入理解AMBA总线(十七)AXI是如何提高性能的
深入理解AMBA总线(十七)AXI是如何提高性能的
1983 1
|
芯片
深入理解AMBA总线(一)APB总线入门(上)
深入理解AMBA总线(一)APB总线入门
1068 0
|
安全 物联网 数据安全/隐私保护
深入理解AMBA总线协议(AXI总结篇)
深入理解AMBA总线协议(AXI总结篇)
1536 1
|
存储 安全
深入理解AMBA总线(四)AHB-lite总线
深入理解AMBA总线(四)AHB-lite总线
1105 0
|
SoC
深入理解AMBA总线(七)AHB设计要点和AHB2APB同步桥设计前言
深入理解AMBA总线(七)AHB设计要点和AHB2APB同步桥设计前言
490 0
深入理解AMBA总线(七)AHB设计要点和AHB2APB同步桥设计前言
|
SoC
深入理解AMBA总线(十六)AXI设计的关键问题(二)
深入理解AMBA总线(十六)AXI设计的关键问题(二)
819 0
深入理解AMBA总线(十六)AXI设计的关键问题(二)
深入理解AMBA总线(一)APB总线入门(下)
深入理解AMBA总线(一)APB总线入门(下)
892 0
|
vr&ar 内存技术
深入理解AMBA总线(十八)一个简单的AXI2SRAM设计
深入理解AMBA总线(十八)一个简单的AXI2SRAM设计
595 0
|
异构计算 SoC 内存技术
深入理解AMBA总线(九)AHB2SRAM设计
深入理解AMBA总线(九)AHB2SRAM设计
766 0