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

Subversion Repositories cryptosorter

[/] [cryptosorter/] [trunk/] [lib/] [bsv/] [PLBMaster/] [src/] [PLBMaster.bsv] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 kfleming
/*
2
Copyright (c) 2007 MIT
3
 
4
Permission is hereby granted, free of charge, to any person
5
obtaining a copy of this software and associated documentation
6
files (the "Software"), to deal in the Software without
7
restriction, including without limitation the rights to use,
8
copy, modify, merge, publish, distribute, sublicense, and/or sell
9
copies of the Software, and to permit persons to whom the
10
Software is furnished to do so, subject to the following
11
conditions:
12
 
13
The above copyright notice and this permission notice shall be
14
included in all copies or substantial portions of the Software.
15
 
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
OTHER DEALINGS IN THE SOFTWARE.
24
 
25
Author: Kermin Fleming
26
*/
27
 
28
/* This file implements a PLB bus master.  The bus master operates on static
29
   sized bursts.  It is written in such a way that read/write bursts may be
30
   overlapped, if the bus and target slave support such a feature. There's also
31
   support for pipelining of read and write requests.  The master is
32
   parameterized by BeatsPerBurst (burst length) and BusWord (bus width),
33
   which allow it to be used for various applications.
34
*/
35
 
36
// Global Imports
37
import GetPut::*;
38
import FIFO::*;
39
import RegFile::*;
40
import BRAMInitiatorWires::*;
41
import RegFile::*;
42
import FIFOF::*;
43
import Vector::*;
44
`ifdef PLB_DEFAULTS
45
  import PLBMasterDefaultParameters::*;
46
`endif
47
 
48
import PLBMasterWires::*;
49
 
50
typedef Bit#(30) BlockAddr;
51
 
52
interface PLBMaster;
53
  interface Put#(Bit#(64)) wordInput;
54
  interface Get#(Bit#(64)) wordOutput;
55
  interface Put#(PLBMasterCommand) plbMasterCommandInput;
56
  interface PLBMasterWires   plbMasterWires;
57
endinterface
58
 
59
typedef union tagged
60
{
61
  BlockAddr LoadPage;
62
  BlockAddr StorePage;
63
}
64
  PLBMasterCommand
65
    deriving(Bits,Eq);
66
 
67
typedef enum {
68
  Idle,
69
  Data,
70
  WaitForBusy
71
} StateTransfer
72
    deriving(Bits, Eq);
73
 
74
typedef enum {
75
  Idle,
76
  RequestingLoad,
77
  RequestingStore
78
} StateRequest
79
    deriving(Bits, Eq);
80
 
81
(* synthesize *)
82
module mkPLBMaster (PLBMaster);
83
  Clock plbClock <- exposeCurrentClock();
84
  Reset plbReset <- exposeCurrentReset();
85
  // state for the actual magic memory hardware
86
  FIFO#(BusWord)            recordInfifo <- mkFIFO;
87
  FIFO#(BusWord)            recordOutfifo <- mkFIFO;
88
  FIFO#(PLBMasterCommand)  plbMasterCommandInfifo <- mkFIFO();
89
 
90
 
91
  // Output buffer
92
  RegFile#(Bit#(TAdd#(1,TLog#(BeatsPerBurst))),BusWord)                            storeBuffer <- mkRegFileFull();
93
 
94
 
95
  // Input buffer
96
  RegFile#(Bit#(TAdd#(1,TLog#(BeatsPerBurst))),BusWord)                            loadBuffer <- mkRegFileFull();
97
 
98
 
99
  Reg#(Bit#(24))                              rowAddrOffsetLoad <- mkReg(0);
100
  Reg#(Bit#(24))                              rowAddrOffsetStore <- mkReg(0);
101
 
102
  Reg#(Bool)                                doingLoad <- mkReg(False);
103
  Reg#(Bool)                                doingStore <- mkReg(False);
104
 
105
  Bit#(TLog#(TMul#(BeatsPerBurst, WordsPerBeat))) zeroOffset = 0; // Words per Burst
106
  Reg#(Bool)                                requestingStore <- mkReg(False);
107
  BlockAddr addressOffset                   = zeroExtend({(requestingStore)?rowAddrOffsetStore:rowAddrOffsetLoad,zeroOffset});
108
 
109
 
110
  Reg#(StateRequest)                        stateRequest <- mkReg(Idle);
111
  Reg#(StateTransfer)                       stateLoad <- mkReg(Idle);
112
  Reg#(StateTransfer)                       stateStore <- mkReg(Idle);
113
  Reg#(Bit#(1))                             request <- mkReg(0);
114
  Reg#(Bit#(1))                             rnw <- mkReg(0);
115
 
116
 
117
  Reg#(Bit#(TLog#(BeatsPerBurst)))              loadDataCount <- mkReg(0);
118
  Reg#(Bit#(TLog#(BeatsPerBurst)))              storeDataCount <-mkReg(0);// If you change this examine mWrDBus_o
119
  Reg#(Bit#(TAdd#(1,TLog#(BeatsPerBurst))))      loadDataCount_plus2 <- mkReg(2);
120
  Reg#(Bit#(TAdd#(1,TLog#(BeatsPerBurst))))      storeDataCount_plus2 <-mkReg(2);
121
 
122
  Reg#(Bool)                                doAckinIdle <- mkReg(False);
123
 
124
  Reg#(Bit#(1))                             rdBurst <- mkReg(0);
125
  Reg#(Bit#(1))                             wrBurst <- mkReg(0);
126
 
127
  Reg#(Bit#(1))                             storeCounter <- mkReg(0);
128
  Reg#(Bit#(1))                             loadCounter <- mkReg(0);
129
 
130
  Reg#(Bit#(TAdd#(1,TLog#(BeatsPerBurst)))) storeBufferWritePointer <- mkReg(0);
131
  FIFOF#(Bit#(0))                           storeValid <- mkUGFIFOF;//XXX: This could be bad
132
  Reg#(Bit#(TAdd#(1,TLog#(BeatsPerBurst)))) loadBufferReadPointer <- mkReg(0);
133
  FIFOF#(Bit#(0))                           loadValid <- mkUGFIFOF;//XXX: This could be bad
134
 
135
 
136
  // Input wires
137
  Wire#(Bit#(1)) mRst <- mkBypassWire();
138
  Wire#(Bit#(1)) mAddrAck <- mkBypassWire();
139
  Wire#(Bit#(1)) mBusy <- mkBypassWire();
140
  Wire#(Bit#(1)) mErr <- mkBypassWire();
141
  Wire#(Bit#(1)) mRdBTerm <- mkBypassWire();
142
  Wire#(Bit#(1)) mRdDAck <- mkBypassWire();
143
  Wire#(Bit#(64))mRdDBus <- mkBypassWire();
144
  Wire#(Bit#(3)) mRdWdAddr <- mkBypassWire();
145
  Wire#(Bit#(1)) mRearbitrate <- mkBypassWire();
146
  Wire#(Bit#(1)) mWrBTerm <- mkBypassWire();
147
  Wire#(Bit#(1)) mWrDAck <- mkBypassWire();
148
  Wire#(Bit#(1)) mSSize <- mkBypassWire();
149
  Wire#(Bit#(1)) sMErr <- mkBypassWire(); // on a read, during the data ack
150
  Wire#(Bit#(1)) sMBusy <- mkBypassWire();
151
 
152
  //  Outputs
153
 
154
 
155
  Bit#(PLBAddrSize) mABus_o = {addressOffset,2'b00}; // Our address Address Bus, we extend to compensate for word
156
 
157
 
158
  Bit#(TAdd#(1,TLog#(BeatsPerBurst))) sbuf_addr = {storeCounter,storeDataCount};
159
 
160
 
161
  Bit#(64)mWrDBus_o   = storeBuffer.sub(sbuf_addr);
162
  Bit#(1) mRequest_o  = request & ~mRst; // Request
163
  Bit#(1) mBusLock_o  = 1'b0 & ~mRst; // Bus lock
164
  Bit#(1) mRdBurst_o  = rdBurst & ~mRst; // read burst
165
  Bit#(1) mWrBurst_o  = wrBurst & ~mRst; // write burst
166
  Bit#(1) mRNW_o      = rnw; // Read Not Write
167
  Bit#(1) mAbort_o    = 1'b0; // Abort
168
  Bit#(2) mPriority_o = 2'b11;// priority indicator
169
  Bit#(1) mCompress_o = 1'b0;// compressed transfer
170
  Bit#(1) mGuarded_o  = 1'b0;// guarded transfer
171
  Bit#(1) mOrdered_o  = 1'b0;// synchronize transfer
172
  Bit#(1) mLockErr_o  = 1'b0;// lock erro
173
  Bit#(4) mSize_o     = 4'b1011; // Burst double word transfer - see PLB p.24
174
  Bit#(3) mType_o     = 3'b000; // Memory Transfer
175
  Bit#(8) mBE_o       = 8'b00001111; // 16 word burst
176
  Bit#(2) mMSize_o    = 2'b00;
177
 
178
 
179
  // precompute the next address offset.  Sometimes
180
 
181
 
182
  PLBMasterCommand cmd_in_first = plbMasterCommandInfifo.first();
183
 
184
  let newloadDataCount  =  loadDataCount + 1;
185
  let newstoreDataCount = storeDataCount + 1;
186
  let newloadDataCount_plus2  =  loadDataCount_plus2 + 1;
187
  let newstoreDataCount_plus2 = storeDataCount_plus2 + 1;
188
 
189
 
190
  rule startPageLoad(cmd_in_first matches tagged LoadPage .ba &&& !doingLoad);
191
        $display("Start Page");
192
        plbMasterCommandInfifo.deq();
193
        $display("Load Page");
194
        rowAddrOffsetLoad   <= truncate(ba>>(valueof(TLog#(TMul#(BeatsPerBurst, WordsPerBeat))))); // this is the log
195
        if (ba[3:0] != 0)
196
          $display("ERROR:Address not 64-byte aligned");
197
        doingLoad <= True;
198
  endrule
199
 
200
  rule startPageStore(cmd_in_first matches tagged StorePage .ba &&& !doingStore);
201
    $display("Start Page");
202
    plbMasterCommandInfifo.deq();
203
    $display("Store Page");
204
    rowAddrOffsetStore <= truncate(ba>>(valueof(TLog#(TMul#(BeatsPerBurst, WordsPerBeat))))); // this is the log
205
                                                                                             // size of burst addr
206
    if (ba[3:0] != 0)
207
      $display("ERROR:Address not 64-byte aligned");
208
    doingStore <= True;
209
  endrule
210
 
211
 
212
  rule loadPage_Idle(doingLoad && stateRequest == Idle && stateLoad == Idle);
213
    // We should not initiate a transfer if the wordOutfifo is not valid
214
    //$display("loadPage_Idle");
215
    requestingStore <= False;
216
    if(loadValid.notFull())// Check for a spot.
217
      begin
218
        request <= 1'b1;
219
        stateRequest <= RequestingLoad;
220
      end
221
    else
222
      begin
223
        request <= 1'b0;  // Not Sure this is needed
224
      end
225
 
226
    rnw <= 1'b1; // We're reading
227
  endrule
228
 
229
 
230
 
231
  rule loadPage_Requesting(doingLoad && stateRequest == RequestingLoad && stateLoad == Idle);
232
    // We've just requested the bus and are waiting for an ack
233
    //$display("loadPage_Requesting");
234
    if(mAddrAck == 1 )
235
      begin
236
        stateRequest <= Idle;
237
        // Check for error conditions
238
        if(mRearbitrate == 1)
239
          begin
240
            // Got terminated by the bus
241
            $display("Terminated by BUS @ %d",$time);
242
            stateLoad <= Idle;
243
            rdBurst <= 1'b0; // if we're rearbing this should be off. It may be off anyway?
244
            request <= 1'b0;
245
          end
246
        else
247
          begin
248
            //Whew! didn't die yet.. wait for acks to come back
249
            stateLoad <= Data;
250
            // Not permissible to assert burst until after addrAck p. 35
251
            rdBurst <= 1'b1;
252
            // Set down request, as we are not request pipelining
253
            request <= 1'b0;
254
          end
255
      end
256
  endrule
257
 
258
  rule loadPage_Data(doingLoad && stateLoad == Data);
259
    if(((mRdBTerm == 1) && (loadDataCount_plus2 < (fromInteger(valueof(BeatsPerBurst))))) || (mErr == 1))
260
      begin
261
        // We got terminated / Errored
262
        rdBurst <= 1'b0;
263
        loadDataCount <= 0;
264
        loadDataCount_plus2 <= 2;
265
        stateLoad <= Idle;
266
      end
267
    else if(mRdDAck == 1)
268
      begin
269
        loadDataCount <= newloadDataCount;
270
        loadDataCount_plus2 <= newloadDataCount_plus2;
271
        loadBuffer.upd({loadCounter,loadDataCount}, mRdDBus);
272
        if(newloadDataCount == 0)
273
          begin
274
            loadCounter <= loadCounter + 1; // Flip the loadCounter
275
            //We're now done reading... what should we do?
276
            loadValid.enq(0);  // This signifies that the data is valid Nirav could probably remove this
277
            doingLoad <= False;
278
            stateLoad <= Idle;
279
          end
280
        else if(newloadDataCount == maxBound) // YYY: ndave used to ~0
281
          begin
282
            // Last read is upcoming.  Need to set down the
283
            // rdBurst signal.
284
            rdBurst <= 1'b0;
285
          end
286
      end
287
  endrule
288
 
289
 
290
 
291
  rule storePage_Idle(doingStore && stateRequest == Idle && stateStore == Idle);
292
    requestingStore <= True;
293
    if(storeValid.notEmpty())
294
      begin
295
        request <= 1'b1;
296
        stateRequest <= RequestingStore;
297
      end
298
    else
299
      begin
300
        request <= 1'b0;
301
      end
302
 
303
    wrBurst <= 1'b1; // Write burst is asserted with the write request
304
    rnw <= 1'b0; // We're writing
305
  endrule
306
 
307
  rule storePage_Requesting(doingStore && stateRequest == RequestingStore && stateStore == Idle);
308
    // We've just requested the bus and are waiting for an ack
309
    if(mAddrAck == 1 )
310
      begin
311
        stateRequest <= Idle;
312
        // Check for error conditions
313
        if(mRearbitrate == 1)
314
          begin
315
            // Got terminated by the bus
316
            wrBurst <= 1'b0;
317
            request <= 1'b0;
318
          end
319
        else
320
          begin
321
            // Set down request, as we are not request pipelining
322
            request <= 1'b0;
323
            // We can be WrDAck'ed at this time p.29 or WrBTerm p.30
324
            if(mWrBTerm == 1)
325
              begin
326
                wrBurst <= 1'b0;
327
              end
328
            else if(mWrDAck == 1)
329
              begin
330
                storeDataCount <= newstoreDataCount;
331
                storeDataCount_plus2 <= newstoreDataCount_plus2;
332
                stateStore <= Data;
333
              end
334
            else
335
              begin
336
                stateStore <= Data;
337
              end
338
          end
339
      end
340
  endrule
341
 
342
 
343
  rule storePage_Data(doingStore && stateStore == Data);
344
    if((mWrBTerm == 1) && (storeDataCount_plus2 < (fromInteger(valueof(BeatsPerBurst)))) || (mErr == 1))
345
      begin
346
        // We got terminated / Errored
347
        wrBurst <= 1'b0;
348
        storeDataCount <= 0;
349
        storeDataCount_plus2 <= 2;
350
        stateStore <= Idle; // Can't burst for a cycle p. 30
351
      end
352
    else if(mWrDAck == 1)
353
      begin
354
        storeDataCount <= newstoreDataCount;
355
        storeDataCount_plus2 <= newstoreDataCount_plus2;
356
        if(newstoreDataCount == 0)
357
          begin
358
            //We're now done reading... what should we do?
359
            // Data transfer complete
360
            if(mBusy == 0)
361
              begin
362
                doingStore <= False;
363
                stateStore <= Idle;
364
                storeValid.deq();
365
                storeCounter <= storeCounter + 1;
366
              end
367
            else
368
              begin
369
                stateStore <= WaitForBusy;
370
              end
371
          end
372
        else if(newstoreDataCount == maxBound) //YYY: used to be ~0
373
          begin
374
            // Last read is upcoming.  Need to set down the
375
            // wrBurst signal.
376
            wrBurst <= 1'b0;
377
          end
378
      end
379
  endrule
380
 
381
  rule storePage_WaitForBusy(doingStore && stateStore == WaitForBusy);
382
    if(mErr == 1)
383
      begin
384
        // We got terminated / Errored
385
        wrBurst <= 1'b0;
386
        storeDataCount <= 0; // may not be necessary
387
        storeDataCount_plus2 <= 2;
388
        stateStore <= Idle; // Can't burst for a cycle p. 30
389
      end
390
    else if(mBusy == 0)
391
      begin
392
        storeCounter <= storeCounter + 1;
393
        doingStore <= False;
394
        stateStore <= Idle;
395
        storeValid.deq();
396
      end
397
  endrule
398
 
399
  /********
400
  /* Code For Handling Record Translation
401
  /*******/
402
 
403
  rule writeStoreData(storeValid.notFull());
404
    storeBufferWritePointer <= storeBufferWritePointer + 1;
405
 
406
 
407
    storeBuffer.upd(storeBufferWritePointer, {recordInfifo.first[31:0] ,recordInfifo.first[63:32]});
408
 
409
 
410
    recordInfifo.deq;
411
 
412
    Bit#(TLog#(BeatsPerBurst)) bottomValue = 0;
413
    if(truncate(storeBufferWritePointer + 1) == bottomValue)
414
      begin
415
        $display("Store Data finished a flight");
416
        storeValid.enq(0);
417
      end
418
  endrule
419
 
420
 
421
  rule wordToRecord(loadValid.notEmpty());
422
    loadBufferReadPointer <= loadBufferReadPointer + 1;
423
    Bit#(64) loadValue = loadBuffer.sub(loadBufferReadPointer);
424
    Bit#(32) loadHigh = loadValue [63:32];
425
    Bit#(32) loadLow = loadValue [31:0];
426
    Bit#(TLog#(BeatsPerBurst)) bottomValue = 0;
427
    if(truncate(loadBufferReadPointer + 1) == bottomValue)
428
      begin
429
        $display("Load Data finished a flight");
430
        loadValid.deq();
431
      end
432
 
433
 
434
    recordOutfifo.enq({loadLow,loadHigh});
435
 
436
  endrule
437
 
438
  interface Put wordInput = fifoToPut(recordInfifo);
439
 
440
  interface Get wordOutput = fifoToGet(recordOutfifo);
441
 
442
  interface Put plbMasterCommandInput = fifoToPut(plbMasterCommandInfifo);
443
 
444
 
445
  interface PLBMasterWires  plbMasterWires;
446
 
447
    method Bit#(PLBAddrSize) mABus();     // Address Bus
448
      return mABus_o;
449
    endmethod
450
    method Bit#(8)           mBE();       // Byte Enable
451
      return mBE_o;
452
    endmethod
453
 
454
    method Bit#(1)           mRNW();      // Read Not Write
455
      return mRNW_o;
456
    endmethod
457
 
458
    method Bit#(1)           mAbort();    // Abort
459
      return mAbort_o;
460
    endmethod
461
 
462
    method Bit#(1)           mBusLock();  // Bus lock
463
      return mBusLock_o;
464
    endmethod
465
 
466
    method Bit#(1)           mCompress(); // compressed transfer
467
      return mCompress_o;
468
    endmethod
469
 
470
    method Bit#(1)           mGuarded();  // guarded transfer
471
      return mGuarded_o;
472
    endmethod
473
 
474
    method Bit#(1)           mLockErr();  // lock error
475
      return mLockErr_o;
476
    endmethod
477
 
478
    method Bit#(2)           mMSize();    // data bus width?
479
      return mMSize_o;
480
    endmethod
481
 
482
    method Bit#(1)           mOrdered();  // synchronize transfer
483
      return mOrdered_o;
484
    endmethod
485
 
486
    method Bit#(2)           mPriority(); // priority indicator
487
      return mPriority_o;
488
    endmethod
489
 
490
    method Bit#(1)           mRdBurst();  // read burst
491
      return mRdBurst_o;
492
    endmethod
493
 
494
    method Bit#(1)           mRequest();  // bus request
495
      return mRequest_o;
496
    endmethod
497
 
498
    method Bit#(4)           mSize();     // transfer size
499
      return mSize_o;
500
    endmethod
501
 
502
    method Bit#(3)           mType();     // transfer type (dma)
503
      return mType_o;
504
    endmethod
505
 
506
    method Bit#(1)           mWrBurst();  // write burst
507
      return mWrBurst_o;
508
    endmethod
509
 
510
    method Bit#(64)          mWrDBus();   // write data bus
511
      return mWrDBus_o;
512
    endmethod
513
 
514
    method Action plbIN(
515
      Bit#(1) mRst_in,            // PLB reset
516
      Bit#(1) mAddrAck_in,             // Addr Ack
517
      Bit#(1) mBusy_in,           // Master Busy
518
      Bit#(1) mErr_in,            // Slave Error
519
      Bit#(1) mRdBTerm_in,             // Read burst terminate signal
520
      Bit#(1) mRdDAck_in,              // Read data ack
521
      Bit#(64)mRdDBus_in,              // Read data bus
522
      Bit#(3) mRdWdAddr_in,       // Read word address
523
      Bit#(1) mRearbitrate_in,    // Rearbitrate
524
      Bit#(1) mWrBTerm_in,             // Write burst terminate
525
      Bit#(1) mWrDAck_in,              // Write data ack
526
      Bit#(1) mSSize_in,               // Slave bus size
527
      Bit#(1) sMErr_in,        // Slave error
528
      Bit#(1) sMBusy_in);              // Slave busy
529
      mRst <= mRst_in;
530
      mAddrAck <= mAddrAck_in;
531
      mBusy <= mBusy_in;
532
      mErr <= mErr_in;
533
      mRdBTerm <= mRdBTerm_in;
534
      mRdDAck <= mRdDAck_in;
535
      mRdDBus <= mRdDBus_in;
536
      mRdWdAddr <= mRdWdAddr_in;
537
      mRearbitrate <= mRearbitrate_in;
538
      mWrBTerm <= mWrBTerm_in;
539
      mWrDAck <= mWrDAck_in;
540
      mSSize <= mSSize_in;
541
      sMErr <= sMErr_in;
542
      sMBusy <= sMBusy_in;
543
    endmethod
544
   endinterface
545
endmodule

powered by: WebSVN 2.1.0

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