前面分析了AHB总线协议。接下来分析APB总线协议。

  (一) APB总线接口:

  PCLK APB总线时钟。

  PRESETn APB总线复位。低有效。

  PADDR 地址总线。

  PSELx 从设备选择。

  PENABLE APB传输选通。

  PWRITE 高为写传输,低为读。

  PRDATA 读数据总线。

  PWDATA 写数据总线。

  接口信号定义如下:

 interface   apb_slv_intf #(
parameter AW = ,
DW =
) (
input logic PCLK,
input logic PRESETn
);
logic PSEL;
logic PENABLE;
logic [AW-:] PADDR;
logic PWRITE;
logic [DW-:] PWDATA; logic [DW-:] PRDATA; modport m (
input PRDATA,
output PSEL, PENABLE, PADDR, PWRITE, PWDATA
); modport s (
input PSEL, PENABLE, PADDR, PWRITE, PWDATA,
output PRDATA
); endinterface: apb_slv_intf

  (二) APB总线时序图:

写传输

读传输

  注意在PENABLE信号有效后从设备需要给出有效数据/读取有效数据。

  (三) AHB总线到APB总线转换桥

 module ahb2apb_bridge #(
parameter AHB_AW = ,
AHB_DW = ,
APB_AW = ,
APB_DW = ,
NSLV =
) (
input logic HCLK,
input logic HRESETn,
input logic PCLK,
input logic PRESETn,
ahb_slv_intf.s ahb,
apb_slv_intf.m apbv[NSLV]
); logic ahb_work;
logic apb_work; genvar i; typedef enum logic [:] {
AHB_IDLE = 'b00,
AHB_WRITE = 'b01,
AHB_READ = 'b10,
AHB_WAIT = 'b11
} ahb_state_e; // Signal of AHB Domain
struct {
logic work;
logic [AHB_AW-:] addr;
logic [AHB_DW-:] data;
logic write;
ahb_state_e cstate, nstate;
} ahbd; typedef enum logic [:] {
APB_IDLE = 'b00,
APB_WRITE = 'b01,
APB_READ = 'b10
} apb_state_e; // Signal of APB Domain
struct {
logic work;
logic [APB_DW-:] data[NSLV];
logic PSEL[NSLV];
logic PENABLE[NSLV];
apb_state_e cstate, nstate;
} apbd; // AHB Control Logic
always_comb begin
case (ahbd.cstate)
AHB_IDLE: begin
if (ahb.HSEL && ahb.HTRANS == HTRANS_NONSEQ) begin
if (ahb.HWRITE)
ahbd.nstate = AHB_WRITE;
else
ahbd.nstate = AHB_READ;
end
else
ahbd.nstate = AHB_IDLE;
end
AHB_WRITE: begin
if (apbd.work)
ahbd.nstate = AHB_WAIT;
else
ahbd.nstate = AHB_WRITE;
end
AHB_READ: begin
if (apbd.work)
ahbd.nstate = AHB_WAIT;
else
ahbd.nstate = AHB_READ;
end
AHB_WAIT: begin
if (!apbd.work)
ahbd.nstate = AHB_IDLE;
else
ahbd.nstate = AHB_WAIT;
end
default: ahbd.nstate = AHB_IDLE;
endcase
end always_ff @(posedge HCLK or negedge HRESETn) begin
if (!HRESETn)
ahbd.cstate <= AHB_IDLE;
else
ahbd.cstate <= ahbd.nstate;
end always_ff @(posedge HCLK or negedge HRESETn) begin
if (!HRESETn) begin
ahbd.work <= 'b0;
ahbd.addr <= '0;
ahbd.data <= '0;
ahbd.write <= 'b0;
ahb.HREADY <= 'b1;
ahb.HRDATA[APB_DW-:] <= '0;
end
else begin
case (ahbd.cstate)
AHB_IDLE: begin
if (ahb.HSEL && ahb.HTRANS == HTRANS_NONSEQ) begin
ahbd.addr <= ahb.HADDR;
ahbd.write <= ahb.HWRITE;
ahb.HREADY <= 'b0;
end
else begin
ahbd.addr <= '0;
ahbd.write <= 'b0;
ahb.HREADY <= 'b1;
end
ahbd.work <= 'b0;
ahbd.data <= '0;
ahb.HRDATA[APB_DW-:] <= apbd.data[ahbd.addr[AHB_AW-:AHB_AW-]];
end
AHB_WRITE: begin
ahb.HREADY <= 'b0;
ahbd.work <= 'b1;
ahbd.data <= ahb.HWDATA;
ahb.HRDATA[APB_DW-:] <= '0;
end
AHB_READ: begin
ahbd.work <= 'b1;
ahbd.data <= '0;
ahb.HREADY <= 'b0;
ahb.HRDATA[APB_DW-:] <= '0;
end
AHB_WAIT: begin
ahbd.work <= 'b0;
ahb.HREADY <= 'b0;
ahb.HRDATA[APB_DW-:] <= '0;
end
endcase
end
end assign ahb.HRESP = HRESP_OKAY;
// assign ahb.HRDATA[AHB_DW-1:APB_DW] = '0; // APB Control Logic
always_comb begin
case (apbd.cstate)
APB_IDLE: begin
if (ahbd.work) begin
if (ahbd.write)
apbd.nstate = APB_WRITE;
else
apbd.nstate = APB_READ;
end
else
apbd.nstate = APB_IDLE;
end
APB_WRITE: apbd.nstate = APB_IDLE;
APB_READ: apbd.nstate = APB_IDLE;
default: apbd.nstate = APB_IDLE;
endcase
end always_ff @(posedge PCLK or negedge PRESETn) begin
if (!PRESETn)
apbd.cstate <= APB_IDLE;
else
apbd.cstate <= apbd.nstate;
end always_ff @(posedge PCLK or negedge PRESETn) begin
if (!PRESETn) begin
apbd.work <= 'b0;
for (int j = ; j < NSLV; j++) begin
apbd.PSEL[j] <= 'b0;
apbd.PENABLE[j] <= 'b0;
end
end
else begin
case (apbd.cstate)
APB_IDLE: begin
if (ahbd.work) begin
apbd.work <= 'b1;
for (int j = ; j < NSLV; j++)
apbd.PSEL[j] <= (ahbd.addr[AHB_AW-:AHB_AW-] == j) ? 'b1 : 1'b0;
end
else begin
apbd.work <= 'b0;
for (int j = ; j < NSLV; j++)
apbd.PSEL[j] <= 'b0;
end
for (int j = ; j < NSLV; j++)
apbd.PENABLE[j] <= 'b0;
end
APB_WRITE: begin
apbd.work <= 'b1;
for (int j = ; j < NSLV; j++)
apbd.PENABLE[j] <= (ahbd.addr[AHB_AW-:AHB_AW-] == j) ? 'b1 : 1'b0;
end
APB_READ: begin
apbd.work <= 'b1;
for (int j = ; j < NSLV; j++)
apbd.PENABLE[j] <= (ahbd.addr[AHB_AW-:AHB_AW-] == j) ? 'b1 : 1'b0;
end
endcase
end
end generate
for (i = ; i < NSLV; i++) begin: apbv_loop
assign apbv[i].PADDR = {'h0, ahbd.addr[APB_AW-4-1:0]};
assign apbv[i].PWRITE = ahbd.write;
assign apbv[i].PWDATA = ahbd.data[APB_DW-:];
assign apbd.data[i] = apbv[i].PRDATA;
assign apbv[i].PSEL = apbd.PSEL[i];
assign apbv[i].PENABLE = apbd.PENABLE[i];
end
endgenerate endmodule: ahb2apb_bridge

AMBA APB总线的更多相关文章

  1. AHB总线和APB总线

    AHB主要用于高性能模块(如CPU.DMA和DSP等)之间的连接,作为SoC的片上系统总线,它包括以下一些特性:单个时钟边沿操作:非三态的实现方式:支持突发传输:支持分段传输:支持多个主控制器:可配置 ...

  2. APB总线

    APB(Advance Peripheral Bus)是AMBA总线的一部分,从1998年第一版至今共有3个版本. AMBA 2 APB Specfication:定义最基本的信号interface, ...

  3. AMBA AHB总线

    Advanced Microcontroller Bus Architecture, 即AMBA,是ARM公司提出的总线规范,被很多SoC设计所采用,常用的实现有AHB(Advanced High-P ...

  4. STM32WB AHB总线、APB总线与外设

    方框图: 如图所示: 1)APB1外设 2)APB2外设 3)AHB1外设 4)AHB2外设 5)AHB3外设 6)AHB4外设(ABH共享总线外设) 内存映射关系图:

  5. AMBA总线介绍

    The Advanced Microcontroller Bus Architecture (AMBA) specification defines an on- chip communication ...

  6. APB协议

    https://wenku.baidu.com/view/2663f629ef06eff9aef8941ea76e58fafab04592.html https://www.cnblogs.com/l ...

  7. AMBA总线协议AHB、APB

    一.什么是AMBA总线 AMBA总线规范是ARM公司提出的总线规范,被大多数SoC设计采用,它规定了AHB (Advanced High-performance Bus).ASB (Advanced ...

  8. AMBA总线协议AHB、APB、AXI对比分析【转】

    转自:https://blog.csdn.net/ivy_reny/article/details/56274412 一.AMBA概述    AMBA (Advanced Microcontrolle ...

  9. [转]AMBA、AHB、APB、ASB总线简介

    [转]http://www.cnblogs.com/zhaozhong1989/articles/3092140.html 1.前言 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大.数字IC ...

随机推荐

  1. xcode 8 清除无用的打印

    OS_ACTIVITY_MODE     disable 虽然模拟器这样写能屏蔽掉无用的打印,但是在真机测试的时候什么都不会打印  Nslog 也打印不出来  , 这时候就要点掉 OS_ACTIVIT ...

  2. mybatis学习笔记--常见的错误

    原文来自:<mybatis学习笔记--常见的错误> 昨天刚学了下mybatis,用的是3.2.2的版本,在使用过程中遇到了些小问题,现总结如下,会不断更新. 1.没有在configurat ...

  3. SeaJS入门教程系列之完整示例(三)

    一个完整的例子上文说了那么多,知识点比较分散,所以最后我打算用一个完整的SeaJS例子把这些知识点串起来,方便朋友们归纳回顾.这个例子包含如下文件: 1.index.html——主页面.2.sea.j ...

  4. Best quotes from The Vampire Diary(《吸血鬼日记》经典台词)

    1. I will start fresh, be someone new. 1. 我要重新开始,做不一样的自己. 2. It's the only way I'll make it through. ...

  5. jquery.Inputmask 插件用法(中文API文档)

      jquery.Inputmask 可以算是input文本输入限制的神器了,内部融合了多种输入限制, 如金额,电话号码,身份证号,网关等..,并且还可以自定义规则. inputmask 据说最早起源 ...

  6. POJ 1065 Wooden Sticks【贪心】

    题意: 有一些木棍,每个有长度和重量,要求把这些木棍排成若干两个属性值均不下降的序列.问至少要分为多少个序列.且要保证排出来的子序列数最少. 思路: ( 9 , 4 ) ,( 2 , 5 ) ,( 1 ...

  7. Codeforces Round #310 (Div. 2)

    Problem A: 题目大意:给你一个由0,1组成的字符串,如果有相邻的0和1要消去,问你最后还剩几个字符. 写的时候不想看题意直接看样例,结果我以为是1在前0在后才行,交上去错了..后来仔细 看了 ...

  8. Hat’s Words HDU1247

    一个很经典的字典树题目 先建树 再拆单词进行判断是否都在树内 因为爆内存错了很久 如果一个四十万的数组  用mamset的话会直接爆几十万的内存 所以要:用多少 初始化多少才对!( 修改了两条初始化语 ...

  9. 【Java】 剑指offer(32) 从上往下打印二叉树

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 (一)从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺 ...

  10. ubuntu16.04下vim的安装与配置

    一.安装vim 使用命令 $ sudo apt-get install vim  来安装vim,安装后的vim需要进行一些配置,不然使用起来会有些不方便,比如不会自动缩进. 二.配置vim 使用命令  ...