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

Subversion Repositories cryptosorter

[/] [cryptosorter/] [trunk/] [memocodeDesignContest2008/] [ctrl/] [mkCtrl.bsv] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 kfleming
/*
2
Copyright (c) 2007 MIT
3
 
4
Permission is hereby granted, free of charge, to any person obtaining
5
a copy of this software and associated documentation files (the
6
"Software"), to deal in the Software without restriction, including
7
without limitation the rights to use, copy, modify, merge, publish,
8
distribute, sublicense, and/or sell copies of the Software, and to
9
permit persons to whom the Software is furnished to do so, subject to
10
the following conditions:
11
 
12
The above copyright notice and this permission notice shall be
13
included in all copies or substantial portions of the Software.
14
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 
23
Author: Myron King
24
*/
25
 
26
 
27
/***************************************************************
28
 *
29
 * The module mkControl is responsible for (as it's name would
30
 * suggest) orchestrating the communication between the various
31
 * sub-modules in the system, as well as directing their
32
 * individual behavior.  The sort tree has a complicated control
33
 * protocol which requires that reservations be made for both
34
 * the insertion and extraction of data.  In order to avoid
35
 * deadlock, guarantees must be made on the availability of data
36
 * to be inserted or space for the extrated data to be buffered
37
 * In addition, the first stage of sorting is distinct from all
38
 * subsequent stages in that the data is organized randomly and
39
 * no assumptions can be made about ordered sub-streams in
40
 * memory.
41
 *
42
 * the module accepts commands in the form of the length of array
43
 * to be sorted, through the doSort interface.  the guarded value
44
 * method finished() returns true upon sort completion.  There is
45
 * a debug interface msgs which can be used to extract debug
46
 * messages.
47
 *
48
 * the mkTH module is for testing purposes only
49
 *
50
 ***************************************************************/
51
 
52
import BRAMFIFO        ::*;
53
import Sort            ::*;
54
import aesCipherTop    ::*;
55
import Memocode08Types ::*;
56
import ExternalMemory  ::*;
57
import PLBMasterDummy  ::*;
58
import Interfaces      ::*;
59
import FIFO            ::*;
60
import FIFOF           ::*;
61
import EHRReg          ::*;
62
import Vector          ::*;
63
import SortTree64      ::*;
64
import RegFile         ::*;
65
import GetPut          ::*;
66
 
67
interface Control;
68
   method Action doSort(Bit#(5) log_len);
69
   method Bool   finished();
70
   interface Get#(Bit#(32)) msgs;
71
endinterface
72
 
73
typedef 64 KMerges;
74
typedef Bit#(TLog#(KMerges)) KMask;
75
typedef Bit#(TAdd#(TLog#(KMerges),1)) KMaskp1;
76
typedef Bit#(TLog#(RecordsPerMemRequest)) RPMRMask;
77
typedef Bit#(TAdd#(1,TLog#(RecordsPerMemRequest))) OBuffCap;
78
typedef Bit#(20) RecAddr;
79
 
80
`define Debug False
81
 
82
(* descending_urgency = "drain_sorter,  write_to_mem" *)
83
(* descending_urgency = "read_request_a, schedule_read_request" *)
84
module mkControl#(ExternalMemory extMem, Clock fastClock, Reset fastReset) (Control);
85
 
86
 
87
   /*
88
 
89
   Bit#(5) log_sub_stream_lengths[3] = {6,  12,   18};
90
 
91
   RecAddr    num_sub_streams[13][3] = {{1,     0,  0},
92
                                        {2,     1,  0},
93
                                        {4,     1,  0},
94
                                        {8,     1,  0},
95
                                        {16,    1,  0},
96
                                        {32,    1,  0},
97
                                        {64,    1,  0},
98
                                        {128,   2,  1},
99
                                        {256,   4,  1},
100
                                        {512,   8,  1},
101
                                        {1024,  16, 1},
102
                                        {2048,  32, 1},
103
                                        {4096,  64, 1}};
104
 
105
   */
106
 
107
   let          sort_tree <- mkSortTree64();
108
   Clock clk <- exposeCurrentClock;
109
   Reset rst <- exposeCurrentReset;
110
   AESCores#(2) aes_cores <-  mkAESCoresMCD(clk,rst,clocked_by(fastClock),reset_by(fastReset));//mkAESCores();
111
 
112
   Reg#(RecAddr)  nss  <- mkRegU();
113
   Reg#(RecAddr)  ssl  <- mkRegU();
114
   Reg#(RecAddr)  nssl <- mkRegU();
115
   //let ssl       = (ra_one<<(log_sub_stream_lengths[iter-1]));
116
   //let nssl      = (ra_one<<(log_sub_stream_lengths[iter]));
117
   //let nss       = num_sub_streams[log_len-6][iter-1];
118
 
119
 
120
   Reg#(RecAddr) read_req_count  <- mkRegU();
121
   Reg#(RecAddr) read_res_count  <- mkRegU();
122
   Reg#(KMask)   res_count       <- mkRegU();
123
   Reg#(KMask)   read_count      <- mkRegU();
124
   Reg#(Bool)    read_eos        <- mkRegU();
125
   Reg#(RecAddr) write_base_addr <- mkRegU();
126
   Reg#(RecAddr) write_req_count <- mkRegU();
127
   Reg#(RecAddr) write_count     <- mkRegU();
128
   Reg#(Bit#(5)) log_len         <- mkRegU();
129
   Reg#(RecAddr) array_len       <- mkRegU();
130
   Reg#(Bit#(3)) iter            <- mkReg(~0);
131
   Reg#(Bool)    last            <- mkReg(False);
132
   Reg#(Bool)    done            <- mkReg(True);
133
   Reg#(Bool)    set_next_stage  <- mkReg(False);
134
   Reg#(RecAddr) set_ptr_count   <- mkRegU();
135
   Reg#(KMask)   set_count       <- mkRegU();
136
 
137
   Reg#(Bool)     pending_read_req   <- mkReg(False);
138
   Reg#(KMask)    pending_req_idx            <- mkRegU();
139
   Reg#(RecAddr)  pending_req_new_base_ptr   <- mkRegU();
140
   Reg#(Addr)     pending_req_req_addr       <- mkRegU();
141
   Reg#(RecAddr)  pending_req_new_eos_left   <- mkRegU();
142
   Reg#(Bool)     pending_req_need_eos       <- mkRegU();
143
   Reg#(RecAddr)  pending_req_new_req_offset <- mkRegU();
144
   Reg#(Bit#(5))  pending_req_rs_toks        <- mkRegU();
145
   Reg#(Bool)     pending_req_is_fin_stage   <- mkRegU();
146
 
147
   FIFO#(Bit#(6))      pending_first_res_count <- mkFIFO();
148
   FIFO#(RecAddr) pending_first_read_res_count <- mkFIFO();
149
   FIFO#(Bit#(6))      pending_pending_reserve <- mkFIFO();
150
 
151
   FIFO#(Tuple2#(KMask, Maybe#(Bit#(128)))) put_rec_fifo <- mkFIFO();
152
 
153
   RecAddr ra_one = 1;
154
   let kmerges   = fromInteger(valueOf(KMerges));
155
   let rpmr      = fromInteger(valueOf(RecordsPerMemRequest));
156
   let readpt    = 0;
157
   let writept   = 0;
158
   let recwid    = fromInteger(valueOf(RecordWidth));
159
   let outbuffsz = 2*rpmr;
160
   let tok_info  = sort_tree.inStream.getTokInfo();
161
 
162
   KMask kmask         = ~0;
163
   KMaskp1 kmask1      = ~0;
164
   RPMRMask rpmr_mask  = ~0;
165
   Bit#(32) bank_mask  = fromInteger(valueOf(MemBankSelector))>>4;
166
 
167
   RegFile#(KMask, RecAddr)   base_ptrs <- mkRegFileFull();
168
   RegFile#(KMask, RecAddr) req_offsets <- mkRegFileFull();
169
   RegFile#(KMask, RecAddr) rsp_offsets <- mkRegFileFull();
170
   RegFile#(KMask, RecAddr)   eos_lefts <- mkRegFileFull();
171
 
172
   Reg#(Vector#(KMerges, Bool)) finish_stage <- mkReg(replicate(False));
173
   FIFO#(KMask)                       rdfifo <- mkFIFO();
174
   FIFO#(Tuple2#(Bool,KMask))         rsfifo <- mkSizedFIFO(1);
175
   FIFOF#(Bit#(1))                    wrfifo <- mkFIFOF();
176
   FIFO#(Bit#(1))                     fsfifo <- mkFIFO();
177
 
178
   FIFOF#(Bit#(RecordWidth)) out_buff <- mkBRAMFIFOF(2*rpmr);
179
   Reg#(RPMRMask)        out_buff_cnt <- mkReg(0);
180
 
181
   FIFO#(Bit#(32)) msg_queue <- mkFIFO();
182
   Reg#(int)       msg_state <- mkReg(0);
183
   Reg#(Bit#(30)) tic_counter <- mkReg(1);
184
 
185
   Reg#(Bit#(32)) debug_read_requests <- mkReg(0);
186
   Reg#(Bit#(32)) debug_write_requests <- mkReg(0);
187
   Reg#(Bit#(32)) debug_drain_sorter_valid <- mkReg(0);
188
   Reg#(Bit#(32)) debug_write_to_mem <- mkReg(0);
189
   Reg#(Bit#(32)) debug_write_to_sort_tree <- mkReg(0);
190
   Reg#(Bit#(32)) debug_write_eos_to_sort_tree <- mkReg(0);
191
   Reg#(Bit#(32)) debug_write_eos_from_sort_tree <- mkReg(0);
192
   Reg#(Bit#(32)) debug_write_eos_first <- mkReg(0);
193
   Reg#(Bit#(32)) debug_write_eos_second <- mkReg(0);
194
   Reg#(Bool)     debug_setup_stream_stage <- mkReg(False);
195
 
196
   rule tic_toc(True);
197
      tic_counter <= tic_counter+1;
198
   endrule
199
 
200
   rule debug_stuff0 (tic_counter==0);
201
      msg_queue.enq(debug_read_requests);
202
      msg_state <= 1;
203
   endrule
204
 
205
   rule debug_stuff1 (msg_state==1);
206
      msg_queue.enq(debug_write_requests);
207
      msg_state <= 2;
208
   endrule
209
 
210
   rule debug_stuff2 (msg_state==2);
211
      msg_queue.enq(debug_drain_sorter_valid);
212
      msg_state <= 3;
213
   endrule
214
 
215
   rule debug_stuff3 (msg_state==3);
216
      msg_queue.enq(debug_write_to_mem);
217
      msg_state <= 4;
218
   endrule
219
 
220
   rule debug_stuff4 (msg_state==4);
221
      msg_queue.enq(debug_write_to_sort_tree);
222
      msg_state <= 5;
223
   endrule
224
 
225
   rule debug_stuff5 (msg_state==5);
226
      msg_queue.enq(debug_write_eos_to_sort_tree);
227
      msg_state <= 6;
228
   endrule
229
 
230
   rule debug_stuff6 (msg_state==6);
231
      msg_queue.enq(debug_write_eos_from_sort_tree);
232
      msg_state <= 7;
233
   endrule
234
 
235
   rule debug_stuff7 (msg_state==7);
236
      msg_queue.enq(debug_write_eos_first);
237
      msg_state <= 8;
238
   endrule
239
 
240
   rule debug_stuff8 (msg_state==8);
241
      msg_queue.enq(debug_write_eos_second);
242
      msg_state <= 9;
243
   endrule
244
 
245
 
246
   rule first_stage_reserve_a(!done &&
247
                              iter==0 &&
248
                              read_res_count > 0 &&
249
                              tok_info[res_count] > 1 );
250
      res_count <= res_count - 1;
251
      pending_first_res_count.enq(res_count);
252
      pending_first_read_res_count.enq(truncate(read_res_count));
253
      if(`Debug) $display("first_stage_reserve %d", res_count);
254
      // reached the end of a 64 element block, decrement the number
255
      // of 64 element blocks remaining
256
      if (res_count == 0)
257
         read_res_count <= read_res_count - 1;
258
   endrule
259
 
260
   rule first_stage_reserve_b (!done &&
261
                               iter==0);
262
      // reserve 1 slot for queue res_count
263
      // reserve 1 slot for corresponding eos
264
      sort_tree.inStream.putDeqTok(pending_first_res_count.first(),2);
265
      pending_first_res_count.deq();
266
      pending_pending_reserve.enq(pending_first_res_count.first());
267
   endrule
268
 
269
   rule first_stage_reserve_c (!done &&
270
                               iter==0);
271
      pending_first_read_res_count.deq();
272
      pending_pending_reserve.deq();
273
      // check if we've completed one burst's worth
274
      if((truncate(pending_pending_reserve.first())&rpmr_mask) == 0)
275
         begin
276
            if(`Debug) $display("first_stage_reserve block: %d, idx %d",
277
                                pending_first_read_res_count.first(),
278
                                pending_pending_reserve.first());
279
            fsfifo.enq(?);
280
         end
281
   endrule
282
 
283
   // once rpmr kmerge slots have been reserved, make a burst request
284
   rule first_stage_read_req (!done &&
285
                              iter == 0);
286
      let new_read_req_count = read_req_count - rpmr;
287
      fsfifo.deq(); // as long as rsfifo has something
288
      debug_read_requests <= debug_read_requests+1;
289
      extMem.read[readpt].readReq(zeroExtend(array_len-read_req_count)*(recwid/32));
290
      read_req_count <= new_read_req_count;
291
      if(`Debug) $display("first_stage_read_req %d", new_read_req_count);
292
   endrule
293
 
294
   // get the records returned from memory and feed the sort_tree
295
   rule first_stage_read_resp (!done &&
296
                               iter == 0);
297
 
298
      // enque data and eos tokens on alterntaing cycles
299
      read_eos <= !read_eos;
300
 
301
      if (read_eos)
302
         begin
303
            debug_write_eos_first <= debug_write_eos_first + 1;
304
            put_rec_fifo.enq(tuple2(read_count, tagged Invalid));
305
            read_count <= read_count - 1;
306
            if(`Debug) $display("first_stage_read_resp eos %d", read_count);
307
         end
308
      else
309
         begin
310
            let a <- extMem.read[readpt].read();
311
            let mask <- aes_cores.get_next();
312
            put_rec_fifo.enq(tuple2(read_count, tagged Valid (a^mask)));
313
            if(`Debug) $display("FIRST first_stage_read_resp idx %h, val %h xor %h",
314
                                read_count, a,a^mask);
315
         end
316
   endrule
317
 
318
   rule drain_sorter (True);
319
      let data <- sort_tree.getRecord();
320
      if(isValid(data))
321
         begin
322
            debug_drain_sorter_valid <= debug_drain_sorter_valid+1;
323
            out_buff.enq(unpack(fromMaybe(?, data)));
324
            out_buff_cnt <= out_buff_cnt + 1;
325
            if (out_buff_cnt == maxBound) // need a new write request
326
               wrfifo.enq(?);
327
            if(`Debug) $display("drain_sorter_finish");
328
         end
329
      else
330
         begin
331
            debug_write_eos_from_sort_tree <= debug_write_eos_from_sort_tree + 1;
332
            // we just dequeued an end of stream token, and
333
            // don't need to write that out to memory
334
            if(`Debug) $display("drain_sorter_finish eos");
335
         end
336
   endrule
337
 
338
   rule write_command (True);
339
         Bit#(AddrWidth) write_addr = zeroExtend(write_base_addr - write_req_count)*(recwid/32);
340
         wrfifo.deq();
341
         debug_write_requests <= debug_write_requests+1;
342
         extMem.write[writept].writeReq(write_addr);
343
         write_req_count <= write_req_count - rpmr;
344
         if(`Debug) $display("write_command %h",write_addr);
345
   endrule
346
 
347
   rule write_to_mem (True);
348
      //TODO: we need to re-encrypt the data on the last pass!
349
      out_buff.deq();
350
      debug_write_to_mem <= debug_write_to_mem+1;
351
      if(last)
352
         begin
353
            let mask <- aes_cores.get_next();
354
            extMem.write[writept].write(out_buff.first()^mask);
355
            if(`Debug) $display("LAST write_to_mem write_count %h, write_val %h xor %h",
356
                                write_count,out_buff.first(),out_buff.first()^mask);
357
         end
358
      else
359
         begin
360
           extMem.write[writept].write(out_buff.first());
361
           if(`Debug) $display("write_to_mem write_count %h, write_val %h",
362
                               write_count,out_buff.first());
363
        end
364
      if(write_count == 1)
365
         begin
366
            write_base_addr <= write_base_addr ^ truncate(bank_mask);
367
            write_count     <= array_len;
368
            write_req_count <= array_len;
369
            set_next_stage  <= True;
370
            set_ptr_count   <= write_base_addr; // last write this iter
371
            set_count       <= 63;
372
            iter            <= iter+1;
373
            finish_stage    <= replicate(False);
374
            if (`Debug) $display("done array, write_base_addr=%x", write_base_addr);
375
            ssl  <= ssl  << 6;
376
            nssl <= nssl << 6;
377
            nss  <= (nss <= 64) ? 1 : (nss>>6);
378
         end
379
      else
380
         write_count <= write_count - 1;
381
 
382
   endrule
383
 
384
 
385
 
386
 
387
 
388
 
389
 
390
 
391
 
392
 
393
 
394
   rule setup_stream_stage(!done &&
395
                           iter > 0 &&
396
                           set_next_stage );
397
      if(!debug_setup_stream_stage)
398
         begin
399
            set_count <= set_count - 1;
400
 
401
            if (set_count == 0)
402
               set_next_stage <= False;
403
            else
404
               debug_setup_stream_stage <= True;
405
 
406
            if(nss==1)
407
               begin
408
                  done <= True;
409
               end
410
            else
411
               begin
412
                  let a = rsp_offsets.sub(set_count);
413
                  let new_set_ptr_count = set_ptr_count - zeroExtend(ssl);
414
                  let chk = zeroExtend(63-set_count) >= nss;
415
                  // set_ptr_count contains an offset in # records with the
416
                  // high bit indicating a bank select. (crying out for strong typing!!!)
417
                  set_ptr_count <= new_set_ptr_count;
418
                  base_ptrs.upd(set_count,   chk ? 0 : set_ptr_count);
419
                  req_offsets.upd(set_count, chk ? 0 : zeroExtend(ssl));
420
                  rsp_offsets.upd(set_count, chk ? 0 : zeroExtend(ssl));
421
                  eos_lefts.upd(set_count,(nss>6); // number of substream / 64
422
                  if (`Debug) $display("%d base %x, req_offset %x, rsp_offset %x, eos_left %x",
423
                                       set_count,
424
                                       set_ptr_count,
425
                                       (chk ? 0 : ssl),
426
                                       (chk ? 0 : ssl),
427
                                       ((nss < kmerges) ? 1 : nss>>6));
428
               end
429
            if(nss<=kmerges)
430
               last <= True;
431
         end
432
      else
433
         begin
434
            debug_setup_stream_stage <= False;
435
            // this is OK for all but the largest size
436
            // 12 bits
437
            Bit#(12) eos_left = truncate(eos_lefts.sub(set_count+1));
438
            // 12 bits
439
            Bit#(12) bp = truncate(base_ptrs.sub(set_count+1)>>6);
440
            // 4 bits  -- 2nd stage, only about 7th bit
441
            Bit#(4) req_off  = truncate(req_offsets.sub(set_count+1)>>6);
442
            let rv = {req_off, bp, eos_left};
443
            //msg_queue.enq(zeroExtend(rv));
444
         end
445
   endrule
446
 
447
 
448
 
449
 
450
 
451
 
452
 
453
 
454
 
455
 
456
 
457
   function Bool rdy_for_requests(Bit#(sz) x, Bool y);
458
      return (x >= rpmr) && !y; // also check for enough for eos
459
   endfunction
460
 
461
 
462
 
463
 
464
 
465
   function Tuple2#(Bool,a) first_possible(Tuple2#(Bool,a) fst,
466
                                           Tuple2#(Bool,a) snd);
467
      return tpl_1(fst) ? fst : snd;
468
   endfunction
469
 
470
 
471
 
472
 
473
 
474
 
475
 
476
   rule schedule_read_request (!done &&
477
                               iter > 0 &&
478
                               !set_next_stage &&
479
                               !pending_read_req);
480
      Vector#(KMerges, Bool) pred =  zipWith(rdy_for_requests,
481
                                             sort_tree.inStream.getTokInfo,
482
                                             finish_stage);
483
      Vector#(KMerges, KMask) idxs = genWith(fromInteger);
484
      let vec  = zip(pred, idxs);
485
      let res  = fold(first_possible,vec);
486
      rsfifo.enq(res);
487
      match {.bv,.idx}  = res;
488
      if (`Debug) $display("schedule_read_requests %d, %d", bv, idx);
489
      if (`Debug) $display("   tok[%d] %d, ",idx,sort_tree.inStream.getTokInfo[idx]);
490
      if (`Debug) $display("finish[%d] %d, ",idx,finish_stage[idx]);
491
   endrule
492
 
493
 
494
// Why do they run when we are setting table?
495
 
496
 
497
   rule read_request_a (!done && iter > 0);
498
      rsfifo.deq();
499
      match {.bv,.idx}  = rsfifo.first();
500
      if(bv)
501
         begin
502
            pending_read_req   <= True;
503
            let base_ptr       = base_ptrs.sub(idx);
504
            let new_base_ptr   = base_ptr - zeroExtend(nssl);
505
            let req_offset     = req_offsets.sub(idx);
506
            let req_addr       = zeroExtend(base_ptr - req_offset)*(recwid/32);
507
            let eos_left       = eos_lefts.sub(idx);
508
            let new_eos_left   = eos_left - 1;
509
            let need_eos       = req_offset == 0;
510
            let new_req_offset = (need_eos) ? zeroExtend(ssl) : req_offset - rpmr;
511
            let rs_toks        = (need_eos) ? 1 : rpmr;
512
            let is_fin_stage   = eos_left==1;
513
 
514
            pending_req_idx            <= idx;
515
            pending_req_new_base_ptr   <= new_base_ptr;
516
            pending_req_req_addr       <= req_addr;
517
            pending_req_new_eos_left   <= new_eos_left;
518
            pending_req_need_eos       <= need_eos;
519
            pending_req_new_req_offset <= new_req_offset;
520
            pending_req_rs_toks        <= rs_toks;
521
            pending_req_is_fin_stage   <= is_fin_stage;
522
 
523
            if (`Debug) $display("read_requests %d, %d", bv, idx);
524
         end
525
   endrule
526
 
527
 
528
 
529
 
530
 
531
 
532
 
533
 
534
   rule read_request_b (!done && iter>0 && pending_read_req);
535
      pending_read_req <= False;
536
      let idx            = pending_req_idx;
537
      let new_base_ptr   = pending_req_new_base_ptr;
538
      let req_addr       = pending_req_req_addr;
539
      let new_eos_left   = pending_req_new_eos_left;
540
      let need_eos       = pending_req_need_eos;
541
      let new_req_offset = pending_req_new_req_offset;
542
      let rs_toks        = pending_req_rs_toks;
543
      let is_fin_stage   = pending_req_is_fin_stage;
544
 
545
      if (need_eos)
546
         begin
547
            finish_stage <= update(finish_stage,idx,is_fin_stage);
548
            eos_lefts.upd(idx,new_eos_left);
549
            base_ptrs.upd(idx,new_base_ptr);
550
            if(`Debug) $display("eos_requests %d is_last_eos %d",
551
                                idx, is_fin_stage);
552
         end
553
      else
554
         begin
555
            debug_read_requests <= debug_read_requests+1;
556
            extMem.read[readpt].readReq(req_addr);
557
            if(`Debug) $display("read_requests idx %d, addr %x",
558
                                idx, req_addr);
559
         end
560
      rdfifo.enq(idx);
561
      req_offsets.upd(idx, new_req_offset);
562
      sort_tree.inStream.putDeqTok(idx,rs_toks);
563
      if(`Debug) $display("read_requests idx %d, new_req_offset %x, deqTok %d",
564
                          idx, new_req_offset, rs_toks);
565
   endrule
566
 
567
 
568
 
569
 
570
 
571
 
572
   rule read_resp (!done &&
573
                   iter > 0 &&
574
                   !set_next_stage);
575
 
576
      let idx            = rdfifo.first();
577
      let rsp_offset     = rsp_offsets.sub(idx);
578
      let need_eos       = rsp_offset == 0;
579
      let new_rsp_offset = (need_eos) ? zeroExtend(ssl) : rsp_offset - 1;
580
 
581
      RPMRMask rpmr_one = 1;
582
 
583
      if (((truncate(rsp_offset)&rpmr_mask) == rpmr_one)||need_eos)
584
         rdfifo.deq();
585
 
586
      rsp_offsets.upd(idx,new_rsp_offset);
587
      if(need_eos)
588
         begin
589
            debug_write_eos_second <= debug_write_eos_second + 1;
590
            put_rec_fifo.enq(tuple2(idx, tagged Invalid));
591
            if(`Debug) $display("read_resps eos %x", idx);
592
         end
593
      else
594
         begin
595
            let val <- extMem.read[readpt].read();
596
            put_rec_fifo.enq(tuple2(idx, tagged Valid val));
597
            if(`Debug) $display("read_resps idx %x val %x", idx, val);
598
         end
599
   endrule
600
 
601
 
602
 
603
 
604
 
605
 
606
   rule put_rec (True);
607
      put_rec_fifo.deq();
608
      match {.idx, .val} = put_rec_fifo.first();
609
      if(isValid(val))
610
         debug_write_to_sort_tree <= debug_write_to_sort_tree+1;
611
      else
612
         debug_write_eos_to_sort_tree <= debug_write_eos_to_sort_tree+1;
613
      sort_tree.inStream.putRecord(idx, val);
614
   endrule
615
 
616
 
617
   method Action doSort(Bit#(5) len) if (done);
618
      $display("doSort");
619
      RecAddr array_sz = 1<
620
      let num_blocks = array_sz>>6;  // no. 64-record blocks we need for first stage = (2^len / 64)
621
      let block_sz = 63;             // 64 to go
622
      read_res_count  <= num_blocks;
623
      res_count       <= 63;
624
      read_req_count  <= array_sz;
625
      read_count      <= 63;
626
      read_eos        <= False;
627
      write_count     <= array_sz;
628
      write_base_addr <= array_sz ^ truncate(bank_mask);
629
      write_req_count <= array_sz;
630
      out_buff_cnt    <= 0;
631
      log_len         <= len;
632
      iter            <= 0;
633
      done            <= False;
634
      array_len       <= array_sz;
635
      nss             <= array_sz;
636
      ssl             <= 1;
637
      nssl            <= 1<<6;
638
      aes_cores.start(len);
639
      if(len==6)
640
         last <= True;
641
      else
642
         last <= False;
643
   endmethod
644
 
645
   method Bool finished();
646
      return done;
647
   endmethod
648
 
649
   interface msgs = fifoToGet(msg_queue);
650
 
651
endmodule
652
 
653
 
654
module mkTH ();
655
 
656
   PLBMaster     plbmaster <- mkPLBMasterDummy;
657
   ExternalMemory   extMem <- mkExternalMemory(plbmaster);
658
   Clock clk <- exposeCurrentClock;
659
   Reset rst <- exposeCurrentReset;
660
   Control             cnt <- mkControl(extMem, clk, rst);
661
 
662
   Bit#(32) left_bank = (fromInteger(valueOf(MemBankSelector))>>2);
663
   Bit#(32) right_bank = 0;
664
   Bit#(32) bank_masks[13] = {left_bank,
665
                              right_bank,
666
                              right_bank,
667
                              right_bank,
668
                              right_bank,
669
                              right_bank,
670
                              right_bank,
671
                              left_bank,
672
                              left_bank,
673
                              left_bank,
674
                              left_bank,
675
                              left_bank,
676
                              left_bank};
677
 
678
   String dump_file_names[13] = {"sorted_array_6.txt",
679
                                 "sorted_array_7.txt",
680
                                 "sorted_array_8.txt",
681
                                 "sorted_array_9.txt",
682
                                 "sorted_array_10.txt",
683
                                 "sorted_array_11.txt",
684
                                 "sorted_array_12.txt",
685
                                 "sorted_array_13.txt",
686
                                 "sorted_array_14.txt",
687
                                 "sorted_array_15.txt",
688
                                 "sorted_array_16.txt",
689
                                 "sorted_array_17.txt",
690
                                 "sorted_array_18.txt"};
691
   RegFile#(Bit#(18), Record)         resmem <- mkRegFileFullLoad("sorted.hex");
692
 
693
   let recwid        = fromInteger(valueOf(RecordWidth));
694
   let rpmr          = fromInteger(valueOf(RecordsPerMemRequest));
695
   RPMRMask rpmr_msk = 0;
696
   let log_len       = `LogArrayLen;  // this should be defined at the command line
697
   let bank_mask     = bank_masks[log_len-6];
698
   let dump_file     = dump_file_names[log_len-6];
699
 
700
 
701
   Reg#(Bit#(64)) cycleCnt  <- mkReg(0);
702
   Reg#(Bit#(64)) startTime <- mkReg(0);
703
   Reg#(Bit#(32)) count <- mkReg(0);
704
   Reg#(int) state      <- mkReg(0);
705
   Reg#(Bool) need_req  <- mkReg(True);
706
   Reg#(Bit#(18)) output_count <- mkReg(0);
707
   Reg#(Bit#(18)) req_count <- mkReg(0);
708
   let fh               <- mkReg(InvalidFile) ;
709
 
710
   rule incrCycle (True);
711
      cycleCnt <= cycleCnt + 1;
712
   endrule
713
 
714
   rule open_file (state == 0 );
715
      $display("sorting an array of log_len %d", log_len);
716
      File lfh <- $fopen( dump_file, "w" ) ;
717
      if ( lfh == InvalidFile )
718
         begin
719
            $display("cannot open %s", dump_file);
720
            $finish(0);
721
         end
722
      fh <= lfh;
723
      state <= 2;
724
   endrule
725
 
726
   rule disp_msg (True);
727
      let a <- cnt.msgs.get();
728
      $display("MESSAGE from control %h",a);
729
   endrule
730
 
731
   rule disp_mem((state==4)&&need_req);
732
     extMem.read[0].readReq(bank_mask|{zeroExtend(req_count),5'b00});
733
     req_count <= req_count + 1;
734
     if(req_count + 1 == (1<<(log_len - 2)))
735
       begin
736
         need_req <= False;
737
       end
738
   endrule
739
 
740
   rule check(state == 4);
741
     let data <- extMem.read[0].read();
742
     output_count <= output_count + 1;
743
     if(data != resmem.sub(output_count))
744
       begin
745
          $display("Error at %d: got %h expected %h",output_count, data, resmem.sub(output_count));
746
          $fwrite(fh, "Error at %d: got %h expected %h",output_count, data, resmem.sub(output_count));
747
          $finish;
748
 
749
       end
750
     if(output_count + 1 == (1<
751
        begin
752
           $display("PASS Size %d!!!!", log_len);
753
           $fwrite(fh, "PASS Size %d!!!!", log_len);
754
           $finish;
755
        end
756
   endrule
757
 
758
   rule start_sort(state==2);
759
      cnt.doSort(log_len);
760
      state <= 3;
761
 
762
      startTime <= startTime + 1;
763
   endrule
764
 
765
   rule disp_orig_a((state==3)&&cnt.finished());
766
      state <= 4;
767
 
768
      $display("Total cycles %d",cycleCnt - startTime);
769
   endrule
770
 
771
   rule finish(state==5);
772
      $finish;
773
   endrule
774
endmodule
775
 

powered by: WebSVN 2.1.0

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