Advertisement
Guest User

Untitled

a guest
Mar 21st, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module my_FIFO
  2.         #(
  3.             parameter address_bits = 4,     // 2^4=16 theseis
  4.             parameter data_bits = 4
  5.         )(
  6.             input logic clk,
  7.             input logic rst_n,
  8.             input logic wr,
  9.             input logic rd,
  10.             input logic [data_bits-1:0] din,
  11.             output logic empty,
  12.             output logic full,
  13.             output logic [data_bits-1:0] dout
  14.         );
  15.  
  16. logic [data_bits-1:0] out;
  17. logic [data_bits-1:0] regarray[2**address_bits-1:0]; //number of words in fifo = 2^(number of address bits)
  18. logic [address_bits-1:0] wr_reg, wr_next, wr_succ; //points to the register that needs to be written to
  19. logic [address_bits-1:0] rd_reg, rd_next, rd_succ; //points to the register that needs to be read from
  20. logic full_reg, empty_reg, full_next, empty_next;
  21. // write operation
  22. assign wr_en = wr & ~full; // write when wr signal high and fifo not full
  23. always_ff @(posedge clk) begin
  24.     if(wr_en) begin
  25.         regarray[wr_reg] <= din;
  26.     end
  27. end
  28.  
  29. // read operation
  30. always_ff @(posedge clk) begin
  31.     if(rd) begin
  32.         out <= regarray[rd_reg];
  33.     end
  34. end
  35.  
  36.  
  37.  
  38. always_ff @(posedge clk or negedge rst_n) begin
  39.     if(~rst_n) begin
  40.         wr_reg <= 0;
  41.         rd_reg <= 0;
  42.         full_reg <= 1'b0;
  43.         empty_reg <= 1'b1;
  44.     end else begin
  45.         wr_reg <= wr_next; //created the next registers to avoid the error of mixing blocking and non blocking assignment to the same signal
  46.         rd_reg <= rd_next;
  47.         full_reg <= full_next;
  48.         empty_reg <= empty_next;
  49.     end
  50. end
  51.  
  52.  
  53.  
  54. always_comb begin
  55.     wr_succ = wr_reg + 1;
  56.     rd_succ = rd_reg + 1;
  57.     wr_next = wr_reg;
  58.     rd_next = rd_reg;
  59.     full_next = full_reg;
  60.     empty_next = empty_reg;
  61.  
  62.     if(~wr_en && rd) begin // read
  63.         if(~empty) begin //if fifo is not empty continue
  64.             rd_next = rd_succ;
  65.             full_next = 1'b0;
  66.             if(rd_succ == wr_reg)begin //all data has been read
  67.                 empty_next = 1'b1;//its empty again
  68.             end
  69.         end
  70.     end else if(wr_en && ~rd) begin // write
  71.         if(~full) begin //if fifo is not full continue
  72.             wr_next = wr_succ;
  73.                                empty_next = 1'b0;
  74.             if(wr_succ == (2**address_bits-1))begin //all registers have been written to
  75.                 full_next = 1'b1; //its full now
  76.             end
  77.         end
  78.     end else if(wr_en && rd) begin //read and write
  79.         wr_next = wr_succ;
  80.         rd_next = rd_succ;
  81.     end
  82.    
  83. end
  84.  
  85.  
  86. assign full = full_reg;
  87. assign empty = empty_reg;
  88. // assign dout = out;
  89. always_comb begin
  90.     if(empty && rd && wr_en) begin
  91.         dout = din;
  92.     end else if(rd) begin
  93.         dout = regarray[rd_reg];
  94.     end else begin
  95.         dout = out;
  96.     end
  97. end
  98.  
  99. endmodule // my_FIFO
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement