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设计的更多相关文章

  1. APB总线

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

  2. DMA-330(一)

    DMA Controller的interface: DMA Controller提供这些feature: 1)instruction set,对DMA transfer进行program 2)AXI ...

  3. 痞子衡嵌入式:Ethos-U55,ARM首款面向Cortex-M的microNPU

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Ethos-U55. ARM 前几天刚发布了 Cortex-M 家族最新一款内核 - Cortex-M55 以及首款面向 Cor ...

  4. AXI 协议翻译介绍

    一.介绍 Introduction 本章描述了axis协议的体系结构和协议定义的基本事务.它包含以下部分:•第1-2页关于AXI协议•第1-3页是架构•第1-7页是基本事务•第1-11页的附加功能. ...

  5. STM

    STM(System Trace macrocell) STM是coresight system中的一个trace source,可以提供high-bandwidth的trace data. STM优 ...

  6. AHB协议

    AHB2 支持多个Bus Master,例如有三个Master,有四个slave,但是同时只有一个Mater可以拿到Bus的访问权.所以,总线的使用权就需要Master去申请,也就需要一个仲裁器(Ar ...

  7. 《大规模web服务开发技术》笔记

    前段时间趁空把<大规模web服务开发技术>这本书看完了,今天用一下午时间重新翻了一遍,把其中的要点记了下来,权当复习和备忘.由于自己对数据压缩.全文检索等还算比较熟,所以笔记内容主要涉及前 ...

  8. AHB 总线问答(转)

    AHB总线问答 http://blog.163.com/huanhuan_hdu/blog/static/1352981182011625916845/ 仲裁:主设备可以在一个突发传输中解除HLOCK ...

  9. Meter Bus解析4:升压斩波电路

             Meter Bus解析1(http://blog.csdn.net/qingwufeiyang12346/article/details/47767595),对Meter Bus进行 ...

  10. AHB总线和APB总线

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

随机推荐

  1. flask统一异常捕获(作用:统一捕获指定的异常并返回)

    flask中可以使用装饰器errorhandler来对指定的异常.状态码等统一捕获并处理. 对指定的状态码进行统一捕获 @app.errorhandler(404) # 参数e是异常的详细信息的对象, ...

  2. rust 过程宏

    简介 Rust 编程语言里面有两种宏系统,一种是声明宏(Declarative Macros),另一种为过程宏(Procedural Macros).声明宏和过程宏是两种基本上完全不一样的宏系统,编写 ...

  3. spring自定义session分布式session

    spring实现自定义session.springboot实现自定义session.自定义sessionid的key.value.实现分布式会话 一.原始方案 自定义生成sessionid的值 修改t ...

  4. DevOps常用工具全家桶,实现高效运维和交付

    DevOps常用工具全家桶,实现高效运维和交付 1.DevOps发展 DevOps发展背景: 随着互联网技术的快速发展,软件开发和运维的挑战也日益增加.传统的软件开发和运维模式往往存在分离.效率低下. ...

  5. 懂分析、会预测,你见过这样的华为云DAS吗?

    摘要:数字化时代下,华为云数据管理服务DAS基于AI技术,于近期推出了智能SQL分析(包括慢SQL发现.SQL透视).workload级别索引推荐.存储空间预测等运维特性,加上原有的数据库运维能力,构 ...

  6. 推理实践丨如何使用MindStudio进行Pytorch模型离线推理

    摘要:本教程所示例的任务是Ascend Pytorch离线推理,即对给定的已经训练好的模型参数和推理脚本,在Ascend 310/710和Tesla设备上进行推理应用. 本文分享自华为云社区<使 ...

  7. 云小课|CDN第5课 CDN入门之—我的网站可以用CDN加速吗?

    摘要:CDN(Content Delivery Network,内容分发网络)通过将源站资源缓存到遍布各地的边缘节点服务器上,用户可以就近获取资源,从而达到加速的效果. 本文分享自华为云社区<[ ...

  8. 无法安装此app,因为无法验证其完整性 ,解决方案

    最近有很多兄弟萌跟我反应"无法安装此app,因为无法验证其完整性 ",看来这个问题无法避免了,今天统一回复下,出现提示主要有以下几种可能 1.安装包不完整 首先申请我所有分享的破解 ...

  9. 注册中心 —— SpringCloud Netflix Eureka

    Eureka 简介 Eureka 是一个基于 REST 的服务发现组件,SpringCloud 将它集成在其子项目 spring-cloud-netflix 中,以实现 SpringCloud 的服务 ...

  10. Hugging News #0203: 3.3 MB 的文生图模型、RHLF 训练框架、手机上能跑的 Transformer

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...