AHB2APB设计
AHB2APB Bridge位置

- AHB子系统时钟在200Mhz左右,APB时钟在几十Khz到几十Mhz
- 所以要进行跨时钟域处理,从AHB高时钟频率转到APB低时钟频率
AHB2APB Bridge规格说明

- Bridge是APB总线上唯一的主机(也可以通过设计使APB支持多个Master)
AHB2APB Bridge接口
- Bridge是连接AHB总线和APB总线的桥梁,所以接口有AHB总线和APB总线
- Bridge是APB总线的Master,是AHA的Slave
- psel - 有多少个外设就有多少个psel信号
- penable - 时钟选通信号

AHB2APB Bridge状态机
- Bridge开始的时候处于IDLE状态,当Bridge收到AHB总线的传输信号之后,进入到setup状态,在setup状态将AHB控制和地址信号进行锁存并将psel置于1,进入到enable状态,可以进行apb的读写操作

AHB2APB Bridge读时序

AHB2APB Bridge 写时序

AHB2APB Bridge设计
设计规格
- 对于输入输出数据进行寄存或者不寄存,由模块控制,主要是为了时序

接口信号

- APBACTIVE - APB激活信号
状态机1:输入输出不寄存

状态机2:输入输出数据寄存

状态机:发生传输错误

RTL
module ahb_to_apb_bridge
#(
parameter ADDRWIDTH = 16 ,
parameter REGISTER_RDATA = 1,
parameter REGISTER_WDATA = 0
)
(
input wire hclk,
input wire hresetn,
input wire pclken,
input wire hsel,
input wire [ADDRWIDTH-1:0] haddr,
input wire [1:0] htrans,
input wire [2:0] hsize,
input wire [4:0] hprot,
input wire hwrite,
input wire hready,
input wire [31:0] hwdata,
output reg hreadyout,
output wire [31:0] hrdata,
output wire hresp,
output wire [ADDRWIDTH-1:0] paddr,
output wire penable,
output wire pwrite,
output wire [3:0] pstrb,
output wire [2:0] pprot,
output wire [31:0] pwdata,
output wire psel,
output wire apbactive,
input wire [31:0] prdata,
input wire pready,
input wire pslverr
);
// 寄存写信号和写地址
reg [ADDRWIDTH-1:0] addr_reg;
reg [2:0] wr_reg;
reg [31:0] rwdata_reg;
// 定义当前状态变量和下一状态变量
reg [2:0] state_reg;
reg [2:0] next_state;
reg [3:0] pstrb_reg;
wire [3:0] pstrb_nxt;
reg [1:0] pprot_reg;
wire [1:0] pprot_nxt;
// apb bridge选择信号
wire apb_select;
// 传输完成信号
wire apb_tran_end;
// 判断数据是否寄存的变量
wire reg_rdata_cfg;
wire reg_wdata_cfg;
// 定义写控制信号寄存的寄存器
reg sample_wdata_reg;
localparam ST_BITS=3;
localparam [ST_BITS-1:0] ST_IDLE =3'b000;
localparam [ST_BITS-1:0] ST_APB_WAIT =3'b001;
localparam [ST_BITS-1:0] ST_APB_TRNF =3'b010;
localparam [ST_BITS-1:0] ST_APB_TRNF2 =3'b011;
localparam [ST_BITS-1:0] ST_APB_NODOK =3'b100;
localparam [ST_BITS-1:0] ST_APB_ERR1 =3'b101;
localparam [ST_BITS-1:0] ST_APB_ERR2 =3'b110;
localparam [ST_BITS-1:0] ST_APB_ILLEGAL =3'b111;
// main code
// 产生读写数据是否寄存的信号
assign reg_rdata_cfg = REGISTER_RDATA == 0? 1'b0 : 1'b1;
assign reg_rdata_cfg = REGISTER_WDATA == 0? 1'b0 : 1'b1;
// 产生bridge被选中的信号
assign apb_select = hsel && htrans[1] && hready;
// apb传输完成信号
assign apb_tran_end = (state_reg == 3'b011) & pready;
//pprot信号产生
assign pprot_nxt[0] = hprot[1];
assign pprot_nxt[1] = ~hprot[0];
// pstrb信号产生
assign pstrb_nxt[0] = hwrite & ((hsize[1]) |(hsize[0] & (~haddr[1])) | (haddr[1:0]==2'b00));
assign pstrb_nxt[1] = hwrite & ((hsize[1]) |(hsize[0] & (~haddr[1])) | (haddr[1:0]==2'b01));
assign pstrb_nxt[2] = hwrite & ((hsize[1]) |(hsize[0] & haddr[1]) | (haddr[1:0]==2'b10));
assign pstrb_nxt[3] = hwrite & ((hsize[1]) |(hsize[0] & haddr[1]) | (haddr[1:0]==2'b11));
// sample control signals 打拍信号
// data和addr对齐
always @(posedge hclk or negedge hresetn) begin
if(!hresetn) begin
addr_reg <= {ADDRWIDTH-2{1'b0}};
wr_reg <= 1'b0;
pprot_reg <= 2'b0;
pstrb_reg <= 4'b0;
end
else if(apb_select) begin
addr_reg <= haddr[ADDRWIDTH-1:2];
wr_reg <= hwrite;
pprot_reg <= pprot_nxt;
pstrb_reg <= pstrb_nxt;
end
end
// 采样写数据的控制信号
wire sample_wdata_set = apb_select & hwrite & reg_wdata_cfg;
wire sample_wdata_clt = sample_wdata_set & pclken;
always @ (posedge hclk or negedge hresetn) begin
if(!hresetn) begin
sample_wdata_reg <= 1'b0;
end
else if(sample_wdata_set | sample_wdata_clt) begin
sample_wdata_reg <= sample_wdata_set;
end
end
// 第一段状态机
always @ (posedge hclk or negedge hresetn) begin
if(!hresetn) begin
state_reg <= 3'b000;
end
else
state_reg <= next_state;
end
// 第二段状态机描述状态转移
always @ (*) begin
case(state_reg)
ST_IDLE:
begin
if(apb_select & pclken & ~(reg_wdata_cfg&hwrite)) begin
next_state = ST_APB_TRNF;
end
else if(apb_select)
next_state = ST_APB_WAIT;
else
next_state = ST_IDLE;
end
ST_APB_WAIT:
begin
if(pclken)
next_state = ST_APB_TRNF;
else
next_state = ST_IDLE;
end
ST_APB_TRNF:
begin
if(pclken)
next_state = ST_APB_TRNF2;
else
next_state = ST_APB_TRNF;
end
ST_APB_TRNF2:
begin
if(pready & pslverr & pclken)
next_state = ST_APB_ERR1;
else if(pready & (~pslverr)&pclken)
begin
if(reg_rdata_cfg)
next_state = ST_APB_NODOK;
else
next_state = ST_APB_TRNF2;
end
end
ST_APB_NODOK:
begin
if(apb_select & pclken & ~(reg_wdata_cfg&hwrite)) begin
next_state = ST_APB_TRNF;
end
else if(apb_select)
next_state = ST_APB_WAIT;
else
next_state = ST_IDLE;
end
ST_APB_ERR1:
next_state = ST_APB_ERR2;
ST_APB_ERR2:
if(apb_select & pclken & ~(reg_wdata_cfg&hwrite)) begin
next_state = ST_APB_TRNF;
end
else if(apb_select)
next_state = ST_APB_WAIT;
else
next_state = ST_IDLE;
default : next_state = 3'bxxx;
endcase
end
// 采样数据
always @ (posedge hclk or negedge hresetn) begin
if(!hresetn)
rwdata_reg = 32'b0;
else if(sample_wdata_reg & reg_wdata_cfg & pclken)
rwdata_reg <= hwdata;
else if(apb_tran_end & reg_rdata_cfg & pclken)
rwdata_reg <= prdata;
end
// 产生输出信号
assign paddr = {addr_reg,2'b00};
assign pwrite = wr_reg;
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];
//产生hready_out
always @(*) begin
case(state_reg)
ST_IDLE:hreadyout = 1'b1;
ST_APB_WAIT:hreadyout=1'b0;
ST_APB_TRNF:hreadyout=1'b0;
ST_APB_TRNF2:hreadyout=(~reg_rdata_cfg) & pready & (~pslverr)&pclken;
ST_APB_NODOK:hreadyout = 1'b0;
ST_APB_ERR1:hreadyout = 1'b0;
ST_APB_ERR1:hreadyout = 1'b1;
default:hreadyout=1'bx;
endcase
end
assign hrdata = reg_rdata_cfg ? rwdata_reg : prdata;
assign hresp = (state_reg == ST_APB_ERR1) |(state_reg == ST_APB_ERR2);
assign apbactive = (hsel & htrans[1]) | state_reg;
endmodule
AHB2APB设计的更多相关文章
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成
阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...
- 设计爬虫Hawk背后的故事
本文写于圣诞节北京下午慵懒的午后.本文偏技术向,不过应该大部分人能看懂. 五年之痒 2016年,能记入个人年终总结的事情没几件,其中一个便是开源了Hawk.我花不少时间优化和推广它,得到的评价还算比较 ...
- 如何一步一步用DDD设计一个电商网站(十)—— 一个完整的购物车
阅读目录 前言 回顾 梳理 实现 结语 一.前言 之前的文章中已经涉及到了购买商品加入购物车,购物车内购物项的金额计算等功能.本篇准备把剩下的购物车的基本概念一次处理完. 二.回顾 在动手之前我对之 ...
- 如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念
一.前言 DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...
- 如何一步一步用DDD设计一个电商网站(七)—— 实现售价上下文
阅读目录 前言 明确业务细节 建模 实现 结语 一.前言 上一篇我们已经确立的购买上下文和销售上下文的交互方式,传送门在此:http://www.cnblogs.com/Zachary-Fan/p/D ...
- 如何一步一步用DDD设计一个电商网站(六)—— 给购物车加点料,集成售价上下文
阅读目录 前言 如何在一个项目中实现多个上下文的业务 售价上下文与购买上下文的集成 结语 一.前言 前几篇已经实现了一个最简单的购买过程,这次开始往这个过程中增加一些东西.比如促销.会员价等,在我们的 ...
- 如何一步一步用DDD设计一个电商网站(五)—— 停下脚步,重新出发
阅读目录 前言 单元测试 纠正错误,重新出发 结语 一.前言 实际编码已经写了2篇了,在这过程中非常感谢有听到观点不同的声音,借着这个契机,今天这篇就把大家提出的建议一个个的过一遍,重新整理,重新出发 ...
- 如何一步一步用DDD设计一个电商网站(四)—— 把商品卖给用户
阅读目录 前言 怎么卖 领域服务的使用 回到现实 结语 一.前言 上篇中我们讲述了“把商品卖给用户”中的商品和用户的初步设计.现在把剩余的“卖”这个动作给做了.这里提醒一下,正常情况下,我们的每一步业 ...
- 如何一步一步用DDD设计一个电商网站(三)—— 初涉核心域
一.前言 结合我们本次系列的第一篇博文中提到的上下文映射图(传送门:如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念),得知我们这个电商网站的核心域就是销售子域.因为电子商务是以信息网络 ...
随机推荐
- vivo 数据库备份恢复系统演化
作者:vivo 互联网数据库团队 - Han Chaobing 介绍 vivo 数据库备份恢复功能的演化,以及对备份文件的功能扩展. 一.概述 vivo互联网领域拥有的数据库组件分别为 MySQL.M ...
- Win10 SFC& Dism修复系统
在Win10开始按钮上点击右键(或按Win + X快捷键),在弹出的系统快捷菜单中点击 Windows PowerShell(管理员)或者 命令提示符CMD (管理员) 方法 1 SFC输入&qu ...
- K8S系列一:概念入门
K8S系列一:概念入门 写在前面 本文组织方式: K8S的架构.作用和目的.需要首先对K8S整体有所了解. K8S是什么? 为什么是K8S? K8S怎么做? K8S的重要概念,即K8S的API对象.要 ...
- JavaImprove--Lesson04--LocalDateTime,ZoneId,Instant,DateTimeFormatter
一.LocalDateTime LocalDateTime是JDK8的新时间特性,它解决了Date类和Calender类的很多不足,如使用不方便,线程不安全,以及获取时间戳只能拿到毫秒而不能拿到纳秒等 ...
- just_audio音频播放器
代码 import 'package:flutter/material.dart'; import 'package:just_audio/just_audio.dart'; void main() ...
- C#数据结构与算法系列(十六):时间复杂度(上)
1.时间频度 介绍: 一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,他花费时间越多.一个算法中的语句执行次数称为语句频度或时间频度 举例说明: 比如计算1-100所有数字 ...
- 华为云自研PB级分布式时序数据库揭秘第一期:初识GaussDB(for Influx)
摘要:GaussDB(for Influx)提供了独特的数据存储管理解决方案,云原生的存储与计算架构,可根据业务变化快速扩容缩容:高效的数据压缩能力和数据冷热分离设计,可大幅降低数据存储成本:高吞吐的 ...
- 实践案例丨Pt-osc工具连接rds for mysql 数据库失败
[现象] 主机可以telent 通rds 端口,并且使用mysql-client 连接正常: 如下图所示:使用pt-osc工具连接时,一直没有响应,一直卡在哪里 等了4-5分钟左右后,会有响应,如下图 ...
- 初探语音识别ASR算法
摘要:语音转写文字ASR技术的基本概念与数学原理简介. 本文分享自华为云社区<新手语音入门(三): 语音识别ASR算法初探 | 编码与解码 | 声学模型与语音模型 | 贝叶斯公式 | 音素> ...
- 再谈P2P技术:网络拓扑结构、核心技术分析
随着P2P应用的蓬勃发展,作为P2P应用中核心问题的发现技术除了遵循技术本身的逻辑以外,也受到某些技术的发展趋势.需求趋势的深刻影响. P2P协议概述 P2P打破了传统的Client/Server ( ...