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. Cisco 交换机利用CDP数据自动绘制网络拓扑图[drawio]-实践

    进行网络运维,必须对网络拓扑情况进行详细的掌握,但是网络改动后,更新网络拓扑比较繁琐,维护人员容易懈怠,久而久之,通过人工绘制的网络拓扑很容易与现有网络出现偏差. 现在,可以通过python 丰富的库 ...

  2. NTP时间服务器优先级介绍

    先思考一个问题:当一个客户端配置向多个NTP时间服务器校时,此时客户端优先向哪个时间服务器同步时间呢? 一个完整的NTP校时请求分四步: 1.客户端向服务器发起校时请求 2.服务器收到客户端发送的校时 ...

  3. 有意思,我的GitHub账号值$23806.2,快来试试你的?

    睡不着,看到一个有意思的网站:Estimate Github Worth Generator. 它可以用来估算 GitHub 账号的价值.马上试了一下. 我的账号估值:$23806.2 操作很简单,点 ...

  4. 国家专用加密数据传输之rsa,3des加密方法-rasor3desc

    title: 国家专用加密数据传输之rsa,3des加密方法 date: 2021-12-20 13:08:21.646 updated: 2022-03-10 16:00:58.65 url: ht ...

  5. 防火墙添加允许服务器IP和端口方法

    一.检测防火墙命令 systemctl status firewalld 如果显示如下active表示防火墙开启 ● firewalld.service - firewalld - dynamic f ...

  6. 在线录屏-通过Web API接口轻松实现录屏

    在线录屏是指在互联网上进行屏幕录制的过程.它允许用户通过网络连接,将自己的屏幕活动记录下来,并可以在需要时进行播放.共享或存档.在线录屏常用于教育.培训.演示.游戏等场景,可以帮助用户展示操作步骤.解 ...

  7. Redis系列(二):解读redis.conf文件、配置、初步使用

    一.解读redis.conf配置文件 # redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k =&g ...

  8. 探索开源工作流引擎Azkaban在MRS中的实践

    摘要:本文主要介绍如何在华为云上从0-1搭建azkaban并指导用户如何提交作业至MRS. 本文分享自华为云社区<开源工作流引擎Azkaban在MRS中的实践>,作者:啊喔YeYe. 环境 ...

  9. 手把手带你做LiteOS的树莓派移植

    摘要:树莓派是英国的慈善组织"Raspberry Pi 基金会"开发的一款基于arm的微型电脑主板.本文介绍基于LiteOS的树莓派移植过程. 本文分享自华为云社区<2021 ...

  10. 从1天到10分钟的超越,华为云DRS在背后做了这些

    摘要:华为云DRS助力一汽-大众BI平台实时查看报表,提升数字化决策能力. 本文分享自华为云社区<分钟级查看报表,华为云&一汽-大众,让商机时刻被洞见>,作者:GaussDB 数据 ...