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

Subversion Repositories bluespec_md6

[/] [bluespec_md6/] [trunk/] [compressionFunction/] [fpga/] [MD6Engine.bsv] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 kfleming
//----------------------------------------------------------------------//
2
// The MIT License
3
//
4
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu
5
//
6
// Permission is hereby granted, free of charge, to any person
7
// obtaining a copy of this software and associated documentation
8
// files (the "Software"), to deal in the Software without
9
// restriction, including without limitation the rights to use,
10
// copy, modify, merge, publish, distribute, sublicense, and/or sell
11
// copies of the Software, and to permit persons to whom the
12
// Software is furnished to do so, subject to the following conditions:
13
//
14
// The above copyright notice and this permission notice shall be
15
// included in all copies or substantial portions of the Software.
16
//
17
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
// OTHER DEALINGS IN THE SOFTWARE.
25
//----------------------------------------------------------------------//
26 2 kfleming
/*
27
Copyright (c) 2008 MIT
28
 
29
Permission is hereby granted, free of charge, to any person
30
obtaining a copy of this software and associated documentation
31
files (the "Software"), to deal in the Software without
32
restriction, including without limitation the rights to use,
33
copy, modify, merge, publish, distribute, sublicense, and/or sell
34
copies of the Software, and to permit persons to whom the
35
Software is furnished to do so, subject to the following
36
conditions:
37
 
38
The above copyright notice and this permission notice shall be
39
included in all copies or substantial portions of the Software.
40
 
41
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
42
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
43
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
44
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
45
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
46
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
47
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
48
OTHER DEALINGS IN THE SOFTWARE.
49
 
50
Author: Kermin Fleming
51
*/
52
 
53
/* This is the top-level sorter module.  It interfaces to the PLB bus, the
54
   DSOCM, and the sorter core. Not much functionality, but it does have
55
   a cycle timer, and sends periodic messages back to the PPC over the
56
   DSOCM
57
*/
58
 
59
// Bluespec Lib
60
import FIFO::*;
61
import GetPut::*;
62
import Vector::*;
63
import Connectable::*;
64
 
65
// CSG Lib
66
import PLBMasterWires::*;
67
import BRAMInitiatorWires::*;
68
import PLBMaster::*;
69
import BRAMFeeder::*;
70
import PLBMaster::*;
71
import PLBMasterDefaultParameters::*;
72
 
73
// Local includes
74
import CompressionFunction::*;
75
import CompressionFunctionLibrary::*;
76
import MD6Parameters::*;
77
import MD6Types::*;
78
 
79
 
80
interface MD6Engine;
81
  interface PLBMasterWires                  plbMasterWires;
82
  interface BRAMInitiatorWires#(Bit#(14))   bramInitiatorWires;
83
endinterface
84
 
85
// Might consider making this size 8 at some point so that it jives with
86
// other parameterizations
87
typedef 16 InterfaceRegister;
88
typedef Bit#(15) RegisterTag;
89
 
90
typedef enum {
91
  Read = 0,
92
  Write = 1
93
} Command deriving (Bits,Eq);
94
 
95
 
96
typedef 7 ControlRegisters;
97
typedef TMul#(MD6_u,TDiv#(MD6_WordWidth,InterfaceRegister)) IdentifierRegisters;
98
typedef TMul#(MD6_k,TDiv#(MD6_WordWidth,InterfaceRegister)) KeyRegisters;
99
typedef 2 SourceRegisters;
100
typedef 2 DestinationRegisters;
101
 
102
typedef 0 RoundRegister;
103
typedef 1 TreeHeightRegister;
104
typedef 2 LastCompressionRegister;
105
typedef 3 PaddingBitsRegister;
106
typedef 4 KeyLengthRegister;
107
typedef 5 DigestLengthRegister;
108
typedef 6 CompressionFunctionStatus;
109
typedef 7 KeyRegisterBase;
110
typedef TAdd#(ControlRegisters,KeyRegisters) IdentifierRegisterBase;
111
typedef TAdd#(ControlRegisters, TAdd#(KeyRegisters,IdentifierRegisters)) SourceRegisterBase;
112
typedef TAdd#(TAdd#(ControlRegisters,IdentifierRegisters), TAdd#(KeyRegisters,SourceRegisters)) DestinationRegisterBase;
113
typedef TAdd#(IdentifierRegisters,TAdd#(TAdd#(ControlRegisters,DestinationRegisters), TAdd#(KeyRegisters,SourceRegisters))) TotalRegisters;
114
 
115
typedef TDiv#(TMul#(SizeOf#(BusWord),BeatsPerBurst), SizeOf#(MD6Word)) MD6WordsPerBurst;
116
 
117
typedef 32'hC0000 MD6CommunicationConstant;
118
 
119
typedef struct {
120
  Command command;
121
  RegisterTag regTag;
122
  Bit#(InterfaceRegister) payload;
123
} IOCommand deriving (Bits,Eq);
124
 
125
typedef enum {
126
  Idle,
127
  Load
128
} LoadState deriving (Bits,Eq);
129
 
130
typedef enum {
131
  Idle,
132
  Store
133
} StoreState deriving (Bits,Eq);
134
 
135
 
136
(*synthesize*)
137
module mkCompressionFunction64 (CompressionFunction#(64));
138
  let m <- mkMult16CompressionFunction;
139
  return m;
140
endmodule
141
 
142
(*synthesize*)
143
module mkCompressionFunction48 (CompressionFunction#(48));
144
  let m <- mkMult16CompressionFunction;
145
  return m;
146
endmodule
147
 
148
(*synthesize*)
149
module mkCompressionFunction32 (CompressionFunction#(32));
150
  let m <- mkMult16CompressionFunction;
151
  return m;
152
endmodule
153
 
154
(*synthesize*)
155
module mkCompressionFunction16 (CompressionFunction#(16));
156
  let m <- mkSimpleCompressionFunction;
157
  return m;
158
endmodule
159
 
160
(*synthesize*)
161
module mkCompressionFunction8 (CompressionFunction#(8));
162
  let m <- mkSimpleCompressionFunction;
163
  return m;
164
endmodule
165
 
166
(*synthesize*)
167
module mkCompressionFunction4 (CompressionFunction#(4));
168
  let m <- mkSimpleCompressionFunction;
169
  return m;
170
endmodule
171
 
172
(*synthesize*)
173
module mkCompressionFunction2 (CompressionFunction#(2));
174
  let m <- mkSimpleCompressionFunction;
175
  return m;
176
endmodule
177
 
178
(*synthesize*)
179
module mkCompressionFunction1 (CompressionFunction#(1));
180
  let m <- mkSimpleCompressionFunction;
181
  return m;
182
endmodule
183
 
184
 
185
module mkMD6Engine (MD6Engine);
186
  Feeder feeder <- mkBRAMFeeder();
187
  PLBMaster     plbMaster <- mkPLBMaster;
188
  CompressionFunction#(4) compressionFunction <- mkSimpleCompressionFunction;
189
  FIFO#(PPCMessage) outputFIFO <- mkFIFO;
190
  Vector#(TotalRegisters, Reg#(Bit#(InterfaceRegister))) interfaceRegisters <-
191
        replicateM(mkReg(0));
192
 
193
 
194
  // Hook Control, PLBMaster and MD6 engine components together.
195
  // This solution WILL NOT WORK for multiple Compression functions
196
  mkConnection(plbMaster.wordInput.put, compressionFunction.outputWord);
197
  mkConnection(compressionFunction.inputWord,plbMaster.wordOutput.get);
198
  mkConnection(feeder.ppcMessageInput.put,(fifoToGet(outputFIFO)).get);
199
 
200
  Reg#(Bit#(TAdd#(1,TDiv#(MD6_b,MD6WordsPerBurst)))) loadCount <- mkReg(0);
201
 
202
  Reg#(Bit#(TAdd#(1,TDiv#(MD6_c,MD6WordsPerBurst)))) storeCount <- mkReg(0);
203
 
204
  Reg#(LoadState) loadState <- mkReg(Idle);
205
 
206
  Reg#(StoreState) storeState <- mkReg(Idle);
207
 
208
  FIFO#(IOCommand) incomingCommands <- mkFIFO;
209
 
210
  function IOCommand extractIOCommand(PPCMessage ppcMessage);
211
    IOCommand command = IOCommand {command: unpack(ppcMessage[31]),
212
                                   regTag: ppcMessage[30:16],
213
                                   payload: ppcMessage[15:0]};
214
    return command;
215
  endfunction
216
 
217
  // This function may require its own unit test
218
  // It should convert interface words to MD6 Words
219
  function Vector#(length,MD6Word) convertWords(
220
           Vector#(TMul#(length,TDiv#(MD6_WordWidth,InterfaceRegister)),Bit#(InterfaceRegister)) inVector);
221
    Vector#(length,MD6Word) outVector = newVector;
222
    for(Integer totalNumber = 0;
223
        totalNumber < valueof(length);
224
        totalNumber = totalNumber + 1)
225
      begin
226
        Vector#(TDiv#(MD6_WordWidth,InterfaceRegister),Bit#(InterfaceRegister)) wordVector = newVector;
227
        for(Integer wordsInMD6Word = 0;
228
            wordsInMD6Word < valueof(TDiv#(MD6_WordWidth,InterfaceRegister));
229
            wordsInMD6Word = wordsInMD6Word + 1)
230
           begin
231
             wordVector[wordsInMD6Word] = inVector[totalNumber*valueof(TDiv#(MD6_WordWidth,InterfaceRegister))
232
                                                   +wordsInMD6Word];
233
           end
234
        outVector[totalNumber] = unpack(pack(wordVector)); // is this sane?
235
      end
236
    return outVector;
237
  endfunction
238
 
239
  rule getCommand;
240
    PPCMessage msg <- feeder.ppcMessageOutput.get;
241
    IOCommand command = extractIOCommand(msg);
242
    incomingCommands.enq(command);
243
  endrule
244
 
245
  // Writing to the CompressionFunctionStatus means kickoff a compression operation
246
  // Reading from it will grab the current status of the Compression Engine
247
 
248
  rule processWrite(incomingCommands.first.command == Write);
249
    incomingCommands.deq;
250
 
251
    if(fromInteger(valueof(CompressionFunctionStatus)) == incomingCommands.first.regTag)
252
      begin
253
        // we can leave this unguarded because the properties of the compression function
254
        // will prevent doing nasty things like confusing the order of memory accesses.
255
        let controlWord =  makeControlWord(truncate(interfaceRegisters[valueof(RoundRegister)]),
256
                                           truncate(interfaceRegisters[valueof(TreeHeightRegister)]),
257
                                           truncate(interfaceRegisters[valueof(LastCompressionRegister)]),
258
                                           truncate(interfaceRegisters[valueof(PaddingBitsRegister)]),
259
                                           truncate(interfaceRegisters[valueof(KeyLengthRegister)]),
260
                                           truncate(interfaceRegisters[valueof(DigestLengthRegister)]));
261
 
262
        compressionFunction.start(convertWords(takeAt(valueof(IdentifierRegisterBase),readVReg(interfaceRegisters))),
263
                                  controlWord,
264
                                  convertWords(takeAt(valueof(KeyRegisterBase),readVReg(interfaceRegisters))));
265
        loadState <= Load;
266
        loadCount <= 0;
267
      end
268
    else
269
      begin
270
        interfaceRegisters[incomingCommands.first.regTag] <= incomingCommands.first.payload;
271
      end
272
  endrule
273
 
274
  rule processRead(incomingCommands.first.command == Read);
275
    incomingCommands.deq;
276
 
277
    // This is a bit ugly, and we should possibly fix it.
278
    if(fromInteger(valueof(CompressionFunctionStatus)) == incomingCommands.first.regTag)
279
      begin
280
        outputFIFO.enq(fromInteger(valueof(MD6CommunicationConstant))|zeroExtend(compressionFunction.status));
281
      end
282
    else
283
      begin
284
        outputFIFO.enq(fromInteger(valueof(MD6CommunicationConstant))|zeroExtend((interfaceRegisters[incomingCommands.first.regTag])));
285
      end
286
 
287
  endrule
288
 
289
 
290
 
291
 
292
  // Probably should handle non-fitting burst sizes.  But, don't have to
293
  // for now.
294
  if(valueof(TotalRegisters) != 47)
295
    begin
296
      error("Total Registers: %d\n",valueof(TotalRegisters));
297
    end
298
 
299
  if(valueof(MD6_b)%valueof(MD6WordsPerBurst) != 0)
300
    begin
301
      error("MD6_b:%d not divisible by MD6WordsPerBurst:%d",valueof(MD6_b), valueof(MD6WordsPerBurst));
302
    end
303
 
304
  if(valueof(MD6_c)%valueof(MD6WordsPerBurst) != 0)
305
    begin
306
      error("MD6_c:%d not divisible by MD6WordsPerBurst:%d",valueof(MD6_c), valueof(MD6WordsPerBurst));
307
    end
308
 
309
  rule issueLoads(loadState == Load);
310
    if(loadCount + 1 == fromInteger(valueof(MD6_b)/valueof(MD6WordsPerBurst)))
311
      begin
312
        loadState <= Idle;
313
        storeState <= Store;
314
        storeCount <= 0;
315
      end
316
    loadCount <= loadCount + 1;
317
    BlockAddr refAddr = truncateLSB({interfaceRegisters[valueof(SourceRegisterBase)+1],
318
                                     interfaceRegisters[valueof(SourceRegisterBase)]})
319
                                     + (zeroExtend(loadCount) << (valueof(TLog#(WordsPerBurst))));
320
 
321
    plbMaster.plbMasterCommandInput.put(tagged LoadPage refAddr);
322
  endrule
323
 
324
 
325
 
326
  rule issueStores(storeState == Store);
327
    if(storeCount + 1 == fromInteger(valueof(MD6_c)/valueof(MD6WordsPerBurst)))
328
      begin
329
        storeState <= Idle;
330
      end
331
    storeCount <= storeCount + 1;
332
 
333
    BlockAddr refAddr = truncateLSB({interfaceRegisters[valueof(DestinationRegisterBase)+1],
334
                                     interfaceRegisters[valueof(DestinationRegisterBase)]})
335
                                     + (zeroExtend(storeCount) << (valueof(TLog#(WordsPerBurst))));
336
 
337
    plbMaster.plbMasterCommandInput.put(tagged StorePage refAddr);
338
  endrule
339
 
340
  interface plbMasterWires = plbMaster.plbMasterWires;
341
  interface bramInitiatorWires = feeder.bramInitiatorWires;
342
 
343
endmodule

powered by: WebSVN 2.1.0

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