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

Subversion Repositories bluespec_md6

[/] [bluespec_md6/] [trunk/] [MD6Control/] [test/] [benchmarks/] [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 mkCompressionFunction16 (CompressionFunction#(16));
138
  let m <- mkSimpleCompressionFunction;
139
  return m;
140
endmodule
141
 
142
(*synthesize*)
143
module mkCompressionFunction8 (CompressionFunction#(8));
144
  let m <- mkSimpleCompressionFunction;
145
  return m;
146
endmodule
147
 
148
(*synthesize*)
149
module mkCompressionFunction4 (CompressionFunction#(4));
150
  let m <- mkSimpleCompressionFunction;
151
  return m;
152
endmodule
153
 
154
(*synthesize*)
155
module mkCompressionFunction2 (CompressionFunction#(2));
156
  let m <- mkSimpleCompressionFunction;
157
  return m;
158
endmodule
159
 
160
(*synthesize*)
161
module mkCompressionFunction1 (CompressionFunction#(1));
162
  let m <- mkSimpleCompressionFunction;
163
  return m;
164
endmodule
165
 
166
 
167
module mkMD6Engine (MD6Engine);
168
  Feeder feeder <- mkBRAMFeeder();
169
  PLBMaster     plbMaster <- mkPLBMaster;
170
  CompressionFunction#(4) compressionFunction <- mkSimpleCompressionFunction;
171
  FIFO#(PPCMessage) outputFIFO <- mkFIFO;
172
  Vector#(TotalRegisters, Reg#(Bit#(InterfaceRegister))) interfaceRegisters <-
173
        replicateM(mkReg(0));
174
 
175
 
176
  // Hook Control, PLBMaster and MD6 engine components together.
177
  // This solution WILL NOT WORK for multiple Compression functions
178
  mkConnection(plbMaster.wordInput.put, compressionFunction.outputWord);
179
  mkConnection(compressionFunction.inputWord,plbMaster.wordOutput.get);
180
  mkConnection(feeder.ppcMessageInput.put,(fifoToGet(outputFIFO)).get);
181
 
182
  Reg#(Bit#(TAdd#(1,TDiv#(MD6_b,MD6WordsPerBurst)))) loadCount <- mkReg(0);
183
 
184
  Reg#(Bit#(TAdd#(1,TDiv#(MD6_c,MD6WordsPerBurst)))) storeCount <- mkReg(0);
185
 
186
  Reg#(LoadState) loadState <- mkReg(Idle);
187
 
188
  Reg#(StoreState) storeState <- mkReg(Idle);
189
 
190
  FIFO#(IOCommand) incomingCommands <- mkFIFO;
191
 
192
  function IOCommand extractIOCommand(PPCMessage ppcMessage);
193
    IOCommand command = IOCommand {command: unpack(ppcMessage[31]),
194
                                   regTag: ppcMessage[30:16],
195
                                   payload: ppcMessage[15:0]};
196
    return command;
197
  endfunction
198
 
199
  // This function may require its own unit test
200
  // It should convert interface words to MD6 Words
201
  function Vector#(length,MD6Word) convertWords(
202
           Vector#(TMul#(length,TDiv#(MD6_WordWidth,InterfaceRegister)),Bit#(InterfaceRegister)) inVector);
203
    Vector#(length,MD6Word) outVector = newVector;
204
    for(Integer totalNumber = 0;
205
        totalNumber < valueof(length);
206
        totalNumber = totalNumber + 1)
207
      begin
208
        Vector#(TDiv#(MD6_WordWidth,InterfaceRegister),Bit#(InterfaceRegister)) wordVector = newVector;
209
        for(Integer wordsInMD6Word = 0;
210
            wordsInMD6Word < valueof(TDiv#(MD6_WordWidth,InterfaceRegister));
211
            wordsInMD6Word = wordsInMD6Word + 1)
212
           begin
213
             wordVector[wordsInMD6Word] = inVector[totalNumber*valueof(TDiv#(MD6_WordWidth,InterfaceRegister))
214
                                                   +wordsInMD6Word];
215
           end
216
        outVector[totalNumber] = unpack(pack(wordVector)); // is this sane?
217
      end
218
    return outVector;
219
  endfunction
220
 
221
  rule getCommand;
222
    PPCMessage msg <- feeder.ppcMessageOutput.get;
223
    IOCommand command = extractIOCommand(msg);
224
    incomingCommands.enq(command);
225
  endrule
226
 
227
  // Writing to the CompressionFunctionStatus means kickoff a compression operation
228
  // Reading from it will grab the current status of the Compression Engine
229
 
230
  rule processWrite(incomingCommands.first.command == Write);
231
    incomingCommands.deq;
232
 
233
    if(fromInteger(valueof(CompressionFunctionStatus)) == incomingCommands.first.regTag)
234
      begin
235
        // we can leave this unguarded because the properties of the compression function
236
        // will prevent doing nasty things like confusing the order of memory accesses.
237
        let controlWord =  makeControlWord(truncate(interfaceRegisters[valueof(RoundRegister)]),
238
                                           truncate(interfaceRegisters[valueof(TreeHeightRegister)]),
239
                                           truncate(interfaceRegisters[valueof(LastCompressionRegister)]),
240
                                           truncate(interfaceRegisters[valueof(PaddingBitsRegister)]),
241
                                           truncate(interfaceRegisters[valueof(KeyLengthRegister)]),
242
                                           truncate(interfaceRegisters[valueof(DigestLengthRegister)]));
243
 
244
        compressionFunction.start(convertWords(takeAt(valueof(IdentifierRegisterBase),readVReg(interfaceRegisters))),
245
                                  controlWord,
246
                                  convertWords(takeAt(valueof(KeyRegisterBase),readVReg(interfaceRegisters))));
247
        loadState <= Load;
248
        loadCount <= 0;
249
      end
250
    else
251
      begin
252
        interfaceRegisters[incomingCommands.first.regTag] <= incomingCommands.first.payload;
253
      end
254
  endrule
255
 
256
  rule processRead(incomingCommands.first.command == Read);
257
    incomingCommands.deq;
258
 
259
    // This is a bit ugly, and we should possibly fix it.
260
    if(fromInteger(valueof(CompressionFunctionStatus)) == incomingCommands.first.regTag)
261
      begin
262
        outputFIFO.enq(fromInteger(valueof(MD6CommunicationConstant))|zeroExtend(compressionFunction.status));
263
      end
264
    else
265
      begin
266
        outputFIFO.enq(fromInteger(valueof(MD6CommunicationConstant))|zeroExtend((interfaceRegisters[incomingCommands.first.regTag])));
267
      end
268
 
269
  endrule
270
 
271
 
272
 
273
 
274
  // Probably should handle non-fitting burst sizes.  But, don't have to
275
  // for now.
276
  if(valueof(TotalRegisters) != 47)
277
    begin
278
      error("Total Registers: %d\n",valueof(TotalRegisters));
279
    end
280
 
281
  if(valueof(MD6_b)%valueof(MD6WordsPerBurst) != 0)
282
    begin
283
      error("MD6_b:%d not divisible by MD6WordsPerBurst:%d",valueof(MD6_b), valueof(MD6WordsPerBurst));
284
    end
285
 
286
  if(valueof(MD6_c)%valueof(MD6WordsPerBurst) != 0)
287
    begin
288
      error("MD6_c:%d not divisible by MD6WordsPerBurst:%d",valueof(MD6_c), valueof(MD6WordsPerBurst));
289
    end
290
 
291
  rule issueLoads(loadState == Load);
292
    if(loadCount + 1 == fromInteger(valueof(MD6_b)/valueof(MD6WordsPerBurst)))
293
      begin
294
        loadState <= Idle;
295
        storeState <= Store;
296
        storeCount <= 0;
297
      end
298
    loadCount <= loadCount + 1;
299
    BlockAddr refAddr = truncateLSB({interfaceRegisters[valueof(SourceRegisterBase)+1],
300
                                     interfaceRegisters[valueof(SourceRegisterBase)]})
301
                                     + (zeroExtend(loadCount) << (valueof(TLog#(WordsPerBurst))));
302
 
303
    plbMaster.plbMasterCommandInput.put(tagged LoadPage refAddr);
304
  endrule
305
 
306
 
307
 
308
  rule issueStores(storeState == Store);
309
    if(storeCount + 1 == fromInteger(valueof(MD6_c)/valueof(MD6WordsPerBurst)))
310
      begin
311
        storeState <= Idle;
312
      end
313
    storeCount <= storeCount + 1;
314
 
315
    BlockAddr refAddr = truncateLSB({interfaceRegisters[valueof(DestinationRegisterBase)+1],
316
                                     interfaceRegisters[valueof(DestinationRegisterBase)]})
317
                                     + (zeroExtend(storeCount) << (valueof(TLog#(WordsPerBurst))));
318
 
319
    plbMaster.plbMasterCommandInput.put(tagged StorePage refAddr);
320
  endrule
321
 
322
  interface plbMasterWires = plbMaster.plbMasterWires;
323
  interface bramInitiatorWires = feeder.bramInitiatorWires;
324
 
325
endmodule

powered by: WebSVN 2.1.0

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