Advertisement
bobomarinov

fifo.sv

Jun 10th, 2019
800
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module fifo (WE, RE, data_in, data_out, write_clk, read_clk, reset, full, empty, data_from_memory);
  2.    parameter MEMORY_WIDTH = 4;
  3.    parameter MEMORY_LENGTH = 16;
  4.    parameter ADDRESS_SIZE = 4;
  5.  
  6.    input [MEMORY_WIDTH - 1:0] data_in;
  7.    input              WE, RE, write_clk, read_clk, reset; //write_clk for write, read_clk for read
  8.    
  9.    output [MEMORY_WIDTH - 1:0] data_out;
  10.    output wire             full;
  11.    output wire             empty;  
  12.    wire [ADDRESS_SIZE - 1:0]   fill;          
  13.  
  14.    output [MEMORY_WIDTH - 1:0] data_from_memory;
  15.    reg [ADDRESS_SIZE:0]        read_pointer_bin, read_pointer_gray, wq1_read_pointer_gray, wq2_read_pointer_gray;
  16.    reg [ADDRESS_SIZE:0]        write_pointer_bin, write_pointer_gray, rq1_write_pointer_gray, rq2_write_pointer_gray;  
  17.    wire                write_request_to_memory;
  18.    
  19.    reg                 empty_delayed;
  20.    reg                 read_delayed;
  21.  
  22.    memory2port mem(.write_clk(write_clk), .write_request1(write_request_to_memory), .address1(write_pointer_bin), .address2(read_pointer_bin), .data_in1(data_in), .data_out2(data_from_memory), .read_clk(read_clk));
  23.    
  24.    assign fill = (write_pointer_bin - read_pointer_bin);
  25.    
  26.    assign read_pointer_gray = read_pointer_bin ^ (read_pointer_bin >> 1);
  27.    assign write_pointer_gray = write_pointer_bin ^ (write_pointer_bin >> 1);
  28.    
  29.    assign write_request_to_memory = ~full & WE;
  30.  
  31.    assign empty = (rq2_write_pointer_gray == read_pointer_gray);
  32.  
  33.    assign full = (write_pointer_gray[ADDRESS_SIZE:ADDRESS_SIZE - 1] == ~wq2_read_pointer_gray[ADDRESS_SIZE:ADDRESS_SIZE - 1]) && (write_pointer_gray[ADDRESS_SIZE - 2:0] == wq2_read_pointer_gray[ADDRESS_SIZE - 2:0]);
  34.  
  35.    
  36.    
  37.    initial begin
  38.       read_pointer_bin = 0;
  39.       write_pointer_bin = 0;
  40.       wq1_read_pointer_gray = 0;
  41.       wq2_read_pointer_gray = 0;
  42.       rq1_write_pointer_gray = 0;
  43.       rq2_write_pointer_gray = 0;
  44.    end
  45.    
  46.    always@(posedge read_clk)begin
  47.       rq2_write_pointer_gray <= rq1_write_pointer_gray; //write pointer on read clock
  48.       rq1_write_pointer_gray <= write_pointer_gray;
  49.    end
  50.    
  51.    always@(posedge write_clk)begin //read pointer on write clock
  52.       wq2_read_pointer_gray <= wq1_read_pointer_gray;
  53.       wq1_read_pointer_gray <= read_pointer_gray;
  54.    end
  55.  
  56.    assign data_out = (~empty_delayed & read_delayed) ? data_from_memory : 4'bz;
  57.    
  58.    always@(posedge read_clk)begin     //delay
  59.       empty_delayed <= empty;
  60.       read_delayed <= RE;
  61.    end
  62.  
  63.    
  64.    always@(posedge write_clk or posedge read_clk or negedge reset)begin  //reset
  65.       if(~reset)begin
  66.          read_pointer_bin <= 0;
  67.      write_pointer_bin <= 0;
  68.      wq1_read_pointer_gray <= 0;
  69.      wq2_read_pointer_gray <= 0;
  70.      rq1_write_pointer_gray <= 0;
  71.      rq2_write_pointer_gray <= 0;
  72.       end
  73.    end
  74.  
  75.    always@(posedge write_clk)begin         //write
  76.       if(WE & ~full & reset)begin
  77.          write_pointer_bin <= write_pointer_bin + 1;
  78.       end
  79.    end
  80.  
  81.    always@(posedge read_clk)begin         //read
  82.       if(RE & ~empty & reset)begin
  83.          read_pointer_bin <= read_pointer_bin + 1;
  84.       end
  85.    end
  86.  
  87.  
  88. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement