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. 安装了华企盾DSC防泄密,所有进程的加密文件都无法打开

    用pchunter等工具查看系统回调中是否有文件厂商不存在的(system目录的除外),在恢复模式删除掉,或者用360系统急救箱查杀一下

  2. 数字孪生结合GIS会为智慧农业带来怎样的改变?

    数字孪生是一种创新的技术,它通过将现实世界的物理实体与数字模型相结合,实现了实时.动态的仿真和预测.而地理信息系统(GIS)则是一种用于收集.管理.分析和展示地理数据的工具.当这两种技术相互融合时,将 ...

  3. int和String的相互转换

  4. STM32CubeMX教程5 TIM 定时器概述及基本定时器

    1.准备材料 开发板(STM32F407G-DISC1) ST-LINK/V2驱动 STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) 逻 ...

  5. 2023-11-29:用go语言,给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。 需保证 返回结果的字典序最小。 要求不能打乱其他字符的相对位置)。 输入:s = “cba

    2023-11-29:用go语言,给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次. 需保证 返回结果的字典序最小. 要求不能打乱其他字符的相对位置). 输入:s = &quo ...

  6. MySQL篇:bug2_ Navicate无法添加或更新子行-外键约束失败

    问题产生原因 Mysql中如果表和表之间建立的外键约束,则无法删除表及修改表结构. 解决办法 解决方法是在Mysql中取消外键约束: SET FOREIGN_KEY_CHECKS=0; 再添加值, 然 ...

  7. 想了解Webpack,看这篇就够了

    摘要:Webpack是一种前端资源构建工具,一个静态模块打包器. 1. 摘要 Webpack是一种前端资源构建工具,一个静态模块打包器.在Webpack看来,前端的所有资源文件(js/json/css ...

  8. CANN AICPU算子耗时分析及优化探索

    摘要:本文以GreaterEqual作为测试算子,该算子计算逻辑较为简单(output = input1 >= input2),旨在尽可能降低计算耗时,使得算子耗时尽可能以数据操作和算子调度作为 ...

  9. SQL优化老出错,那是你没弄明白MySQL解释计划

    摘要:数据库的解释计划阐明了sql的执行过程,展示了执行的细节,只要根据数据库告诉我们的问题按图索骥的分析就可以. 本文分享自华为云社区<轻松搞懂mysql的执行计划,再也不怕sql优化了> ...

  10. 通过windows自带管理工具、系统命令行、快捷键等快速操作

    windows自带管理工具 我们win+R 输入一些命令,可以快速打开一些界面,比如: sysdm.cpl win10.win11 我电脑,属性与之前win7不同了,我希望打开之前的属性打不开了 通过 ...