当前位置: 首页 > news >正文

公司以前做的免费网站太多 新网站搜索不到济宁鱼台网站建设

公司以前做的免费网站太多 新网站搜索不到,济宁鱼台网站建设,seo站群优化,网站开发脚本解析器AMBA总线--APB协议时序及Verilog实现 1 APB3协议1.1 APB3时序1.1.1 APB写操作1.1.2 APB读操作 2 代码2.1 apb_master2.2 apb_slave 【博客首发于微信公众号《漫谈芯片与编程》,欢迎专注一下,多谢大家】 AMBA总线是用于连接微控制器和外围设备的总线协议&…

AMBA总线--APB协议时序及Verilog实现

  • 1 APB3协议
    • 1.1 APB3时序
      • 1.1.1 APB写操作
      • 1.1.2 APB读操作
  • 2 代码
    • 2.1 apb_master
    • 2.2 apb_slave

【博客首发于微信公众号《漫谈芯片与编程》,欢迎专注一下,多谢大家】

AMBA总线是用于连接微控制器和外围设备的总线协议,由ARM公司提出的一种片上系统SoC互联标准。
AMBA总线协议家族主要包括:APB、AHB、AXI、ACI、CHI协议;其中后两个协议主要是专门为了缓存一致性;

本篇博客主要介绍 APB3协议;
在这里插入图片描述

1 APB3协议

APB3协议:APB用来实现与外围设备进行通信–一般用来配置寄存器;APB协议是一主多从,唯一的master一般是apb_bridge模块;
总体特点:低功耗、低带宽、无流水线结构、每次传输至少需要两个时钟周期;
在这里插入图片描述

1.1 APB3时序

在这里会分别给出有等待和无等待的时序图做对比,在项目中主要还是用的有等待时序图;
什么是无等待:即slave会直接在maste拉高penable时进行拉高,只维持一个周期;
什么是有等待:即slave会跟自己内部业务进行任意时刻拉高pready,而在此期间以上master的信号都要维持不变;

1.1.1 APB写操作

在这里插入图片描述

【描述】
1.T0周期(T0-T1):IDLE状态;
2.T1周期(T1-T2):master提前准备好pasel,paddr,pwrite,pwdata;
3.T2周期(T2-T3):master拉高penable,告知当前数据有效,进行采样传输;
–>T3周期(T3-T4):是代表数据传输结束,回到IDLE状态;

1.1.2 APB读操作

在这里插入图片描述

T0周期:IDLE状态;
T1周期:master提前准备好psel,paddr,pwrite;
T2周期:在无等待模式下:slave准备好prdate并拉高pready;当然在有等待模式下,pready可以继续没准备好,当pready准备好拉高后,prdata同时返回并有效;

2 代码

从前面系列篇可知:对待时序,我们尽量用状态机来设计指导编码;
在这里官方给出状态机:正好对应上面时序图上的周期;
在这里插入图片描述

IDLE:deault state;
SetUp:psel立刻拉高,相关信号在setup阶段准备好,并且下一周期就立刻转移到下一状态;
Access:penable在该状态拉高,相关信号paddr,pwrite,psel,pwdata等在这保持;

2.1 apb_master

在这里实现一个apb_master的代码示例:
在这里插入图片描述

/*-------------------------------------------------------------
-- modified by xlinxdu, 2022/05/27
-- pclk 50MHz
-- APB3,No pslverr signal
-- cmd_i:56bit;[55:48]:r/w ,8'b0 -> read,8'b1 -> write[47:32]:paddr ,[31:0]:pwdata
-------------------------------------------------------------*/
module apb
#(parameter RD_FLAG        = 8'b0           ,parameter WR_FLAG        = 8'b1           ,parameter CMD_RW_WIDTH   = 8              ,parameter CMD_ADDR_WIDTH = 16             ,parameter CMD_DATA_WIDTH = 32             ,parameter CMD_WIDTH      = CMD_RW_WIDTH   + CMD_ADDR_WIDTH + CMD_DATA_WIDTH
)(
//-- system signalinput                           pclk_i       ,input                           prst_n_i     ,//-- cmd_ininput      [CMD_WIDTH-1:0]      cmd_i        ,input                           cmd_vld_i    ,output reg [CMD_DATA_WIDTH-1:0] cmd_rd_data_o,//-- apb interfaceoutput reg [CMD_ADDR_WIDTH-1:0] paddr_o      ,output reg                      pwrite_o     ,output reg                      psel_o       ,output reg                      penable_o    ,output reg [CMD_DATA_WIDTH-1:0] pwdata_o     ,input      [CMD_DATA_WIDTH-1:0] prdata_i     ,input                           pready_i     ,input                           pslverr_i
);//-- FSM state
parameter IDLE   = 3'b001;
parameter SETUP  = 3'b010;
parameter ACCESS = 3'b100;//-- current state and next state
reg [2:0] cur_state;
reg [2:0] nxt_state;//-- data buf
reg                      start_flag     ;
reg [CMD_WIDTH-1:0]      cmd_in_buf     ;
reg [CMD_DATA_WIDTH-1:0] cmd_rd_data_buf;/*-----------------------------------------------\--             update cmd_in_buf              --
\-----------------------------------------------*/
always @ (posedge pclk_i or negedge prst_n_i) beginif (!prst_n_i) begincmd_in_buf <= {(CMD_WIDTH){1'b0}};endelse if (cmd_vld_i && pready_i) begincmd_in_buf <= cmd_i;end
end/*-----------------------------------------------\--             start flag of transfer         --
\-----------------------------------------------*/
always @ (posedge pclk_i or negedge prst_n_i) beginif (!prst_n_i) beginstart_flag <= 1'b0;endelse if (cmd_vld_i && pready_i) beginstart_flag <= 1'b1;endelse beginstart_flag <= 1'b0;end
end/*-----------------------------------------------\--           update current state             --
\-----------------------------------------------*/
always @ (posedge pclk_i or negedge prst_n_i) beginif (!prst_n_i) begincur_state <= IDLE;endelse begincur_state <= nxt_state;end
end/*-----------------------------------------------\--               update next state            --
\-----------------------------------------------*/
always @ (*) begincase(cur_state)IDLE  :if(start_flag)beginnxt_state = SETUP;endelse beginnxt_state = IDLE;endSETUP :nxt_state = ACCESS;ACCESS:if (!pready_i)beginnxt_state = ACCESS;endelse if(start_flag)beginnxt_state = SETUP;endelse if(!cmd_vld_i && pready_i)beginnxt_state = IDLE;endendcase
end/*-----------------------------------------------\--         update signal of output            --
\-----------------------------------------------*/
always @ (posedge pclk_i or negedge prst_n_i) beginif (!prst_n_i) beginpwrite_o  <= 1'b0;psel_o    <= 1'b0;penable_o <= 1'b0;paddr_o   <= {(CMD_ADDR_WIDTH){1'b0}};pwdata_o  <= {(CMD_DATA_WIDTH){1'b0}};endelse if (nxt_state == IDLE) beginpsel_o    <= 1'b0;penable_o <= 1'b0;endelse if(nxt_state == SETUP)beginpsel_o    <= 1'b1;penable_o <= 1'b0;paddr_o   <= cmd_in_buf[CMD_WIDTH-CMD_RW_WIDTH-1:CMD_DATA_WIDTH];//-- readif(cmd_in_buf[CMD_WIDTH-1:CMD_WIDTH-8] == RD_FLAG)beginpwrite_o <= 1'b0;end//-- writeelse beginpwrite_o  <= 1'b1;pwdata_o  <= cmd_in_buf[CMD_DATA_WIDTH-1:0];endendelse if(nxt_state == ACCESS)beginpenable_o <= 1'b1;end
end/*-----------------------------------------------\--            update cmd_rd_data_buf          --
\-----------------------------------------------*/
always @ (posedge pclk_i or negedge prst_n_i) beginif (!prst_n_i) begincmd_rd_data_buf <= {(CMD_DATA_WIDTH){1'b0}};endelse if (pready_i && psel_o && penable_o) begincmd_rd_data_buf <= prdata_i;end
end/*-----------------------------------------------\--            update cmd_rd_data_o            --
\-----------------------------------------------*/
always @ (posedge pclk_i or negedge prst_n_i) beginif (!prst_n_i) begincmd_rd_data_o <= {(CMD_DATA_WIDTH){1'b0}};endelse begincmd_rd_data_o <= cmd_rd_data_buf;end
endendmodule

2.2 apb_slave

在这里实现一个apb_slave读写寄存器的Demo;

`timescale 1ns/100psmodule apb_slave #(parameter AW = 32,//地址总线宽度parameter DW = 32 //数据总线宽度) (//systeminput               reset_n,//apb_interfaceinput               pclk,     //时钟input [AW-1:0]      paddr,    //地址input               pwrite,   //读/写控制信号input               psel,     //选择信号input               penable,  //使能信号input [DW-1:0]      pwdata,   //写(输入)数据output reg [DW-1:0] prdata,   //读(输出)数据output reg          pready,   //传输完成标志,low未完成,high完成output reg          pslverr   //错误标志,high出现错误);
//apb状态机
parameter IDLE   = 2'b00;
parameter SETUP  = 2'b01;
parameter ACCESS = 2'b10;
reg [1:0] state_now  = 2'b00;
reg [1:0] state_next  = 2'b00;//映射到总线上的寄存器
reg [31:0]   readonly32;     //0x10000000,只可读
reg [15:0]   readonly16;     //0x10000004,只可读
reg [31:0]   readwrite32;    //0x10000008,可读可写
reg [15:0]   readwrite16;    //0x1000000C,可读可写always @(posedge pclk or negedge reset_n) begin: init_and_change_stateif (!reset_n) beginpready  <= 1'b0;pslverr <= 1'b0;prdata  <= 32'h0;readwrite32 <= 32'h0;readwrite16 <= 16'h0;readonly32 <= 32'h12345678;readonly16 <= 16'habcd;state_now <= IDLE;endelse beginstate_now <= state_next;end
end//! fsm_extract
always @(posedge pclk) begin :main_fsm_of_apbcase (state_now)IDLE: begin //IDLE状态case (psel)1'b1: state_next <= SETUP;  //选择本apb外设,进入setup状态1'b0: state_next <= IDLE;default: state_next <= IDLE;endcaseendSETUP: begin//SETUP状态case (psel)1'b1: begincase (penable)1'b1: state_next <= ACCESS;//选中且enable信号拉高,进入ACCESS模式传输数据1'b0: state_next <= SETUP;default: state_next <= SETUP;endcaseend1'b0: state_next <= IDLE;   //未被选中,回到IDLEdefault: state_next <= IDLE;endcasepready <= 1'b0;endACCESS: begin //ACCESS状态,根据寄存器地址读写prdata <= 32'h0;pslverr <= 1'b0;if (pwrite) begin   //wirte信号拉高,写入模式case (paddr)32'h10000008: begin readwrite32 <= pwdata; pready <= 1'b1; end//数据传输完成 32'h1000000C: begin readwrite16 <= pwdata[15:0]; pready <= 1'b1; end//数据传输完成 default: pslverr <= 1'b1;endcaseendelse if(!pwrite) begin  //write信号拉低,读取模式case (paddr)32'h10000000: begin prdata <= readonly32; pready <= 1'b1; end//数据传输完成 32'h10000004: begin prdata <= readonly16; pready <= 1'b1; end//数据传输完成 32'h10000008: begin prdata <= readwrite32; pready <= 1'b1; end//数据传输完成 32'h1000000C: begin prdata <= readwrite16; pready <= 1'b1; end//数据传输完成 default: pslverr <= 1'b1;endcaseendif (pready) begincase (psel)1'b1: state_next <= SETUP;  //不需要传输数据,回到SETUP1'b0: state_next <= IDLE;   //未被选中,回到IDLEdefault: state_next <= IDLE;endcaseendelse state_next <= ACCESS; //需要继续传输数据,则回到ACCESS       enddefault: state_next <= IDLE;endcase
end
endmodule

[ref]
1.https://blog.csdn.net/qq_43244515/article/details/124968189
2.https://www.amghank.cn/2021/08/24/CORE%E5%AD%A6%E4%B9%A0%EF%BC%9AAMBA3–APB%E6%80%BB%E7%BA%BF%E5%8D%8F%E8%AE%AE%E5%8F%8A%E7%AE%80%E5%8D%95%E4%BE%8B%E5%AD%90/

http://www.yayakq.cn/news/295547/

相关文章:

  • 前端开发学习网站在线捕鱼网站建设
  • 建一个动物网站怎么做沛县网站定制
  • 网站建设毕业设计论文wordpress 模板 删除
  • 公司英文网站多少钱做网站的基本流程
  • 酒泉百度做网站多少钱semir
  • 昆明建企业网站多少钱wordpress docker安装目录
  • 让人做网站需要准备什么条件个人展示网站
  • 成都新津网站建设简历制作官网
  • 能力天空的网站建设优劣势交易平台网站怎么做
  • 个人网站开发工具东阿网站建设电话
  • 湖南商城网站建设默认网站预览能能显示建设中
  • 企业网站的建设费用看设计比较好的网站
  • 知名设计公司网站永州公司做网站
  • 静态网站seo怎么做平面设计提高审美网站
  • 技术网站网络推广公司名字
  • 临海企业网站建设公司广州手机软件开发制作
  • 如何建立自己的网站去推广有赞分销平台
  • WordPress建站步骤免费申请无限流量卡
  • 河北网站建设工程wordpress自己新建模板
  • 可以做夫妻的游戏视频网站wordpress首页获取文章的图片
  • 家具网站建设策划书企业所得税怎么征收几个点
  • 滨州建网站尚硅谷python基础教程
  • 门店管理网站建设乐清网站建设推广
  • 顺德乐从有做阿里巴巴的网站吗编程如何自学
  • 国家建设工程网官方网站ps网页设计尺寸规范
  • 北京建设网站有哪些公司网站开发手机销售网站用例图
  • 网站开发过程的基本环节益阳中国网
  • 哪个网站专做进口商品的东莞免费做网站公司
  • 网站建设价格为何相差甚大施工企业施工生产计划
  • 公司网站建设怎么弄如何做一个企业的网站