Advertisement
MysteriousWolf

ram.v

Oct 31st, 2024
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VeriLog 3.13 KB | Source Code | 0 0
  1. module fifo
  2. #(
  3.     parameter addr_width = 12,
  4.     parameter data_width = 24,
  5.     parameter max_data_count = (1<<addr_width)
  6. )(
  7.     input rst,
  8.  
  9.     input write_en,
  10.     input wclk,
  11.     input [data_width-1:0] din,
  12.  
  13.     input rclk,
  14.     output [data_width-1:0] dout,
  15.    
  16.     output reg full,
  17.     output reg empty,
  18.     output reg direction // 0 is write, 1 is read
  19. );
  20.     /*
  21.     After being reset, the FIFO should be empty and ready to accept data. The empty flag is high until we write data to the FIFO.
  22.     The FIFO then takes in data and stores it in the RAM until it is full. When full, the full flag is high and the counter resets to be ready for readout.
  23.     The readout process is similar to the write process, but the data is read out of the RAM and the empty flag is low until the FIFO is empty.
  24.     */
  25.     // Counter and states for the FIFO
  26.     reg [addr_width-1:0] data_count;
  27.     wire counter_clock = direction ? rclk : wclk;
  28.  
  29.     // Assert output flags (full when counter is at max and direction is write, empty when counter is at max and direction is read)
  30.     // Max counter value is 2^addr_width
  31.     wire overflow = data_count == (max_data_count - 1);
  32.     wire underflow = data_count == 0;
  33.     //wire overflow_warn = data_count >= (max_data_count-2);
  34.  
  35.     // RAM module for the FIFO
  36.     ram #(
  37.         .addr_width(addr_width),
  38.         .data_width(data_width)
  39.     ) ram_inst (
  40.         .din(din),
  41.         .write_en(write_en),
  42.         .waddr(data_count),
  43.         .wclk(wclk),
  44.         .raddr(data_count),
  45.         .rclk(rclk),
  46.         .dout(dout)
  47.     );
  48.  
  49.     // Count up until we reach the maximum address width based on the direction
  50.     always @(negedge counter_clock or posedge rst) begin
  51.         if (rst) begin
  52.             full <= 0;
  53.             empty <= 1;
  54.             data_count <= 0;
  55.             direction <= 0;
  56.         end else begin
  57.             if (!direction && write_en) begin
  58.                 full <= (direction && underflow) || (!direction && overflow);
  59.                 empty <= 0;
  60.             end else if (direction) begin
  61.                 full <= 0;
  62.                 empty <= (direction && overflow) || (!direction && underflow);
  63.             end
  64.  
  65.             if (overflow) begin
  66.                 direction <= ~direction;
  67.                 data_count <= 0;
  68.             end else begin
  69.                 if (direction || (!direction && write_en)) begin
  70.                     data_count <= data_count + 1;
  71.                 end
  72.             end
  73.         end
  74.     end
  75.  
  76. endmodule
  77.  
  78. module ram (din, write_en, waddr, wclk, raddr, rclk, dout); //4096x24
  79.     parameter addr_width = 12;
  80.     parameter data_width = 24;
  81.     input [addr_width-1:0] waddr, raddr;
  82.     input [data_width-1:0] din;
  83.     input write_en, wclk, rclk;
  84.     output reg [data_width-1:0] dout;
  85.     reg [data_width-1:0] mem [(1<<addr_width)-1:0];
  86.  
  87.     always @(posedge wclk) // Write memory.
  88.         begin if (write_en)
  89.             mem[waddr] <= din; // Using write address bus.
  90.         end
  91.    
  92.     always @(posedge rclk) // Read memory.
  93.         begin
  94.             dout <= mem[raddr]; // Using read address bus.
  95.         end
  96. endmodule
Tags: FPGA
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement