zoukankan      html  css  js  c++  java
  • Verilog 学习笔记之—FIFO

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

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

     

    Verilog <wbr>学习笔记之—FIFO

     

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

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

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

    具体Verilog 代码如下:

    module fifo
    #(
    parameter B = 8,   //number of bits in a word
              = 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 ,编译完成后生成了网标,可以看一看:

    Verilog <wbr>学习笔记之—FIFO

        

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

        working harder tomorrow!

  • 相关阅读:
    C#委托、事件、消息(入门级)
    WinForm编程数据视图之DataGridView浅析(续)
    WinForm编程数据视图之DataGridView浅析
    在Java窗体表格中插入复选框
    单向链表(单链表)的Java实现
    C#委托、事件、消息(入门级)(续)
    Windows7操作系统自定义运行命令(简单方法之一)
    Unity的外部配置文件使用方法
    aspnet_regsql如何给sqlexpress添加aspnetdb
    联想Y530改装XP经验
  • 原文地址:https://www.cnblogs.com/JustDoFPGA/p/8412744.html
Copyright © 2011-2022 走看看