APB模块设计及仿真

第一章:APB协议相关概念

1.1APB总线介绍

1APB基本介绍

APB协议,Advanced Peripheral Bus,高级外设总线。属于AMBA家族协议其中之一,AMBA(Advanced Microcontroller Bus Architecture)高级微控总线架构是由ARM公司制定的高性能片上总线协议集。AMBA包括AXI,AHB,APB三大总线。ACE(4.0) CHI(5.0),ASB被AHB淘汰。

  • APB接口用在低带宽和不需要高性能总线的外围设备上。
    总线:在一条通路上接多个模块,各个模块之间的传数接收都通过一条线传数,总线类似与一条高速公路;不过同一时间只允许一台主机和从机进行通讯。允许多条数据传数的方法:Bus matrix(总线矩阵) 和crossbar(交叉拓扑)。
    APB在AMBA总线系统中的位置
    在这里插入图片描述
    在这里插入图片描述
    UART和另一个芯片/模块进行TX/RX数据交换,SPI外接FLASH。这些模块都是挂在芯片外围,所以APB是高级外设总线。
    AHB:High-performance ARM processor(cortex m0,1,3,4)高性能处理器;高带宽存储器;
    AHB2APB Bridge:信号转接桥
    AXI2AHB Bridge。协议不同却要进行传数,都需要转换桥。
    Master:主机。数据传输中的发起者
    Slave:从机。数据传输中的接收者。
    APB Master:只有一个Master ---- Bridge桥。其余挂在APB接口上的都是他的从机(slave)。单Master多Slave系统。通过psel选择某个从机。

2APB协议实现多Slave互联架构

在这里插入图片描述
桥为Master,发送信号到多个Slave从机,所有从机都会收到数据信号。Decoder片选译码器,Master发出的地址信号先发到地址译码器。
Master读取Slave发送的数据,通过mux选择信号(也由Decoder产生)

1.2APB BUS接口信号(AMBA3 APB)

在这里插入图片描述
apb_write:1write 0read
apb_ready:Master发数时要先握手(acknowledge),确保APB总线可以传数。
其中,只有apb_rdata和apb_ready是从机slave到主机master的信号;其余都是主机到从机的信号。如果ready拉低,读写的数据都无效,如果从机发数到主机来不及,拉低ready,称为反压;

1.3APB接口时序

时钟从高电平到低电平,灰色部分表示亚稳态,瞬态,high imdedance高阻态,多比特中数据未对齐。
在这里插入图片描述

APB状态机

在这里插入图片描述
Master发出APB信号时,由状态机控制;有三个状态。IDLE——SETUP——ENABLE,初始化后有建立和保持两个状态,传数不是一个周期就能完成的。
做APB接口时,要分开Master和Slave接口。
在这里插入图片描述
APB两种操作:读/写。
写分为有等待和无等待两种操作;

  • 无等待写操作:主机发数时候需不需要等待从机接收。由pready确定
    slave在T2时刻,就能采样到地址信号PADDR,写信号PWRITE,片选信号PSEL,写数据内容PWDATA。此时由pready告诉主机是否要等待,不等待,则拉高pready,直接写数据;同时拉高penable,这信号不用看pready的值,在数据信号发出的下个周期拉高penable。发送完数据,拉低penable,状态机进入IDLE状态。paddr和pwrite和pwdata信号不用刻意拉低,以降低信号反转频率,信号反转率越高,电路功耗就越大。

  • APB无等待读操作,T1时刻后,发送PADDR,PWRITE,PSEL,PRDATA,T2时刻,Slave采集到Pready有效,把要读的数据放到PRDATA。T3时刻,Master采样到Pready高信号,此时data1读数有效。
    在这里插入图片描述

  • 有等待写操作(带反压)
    在这里插入图片描述

等待到T5时刻,采样到PREADY信号拉高,完成写数。Slave延长了两个周期。

  • APB有等待读操作
    在这里插入图片描述

第二章 APB2UART模块设计代码实现及仿真

UART是APB的slave接口。
在这里插入图片描述
SBUF_REG用于接收和发数。即作为TX的寄存器,也用于RX的寄存器。作为半双工接口。

在这里插入图片描述

UART是个低速模块,收发都是比较慢的。
在这里插入图片描述

module apb_uart(
    //apb interface
    input                  pclk    ,
    input                  prst_n  ,
    input                  psel    ,
    input                  penable ,
    input                  pwrite  ,
    input            [  31: 0]paddr,
    input            [  31: 0]pwdata,
    output reg       [  31: 0]prdata,
    output                 pready  ,
    //uart interface
    input                  rx      ,
    output                 tx       
);
    reg                    start_reg  ;
    reg              [  15: 0]sbuf_reg  ;
    reg                    uint_reg  ;

    wire                   apb_wr  ;
    wire                   apb_rd  ;
    reg              [  15: 0]cmd_in  ;
    reg                    cmd_vld  ;
    reg                    txrx_flag  ;
    wire             [  15: 0]read_data  ;
    wire                   read_vld  ;
    parameter                START_REG_ADDR= 32'H0 ; //only write
    parameter                SBUF_REG_ADDR= 32'H4 ; // wirte/read
    parameter                UINT_REG_ADDR= 32'H8 ; //only read
    //apb write/read enable //
    assign                   apb_wr = psel & penable & pwrite;
    assign                   apb_rd = psel & penable & !pwrite;

    //register//
        always @(posedge pclk or negedge prst_n)
            begin
                if(!prst_n)
                    start_reg <= 0;
                else if(apb_wr && (paddr == START_REG_ADDR))
                    start_reg <= 1'b1;                              //pwdata=32'b1;                                     
                else
                    start_reg <= 0;
            end
    always @(posedge pclk or negedge prst_n)
        begin
            if(!prst_n)
                sbuf_reg <= 16'b0;
            else if(apb_wr && (paddr == SBUF_REG_ADDR))
                sbuf_reg <= pwdata[15:0];                           //tx data                              
            else if (read_vld) begin
                sbuf_reg <= {8'b0,read_data}                        //rx data
            end
        end

    // cmd interface
    always @(posedge pclk or negedge prst_n)
        begin
            if(!prst_n)
                begin
                    cmd_in <= 16'b0;
                    cmd_vld <= 0;
                end
            else if(start_reg == 1)
                begin
                    cmd_in <= sbuf_reg;
                    cmd_vld <= 1;
                end

        end
    //interrupt register //
    always @(posedge pclk or negedge prst_n)
        begin
            if(!prst_n)  begin
                uint_reg <= 0;
            end
                                                     
            else if(cmd_vld)
                uint_reg <= 0;
                                                 
            else if (cmd_rdy & txrx_flag) begin
                uint_reg <= 1;
            end
            else if(apb_rd && (paddr == UINT_REG_ADDR))
                uint_reg <= 0;
        end

    always @(posedge pclk or negedge prst_n)
        begin
            if(!prst_n)
                txrx_flag <= 0;
            else if(cmd_rdy)
                txrx_flag <=1;
            else if (cmd_rdy) begin
                txrx_flag <= 0;
            end
        end
    // apb buf read//
    always@(*)
        begin
            if (apb_rd) begin
                case (paddr)
                   SBUF_REG_ADDR : prdata = {16'b0,sbuf_reg};
                   UINT_REG_ADDR : prdata = {31'b0,uint_reg};
                    default:      prdata = 32'b0;  
                endcase
            end
        end
    assign pready = psel & penable;
  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值