-
Notifications
You must be signed in to change notification settings - Fork 0
/
n2p_fifo.sv
92 lines (84 loc) · 2.48 KB
/
n2p_fifo.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
module n2p_fifo (clk, rst, data_in, rd_en, wr_en, data_out, empty, full);
parameter DATA_WIDTH = 9;
parameter ADDR_WIDTH = 2;
parameter RAM_DEPTH = (1 << ADDR_WIDTH);
input logic clk ; // Clock input
input logic rst ; // Active high reset
input logic [DATA_WIDTH-1:0] data_in ; // Data input
input logic rd_en ; // Read enable
input logic wr_en ; // Write Enable
output logic [DATA_WIDTH-1:0] data_out ; // Data Output
output logic empty ; // FIFO empty
output logic full ; // FIFO full
//-----------Internal variables-------------------
/*
reg [ADDR_WIDTH-1:0] wr_pointer;
reg [ADDR_WIDTH-1:0] rd_pointer;
reg [ADDR_WIDTH :0] status_cnt;
wire [DATA_WIDTH-1:0] data_ram;
reg [DATA_WIDTH-1:0] fifo_mem [RAM_DEPTH-1:0];
integer i;
*/
logic [ADDR_WIDTH-1:0] wr_pointer;
logic [ADDR_WIDTH-1:0] rd_pointer;
logic [ADDR_WIDTH :0] status_cnt;
logic [DATA_WIDTH-1:0] data_ram;
logic [DATA_WIDTH-1:0] fifo_mem [RAM_DEPTH-1:0];
integer i;
//-----------Variable assignments---------------
assign full = (status_cnt == (RAM_DEPTH-1));
assign empty = (status_cnt == 0);
//-----------Code Start---------------------------
always_ff @ (posedge clk or posedge rst)
begin : WRITE_POINTER
if (rst) begin
wr_pointer <= #1 0;
end else if (wr_en) begin
wr_pointer <= #1 wr_pointer + 1;
end
end
always_ff @ (posedge clk or posedge rst)
begin : READ_POINTER
if (rst) begin
rd_pointer <= #1 0;
end else if (rd_en) begin
rd_pointer <= #1 rd_pointer + 1;
end
end
always_ff @ (posedge clk or posedge rst) begin: WRITE_DATA
if (rst) begin
for (i=0; i<RAM_DEPTH; i=i+1)
fifo_mem[i] <= #1 0;
end
else begin
if (wr_en && !full)
fifo_mem[wr_pointer] <= #1 data_in;
// else
// fifo_mem[wr_pointer] <= #1
end
end
always_ff @ (posedge clk or posedge rst)
begin : READ_DATA
if (rst) begin
data_out <= #1 9'b100000000;
end else if (rd_en) begin
data_out <= #1 fifo_mem[rd_pointer];
end else if (~rd_en) begin
data_out <= #1 9'b100000000;
end
end
always_ff @ (posedge clk or posedge rst)
begin : STATUS_COUNTER
if (rst) begin
status_cnt <= #1 0;
// Read but no write.
end else if ((rd_en) && (!wr_en)
&& (status_cnt != 0)) begin
status_cnt <= #1 status_cnt - 1;
// Write but no read.
end else if ((wr_en) && (!rd_en)
&& (status_cnt != RAM_DEPTH)) begin
status_cnt <= #1 status_cnt + 1;
end
end
endmodule