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的片上系统总线,它包括以下一些特性:单个时钟边沿操作:非三态的实现方式:支持突发传输:支持分段传输:支持多个主控制器:可配置 ...
随机推荐
- Cisco 交换机利用CDP数据自动绘制网络拓扑图[drawio]-实践
进行网络运维,必须对网络拓扑情况进行详细的掌握,但是网络改动后,更新网络拓扑比较繁琐,维护人员容易懈怠,久而久之,通过人工绘制的网络拓扑很容易与现有网络出现偏差. 现在,可以通过python 丰富的库 ...
- NTP时间服务器优先级介绍
先思考一个问题:当一个客户端配置向多个NTP时间服务器校时,此时客户端优先向哪个时间服务器同步时间呢? 一个完整的NTP校时请求分四步: 1.客户端向服务器发起校时请求 2.服务器收到客户端发送的校时 ...
- 有意思,我的GitHub账号值$23806.2,快来试试你的?
睡不着,看到一个有意思的网站:Estimate Github Worth Generator. 它可以用来估算 GitHub 账号的价值.马上试了一下. 我的账号估值:$23806.2 操作很简单,点 ...
- 国家专用加密数据传输之rsa,3des加密方法-rasor3desc
title: 国家专用加密数据传输之rsa,3des加密方法 date: 2021-12-20 13:08:21.646 updated: 2022-03-10 16:00:58.65 url: ht ...
- 防火墙添加允许服务器IP和端口方法
一.检测防火墙命令 systemctl status firewalld 如果显示如下active表示防火墙开启 ● firewalld.service - firewalld - dynamic f ...
- 在线录屏-通过Web API接口轻松实现录屏
在线录屏是指在互联网上进行屏幕录制的过程.它允许用户通过网络连接,将自己的屏幕活动记录下来,并可以在需要时进行播放.共享或存档.在线录屏常用于教育.培训.演示.游戏等场景,可以帮助用户展示操作步骤.解 ...
- Redis系列(二):解读redis.conf文件、配置、初步使用
一.解读redis.conf配置文件 # redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k =&g ...
- 探索开源工作流引擎Azkaban在MRS中的实践
摘要:本文主要介绍如何在华为云上从0-1搭建azkaban并指导用户如何提交作业至MRS. 本文分享自华为云社区<开源工作流引擎Azkaban在MRS中的实践>,作者:啊喔YeYe. 环境 ...
- 手把手带你做LiteOS的树莓派移植
摘要:树莓派是英国的慈善组织"Raspberry Pi 基金会"开发的一款基于arm的微型电脑主板.本文介绍基于LiteOS的树莓派移植过程. 本文分享自华为云社区<2021 ...
- 从1天到10分钟的超越,华为云DRS在背后做了这些
摘要:华为云DRS助力一汽-大众BI平台实时查看报表,提升数字化决策能力. 本文分享自华为云社区<分钟级查看报表,华为云&一汽-大众,让商机时刻被洞见>,作者:GaussDB 数据 ...