APB Slave设计

APB Slave位置

- 实现通过CPU对于APB Slave读写模块进行读写操作
规格说明

- 不支持反压,即它反馈给APB的pready信号始终为1
- 不支持错误传输,就是说他反馈给APB总线的PSLVERR始终是为0的
- 支持4个可读写的寄存器
- 支持12个只读寄存器
- 支持字节选通信号,根据字节选通信号进行操作数据
接口

寄存器表

- PID3寄存器的[7:4]位就是输入的版本控制信号
寄存器电路

架构图

- interface模块就是将APB的信号转变为slave的控制信号(读写使能信号,地址信号,写数据,读数据,写选通信号)
RTL
apb_interface
module apb_slave_if
#(
parameter ADDRWIDTH=12
)
(
input wire pclk ,
input wire preset ,
// input apb control signal
input wire psel ,
input wire [ADDRWIDTH-1:0] paddr ,
input wire penable ,
input wire pwrite ,
input wire [31:0] pwdata ,
input wire [3:0] pstrb ,
input wire [31:0] rdata ,
input wire [3:0] ecorevnum,
// apb outputs
output wire [31:0] prdata ,
output wire pready ,
output wire pslverr ,
// output signals to apb slave
output wire [ADDRWIDTH-1:0] addr ,
output wire read_en ,
output wire write_en,
output wire [31:0] wdata ,
output wire [3:0] byte_strobe,
output wire [3:0] ecorevnum_pid3
);
assign pready = 1'b1;
assign pslverr = 1'b0;
assign addr = paddr;
assign read_en = psel && (~pwrite);
assign write_en = psel && pwrite && (~penable);
assign byte_strobe = pstrb;
assign wdata = pwdata;
assign prdata = rdata;
assign ecorevnum_pid3 =ecorevnum;
endmodule
apb_slave
module apb_slave
#(
parameter ADDRWIDTH = 12
)
(
input wire pclk ,
input wire preset ,
input wire [ADDRWIDTH-1:0] addr ,
input wire [31:0] wdata ,
input wire read_en ,
input wire write_en ,
input wire [3:0] byte_strobe ,
input wire [3:0] ecorevnum_pid3 ,
// output signals
output reg [31:0] rdata
);
// 定义只读寄存器内容
localparam ARM_CHSDK_APB4_EG_SLAVE_PID4 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_PID5 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_PID6 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_PID7 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_PID0 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_PID1 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_PID2 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_PID3 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_CID0 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_CID1 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_CID2 = 32'h0000_0004;
localparam ARM_CHSDK_APB4_EG_SLAVE_CID3 = 32'h0000_0004;
// 定义读写寄存器
reg [31:0] data0;
reg [31:0] data1;
reg [31:0] data2;
reg [31:0] data3;
wire [3:0] wr_sel;
// 通过addr[2:3]bit选择data寄存器
assign wr_sel[0] = ((addr[ADDRWIDTH-1:2]==10'b0000_0000_00 &&(write_en)) ? 1'b1 : 1'b0);
assign wr_sel[1] = ((addr[ADDRWIDTH-1:2]==10'b0000_0000_01 &&(write_en)) ? 1'b1 : 1'b0);
assign wr_sel[2] = ((addr[ADDRWIDTH-1:2]==10'b0000_0000_10 &&(write_en)) ? 1'b1 : 1'b0);
assign wr_sel[3] = ((addr[ADDRWIDTH-1:2]==10'b0000_0000_11 &&(write_en)) ? 1'b1 : 1'b0);
// register wirte
always @(posedge pclk or negedge preset) begin
if(~preset)
data0 <= 32'b0;
else if(wr_sel[0]) begin
// according to byte_strobe write the data0 register
if(byte_strobe[0])
data0[7:0] <= wdata[7:0];
else if(byte_strobe[1])
data0[15:8] <= wdata[15:8];
else if(byte_strobe[2])
data0[23:16] <= wdata[23:16];
else if(byte_strobe[3])
data0[31:24] <= wdata[31:24];
else
data0 <= 32'b0;
end
end
always @(posedge pclk or negedge preset) begin
if(~preset)
data1 <= 32'b0;
else if(wr_sel[0]) begin
// according to byte_strobe write the data0 register
if(byte_strobe[0])
data1[7:0] <= wdata[7:0];
else if(byte_strobe[1])
data1[15:8] <= wdata[15:8];
else if(byte_strobe[2])
data1[23:16] <= wdata[23:16];
else if(byte_strobe[3])
data1[31:24] <= wdata[31:24];
else
data1 <= 32'b0;
end
end
always @(posedge pclk or negedge preset) begin
if(~preset)
data2 <= 32'b0;
else if(wr_sel[0]) begin
// according to byte_strobe write the data0 register
if(byte_strobe[0])
data2[7:0] <= wdata[7:0];
else if(byte_strobe[1])
data2[15:8] <= wdata[15:8];
else if(byte_strobe[2])
data2[23:16] <= wdata[23:16];
else if(byte_strobe[3])
data2[31:24] <= wdata[31:24];
else
data2 <= 32'b0;
end
end
always @(posedge pclk or negedge preset) begin
if(~preset)
data3 <= 32'b0;
else if(wr_sel[0]) begin
// according to byte_strobe write the data0 register
if(byte_strobe[0])
data3[7:0] <= wdata[7:0];
else if(byte_strobe[1])
data3[15:8] <= wdata[15:8];
else if(byte_strobe[2])
data3[23:16] <= wdata[23:16];
else if(byte_strobe[3])
data3[31:24] <= wdata[31:24];
else
data3 <= 32'b0;
end
end
// register read
always @(*) begin
case (read_en)
1'b1:
begin
// 读取RW寄存器的值,通过高addr[2:3]进行寻址,高位都为0
if(addr[11:4]==8'b0) begin
case (addr[3:2])
2'b00 : rdata = data0;
2'b01 : rdata = data1;
2'b10 : rdata = data2;
2'b11 : rdata = data3;
default:rdata = 32'b0;
endcase
end
else if(addr[11:6] == 6'h3f) begin
case(addr[5:2])
4'b0100:rdata = ARM_CHSDK_APB4_EG_SLAVE_PID4;
4'b0101:rdata = ARM_CHSDK_APB4_EG_SLAVE_PID5;
4'b0110:rdata = ARM_CHSDK_APB4_EG_SLAVE_PID6;
4'b0111:rdata = ARM_CHSDK_APB4_EG_SLAVE_PID7;
4'b1000:rdata = ARM_CHSDK_APB4_EG_SLAVE_PID0;
4'b1001:rdata = ARM_CHSDK_APB4_EG_SLAVE_PID1;
4'b1010:rdata = ARM_CHSDK_APB4_EG_SLAVE_PID2;
4'b1011:rdata = {ARM_CHSDK_APB4_EG_SLAVE_PID3[31:8],
ecorevnum_pid3[3:0],4'h0};
4'b1100:rdata = ARM_CHSDK_APB4_EG_SLAVE_CID0;
4'b1101:rdata = ARM_CHSDK_APB4_EG_SLAVE_CID1;
4'b1110:rdata = ARM_CHSDK_APB4_EG_SLAVE_CID2;
4'b1111:rdata = ARM_CHSDK_APB4_EG_SLAVE_CID3;
default:rdata = 32'bx;
endcase
end
else
rdata = 32'b0;
end
1'b0:
begin
rdata = 32'b0;
end
default:rdata=32'bx;
endcase
end
endmodule
APB Slave设计的更多相关文章
- APB总线
APB(Advance Peripheral Bus)是AMBA总线的一部分,从1998年第一版至今共有3个版本. AMBA 2 APB Specfication:定义最基本的信号interface, ...
- DMA-330(一)
DMA Controller的interface: DMA Controller提供这些feature: 1)instruction set,对DMA transfer进行program 2)AXI ...
- 痞子衡嵌入式:Ethos-U55,ARM首款面向Cortex-M的microNPU
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Ethos-U55. ARM 前几天刚发布了 Cortex-M 家族最新一款内核 - Cortex-M55 以及首款面向 Cor ...
- AXI 协议翻译介绍
一.介绍 Introduction 本章描述了axis协议的体系结构和协议定义的基本事务.它包含以下部分:•第1-2页关于AXI协议•第1-3页是架构•第1-7页是基本事务•第1-11页的附加功能. ...
- STM
STM(System Trace macrocell) STM是coresight system中的一个trace source,可以提供high-bandwidth的trace data. STM优 ...
- AHB协议
AHB2 支持多个Bus Master,例如有三个Master,有四个slave,但是同时只有一个Mater可以拿到Bus的访问权.所以,总线的使用权就需要Master去申请,也就需要一个仲裁器(Ar ...
- 《大规模web服务开发技术》笔记
前段时间趁空把<大规模web服务开发技术>这本书看完了,今天用一下午时间重新翻了一遍,把其中的要点记了下来,权当复习和备忘.由于自己对数据压缩.全文检索等还算比较熟,所以笔记内容主要涉及前 ...
- AHB 总线问答(转)
AHB总线问答 http://blog.163.com/huanhuan_hdu/blog/static/1352981182011625916845/ 仲裁:主设备可以在一个突发传输中解除HLOCK ...
- Meter Bus解析4:升压斩波电路
Meter Bus解析1(http://blog.csdn.net/qingwufeiyang12346/article/details/47767595),对Meter Bus进行 ...
- AHB总线和APB总线
AHB主要用于高性能模块(如CPU.DMA和DSP等)之间的连接,作为SoC的片上系统总线,它包括以下一些特性:单个时钟边沿操作:非三态的实现方式:支持突发传输:支持分段传输:支持多个主控制器:可配置 ...
随机推荐
- flask统一异常捕获(作用:统一捕获指定的异常并返回)
flask中可以使用装饰器errorhandler来对指定的异常.状态码等统一捕获并处理. 对指定的状态码进行统一捕获 @app.errorhandler(404) # 参数e是异常的详细信息的对象, ...
- rust 过程宏
简介 Rust 编程语言里面有两种宏系统,一种是声明宏(Declarative Macros),另一种为过程宏(Procedural Macros).声明宏和过程宏是两种基本上完全不一样的宏系统,编写 ...
- spring自定义session分布式session
spring实现自定义session.springboot实现自定义session.自定义sessionid的key.value.实现分布式会话 一.原始方案 自定义生成sessionid的值 修改t ...
- DevOps常用工具全家桶,实现高效运维和交付
DevOps常用工具全家桶,实现高效运维和交付 1.DevOps发展 DevOps发展背景: 随着互联网技术的快速发展,软件开发和运维的挑战也日益增加.传统的软件开发和运维模式往往存在分离.效率低下. ...
- 懂分析、会预测,你见过这样的华为云DAS吗?
摘要:数字化时代下,华为云数据管理服务DAS基于AI技术,于近期推出了智能SQL分析(包括慢SQL发现.SQL透视).workload级别索引推荐.存储空间预测等运维特性,加上原有的数据库运维能力,构 ...
- 推理实践丨如何使用MindStudio进行Pytorch模型离线推理
摘要:本教程所示例的任务是Ascend Pytorch离线推理,即对给定的已经训练好的模型参数和推理脚本,在Ascend 310/710和Tesla设备上进行推理应用. 本文分享自华为云社区<使 ...
- 云小课|CDN第5课 CDN入门之—我的网站可以用CDN加速吗?
摘要:CDN(Content Delivery Network,内容分发网络)通过将源站资源缓存到遍布各地的边缘节点服务器上,用户可以就近获取资源,从而达到加速的效果. 本文分享自华为云社区<[ ...
- 无法安装此app,因为无法验证其完整性 ,解决方案
最近有很多兄弟萌跟我反应"无法安装此app,因为无法验证其完整性 ",看来这个问题无法避免了,今天统一回复下,出现提示主要有以下几种可能 1.安装包不完整 首先申请我所有分享的破解 ...
- 注册中心 —— SpringCloud Netflix Eureka
Eureka 简介 Eureka 是一个基于 REST 的服务发现组件,SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务 ...
- Hugging News #0203: 3.3 MB 的文生图模型、RHLF 训练框架、手机上能跑的 Transformer
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...