Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module fifo (WE, RE, data_in, data_out, write_clk, read_clk, reset, full, empty, data_from_memory);
- parameter MEMORY_WIDTH = 4;
- parameter MEMORY_LENGTH = 16;
- parameter ADDRESS_SIZE = 4;
- input [MEMORY_WIDTH - 1:0] data_in;
- input WE, RE, write_clk, read_clk, reset; //write_clk for write, read_clk for read
- output [MEMORY_WIDTH - 1:0] data_out;
- output wire full;
- output wire empty;
- wire [ADDRESS_SIZE - 1:0] fill;
- output [MEMORY_WIDTH - 1:0] data_from_memory;
- reg [ADDRESS_SIZE:0] read_pointer_bin, read_pointer_gray, wq1_read_pointer_gray, wq2_read_pointer_gray;
- reg [ADDRESS_SIZE:0] write_pointer_bin, write_pointer_gray, rq1_write_pointer_gray, rq2_write_pointer_gray;
- wire write_request_to_memory;
- reg empty_delayed;
- reg read_delayed;
- 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));
- assign fill = (write_pointer_bin - read_pointer_bin);
- assign read_pointer_gray = read_pointer_bin ^ (read_pointer_bin >> 1);
- assign write_pointer_gray = write_pointer_bin ^ (write_pointer_bin >> 1);
- assign write_request_to_memory = ~full & WE;
- assign empty = (rq2_write_pointer_gray == read_pointer_gray);
- 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]);
- initial begin
- read_pointer_bin = 0;
- write_pointer_bin = 0;
- wq1_read_pointer_gray = 0;
- wq2_read_pointer_gray = 0;
- rq1_write_pointer_gray = 0;
- rq2_write_pointer_gray = 0;
- end
- always@(posedge read_clk)begin
- rq2_write_pointer_gray <= rq1_write_pointer_gray; //write pointer on read clock
- rq1_write_pointer_gray <= write_pointer_gray;
- end
- always@(posedge write_clk)begin //read pointer on write clock
- wq2_read_pointer_gray <= wq1_read_pointer_gray;
- wq1_read_pointer_gray <= read_pointer_gray;
- end
- assign data_out = (~empty_delayed & read_delayed) ? data_from_memory : 4'bz;
- always@(posedge read_clk)begin //delay
- empty_delayed <= empty;
- read_delayed <= RE;
- end
- always@(posedge write_clk or posedge read_clk or negedge reset)begin //reset
- if(~reset)begin
- read_pointer_bin <= 0;
- write_pointer_bin <= 0;
- wq1_read_pointer_gray <= 0;
- wq2_read_pointer_gray <= 0;
- rq1_write_pointer_gray <= 0;
- rq2_write_pointer_gray <= 0;
- end
- end
- always@(posedge write_clk)begin //write
- if(WE & ~full & reset)begin
- write_pointer_bin <= write_pointer_bin + 1;
- end
- end
- always@(posedge read_clk)begin //read
- if(RE & ~empty & reset)begin
- read_pointer_bin <= read_pointer_bin + 1;
- end
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement