| 
 | 
 
用verilog实现两种同步FIFO的方法,非常适合初学者理解时序的控制过程和方法! 
理解了这个东西,很多verilog 的实现方法和思想你会有一个深入的理解的! 
慢慢积累呀! 
//16*16 fifo// 
//方法1 
// 
module fifo(clock,reset,read,write,fifo_in,fifo_out,fifo_empty,fifo_half,fifo_full); 
  input clock,reset,read,write; 
  input [15:0]fifo_in; 
  output[15:0]fifo_out; 
  output fifo_empty,fifo_half,fifo_full;//标志位 
  reg [15:0]fifo_out; 
  reg [15:0]ram[15:0]; 
  reg [3:0]read_ptr,write_ptr,counter;//指针与计数 
  wire fifo_empty,fifo_half,fifo_full; 
   
  always@(posedge clock) 
  if(reset) 
    begin 
      read_ptr=0; 
      write_ptr=0; 
      counter=0; 
      fifo_out=0;                    //初始值 
    end 
  else 
    case({read,write}) 
      2'b00: 
            counter=counter;        //没有读写指令 
      2'b01:                            //写指令,数据输入fifo 
            begin 
              ram[write_ptr]=fifo_in; 
              counter=counter+1; 
              write_ptr=(write_ptr==15)?0:write_ptr+1; 
            end 
      2'b10:                          //读指令,数据读出fifo 
            begin 
              fifo_out=ram[read_ptr]; 
              counter=counter-1; 
              read_ptr=(read_ptr==15)?0:read_ptr+1; 
            end 
      2'b11:                        //读写指令同时,数据可以直接输出 
            begin 
              if(counter==0) 
                fifo_out=fifo_in; 
              else 
                begin 
                  ram[write_ptr]=fifo_in; 
                  fifo_out=ram[read_ptr]; 
                  write_ptr=(write_ptr==15)?0:write_ptr+1; 
                  read_ptr=(read_ptr==15)?0:write_ptr+1; 
                end 
              end 
        endcase 
         
        assign fifo_empty=(counter==0);    //标志位赋值 组合电路 
        assign fifo_half=(counter==8); 
        assign fifo_full=(counter==15); 
       
    endmodule 
 
 
 
//4*16 fifo 
//方法2 
// 
module fifo_four(clk,rstp,din,readp,writep,dout,emptyp,fullp); 
  input clk;                //时钟 
  input rstp;               //复位 
  input[15:0]din;           //16位输入信号 
  input readp;              //读指令 
  input writep;              //写指令 
  output[15:0]dout;         //16位输出信号 
  output emptyp;            //空指示信号 
  output fullp;             //满指示信号 
   
  parameter DEPTH=2,MAX_COUNT=2'b11; 
   
  reg[15:0]dout; 
  reg emptyp; 
  reg fullp; 
   
  reg[(DEPTH-1):0] tail; //读指针 
  reg[(DEPTH-1):0] head;//写指针 
  reg[(DEPTH-1):0] count; //计数器 
  reg[15:0]fifomem[0:MAX_COUNT]; //四个16位存储单元 
   
  //read 
  always@(posedge clk) 
    if(rstp==1)     
        dout<=0;   
    else if(readp==1&&emptyp==0) 
      dout<=fifomem[tail]; 
   //write    
  always@(posedge clk) 
      if(rstp==1&&writep==1&&fullp==0) 
        fifomem[head]<=din; 
   
  //更新head指针 
  always@(posedge clk)     
  if(rstp==1) 
    head<=0; 
  else if(writep==1&&fullp==0) 
    head<=head+1; 
     
  //更新tail指针 
  always@(posedge clk)     
  if(rstp==1) 
    tail<=0; 
  else if(readp==1&&emptyp==0) 
    tail<=tail+1; 
     
  //count 
  always@(posedge clk) 
  if(rstp==1) 
    count<=0; 
  else 
     case({readp,writep}) 
     2'b00: 
          count<=count; 
     2'b01: 
          if(count!=MAX_COUNT) 
          count<=count+1; 
     2'b10: 
          if(count!=0) 
          count<=count-1; 
     2'b11: 
          count<=count; 
    endcase 
     
  //更新标志位emptyp 
  always@(count) 
  if(count==0) 
     emptyp<=1; 
   else 
     emptyp<=0; 
   
  //更新标志位tail 
  always@(count) 
  if(count==MAX_COUNT) 
    tail<=1; 
  else 
    tail<=0; 
     
endmodule |   
 
 
 
 |