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 54

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

powered by: WebSVN 2.1.0

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