1 |
83 |
jamey.hick |
|
2 |
|
|
// The MIT License
|
3 |
|
|
|
4 |
|
|
// Copyright (c) 2006-2007 Massachusetts Institute of Technology
|
5 |
|
|
|
6 |
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 |
|
|
// of this software and associated documentation files (the "Software"), to deal
|
8 |
|
|
// in the Software without restriction, including without limitation the rights
|
9 |
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 |
|
|
// copies of the Software, and to permit persons to whom the Software is
|
11 |
|
|
// furnished to do so, subject to the following conditions:
|
12 |
|
|
|
13 |
|
|
// The above copyright notice and this permission notice shall be included in
|
14 |
|
|
// all copies or substantial portions of the Software.
|
15 |
|
|
|
16 |
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 |
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19 |
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 |
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 |
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 |
|
|
// THE SOFTWARE.
|
23 |
|
|
|
24 |
3 |
jamey.hick |
package mkSizedFIFO_fpga;
|
25 |
|
|
|
26 |
|
|
import FIFO::*;
|
27 |
|
|
import RWire::*;
|
28 |
|
|
import RegFile::*;
|
29 |
|
|
import IFPGA_FIFO::*;
|
30 |
|
|
|
31 |
|
|
module mkSizedFIFO_fpga (IFPGA_FIFO#(f_type, size))
|
32 |
|
|
provisos(
|
33 |
|
|
Bits#(f_type, f_type_length),
|
34 |
|
|
Add#(TLog#(size), 0, lg_size),
|
35 |
|
|
Add#(TLog#(size), 1, lg_size_plus),
|
36 |
|
|
Add#(2, TLog#(size),lg_size_plus_plus),
|
37 |
|
|
Add#(1, lg_size_plus, lg_size_plus_plus)
|
38 |
|
|
);
|
39 |
|
|
|
40 |
|
|
RegFile#(Bit#(TLog#(size)), f_type) data <- mkRegFile(0, fromInteger(valueof(TSub#(size,1))));
|
41 |
|
|
Reg#(Bit#(lg_size_plus)) number_enqueued <- mkReg(0);
|
42 |
|
|
Reg#(Bit#(TLog#(size))) base_ptr <- mkReg(0);
|
43 |
|
|
RWire#(Bit#(0)) deque_pending <- mkRWire();
|
44 |
|
|
RWire#(Bit#(0)) clear_pending <- mkRWire();
|
45 |
|
|
RWire#(f_type) enque_pending <- mkRWire();
|
46 |
|
|
|
47 |
|
|
// We'll have problems with non-saturating additions, so we ought to add some checks
|
48 |
|
|
// Strongly Recommend power of 2 sizes to simpilfy logic.
|
49 |
|
|
|
50 |
|
|
rule update;
|
51 |
|
|
if(clear_pending.wget() matches tagged Valid .v)
|
52 |
|
|
begin
|
53 |
|
|
//clear is occuring, we drop a pending enqueue on the floor.
|
54 |
|
|
number_enqueued <= 0;
|
55 |
|
|
base_ptr <= 0;
|
56 |
|
|
end
|
57 |
|
|
else
|
58 |
|
|
begin
|
59 |
|
|
if(enque_pending.wget() matches tagged Valid .new_data)
|
60 |
|
|
begin
|
61 |
|
|
if(deque_pending.wget() matches tagged Valid .dp)
|
62 |
|
|
begin
|
63 |
|
|
// enque and deque occuring.. no change to net.
|
64 |
|
|
base_ptr <= (zeroExtend(base_ptr) == fromInteger(valueof(size)-1))? 0:base_ptr + 1;
|
65 |
|
|
Bit#(lg_size_plus_plus) offset = zeroExtend((zeroExtend(base_ptr) + number_enqueued));
|
66 |
|
|
data.upd((offset >= fromInteger(valueof(size)))?
|
67 |
|
|
truncate(offset - truncate(fromInteger(valueof(size)))):
|
68 |
|
|
truncate(offset),
|
69 |
|
|
new_data);
|
70 |
|
|
end
|
71 |
|
|
else
|
72 |
|
|
begin
|
73 |
|
|
number_enqueued <= number_enqueued + 1;
|
74 |
|
|
Bit#(lg_size_plus_plus) offset = zeroExtend((zeroExtend(base_ptr) + number_enqueued));
|
75 |
|
|
data.upd((offset >= fromInteger(valueof(size)))?
|
76 |
|
|
truncate(offset - truncate(fromInteger(valueof(size)))):
|
77 |
|
|
truncate(offset),
|
78 |
|
|
new_data);
|
79 |
|
|
end
|
80 |
|
|
end
|
81 |
|
|
else
|
82 |
|
|
begin
|
83 |
|
|
if(deque_pending.wget() matches tagged Valid .dp)
|
84 |
|
|
begin
|
85 |
|
|
//enque and deque occuring.. no change to net.
|
86 |
|
|
base_ptr <= (zeroExtend(base_ptr) == truncate(fromInteger(valueof(size)-1)))? 0:base_ptr + 1;
|
87 |
|
|
number_enqueued <= number_enqueued - 1;
|
88 |
|
|
end
|
89 |
|
|
end
|
90 |
|
|
end
|
91 |
|
|
endrule
|
92 |
|
|
|
93 |
|
|
interface FIFO fifo;
|
94 |
|
|
|
95 |
|
|
method Action enq (f_type value) if(number_enqueued < fromInteger(valueof(size)));
|
96 |
|
|
enque_pending.wset(value);
|
97 |
|
|
endmethod
|
98 |
|
|
|
99 |
|
|
method Action deq() if(number_enqueued > 0);
|
100 |
|
|
deque_pending.wset(0);
|
101 |
|
|
endmethod
|
102 |
|
|
|
103 |
|
|
method f_type first() if(number_enqueued > 0);
|
104 |
|
|
return data.sub(base_ptr);
|
105 |
|
|
endmethod
|
106 |
|
|
|
107 |
|
|
method Action clear();
|
108 |
|
|
clear_pending.wset(0);
|
109 |
|
|
endmethod
|
110 |
|
|
|
111 |
|
|
endinterface
|
112 |
|
|
|
113 |
|
|
endmodule
|
114 |
|
|
endpackage
|