zoukankan      html  css  js  c++  java
  • 同步fifo的verilogHDL设计实例

    原创

    设计一个fifo,输入16bit,输出16bit的data,寻址宽度5bit,有空满标志。

     top 层如下所示:

     1 /*
     2 date :  2014/10/14
     3 version : modelsim 10.1e-altera 
     4 design  : pengxiaoen 
     5 function : 同步fifo设计
     6 */
     7 module test2 (
     8                     clock ,
     9                     reset,
    10                     in_data ,
    11                     
    12                     ou_data ,
    13                     wr_full ,
    14                     rd_empty ,
    15                     wr_en ,
    16                     rd_en 
    17                     );
    18                     
    19                     
    20 input  clock ,reset ; 
    21 input  [15:0] in_data ; // 写入的数据
    22 input         wr_en  ; //写使能
    23 input         rd_en  ; //读使能
    24 
    25 output  [15:0] ou_data ; // 读出的数据
    26 output         wr_full ;  //写满标志
    27 output         rd_empty ;  //读空标志
    28  
    29 wire [4:0]  add_head; //ram地址头,当读使能有效+1 
    30 wire [4:0]  add_end ; //ram地址尾,当写使能有效+1 
    31 
    32 //---------ram 模块,用来存储数据和输出数据--------------------------
    33 data_memory  U1_mem(  
    34                             .clock (clock),
    35                             .reset (reset),
    36                             .wr_en  (wr_en),  
    37                             .rd_en  (rd_en),
    38                             .add_head (add_head) ,
    39                             .add_end (add_end),
    40                             .in_data (in_data),
    41                             .ou_data (ou_data)
    42                             );
    43 
    44 //------------地址产生器 + 标志产生器---------------------------------                            
    45 fifo_control U2_cont(
    46                             .clock (clock),
    47                             .reset (reset),
    48                             .wr_en (wr_en),
    49                             .rd_en (rd_en),
    50                             .wr_full (wr_full),
    51                             .rd_empty (rd_empty),
    52                             .add_head (add_head),
    53                             .add_end (add_end)
    54                             );                            
    55         
    56 
    57 endmodule 
     1 module  data_memory (
     2                             clock ,reset ,
     3                             wr_en  ,  rd_en  ,
     4                             add_head ,add_end ,
     5                             in_data ,ou_data 
     6                             );
     7   input           clock ,reset ; // system clock and system reset  
     8   input           wr_en  ;     // write enable 
     9   input           rd_en ;      // read enable 
    10   input   [4:0]   add_head ;  // memory address head 
    11   input   [4:0]   add_end ;   // memory address end 
    12   input     [15:0]in_data ;   // data input to memory 
    13   output    reg[15:0]ou_data ;   // data output
    14                             
    15   reg [15:0] mem [0:31]  ;   //define the memory                          
    16   always @ (posedge clock )
    17         if(!reset)
    18                 begin
    19                         ou_data  <=  16'dx ;
    20                 end 
    21         else 
    22                 begin 
    23                         case ({wr_en, rd_en})
    24                             2'b00  :  ou_data       <=  16'dx ; 
    25                             2'b01  :  ou_data       <=  mem[add_head] ;
    26                             2'b10  :  mem[add_end] <=  in_data ;
    27                             2'b11  :  begin 
    28                                                 ou_data       <=  mem[add_end] ;
    29                                                 mem[add_head] <=  in_data ;
    30                                          end 
    31                         endcase 
    32                 end 
    33     
    34 endmodule 
     1 module fifo_control (
     2                             clock ,reset ,
     3                             wr_en ,rd_en ,
     4                             wr_full ,rd_empty,
     5                             add_head,add_end 
     6                             );
     7   input            clock ,reset ;   // system clock and system reset 
     8   input            wr_en ;          // write enable 
     9   input            rd_en  ;         // read  enable 
    10   output reg       wr_full ;        // fifo full flag                             
    11   output reg       rd_empty ;       // fifo empty 
    12   output reg [4:0] add_head  ,add_end ; 
    13     
    14  reg  [4:0] head_temp , end_temp ;     
    15  //------地址产生块,依据读写使能进行相应地址递增,并保存原始的位置信息-----------------------
    16   always @ (posedge clock)
    17         if(!reset)
    18                 begin 
    19                         head_temp <=   5'd0  ;
    20                         end_temp  <=   5'd0  ;
    21                         add_head  <=   5'd0  ;
    22                         add_end   <=   5'd0  ; 
    23                 end 
    24                         
    25         else 
    26                 begin 
    27                         case ({wr_en, rd_en})
    28                                 2'b00  :   begin 
    29                                                         head_temp  <=  add_head  ;
    30                                                         end_temp   <=  add_end   ;
    31                                               end 
    32                                 2'b01  :   begin 
    33                                                         end_temp  <=   add_end ; 
    34                                                         add_head  <=   add_head + 5'd1 ;
    35                                               end    
    36                                 2'b10  :   begin 
    37                                                         head_temp <=   add_head ; 
    38                                                         add_end   <=   add_end  + 5'd1 ;
    39                                               end 
    40                                 2'b11  :   begin
    41                                                         add_head  <=  add_head  +  5'd1  ; 
    42                                                         add_end   <=  add_end   +  5'd1  ;
    43                                               end 
    44                         endcase 
    45                 end 
    46         
    47 //--------标志产生块-------------------                            
    48   always @ (posedge clock)
    49         if(!reset)
    50                 begin 
    51                         wr_full   <=   1'd0  ; 
    52                         rd_empty  <=   1'd0  ; 
    53                 end 
    54         else
    55                 begin 
    56                         case ({wr_en , rd_en})
    57                                 2'b00 :  begin   
    58                                                     rd_empty  <=  1'd0 ; 
    59                                                     wr_full   <=  1'd0 ;
    60                                         end 
    61                                 2'b01 :  begin 
    62                                                     wr_full  <=  1'd0 ; //写标志复位
    63                                                     if ((add_head +  5'd1) == head_temp)
    64                                                             rd_empty  <=  1'd1 ; //只有切换到写使能才复位
    65                                         end 
    66                                 2'b10 :  begin 
    67                                                     rd_empty  <=  1'd0 ; //读标志复位
    68                                                     if ((add_end +  5'd1) == end_temp)
    69                                                             wr_full  <=  1'd1 ; //只有切换到读使能才复位    
    70                                         end 
    71                                 2'b11 : begin
    72                                                     rd_empty  <=  1'd0 ; 
    73                                                     wr_full   <=  1'd0 ;
    74                                         end 
    75                         endcase 
    76                 end 
    77 
    78                             
    79 endmodule

    下面附上测试代码

     1 `timescale  1ns/1ps 
     2 
     3 module test2_tb ; 
     4 reg clock ,reset ; 
     5 reg [15:0] in_data ; 
     6 reg        wr_en ; 
     7 reg        rd_en ; 
     8 
     9 wire [15:0] ou_data ; 
    10 wire        wr_full ; 
    11 wire        rd_empty ; 
    12 
    13 
    14 test2  U_top (
    15                     .clock (clock),
    16                     .reset (reset),
    17                     .in_data (in_data),
    18                     
    19                     .ou_data (ou_data),
    20                     .wr_full (wr_full),
    21                     .rd_empty (rd_empty),
    22                     .wr_en (wr_en),
    23                     .rd_en (rd_en)
    24                     );
    25             
    26 integer i ; 
    27             
    28 always #10  clock = ~clock ; 
    29 
    30 initial 
    31     begin 
    32             clock =1'd0 ;   reset = 1'd0  ;   wr_en <= 1'd0 ;  rd_en  <= 1'd0 ;
    33             in_data = 16'd0 ; 
    34             #20 reset = 1'd1 ; wr_en <= 1'd1 ; 
    35           for (i=0;i<40;i=i+1) // 故意溢出
    36                 #20 in_data  <=  in_data + 16'd1 ; 
    37                 
    38             rd_en  <=  1'd1 ; wr_en <= 1'd0 ;
    39             #(40*20 ) // 让读空标志位触发
    40             $stop   ; 
    41             
    42     end 
    43 
    44 endmodule 
  • 相关阅读:
    后台执行linux命令
    日志
    配置文件
    后台
    后台代码注释
    递归建立文件夹
    图片合成
    java.awt.Font
    java-日期取特定值
    linux乱码
  • 原文地址:https://www.cnblogs.com/sepeng/p/4024662.html
Copyright © 2011-2022 走看看