博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Verilog 学习笔记之—FIFO
阅读量:6534 次
发布时间:2019-06-24

本文共 2272 字,大约阅读时间需要 7 分钟。

    暑期在家,有充足的时间,于是希望自己能在专业技能上有所长,结合自己的爱好于是选择了Verilog。记得大三开设EDA这门课的时候,自己对EDA以及Verilog完全不感兴趣,认为他就是数字电路的重复。因为这种狭隘的眼光,现在才知道当时自己有多么愚蠢没有好好学... ...

   今天先讲一讲队列的实现,因为这个比较容易。有过C语言的基础,就会知道所谓的队列就是一块连续的存储个空间,遵循先进先出的规则,即first in first out.如示意图所描述

 

 

    实现过程中,我们把队列看作是一个圆,用write pointer指向队首,用read pointer指向队尾,完成一次读或写操作pointer加1,这样做可以避免对空寄存器进行读操作,对满寄存器进行写操作,这里有附图片很好的说明了这个问题:

  同时在硬件设计中,我们用两个FF分别记录空状态和满状态,在系统初始化式分别将其置为1和0,然后在每个时钟周期根据续读/写信号修改他们的值。

  这里,我们采用Verilog语言进行描述

具体Verilog 代码如下:

module fifo

#(
parameter B = 8,   //number of bits in a word
          W  = 4   //number of address bits
)
(
input wire clk,reset,
input rd,wr,
input wire [B-1:0] w_data,
output wire empty,full,
output wire [B-1:0] r_data
);

//signal declaration
reg [B-1:0] array_reg [2**W-1:0]; //register array
reg [W-1:0] w_ptr_reg,w_ptr_next,w_ptr_succ;
reg [W-1:0] r_ptr_reg,r_ptr_next,r_ptr_succ;
reg full_reg, empty_reg,full_next,empty_next;
wire wr_en;

 

//body

//register file write operation
always @(posedge clk)
 if(wr_en)
 array_reg[w_ptr_reg] <= w_data;
 //register file read operatiom
assign wr_en = wr & ~full_reg;

 

//fifo control logic

//register for read and write pointers
always @(posedge clk, posedge reset)
 if(reset)
 begin
  w_ptr_reg <= 0;
  r_ptr_reg <=0;
  full_reg <= 1'b0;
  empty_reg <= 1'b1;
 end
 else
 begin
  w_ptr_reg <= w_ptr_next;
  r_ptr_reg <= r_ptr_next;
  full_reg <= full_next;
  empty_reg <= empty_next;
 end 

 

//next-state logic for read and write pointers

always @*
begin
//successive pointer valus
w_ptr_succ = w_ptr_reg + 1;
r_ptr_succ = r_ptr_reg + 1;
//default : keep old values
w_ptr_next = w_ptr_reg;
r_ptr_next = r_ptr_reg;
full_next = full_reg;
empty_next = empty_reg;
case({wr,rd})
//2;b00 : no op
2'b01:  //read
 if(~empty_reg) // not empty
 begin
  r_ptr_next = r_ptr_succ;
  full_next = 1'b0;
  if(r_ptr_succ == w_ptr eg)
  empty_next = 1'b1;
 end
2'b10:  //write
 if(~full_reg) //not full
 begin
 w_ptr_next = w_ptr_succ;
 empty_next = 1'b0;
 if(w_ptr_succ == r_ptr_reg)
 full_next = 1'b1;
 end
2'b11: //write anmd read
 begin
 w_ptr_next = w_ptr_succ;
 r_ptr_next = r_ptr_succ;
 end
endcase
end

 

//output

assign full = full_reg;
assign empty = empty_reg;
endmodule

   我用的编辑环境为quartus ii 9.0 ,编译完成后生成了网标,可以看一看:

    

    暑假还有不到连个月,希望自己能充分利用好这段时间学点什么,不要眼高手低,不要放弃!

    working harder tomorrow!

转载于:https://www.cnblogs.com/JustDoFPGA/archive/2012/07/04/8412744.html

你可能感兴趣的文章
MOXA的智能通信产品也大力支持WinCE.net了
查看>>
ActiveX开发知多少?
查看>>
你不得不知道的Visual Studio 2012(3)- 创建Windows应用程序
查看>>
Android操作系统2.0制作备份
查看>>
To XSS or not ? 杂谈
查看>>
TFTP服务器在Cisco设备上的应用(上传、下载IOS)
查看>>
获得文件和文件夹的所有权
查看>>
烂泥:学习mysql数据库主从同步复制原理
查看>>
Java相对路径读取文件
查看>>
PostgreSQL 商用版本EPAS(阿里云ppas) 自动(postgresql.conf)参数计算与适配功能
查看>>
烂泥:学习ssh之ssh隧道应用
查看>>
Android TableLayout 常用的属性介绍及演示
查看>>
Ajax跨域访问XML数据的另一种方式——使用YQL查询语句
查看>>
[原创]让您的服务器不再有被挂马的烦恼---文件安全卫士
查看>>
流水线和PC指针
查看>>
Fiddler设置抓取https请求
查看>>
div布局小技巧
查看>>
OCP 12c最新考试原题及答案(071-4)
查看>>
MHA故障切换和在线手工切换原理
查看>>
JAVA并发,同步锁性能测试
查看>>