OpenCores
URL https://opencores.org/ocsvn/cryptosorter/cryptosorter/trunk

Subversion Repositories cryptosorter

[/] [cryptosorter/] [trunk/] [memocodeDesignContest2008/] [sort/] [BRAMLevelFIFOMuxes/] [BRAMVLevelFIFO.bsv] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 kfleming
// import standard library
2
import FIFO::*;
3
import RegFile::*;
4
import StmtFSM::*;
5
import Vector::*;
6
 
7
// import self-made library
8
import BRAM::*;
9
import VLevelFIFO::*;
10
 
11
// implementation of VLevelFIFO with BRAM
12
module mkBRAMVLevelFIFO (VLevelFIFO#(no_fifo, fifo_sz, data_t))
13
   provisos (Bits#(data_t,data_sz),
14
             Add#(TLog#(no_fifo),TLog#(fifo_sz),bram_idx_sz));
15
 
16
   // instantiate an unguarded 1 cycle latency bram (i.e. the read response will only valid for 1 cycle)
17
   UGBRAM#(Bit#(bram_idx_sz), data_t)           ugbram <- mkBypassUGBRAM_Full();
18
 
19
   RegFile#(Bit#(TLog#(no_fifo)),Bit#(TLog#(fifo_sz)))  head <- mkRegFileFull();
20
   RegFile#(Bit#(TLog#(no_fifo)),Bit#(TLog#(fifo_sz)))  tail <- mkRegFileFull();
21
   Reg#(Bit#(TLog#(no_fifo))) i <- mkReg(0);
22
   Reg#(Bool)                 finishInit <- mkReg(False);
23
 
24
   Reg#(Vector#(no_fifo,Bit#(TLog#(TAdd#(fifo_sz,1)))))  usedReg <- mkReg(replicate(0));
25
   Wire#(Vector#(no_fifo,Bit#(TLog#(TAdd#(fifo_sz,1))))) usedW   <- mkDWire(replicate(0));
26
 
27
   Reg#(Vector#(no_fifo,Bit#(TLog#(TAdd#(fifo_sz,1)))))  freeReg <- mkReg(replicate(fromInteger(valueOf(fifo_sz))));
28
 
29
   Wire#(Maybe#(Bit#(TLog#(no_fifo)))) enqIdx <- mkDWire(tagged Invalid);
30
   Wire#(data_t)                       enqVal <- mkDWire(?);
31
 
32
   Wire#(Maybe#(Bit#(TLog#(no_fifo)))) deqIdx <- mkDWire(tagged Invalid);
33
 
34
   Wire#(Maybe#(Bit#(TLog#(no_fifo)))) firstIdx <- mkDWire(tagged Invalid);
35
 
36
   Wire#(Maybe#(Bit#(TLog#(no_fifo)))) decrFreeIdx <- mkDWire(tagged Invalid);
37
 
38
   let enqIdxVal         = fromMaybe(0,enqIdx);
39
   let deqIdxVal         = fromMaybe(0,deqIdx);
40
   let firstIdxVal       = fromMaybe(0,firstIdx);
41
   let decrFreeIdxVal    = fromMaybe(0,decrFreeIdx);
42
   let deqIdxNEQFirstIdx = deqIdxVal != firstIdxVal;
43
   let readResp          = ugbram.read_resp();
44
 
45
   // start the initialization processor
46
   rule initialization(!finishInit);
47
      head.upd(i,0);
48
      tail.upd(i,0);
49
      i <= i + 1;
50
      if (i == fromInteger(valueOf(no_fifo)-1))
51
         finishInit <= True;
52
   endrule
53
 
54
   rule updateUsedReg(finishInit && (isValid(enqIdx) || isValid(deqIdx)));
55
      Vector#(no_fifo,Bit#(TLog#(TAdd#(fifo_sz,1)))) newUsedReg = newVector();
56
 
57
      for (Integer i = 0; i < valueOf(no_fifo); i = i + 1)
58
         newUsedReg[i] = usedReg[i];
59
 
60
      if (isValid(enqIdx))
61
         newUsedReg[enqIdxVal] = usedReg[enqIdxVal] + 1;
62
 
63
      if (isValid(deqIdx))
64
         newUsedReg[deqIdxVal] = newUsedReg[deqIdxVal] - 1;
65
 
66
      usedReg <= newUsedReg;
67
      usedW <= newUsedReg;
68
 
69
//      $display("updateUsedReg");
70
   endrule
71
 
72
   rule updateUsedW(finishInit && !(isValid(enqIdx) || isValid(deqIdx)));
73
      usedW <= usedReg;
74
   endrule
75
 
76
   rule updateFreeReg(finishInit && (isValid(decrFreeIdx) || isValid(deqIdx)));
77
      Vector#(no_fifo,Bit#(TLog#(TAdd#(fifo_sz,1)))) newFreeReg = newVector();
78
 
79
      for (Integer i = 0; i < valueOf(no_fifo); i = i + 1)
80
         newFreeReg[i] = freeReg[i];
81
 
82
      if (isValid(decrFreeIdx))
83
         newFreeReg[decrFreeIdxVal] = freeReg[decrFreeIdxVal] - 1;
84
 
85
      if (isValid(deqIdx))
86
         newFreeReg[deqIdxVal] = newFreeReg[deqIdxVal] + 1;
87
 
88
      freeReg <= newFreeReg;
89
 
90
//      $display("updateFreeReg");
91
   endrule
92
 
93
   rule processEnq(finishInit && isValid(enqIdx));
94
      let tailVal = tail.sub(enqIdxVal);
95
      tail.upd(enqIdxVal, (tailVal + 1));
96
      ugbram.write({enqIdxVal,tailVal},enqVal);
97
 
98
//      $display("enq data %d to fifo %d with tailVal %d",data,idx,tailVal);
99
   endrule
100
 
101
   rule processFirstReq(finishInit && isValid(firstIdx));
102
      let headVal = head.sub(firstIdxVal);
103
      if (deqIdxNEQFirstIdx || !isValid(deqIdx))
104
         begin
105
            ugbram.read_req({firstIdxVal,headVal});
106
            //$display("first read idx %d headVal %d",firstIdxVal,headVal);
107
         end
108
      else // the fifo is dequeued at that cycle, we should read the next head
109
         begin
110
            ugbram.read_req({firstIdxVal,headVal+1});
111
            //$display("first read idx %d headVal+1 %d",firstIdxVal,headVal+1);
112
         end
113
   endrule
114
 
115
   rule processDeq(finishInit && isValid(deqIdx));
116
      let headVal = head.sub(deqIdxVal);
117
      head.upd(deqIdxVal, (headVal + 1));
118
   endrule
119
 
120
   // enq is unguarded here, we expect the user to check it before they enq
121
   method Action enq(Bit#(TLog#(no_fifo)) idx, data_t data) if (finishInit);
122
      enqIdx <= tagged Valid idx;
123
      enqVal <= data;
124
   endmethod
125
 
126
   // deq is unguarded here, we expect the user to check it before they deq
127
   method Action deq(Bit#(TLog#(no_fifo)) idx) if (finishInit);
128
      deqIdx <= tagged Valid idx;
129
 
130
//      $display("deq fifo %d",idx);
131
   endmethod
132
 
133
   method Action firstReq(Bit#(TLog#(no_fifo)) idx) if (finishInit);
134
      firstIdx <= tagged Valid idx;
135
   endmethod
136
 
137
   // first is unguarded here, we expecte the user to check it before they call first
138
   method data_t firstResp() if (finishInit);
139
      return readResp;
140
   endmethod
141
 
142
   method Action clear() if (finishInit);
143
      noAction;
144
   endmethod
145
 
146
   // return the usage of each fifo at the beginning of the cycle
147
   method Vector#(no_fifo,Bit#(TLog#(TAdd#(fifo_sz,1)))) used() if (finishInit);
148
      return usedReg;
149
   endmethod
150
 
151
   // return the usage of each fifo at the end of the cycle
152
   method Vector#(no_fifo,Bit#(TLog#(TAdd#(fifo_sz,1)))) used2() if (finishInit);
153
      return usedW;
154
   endmethod
155
 
156
   // return enq credit token available for each fifo
157
   method Vector#(no_fifo,Bit#(TLog#(TAdd#(fifo_sz,1)))) free() if (finishInit);
158
      return freeReg;
159
   endmethod
160
 
161
   // get credit token to enq fifo idx in the future
162
   // this method is unguarded (i.e. user need to call method free
163
   // and check for token availability before calling this action)
164
   method Action decrFree(Bit#(TLog#(no_fifo)) idx) if (finishInit);
165
      decrFreeIdx <= tagged Valid idx;
166
   endmethod
167
 
168
endmodule
169
 
170
(* synthesize *)
171
module mkBRAMVLevelFIFOInstance(VLevelFIFO#(32, 16, Bit#(129)));
172
   let fifo <- mkBRAMVLevelFIFO();
173
   return fifo;
174
endmodule
175
 
176
/*
177
(* synthesize *)
178
module mkBRAMVLevelFIFOTest(Empty);
179
   let fifo <- mkBRAMVLevelFIFOInstance();
180
   Reg#(Bit#(8)) enqIdx <- mkReg(0);
181
   Reg#(Bit#(129)) enqData <- mkReg(0);
182
   Reg#(Bit#(8)) firstIdx <- mkReg(0);
183
   FIFO#(Bit#(0)) reqQ <- mkFIFO();
184
   Reg#(Bit#(8)) deqIdx <- mkReg(0);
185
   Reg#(Bit#(32)) cycleCnt <- mkReg(0);
186
   let used = fifo.used();
187
   let free = fifo.free();
188
 
189
   rule enqFifo(free[enqIdx[7:2]] > 0);
190
      enqIdx <= enqIdx + 1;
191
      enqData <= enqData + 1;
192
      fifo.enq(enqIdx[7:2],enqData);
193
      fifo.decrFree(enqIdx[7:2]);
194
 
195
      $display("enq fifo %d with data %d",enqIdx[7:2],enqData);
196
   endrule
197
 
198
   rule firstFifo(used[deqIdx[7:2]] > 0);
199
      firstIdx <= firstIdx + 1;
200
      fifo.firstReq(firstIdx[7:2]);
201
      reqQ.enq(?);
202
 
203
      $display("first req fifo %d",firstIdx[7:2]);
204
   endrule
205
 
206
   rule deqFifo(True);
207
      reqQ.deq();
208
      if (used[deqIdx[7:2]] > 0)
209
         begin
210
            deqIdx <= deqIdx + 1;
211
            let deqData = fifo.firstResp();
212
            fifo.deq(deqIdx[7:2]);
213
 
214
            $display("deq fifo %d with data %d",deqIdx[7:2],deqData);
215
         end
216
      else
217
        $display("last first req is not reading valid data");
218
   endrule
219
 
220
   rule displayStat(True);
221
      for (Integer i = 0; i < 64; i = i + 1)
222
         $display("%d: used %d, free %d",i,used[i],free[i]);
223
   endrule
224
 
225
   rule countCycle(True);
226
      cycleCnt <= cycleCnt + 1;
227
      $display("cycle %d",cycleCnt);
228
      if (cycleCnt == 5000)
229
         $finish();
230
   endrule
231
 
232
endmodule
233
 */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.