OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [main_comp.v] - Blame information for rev 48

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
 `timescale  1ns/1ps
2
 
3
 
4
/**********************************************************************
5
**      File:  main_comp.v
6
**
7
**      Copyright (C) 2014-2017  Alireza Monemi
8
**
9
**      This file is part of ProNoC
10
**
11
**      ProNoC ( stands for Prototype Network-on-chip)  is free software:
12
**      you can redistribute it and/or modify it under the terms of the GNU
13
**      Lesser General Public License as published by the Free Software Foundation,
14
**      either version 2 of the License, or (at your option) any later version.
15
**
16
**      ProNoC is distributed in the hope that it will be useful, but WITHOUT
17
**      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18
**      or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
19
**      Public License for more details.
20
**
21
**      You should have received a copy of the GNU Lesser General Public
22
**      License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
23
**
24
**
25
**      Description:
26
**      This file contains several general RTL modules such as
27
**      different types of multiplexors, converters and counters ...
28
**
29
**************************************************************/
30
 
31
 
32
 
33
 
34
 
35
 
36
 
37
/*********************************
38
 
39
 
40
 
41
    multiplexer
42
 
43
 
44
 
45
********************************/
46
 
47
module one_hot_mux #(
48
        parameter   IN_WIDTH      = 20,
49
        parameter   SEL_WIDTH =   5,
50
        parameter   OUT_WIDTH = IN_WIDTH/SEL_WIDTH
51
 
52
    )
53
    (
54
        input [IN_WIDTH-1       :0] mux_in,
55
        output[OUT_WIDTH-1  :0] mux_out,
56
        input[SEL_WIDTH-1   :0] sel
57
 
58
    );
59
 
60
    wire [IN_WIDTH-1    :0] mask;
61
    wire [IN_WIDTH-1    :0] masked_mux_in;
62
    wire [SEL_WIDTH-1:0]    mux_out_gen [OUT_WIDTH-1:0];
63
 
64
    genvar i,j;
65
 
66
    //first selector masking
67
    generate    // first_mask = {sel[0],sel[0],sel[0],....,sel[n],sel[n],sel[n]}
68
        for(i=0; i<SEL_WIDTH; i=i+1) begin : mask_loop
69
            assign mask[(i+1)*OUT_WIDTH-1 : (i)*OUT_WIDTH]  =   {OUT_WIDTH{sel[i]} };
70
        end
71
 
72
        assign masked_mux_in    = mux_in & mask;
73
 
74
        for(i=0; i<OUT_WIDTH; i=i+1) begin : lp1
75
            for(j=0; j<SEL_WIDTH; j=j+1) begin : lp2
76
                assign mux_out_gen [i][j]   =   masked_mux_in[i+OUT_WIDTH*j];
77
            end
78
            assign mux_out[i] = | mux_out_gen [i];
79
        end
80
    endgenerate
81
 
82
endmodule
83
 
84
 
85
 
86
 
87
 
88
 
89
/******************************
90
 
91
    One hot demultiplexer
92
 
93
****************************/
94
 
95
 
96
module one_hot_demux    #(
97
        parameter IN_WIDTH=5,
98
        parameter SEL_WIDTH=4,
99
        parameter OUT_WIDTH=IN_WIDTH*SEL_WIDTH
100
    )
101
    (
102
        input   [SEL_WIDTH-1        :   0] demux_sel,//selectore
103
        input   [IN_WIDTH-1         :   0] demux_in,//repeated
104
        output  [OUT_WIDTH-1        :   0]  demux_out
105
    );
106
 
107
    genvar i,j;
108
    generate
109
    for(i=0;i<SEL_WIDTH;i=i+1)begin :loop1
110
        for(j=0;j<IN_WIDTH;j=j+1)begin :loop2
111
                assign demux_out[i*IN_WIDTH+j] =     demux_sel[i]   &   demux_in[j];
112
        end//for j
113
    end//for i
114
    endgenerate
115
 
116
 
117
 
118
endmodule
119
 
120
/**************************
121
 
122
 
123
    custom_or
124
 
125
 
126
***************************/
127
 
128
 
129
module custom_or #(
130
    parameter IN_NUM        =   4,
131
    parameter OUT_WIDTH =   5
132
)(
133
    or_in,
134
    or_out
135
);
136
 
137
    localparam IN_WIDTH  = IN_NUM*OUT_WIDTH;
138
 
139
    input [IN_WIDTH-1       :   0]  or_in;
140
    output[OUT_WIDTH-1      :   0]  or_out;
141
 
142
    wire        [IN_NUM-1       :   0] in_sep   [OUT_WIDTH-1        :   0];
143
    genvar i,j;
144
    generate
145
    for (i=0;i<OUT_WIDTH;i=i+1) begin: sep_loop
146
        for (j=0;j<IN_NUM;j=j+1) begin: sep_loop
147
            assign in_sep[i][j]= or_in [j*OUT_WIDTH+i];
148
        end
149
        assign or_out[i]= |in_sep[i];
150
    end
151
    endgenerate
152
 
153
 
154
endmodule
155
 
156
 
157
/*****************************************
158
 
159
sum the output of all ports except the output of  port itself
160
 
161
 
162
****************************************/
163
 
164
 
165
module outport_sum #(
166
    parameter IN_ARRAY_WIDTH =10,
167
    parameter IN_NUM     =5,
168
    parameter IN_WIDTH  =   IN_ARRAY_WIDTH/IN_NUM,
169
    parameter CMP_VAL   =   IN_WIDTH/(IN_NUM-1),
170
    parameter OUT_WIDTH = (IN_ARRAY_WIDTH/IN_NUM)+CMP_VAL
171
 
172
    )
173
    (
174
    input   [IN_ARRAY_WIDTH-1       :   0]  in,
175
    output  [OUT_WIDTH-1                :   0]  out
176
);
177
 
178
    genvar i,j;
179
    wire [IN_WIDTH-1        :   0]      in_sep  [IN_NUM-1       :   0];
180
    wire [IN_NUM-2          :   0]      gen         [OUT_WIDTH-1    :   0];
181
    generate
182
        for(i=0;i<IN_NUM; i=i+1      ) begin : lp
183
            assign in_sep[i]  = in[(IN_WIDTH*(i+1))-1   : IN_WIDTH*i];
184
        end
185
        for (j=0;j<IN_NUM-1;j=j+1)begin : loop1
186
                for(i=0;i<OUT_WIDTH; i=i+1  )begin : loop2
187
                    if(i>=CMP_VAL*(j+1))begin : if1
188
                        assign gen[i][j] = in_sep[j][i-CMP_VAL];
189
                    end
190
                    else if( i< CMP_VAL*(j+1) && i>= (CMP_VAL*j)) begin :if2
191
                        assign gen[i][j] = in_sep[IN_NUM-1][i];
192
                    end
193
                    else    begin :els
194
                        assign gen[i][j] = in_sep[j][i];
195
                    end
196
                end// for i
197
            end// for j
198
        for(i=0;i<OUT_WIDTH; i=i+1       ) begin : lp2
199
            assign out[i]               = |  gen[i];
200
        end
201
    endgenerate
202
endmodule
203
 
204
/***********************************
205
 
206
        module bin_to_one_hot
207
 
208
 
209
************************************/
210
 
211
 
212
module bin_to_one_hot #(
213
    parameter BIN_WIDTH     =   2,
214
    parameter ONE_HOT_WIDTH =   2**BIN_WIDTH
215
 
216
)
217
(
218
    input   [BIN_WIDTH-1            :   0]  bin_code,
219
    output  [ONE_HOT_WIDTH-1        :   0] one_hot_code
220
 );
221
 
222
    genvar i;
223
    generate
224
        for(i=0; i<ONE_HOT_WIDTH; i=i+1) begin :one_hot_gen_loop
225
                assign one_hot_code[i] = (bin_code == i[BIN_WIDTH-1         :   0]);
226
        end
227
    endgenerate
228
 
229
endmodule
230
 
231
/***********************************
232
 
233
        one_hot_to_binary
234
 
235
************************************/
236
 
237
 
238
 
239
module one_hot_to_bin #(
240
    parameter ONE_HOT_WIDTH =   4,
241
    parameter BIN_WIDTH     =  (ONE_HOT_WIDTH>1)? log2(ONE_HOT_WIDTH):1
242
)
243
(
244
    input   [ONE_HOT_WIDTH-1        :   0] one_hot_code,
245
    output  [BIN_WIDTH-1            :   0]  bin_code
246
 
247
);
248
 
249
 
250
    function integer log2;
251
      input integer number; begin
252
         log2=(number <=1) ? 1: 0;
253
         while(2**log2<number) begin
254
            log2=log2+1;
255
         end
256
      end
257
    endfunction // log2 
258
 
259
localparam MUX_IN_WIDTH =   BIN_WIDTH* ONE_HOT_WIDTH;
260
 
261
wire [MUX_IN_WIDTH-1        :   0]  bin_temp ;
262
 
263
genvar i;
264
generate
265
    if(ONE_HOT_WIDTH>1)begin :if1
266
        for(i=0; i<ONE_HOT_WIDTH; i=i+1) begin :mux_in_gen_loop
267
            assign bin_temp[(i+1)*BIN_WIDTH-1 : i*BIN_WIDTH] =  i[BIN_WIDTH-1:0];
268
        end
269
 
270
 
271
        one_hot_mux #(
272
            .IN_WIDTH   (MUX_IN_WIDTH),
273
            .SEL_WIDTH  (ONE_HOT_WIDTH)
274
 
275
        )
276
        one_hot_to_bcd_mux
277
        (
278
            .mux_in     (bin_temp),
279
            .mux_out        (bin_code),
280
            .sel            (one_hot_code)
281
 
282
        );
283
     end else begin :els
284
       // assign  bin_code = one_hot_code;
285
       assign  bin_code = 1'b0;
286
     end
287
 
288
endgenerate
289
 
290
endmodule
291
 
292
 
293
 
294
/****************************************
295
 
296
            binary_mux
297
 
298
***************************************/
299
 
300
module binary_mux #(
301
        parameter   IN_WIDTH         =   20,
302
        parameter   OUT_WIDTH       =   5
303
    )
304
    (
305
        mux_in,
306
        mux_out,
307
        sel
308
 
309
    );
310
 
311
 
312
    function integer log2;
313
      input integer number; begin
314
         log2=(number <=1) ? 1: 0;
315
         while(2**log2<number) begin
316
            log2=log2+1;
317
         end
318
      end
319
    endfunction // log2 
320
 
321
     localparam  IN_NUM          =   IN_WIDTH/OUT_WIDTH,
322
                 SEL_WIDTH_BIN   = (IN_NUM>1)?  log2(IN_NUM): 1;
323
 
324
 
325
    input   [IN_WIDTH-1         :0] mux_in;
326
    output  [OUT_WIDTH-1        :0] mux_out;
327
    input   [SEL_WIDTH_BIN-1    :0] sel;
328
    genvar i;
329
 
330
 
331
        generate
332
                if(IN_NUM>1) begin :if1
333
                        wire [OUT_WIDTH-1       :0] mux_in_2d [IN_NUM -1    :0];
334
                        for (i=0; i< IN_NUM; i=i+1) begin : loop
335
                                assign mux_in_2d[i] =mux_in[((i+1)*OUT_WIDTH)-1 :   i*OUT_WIDTH];
336
                        end
337
                        assign mux_out = mux_in_2d[sel];
338
                end else  begin :els
339
                        assign mux_out = mux_in;
340
                end
341
        endgenerate
342
 
343
endmodule
344
 
345
 
346
 
347
module  accumulator #(
348
    parameter INw= 20,
349
    parameter OUTw=4,
350
    parameter NUM =5
351
)
352
(
353
    in_all,
354
    out
355
);
356
 
357
    function integer log2;
358
      input integer number; begin
359
         log2=(number <=1) ? 1: 0;
360
         while(2**log2<number) begin
361
            log2=log2+1;
362
         end
363
      end
364
    endfunction // log2 
365
 
366
    localparam N= INw/NUM,
367
               SUMw= log2(NUM)+N;
368
    input [INw-1  :   0] in_all;
369
    output[OUTw-1 :   0] out;
370
 
371
    wire [N-1   :   0] in [NUM-1    :   0];
372
    reg [SUMw-1 :   0] sum;
373
 
374
 
375
    genvar i;
376
    generate
377
    for (i=0; i<NUM; i=i+1)begin : lp
378
        assign in[i] = in_all[(i+1)*N-1 : i*N];
379
    end
380
 
381
    if(  SUMw ==  OUTw) begin :  equal
382
        assign out = sum;
383
    end else if(SUMw >  OUTw) begin : bigger
384
        assign out = (sum[SUMw-1 : OUTw] > 0 ) ? {OUTw{1'b1}} : sum[OUTw-1  :   0] ;
385
    end else begin : less
386
          assign out = {{(OUTw-SUMw){1'b0}},  sum} ;
387
    end
388
 
389
 
390
 
391
    endgenerate
392
 
393
  // This is supposed to be synyhesized as "sum=in[0]+in[1]+...in[Num-1]"; 
394
  // It works with Quartus, Verilator and Modelsim compilers  
395
    integer k;
396
    always @(*)begin
397
        sum=0;
398
        for (k=0;k<NUM;k=k+1)begin
399
             sum= sum + {{(SUMw-N){1'b0}},in[k]};
400
        end
401
    end
402
    //In case your compiler could not synthesize or wrongly synthesizes it try this
403
    //assumming the maximum NUM as parameter can be 20:
404
    /*
405
    generate
406
     wire [N-1   :   0] tmp [19    :   0];
407
     for (i=0; i<NUM; i=i+1)begin : lp
408
        assign tmp[i] = in_all[(i+1)*N-1 : i*N];
409
     end
410
     for (i=NUM; i<20; i=i+1)begin : lp2
411
        assign tmp[i] = {N{1'b0}};
412
     end
413
 
414
    always @(*)begin
415
              sum= tmp[0] + tmp[1]+ tmp[2] + ...+ tmp[19];
416
    end
417
    endgenerate
418
    */
419
 
420
endmodule
421
 
422
 
423
 
424
/******************************
425
 
426
    set_bits_counter
427
 
428
*******************************/
429
 
430
 
431
module set_bits_counter #(
432
    parameter IN_WIDTH =120,
433
    parameter OUT_WIDTH = log2(IN_WIDTH+1)
434
    )
435
    (
436
    input   [IN_WIDTH-1         :   0]  in,
437
    output  [OUT_WIDTH-1        :   0]  out
438
 
439
);
440
 
441
    function integer log2;
442
      input integer number; begin
443
         log2=(number <=1) ? 1: 0;
444
         while(2**log2<number) begin
445
            log2=log2+1;
446
         end
447
      end
448
    endfunction // log2 
449
 
450
 
451
    wire    [IN_WIDTH-2     :   0]  addrin2;
452
    wire    [OUT_WIDTH-1    :   0]  addrout [IN_WIDTH-2         :   0];
453
    wire    [OUT_WIDTH-1    :   0]  addrin1 [IN_WIDTH-1         :   0];
454
 
455
 
456
    assign out          = addrin1 [IN_WIDTH-1];
457
 
458
    genvar i;
459
    //always @(*)begin
460
    assign  addrin1[0] = {{(OUT_WIDTH-1){1'b0}},in[0]};
461
    generate
462
        for (i=0; i<IN_WIDTH-1; i=i+1) begin : loop
463
                assign  addrin1[i+1]  = addrout[i];
464
                assign  addrin2[i]    = in[i+1];
465
                assign  addrout[i]    = addrin1[i] + addrin2 [i];
466
        end
467
    endgenerate
468
 
469
endmodule
470
 
471
 
472
 
473
 
474
 
475
 
476
/******************************
477
 
478
    check_single_bit_assertation
479
 
480
*******************************/
481
 
482
 
483
module check_single_bit_assertation #(
484
    parameter IN_WIDTH =2
485
 
486
    )
487
    (
488
    input   [IN_WIDTH-1         :   0]  in,
489
    output  result
490
 
491
    );
492
 
493
    function integer log2;
494
      input integer number; begin
495
         log2=(number <=1) ? 1: 0;
496
         while(2**log2<number) begin
497
            log2=log2+1;
498
         end
499
      end
500
    endfunction // log2 
501
 
502
 
503
 
504
    localparam OUT_WIDTH = log2(IN_WIDTH+1);
505
 
506
    wire [OUT_WIDTH-1   :   0]  sum;
507
 
508
    parallel_counter #(
509
        .IN_WIDTH (IN_WIDTH)
510
    )counter
511
    (
512
        .in(in),
513
        .out(sum)
514
    );
515
 
516
    assign result = (sum <=1)? 1'b1: 1'b0;
517
 
518
 
519
endmodule
520
 
521
/**********************************
522
 
523
fast_minimum_number
524
 
525
***********************************/
526
 
527
 
528
module fast_minimum_number#(
529
    parameter NUM_OF_INPUTS     =   8,
530
    parameter DATA_WIDTH            =   5,
531
    parameter IN_ARRAY_WIDTH    =   NUM_OF_INPUTS   * DATA_WIDTH
532
)
533
(
534
    input  [IN_ARRAY_WIDTH-1            :   0] in_array,
535
    output [NUM_OF_INPUTS-1             :   0]  min_out
536
);
537
 
538
    genvar i,j;
539
    wire [DATA_WIDTH-1                  :   0]  numbers             [NUM_OF_INPUTS-1            :0];
540
    wire [NUM_OF_INPUTS-2               :   0]  comp_array          [NUM_OF_INPUTS-1            :0];
541
 
542
    generate
543
    if(NUM_OF_INPUTS==1)begin:if1
544
        assign min_out = 1'b1;
545
    end
546
    else begin : els//(vc num >1)
547
        for(i=0; i<NUM_OF_INPUTS;  i=i+1) begin : loop_i
548
                assign numbers[i]   = in_array  [(i+1)* DATA_WIDTH-1: i*DATA_WIDTH];
549
                for(j=0; j<NUM_OF_INPUTS-1;  j=j+1) begin : loop_j
550
                            if(i>j) begin :if1 assign comp_array [i][j] = ~ comp_array [j][i-1]; end
551
                            else   begin :els     assign comp_array [i]   [j] = numbers[i]<= numbers[j+1]; end
552
                end//for j
553
                assign min_out[i]=  & comp_array[i];
554
        end//for i
555
    end//else
556
    endgenerate
557
 
558
endmodule
559
 
560
 
561
 
562
 
563
 
564
/********************************************
565
 
566
        Carry-based reduction parallel counter
567
 
568
 
569
********************************************/
570
module parallel_counter  #(
571
    parameter IN_WIDTH =120 // max 127
572
)
573
(
574
    in,
575
    out
576
);
577
 
578
 
579
 
580
    function integer log2;
581
      input integer number; begin
582
         log2=(number <=1) ? 1: 0;
583
         while(2**log2<number) begin
584
            log2=log2+1;
585
         end
586
      end
587
    endfunction // log2 
588
 
589
  localparam OUT_WIDTH = log2(IN_WIDTH+1);
590
  localparam PCIw      = (IN_WIDTH < 8   )? 7    :
591
                         (IN_WIDTH < 16  )? 15   :
592
                         (IN_WIDTH < 31  )? 31   :
593
                         (IN_WIDTH < 36  )? 63   :   127;
594
 
595
 
596
   localparam PCOw      = (IN_WIDTH < 8  )? 3   :
597
                         (IN_WIDTH < 16  )? 4   :
598
                         (IN_WIDTH < 31  )? 5   :
599
                         (IN_WIDTH < 36  )? 6   :   7;
600
 
601
input   [IN_WIDTH-1         :   0]  in;
602
output  [OUT_WIDTH-1        :   0]  out;
603
 
604
wire [PCIw-1    :   0]  pc_in;
605
wire [PCOw-1    :   0]  pc_out;
606
 
607
generate
608
    if(PCIw > IN_WIDTH ) begin :w1
609
        assign   pc_in = {{(PCIw-IN_WIDTH){1'b0}},in};
610
    end else begin:els
611
         assign   pc_in=in;
612
    end // if 
613
 
614
    if(PCIw == 7) begin :w7
615
 
616
        PC_7_3   pc (
617
            .in(pc_in),
618
            .out(pc_out)
619
        );
620
 
621
    end else if(PCIw == 15) begin :w15
622
          PC_15_4   pc (
623
            .in(pc_in),
624
            .out(pc_out)
625
           );
626
 
627
    end else if(PCIw == 31) begin :w31
628
        PC_31_5   pc (
629
            .in(pc_in),
630
            .out(pc_out)
631
        );
632
    end else if(PCIw == 63) begin :w63
633
         PC_63_6   pc (
634
            .in(pc_in),
635
            .out(pc_out)
636
        );
637
 
638
    end else  begin :w127
639
         PC_127_7 pc (
640
            .in(pc_in),
641
            .out(pc_out)
642
        );
643
    end
644
 
645
 endgenerate
646
 
647
 assign out = pc_out[OUT_WIDTH-1    :   0];
648
 
649
endmodule
650
 
651
 
652
 
653
//carry-sum generation blocks
654
module CS_GEN (
655
    in,
656
    abc,
657
    s
658
);
659
    input   [6  :   0] in;
660
    output  s;
661
    output  [2  :   0] abc;
662
 
663
    wire      a,b,c,s;
664
    wire    [3  :   0] in1;
665
    wire    [2  :   0] in2;
666
    wire    [2  :   0] j1;
667
    wire    [1  :   0] j2;
668
 
669
    assign {in2,in1} =  in;
670
/* verilator lint_off WIDTH */
671
    assign j1= in1[3]+in1[2]+in1[1]+in1[0];
672
    assign j2= in2[2]+in2[1]+in2[0];
673
/* verilator lint_on WIDTH */
674
 
675
    //s is asserted when both in1 and in2 have odd number of ones.
676
    assign s    = j1[0] ^ j2[0];
677
    // a is asserted when there are at least two ones in in1 (i.e., j1 >= 2);
678
    assign  a   =   (j1 >   3'd1);
679
 
680
    //b is asserted when there are at least two ones in in2 (i.e., j2 >= 2);
681
    assign  b   =   (j2 >   2'd1);
682
 
683
    // C is asserted when when j1 equals 4 or when  s is asserted
684
    assign c    =   (j1==4) | (j1[0] & j2[0]);
685
 
686
    assign abc = {a,b,c};
687
endmodule
688
 
689
/*************************
690
 
691
 (7,3) parallel counter
692
 
693
*************************/
694
 
695
module PC_7_3 (
696
    in,
697
    out
698
 
699
);
700
    input   [6    : 0]  in;
701
    output  [2    : 0]  out;
702
 
703
    wire    [2    : 0] abc;
704
 
705
    CS_GEN cs(
706
        .in(in),
707
        .abc(abc),
708
        .s(out[0])
709
    );
710
 
711
    assign out[2:1] = abc[2]+abc[1]+abc[0];
712
 
713
 
714
 
715
 
716
endmodule
717
 
718
/*************************
719
 
720
    (15,4) parallel counter
721
 
722
*************************/
723
 
724
module PC_15_4 (
725
    in,
726
    out
727
 
728
);
729
    input   [14   : 0]  in;
730
    output  [3    : 0]  out;
731
 
732
    wire    [2:0]   abc0,abc1;
733
    wire            s0,s1,b2;
734
 
735
    CS_GEN cs0(
736
        .in     (in  [6  :   0]),
737
        .abc    (abc0),
738
        .s      (s0)
739
    );
740
 
741
     CS_GEN cs1(
742
        .in     (in  [13  :   7]),
743
        .abc    (abc1),
744
        .s      (s1)
745
    );
746
 
747
    assign {b2,out[0]}  =in  [14] + s0 +s1;
748
 
749
    PC_7_3 pc_sub(
750
        .in({abc0,abc1,b2}),
751
        .out(out[3:1])
752
    );
753
 
754
 
755
 
756
 
757
endmodule
758
 
759
 
760
// (31,5) parallel counter
761
module PC_31_5 (
762
    in,
763
    out
764
 
765
);
766
    localparam CS_NUM   =   5;
767
 
768
    input   [30         : 0]  in;
769
    output  [4          : 0]  out;
770
 
771
 
772
    wire    [CS_NUM-1   : 0]   s;
773
    wire    [(CS_NUM*7)-1   :   0]  cs_in;
774
    wire    [14         :   0]  pc_15_in;
775
 
776
    assign cs_in ={s[3:0] ,in };
777
 
778
    genvar i;
779
    generate
780
    for (i=0;i<CS_NUM;i=i+1) begin: lp
781
        CS_GEN cs(
782
            .in     (cs_in     [(i+1)*7-1  :  i*7]),
783
            .abc    (pc_15_in  [(i+1)*3-1  :  i*3]),
784
            .s      (s      [i])
785
        );
786
 
787
    end//for
788
    endgenerate
789
 
790
    PC_15_4 pc_15(
791
        .in    (pc_15_in ),
792
        .out   (out[4:1])
793
    );
794
 
795
    assign out[0] = s[4];
796
 
797
 endmodule
798
 
799
/*************************
800
 
801
 (63,6) parallel counter
802
 
803
**************************/
804
 
805
module PC_63_6 (
806
    in,
807
    out
808
 
809
);
810
    localparam CS_NUM   =   10;
811
 
812
    input   [62         : 0]  in;
813
    output  [5          : 0]  out;
814
 
815
 
816
    wire    [CS_NUM-1   : 0]   s;
817
    wire    [(CS_NUM*7)-1   :   0]  cs_in;
818
    wire    [30         : 0]  pc_31_in;
819
 
820
    assign cs_in ={s[7:0] ,in };
821
 
822
    genvar i;
823
    generate
824
    for (i=0;i<CS_NUM;i=i+1) begin:lp
825
        CS_GEN cs(
826
            .in     (cs_in     [(i+1)*7-1  :  i*7]),
827
            .abc    (pc_31_in  [(i+1)*3-1  :  i*3]),
828
            .s      (s      [i])
829
        );
830
 
831
    end//for
832
    endgenerate
833
 
834
    assign {pc_31_in[30],out[0]}    =   s[7]+s[8]+s[9];
835
 
836
    PC_31_5 pc_31(
837
        .in(pc_31_in ),
838
        .out(out[5:1])
839
    );
840
 endmodule
841
 
842
/*************************
843
 
844
 (127,7) parallel counter
845
 
846
*************************/
847
 
848
module PC_127_7 (
849
    in,
850
    out
851
 
852
);
853
    localparam CS_NUM   =   21;
854
 
855
    input   [126        : 0]  in;
856
    output  [6          : 0]  out;
857
 
858
 
859
    wire    [CS_NUM-1       : 0]   s;
860
    wire    [(CS_NUM*7)-1   : 0]  cs_in;//147
861
    wire    [62             : 0]  pc_63_in;
862
 
863
    assign cs_in ={s[19:0] ,in };
864
 
865
    genvar i;
866
    generate
867
    for (i=0;i<CS_NUM;i=i+1) begin :lp
868
        CS_GEN cs(
869
            .in     (cs_in     [(i+1)*7-1  :  i*7]),
870
            .abc    (pc_63_in  [(i+1)*3-1  :  i*3]),
871
            .s      (s      [i])
872
        );
873
 
874
    end//for
875
    endgenerate
876
 
877
    assign {out[0]}    =   s[20];
878
 
879
    PC_63_6 pc63(
880
        .in(pc_63_in),
881
        .out(out[6:1])
882
    );
883
 
884
 
885
 endmodule
886
 
887
 
888
module start_delay_gen #(
889
    parameter NC     =    64 //number of cores
890
 
891
)(
892
    clk,
893
    reset,
894
    start_i,
895
    start_o
896
);
897
 
898
    input reset,clk,start_i;
899
    output [NC-1    :    0] start_o;
900
    reg start_i_reg;
901
    wire start;
902
    wire cnt_increase;
903
    reg  [NC-1    :    0] start_o_next;
904
    reg [NC-1    :    0] start_o_reg;
905
 
906
    assign start= start_i_reg|start_i;
907
 
908
generate
909
if(NC > 2) begin :l1
910
    always @(*)begin
911
        if(NC[0]==1'b0)begin // odd
912
            start_o_next={start_o[NC-3:0],start_o[NC-2],start};
913
        end else begin //even
914
            start_o_next={start_o[NC-3:0],start_o[NC-1],start};
915
 
916
        end
917
    end
918
 end
919
else begin :l2
920
         always @(*) start_o_next = {NC{start}};
921
end
922
 
923
endgenerate
924
 
925
    reg [2:0] counter;
926
    assign cnt_increase=(counter==3'd0);
927
    always @(posedge clk or posedge reset) begin
928
        if(reset) begin
929
            start_o_reg <= {NC{1'b0}};
930
            start_i_reg <= 1'b0;
931
            counter <= 3'd0;
932
        end else begin
933
            counter <= counter+3'd1;
934
            start_i_reg <= start_i;
935
            if(cnt_increase | start) start_o_reg <= start_o_next;
936
 
937
 
938
        end//reset
939
    end //always
940
 
941
    assign start_o=(cnt_increase | start)? start_o_reg : {NC{1'b0}};
942
 
943
endmodule
944
 
945
 
946
 
947
 

powered by: WebSVN 2.1.0

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