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

单页网站如何制作/厦门关键词排名优化

单页网站如何制作,厦门关键词排名优化,做网站最低多少钱,整合营销策略本文从微信公众号--数字IC小站,​转载,欢迎关注,微信公众号更新更多更快带选通信号的同步FIFO(可综合RTL设计)​mp.weixin.qq.com​还是上次那个同步FIFO,传送门在这~带选通信号的同步FIFO(重发…

本文从微信公众号--数字IC小站,​转载,欢迎关注,微信公众号更新更多更快

带选通信号的同步FIFO(可综合RTL设计)​mp.weixin.qq.com
e59a5309a88d510cfe4e0f5114e74db1.png

​还是上次那个同步FIFO,传送门在这~

带选通信号的同步FIFO(重发)​mp.weixin.qq.com
f1bec6a27341453801ae06c231876cf8.png

上次讲的是用SystemVerilog去设计这个FIFO,那么如果用可综合的RTL代码怎么设计呢?

  • 因为本次FIFO的输入数据位宽实际上可以看成是不固定的,每次输出的数据却都是4byte,那么很容易产生的一个问题就是,前一时刻还是未满状态,下一时刻却已经是溢出(overflow)了
  • 那么为了解决上一个问题,我的想法是,当FIFO深度不足8byte时,就拉低Ready_in信号,不再写入数据。
  • 有同学和我讨论过一个问题,那就是设置为深度不足4byte的时候可不可以,原本想法是当FIFO中存在足够数据时,那么每个clock都会输出4byte数据,此时输入8byte还是可以存储的,可能这个问题和仿真器有关,我们不确定到底是先读还是先写,这个会存在不确定态,所以最好还是预留8byte的空间为好。
  • 我们最好把FIFO宽度设置为1byte,从交上来的作业来看,我们常犯的错误是写入数据指针的设置,有点同学直接设置一个基指针,然后就是如下代码所示:
// write pointer always @(posedge clock or negedge reset_n) beginif (!reset_n) beginwptr <= 0;end else beginif (valid_in & ready_in) begin// can write into the fifo when input is valid and fifo is readycase (size)2'b00: begin fifo_mem[wptr[ADDR_WIDTH-1:0]]    <= data_in[7:0];wptr <= wptr + 1;end2'b01: beginfifo_mem[wptr[ADDR_WIDTH-1:0]]    <= data_in[7:0];fifo_mem[wptr[ADDR_WIDTH-1:0]+1] <= data_in[15:8];wptr <= wptr + 2;end2'b10: begin fifo_mem[wptr[ADDR_WIDTH-1:0]]    <= data_in[7:0];fifo_mem[wptr[ADDR_WIDTH-1:0]+1] <= data_in[15:8];fifo_mem[wptr[ADDR_WIDTH-1:0]+2] <= data_in[23:16];fifo_mem[wptr[ADDR_WIDTH-1:0]+3] <= data_in[31:24];wptr <= wptr + 4;

上述代码的主要问题是,会存在数据写飞的情况...

数据在哪会丢失呢?确实,我们把wptr写指针的数据宽度设置好了,为5位宽,因此wptr最多为31,没毛病,可是这时候wptr[ADDR_WIDTH-1:0]+3为多少呢?这个数据会写到地址为34的FIFO中,因为不存在这个地址,然后数据就丢了...丢了解决方法有好几种,比如我们多设计几个中间变量,把变量的宽度进行限制;比如我们把上述写指针取余,这样就不可能宽度溢出...还有很多方法设计FIFO的方法有很多,可以加计数器,判断FIFO内部还有多少数据,甚至可以写状态机...

我设计的时候就是不想加计数器,这样可以减少硬件资源,只通过读写地址之间的关系判断是否空满...

主要思路如下(code仅供参考,欢迎讨论):

`timescale 1ns / 100ps
//******************************************************************
​
// Author:SJTU_chen
// Date: 2019/10/26
// Version: v1.0
// Module Name: fifo-dut
// Project Name: SystemVerilog Lab1
​
//*******************************************************************
module fifo_dut(clock,reset_n,valid_in,wstrb,data_in,valid_out,data_out,ready_in);
​input           clock,reset_n,valid_in;input [1:0]     wstrb;input [63:0]    data_in;output          valid_out;   output[31:0]    data_out;output          ready_in;
​parameter FIFO_DATA_WIDTH = 8   ; parameter FIFO_DP = 32 ;
​parameter FIFO_ADDR_WIDTH = clogb2(FIFO_DP)  ;
​reg     [31:0]                  data_out;reg                             valid_out;wire                            enough_data;wire                            enough_space; wire                            ready_in;wire         [4:0]              fifo_wr_addr1,fifo_wr_addr2,fifo_wr_addr3,fifo_wr_addr4,fifo_wr_addr5,fifo_wr_addr6,fifo_wr_addr7;wire     [FIFO_ADDR_WIDTH-1:0]  fifo_wr_addr ;  //fifo write addresswire     [FIFO_ADDR_WIDTH-1:0]  fifo_rd_addr ;  //fifo read addressreg      [FIFO_ADDR_WIDTH:0]    wr_addr_ptr;    //fifo write pointerreg      [FIFO_ADDR_WIDTH:0]    rd_addr_ptr;    //fifo read pointer
​reg [FIFO_DATA_WIDTH-1:0] fifo_mem [FIFO_DP-1:0] ;  //fifo data width is 8 .depth is 32
​assign   fifo_wr_addr1=fifo_wr_addr+1;assign   fifo_wr_addr2=fifo_wr_addr+2;assign   fifo_wr_addr3=fifo_wr_addr+3;assign   fifo_wr_addr4=fifo_wr_addr+4;assign   fifo_wr_addr5=fifo_wr_addr+5;assign   fifo_wr_addr6=fifo_wr_addr+6;assign   fifo_wr_addr7=fifo_wr_addr+7;

上述参数和中间变量设置好以后,接下来就是读写数据啦

// write data to fifoalways @(posedge clock or negedge reset_n)if (reset_n &&valid_in && enough_space) beginif(wstrb==2'b00) beginfifo_mem[fifo_wr_addr]   <= data_in[7:0];endelse if (wstrb==2'b01) beginfifo_mem[fifo_wr_addr]   <= data_in[7:0];fifo_mem[fifo_wr_addr1] <= data_in[15:8];endelse if (wstrb==2'b10) beginfifo_mem[fifo_wr_addr]   <= data_in[7:0];fifo_mem[fifo_wr_addr1] <= data_in[15:8];fifo_mem[fifo_wr_addr2] <= data_in[23:16];fifo_mem[fifo_wr_addr3] <= data_in[31:24];endelse if (wstrb==2'b11) beginfifo_mem[fifo_wr_addr]   <= data_in[7:0];fifo_mem[fifo_wr_addr1] <= data_in[15:8];fifo_mem[fifo_wr_addr2] <= data_in[23:16];fifo_mem[fifo_wr_addr3] <= data_in[31:24];fifo_mem[fifo_wr_addr4] <= data_in[39:32];fifo_mem[fifo_wr_addr5] <= data_in[47:40];fifo_mem[fifo_wr_addr6] <= data_in[55:48];fifo_mem[fifo_wr_addr7] <= data_in[63:56];endendelse beginfifo_mem[fifo_wr_addr] <= fifo_mem[fifo_wr_addr];end// read dataalways @(posedge clock or negedge reset_n)beginif(reset_n == 1'b0) begindata_out <= {32{1'b0}} ;endelse if (enough_data) begindata_out[7:0]     <= fifo_mem[fifo_rd_addr] ; data_out[15:8]    <= fifo_mem[fifo_rd_addr+1] ; data_out[23:16]   <= fifo_mem[fifo_rd_addr+2] ;         data_out[31:24]   <= fifo_mem[fifo_rd_addr+3] ; endelse  begindata_out          <=data_out;end    end

指针变化

 // write pointer always @(posedge clock or negedge reset_n)beginif(reset_n == 1'b0)wr_addr_ptr <= {(FIFO_ADDR_WIDTH+1){1'b0}} ;else if (valid_in && enough_space)beginif(wstrb==2'b00) beginwr_addr_ptr <= wr_addr_ptr + 1'b1 ;endelse if(wstrb==2'b01) beginwr_addr_ptr <= wr_addr_ptr + 2'b10 ;endelse if(wstrb==2'b10) beginwr_addr_ptr <= wr_addr_ptr + 3'b100 ;endelse if(wstrb==2'b11) beginwr_addr_ptr <= wr_addr_ptr + 4'b1000 ;endendelse beginwr_addr_ptr <= wr_addr_ptr;end      end
​//read pointeralways @(posedge clock or negedge reset_n)beginif(reset_n == 1'b0)rd_addr_ptr <= {(FIFO_ADDR_WIDTH+1){1'b0}} ;else if (enough_data)rd_addr_ptr <= rd_addr_ptr + 3'b100 ; elserd_addr_ptr <= rd_addr_ptr;end

状态变化

    // valid_out statealways @(posedge clock or negedge reset_n)beginif(reset_n == 1'b0) beginvalid_out     <='0;endelse if (enough_data) beginvalid_out     <='1;endelse  beginvalid_out     <='0;end    end  

判断内部空间:

    //ready_inassign ready_in     = enough_space;
​assign fifo_wr_addr = wr_addr_ptr[FIFO_ADDR_WIDTH-1:0];assign fifo_rd_addr = rd_addr_ptr[FIFO_ADDR_WIDTH-1:0];
​assign enough_data  = ((wr_addr_ptr >= rd_addr_ptr+4)||(rd_addr_ptr >= wr_addr_ptr+4))?1:0;
​wire  addr_select1,addr_select2,addr_select3;assign addr_select1 =((fifo_rd_addr>fifo_wr_addr)&&( fifo_rd_addr-fifo_wr_addr<8))?1:0;assign addr_select2 =((fifo_rd_addr<fifo_wr_addr)&&( fifo_wr_addr-fifo_rd_addr>24))?1:0;assign addr_select3 = (wr_addr_ptr[FIFO_ADDR_WIDTH]^rd_addr_ptr[FIFO_ADDR_WIDTH])?1:0;assign addr_select4 = (wr_addr_ptr[FIFO_ADDR_WIDTH]~^rd_addr_ptr[FIFO_ADDR_WIDTH])?1:0;assign enough_space =((addr_select1&addr_select3)|(addr_select2&addr_select4))?0:1;

上述代码中,addr_select判断读指针和写指针的位置,1.当读指针大于写指针,两个指针位置小于8,并且wr_addr_ptr的最高位不相同时则接近满。2.当写指针大于读指针,两个指针位置大于24,并且wr_addr_ptr的最高位相同时则接近满。这个是在深度为32时的情况,当深度为其他深度n时,则数值24应该改为n-8。

 function integer clogb2 (input integer size);beginsize = size - 1;for (clogb2=1; size>1; clogb2=clogb2+1)size = size >> 1;endendfunction // clogb2

上述代码实现的就是一个取对数函数,用来生成地址宽度与数据深度之间的关系。

上述代码经过questa sim10.6c验证,应该是没问题,但是不保证完全正确,如有bug,欢迎私信交流~

欢迎关注,分享~~

http://www.lbrq.cn/news/949771.html

相关文章:

  • 合肥手机网站建设/微信软文怎么写
  • java做web网站的流程/住房和城乡建设部
  • 微信上的网站/百度广告屏蔽
  • 网站建设科技公司/线下推广有哪几种渠道
  • 快速做网站用什么软件/长沙企业关键词优化
  • 重庆网站建设jwzcq/seo关键词快速排名前三位
  • 做网站怎么收费多少/今日新闻最新头条10条内容
  • 选择合肥网站建设/什么是网络营销的核心
  • 沈阳网站制作思路网络/快手秒赞秒评网站推广
  • 西安建设学院网站/长沙营销网站建设
  • 如何做psd的模板下载网站/百度一下官网手机版
  • 如何布局网站/西安seo优化培训机构
  • 免费房地产网站模板/推广费用一般多少
  • 北京seo平台/商丘网站seo
  • 广州化妆品网站建设/今日全国最新疫情通报
  • 免费行情软件app网站大全下载u288/网站提交入口链接
  • 怎么做有图有声的网站/100个免费推广b站
  • 广东企业网站建设公司/手机百度app下载安装
  • 河南做网站 河南网站建设/软文推广名词解释
  • 网站建设业务怎么开展/西安做网站的网络公司
  • 柞水县住房和城乡建设局网站/google关键词优化
  • 做虚拟币网站需要什么手续/游戏推广对接平台
  • 全国可信网站/市场营销策划包括哪些内容
  • 大连网站制作的公司哪家好/怎么在网上销售
  • 网站建设工作报告/教育培训机构加盟十大排名
  • 购物形式网站制作/百度网盘账号登录入口
  • 网站安全建设方案报告/百度上打广告怎么收费
  • html5微信网站模板/河南网站推广多少钱
  • 汕头网站建设小程序/网站维护一年一般多少钱?
  • 建wiki网站/seo网站排名优化工具
  • Linux find命令:强大的文件搜索工具
  • vscode 使用说明二
  • 【前端状态更新与异步协调完全指南:React、Vue架构原理与复杂业务场景实战】
  • 《杜甫传》读书笔记与经典摘要(一)
  • 前端静态资源免费cdn服务推荐
  • 企业安全防护:堡垒机技术解析