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/] [src_peripheral/] [bus/] [wishbone_bus.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
/**********************************************************************
2
**      File:  wishbone_bus.v
3
**
4
**
5
**      Copyright (C) 2014-2017  Alireza Monemi
6
**
7
**      This file is part of ProNoC
8
**
9
**      ProNoC ( stands for Prototype Network-on-chip)  is free software:
10
**      you can redistribute it and/or modify it under the terms of the GNU
11
**      Lesser General Public License as published by the Free Software Foundation,
12
**      either version 2 of the License, or (at your option) any later version.
13
**
14
**      ProNoC is distributed in the hope that it will be useful, but WITHOUT
15
**      ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
**      or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
17
**      Public License for more details.
18
**
19
**      You should have received a copy of the GNU Lesser General Public
20
**      License along with ProNoC. If not, see <http:**www.gnu.org/licenses/>.
21
**
22
**
23
**      Description:
24
**      parametrizable wishbone bus
25
**
26
*******************************************************************/
27
 
28
 
29
 
30
 
31
 
32
 
33
 
34
 
35
// synthesis translate_off
36
`timescale 1ns / 1ps
37
// synthesis translate_on
38
 
39
 
40
module wishbone_bus #(
41
 
42
        parameter M        =   4,               //number of master port
43
        parameter S        =   4,               //number of slave port
44
        parameter Dw       =   32,         // maximum data width
45
        parameter Aw       =   32,    // address width
46
        parameter SELw     =   2,
47
        parameter TAGw     =   3,    //merged  {tga,tgb,tgc}
48
        parameter CTIw     =   3,
49
        parameter BTEw     =   2
50
 
51
 
52
)
53
(
54
        //slaves interface
55
        s_adr_o_all,
56
        s_dat_o_all,
57
        s_sel_o_all,
58
        s_tag_o_all,
59
        s_we_o_all,
60
        s_cyc_o_all,
61
        s_stb_o_all,
62
        s_cti_o_all,
63
    s_bte_o_all,
64
 
65
        s_dat_i_all,
66
        s_ack_i_all,
67
        s_err_i_all,
68
        s_rty_i_all,
69
 
70
 
71
        //masters interface
72
        m_dat_o_all,
73
        m_ack_o_all,
74
        m_err_o_all,
75
        m_rty_o_all,
76
 
77
 
78
        m_adr_i_all,
79
        m_dat_i_all,
80
        m_sel_i_all,
81
        m_tag_i_all,
82
        m_we_i_all,
83
        m_stb_i_all,
84
        m_cyc_i_all,
85
        m_cti_i_all,
86
    m_bte_i_all,
87
 
88
        //address compar
89
        m_grant_addr,
90
    s_sel_one_hot,
91
 
92
 
93
    //snoop_interface
94
    snoop_adr_o,
95
    snoop_en_o,
96
 
97
 
98
        //system signals
99
 
100
        clk,
101
        reset
102
 
103
);
104
 
105
    function integer log2;
106
      input integer number; begin
107
         log2=0;
108
         while(2**log2<number) begin
109
            log2=log2+1;
110
         end
111
      end
112
   endfunction // log2 
113
 
114
 
115
 
116
    localparam  DwS     =   Dw * S,
117
                AwS     =   Aw * S,
118
                SELwS   =   SELw * S,
119
                TAGwS   =   TAGw * S,
120
                CTIwS   =   CTIw * S,
121
                BTEwS   =   BTEw * S,
122
                DwM     =   Dw * M,
123
                AwM     =   Aw  * M,
124
                SELwM   =   SELw   * M,
125
                TAGwM   =   TAGw   * M,
126
                Mw      =   (M>1)? log2(M):1,
127
                Sw      =   (S>1)? log2(S):1,
128
                CTIwM   =   CTIw * M,
129
                BTEwM   =   BTEw * M;
130
 
131
 
132
 
133
 
134
 
135
    output  [AwS-1      :   0]   s_adr_o_all;
136
    output  [DwS-1      :   0]   s_dat_o_all;
137
    output  [SELwS-1    :   0]   s_sel_o_all;
138
    output  [TAGwS-1    :   0]   s_tag_o_all;
139
    output  [S-1        :   0]   s_we_o_all;
140
    output  [S-1        :   0]   s_cyc_o_all;
141
    output  [S-1        :   0]   s_stb_o_all;
142
    output  [CTIwS-1    :   0]   s_cti_o_all;
143
    output  [BTEwS-1    :   0]   s_bte_o_all;
144
 
145
 
146
    input   [DwS-1      :   0]   s_dat_i_all;
147
    input   [S-1        :   0]   s_ack_i_all;
148
    input   [S-1        :   0]   s_err_i_all;
149
    input   [S-1        :   0]   s_rty_i_all;
150
 
151
 
152
 
153
 
154
 
155
    //masters interface
156
    output  [DwM-1      :   0]   m_dat_o_all;
157
    output  [M-1        :   0]   m_ack_o_all;
158
    output  [M-1        :   0]   m_err_o_all;
159
    output  [M-1        :   0]   m_rty_o_all;
160
 
161
 
162
    input   [AwM-1      :   0]   m_adr_i_all;
163
    input   [DwM-1      :   0]   m_dat_i_all;
164
    input   [SELwM-1    :   0]   m_sel_i_all;
165
    input   [TAGwM-1    :   0]   m_tag_i_all;
166
    input   [M-1        :   0]   m_we_i_all;
167
    input   [M-1        :   0]   m_stb_i_all;
168
    input   [M-1        :   0]   m_cyc_i_all;
169
    input   [CTIwM-1    :   0]   m_cti_i_all;
170
    input   [BTEwM-1    :   0]   m_bte_i_all;
171
 
172
    //
173
     output [Aw-1       :   0]  m_grant_addr;
174
     input  [S-1        :   0]  s_sel_one_hot;
175
 
176
 
177
     //snoop interface 
178
    output   [Aw-1      :   0]   snoop_adr_o;
179
    output                snoop_en_o;
180
 
181
    //system signals
182
 
183
    input                           clk,     reset;
184
 
185
 
186
    wire                            any_s_ack,any_s_err,any_s_rty;
187
    wire                        m_grant_we,m_grant_stb,m_grant_cyc;
188
 
189
    wire    [Dw-1       :       0]       m_grant_dat,s_read_dat;
190
    wire        [SELw-1     :   0]       m_grant_sel;
191
    wire    [BTEw-1     :   0]  m_grant_bte;
192
    wire    [CTIw-1     :   0]  m_grant_cti;
193
    wire        [TAGw-1     :   0]       m_grant_tag;
194
 
195
 
196
    wire        [Sw-1       :   0]       s_sel_bin;
197
    wire        [M-1        :   0]       m_grant_onehot;
198
    wire        [Mw-1       :   0]       m_grant_bin;
199
 
200
    wire        [Aw-1      :    0]       s_adr_o;
201
    wire        [Dw-1      :    0]       s_dat_o;
202
    wire        [SELw-1    :    0]       s_sel_o;
203
    wire    [BTEw-1    :    0]  s_bte_o;
204
    wire    [CTIw-1    :    0]  s_cti_o;
205
 
206
    wire        [TAGw-1    :    0]       s_tag_o;
207
    wire                        s_we_o;
208
    wire                        s_cyc_o;
209
    wire        [Dw-1       :   0]       m_dat_o;
210
 
211
 
212
 
213
 
214
    assign      s_adr_o_all     =       {S{s_adr_o}};
215
    assign      s_dat_o_all     =       {S{s_dat_o}};
216
    assign      s_sel_o_all     =       {S{s_sel_o}};
217
    assign  s_cti_o_all =   {S{s_cti_o}};
218
    assign  s_bte_o_all =   {S{s_bte_o}};
219
 
220
    assign      s_tag_o_all     =       {S{s_tag_o}};
221
    assign      s_we_o_all      =       {S{s_we_o}};
222
    assign      s_cyc_o_all     =       {S{s_cyc_o}};
223
    assign      m_dat_o_all=    {M{m_dat_o}};
224
 
225
    assign      any_s_ack   =|  s_ack_i_all;
226
    assign      any_s_err   =|  s_err_i_all;
227
    assign      any_s_rty   =|  s_rty_i_all;
228
 
229
    assign      s_adr_o     =   m_grant_addr;
230
    assign      s_dat_o     =   m_grant_dat;
231
    assign      s_sel_o     =   m_grant_sel;
232
    assign  s_bte_o     =   m_grant_bte;
233
    assign  s_cti_o     =   m_grant_cti;
234
    assign      s_tag_o     =   m_grant_tag;
235
    assign      s_we_o      =   m_grant_we;
236
    assign      s_cyc_o     =   m_grant_cyc;
237
    assign      s_stb_o_all     =       s_sel_one_hot & {S{m_grant_stb & m_grant_cyc}};
238
 
239
    //snoop address comes directly from master bus 
240
    assign snoop_adr_o = m_grant_addr;
241
 
242
    //snoop on ack and write.mask with strobe
243
    assign snoop_en_o = any_s_ack & m_grant_stb & m_grant_we;
244
 
245
 
246
//wire  [ADDR_PERFIX-1          :       0]      m_perfix_addr;
247
//assign m_perfix_addr          =       m_grant_addr[Aw-3       :       Aw-ADDR_PERFIX-2];
248
 
249
 
250
assign  m_dat_o         =       s_read_dat;
251
assign  m_ack_o_all     =       m_grant_onehot  & {M{any_s_ack}};
252
assign  m_err_o_all     =       m_grant_onehot  & {M{any_s_err}};
253
assign  m_rty_o_all     =       m_grant_onehot  & {M{any_s_rty}};
254
 
255
 
256
 
257
 
258
//convert one hot to bin 
259
    one_hot_to_bin #(
260
        .ONE_HOT_WIDTH(S)
261
    )
262
    s_sel_conv
263
    (
264
        .one_hot_code(s_sel_one_hot),
265
        .bin_code(s_sel_bin)
266
    );
267
 
268
 
269
 
270
    one_hot_to_bin #(
271
        .ONE_HOT_WIDTH(M)
272
    )
273
    m_grant_conv
274
    (
275
        .one_hot_code   (m_grant_onehot),
276
        .bin_code               (m_grant_bin)
277
    );
278
 
279
 
280
 
281
    //slave multiplexer 
282
    binary_mux #(
283
        .IN_WIDTH       (DwS),
284
        .OUT_WIDTH      (Dw)
285
    )
286
     s_read_data_mux
287
    (
288
        .mux_in         (s_dat_i_all),
289
        .mux_out                (s_read_dat),
290
        .sel                    (s_sel_bin)
291
 
292
    );
293
 
294
 
295
    //master ports multiplexers
296
 
297
    binary_mux #(
298
        .IN_WIDTH       (AwM),
299
        .OUT_WIDTH      (Aw)
300
    )
301
     m_adr_mux
302
    (
303
        .mux_in         (m_adr_i_all),
304
        .mux_out                (m_grant_addr),
305
        .sel                    (m_grant_bin)
306
 
307
    );
308
 
309
 
310
 
311
    binary_mux #(
312
        .IN_WIDTH       (DwM),
313
        .OUT_WIDTH      (Dw)
314
    )
315
     m_data_mux
316
    (
317
        .mux_in         (m_dat_i_all),
318
        .mux_out                (m_grant_dat),
319
        .sel                    (m_grant_bin)
320
 
321
    );
322
 
323
 
324
 
325
    binary_mux #(
326
        .IN_WIDTH       (SELwM),
327
        .OUT_WIDTH      (SELw)
328
    )
329
     m_sel_mux
330
    (
331
        .mux_in         (m_sel_i_all),
332
        .mux_out                (m_grant_sel),
333
        .sel                    (m_grant_bin)
334
 
335
    );
336
 
337
     binary_mux #(
338
        .IN_WIDTH   (BTEwM),
339
        .OUT_WIDTH  (BTEw)
340
    )
341
     m_bte_mux
342
    (
343
        .mux_in         (m_bte_i_all),
344
        .mux_out        (m_grant_bte),
345
        .sel            (m_grant_bin)
346
 
347
    );
348
 
349
    binary_mux #(
350
        .IN_WIDTH   (CTIwM),
351
        .OUT_WIDTH  (CTIw)
352
    )
353
     m_cti_mux
354
    (
355
        .mux_in         (m_cti_i_all),
356
        .mux_out        (m_grant_cti),
357
        .sel            (m_grant_bin)
358
 
359
    );
360
 
361
 
362
    binary_mux #(
363
        .IN_WIDTH       (TAGwM),
364
        .OUT_WIDTH      (TAGw)
365
    )
366
     m_tag_mux
367
    (
368
        .mux_in         (m_tag_i_all),
369
        .mux_out                (m_grant_tag),
370
        .sel                    (m_grant_bin)
371
 
372
    );
373
 
374
 
375
    binary_mux #(
376
        .IN_WIDTH       (M),
377
        .OUT_WIDTH      (1)
378
    )
379
     m_we_mux
380
    (
381
        .mux_in         (m_we_i_all),
382
        .mux_out                (m_grant_we),
383
        .sel                    (m_grant_bin)
384
 
385
    );
386
 
387
 
388
   /*
389
    binary_mux #(
390
        .IN_WIDTH       (M),
391
        .OUT_WIDTH      (1)
392
    )
393
     m_stb_mux
394
    (
395
        .mux_in         (m_stb_i_all),
396
        .mux_out                (m_grant_stb),
397
        .sel                    (m_grant_bin)
398
 
399
    );
400
 
401
 
402
 
403
    binary_mux #(
404
        .IN_WIDTH       (M),
405
        .OUT_WIDTH      (1)
406
    )
407
     m_cyc_mux
408
    (
409
        .mux_in         (m_cyc_i_all),
410
        .mux_out                (m_grant_cyc),
411
        .sel                    (m_grant_bin)
412
 
413
    );
414
   */
415
   // if m_grant_one_hot is zero the stb and cyc  must not be asserted hence have to use one-hot mux 
416
 
417
 
418
    one_hot_mux #(
419
        .IN_WIDTH(M),
420
        .SEL_WIDTH(M),
421
        .OUT_WIDTH(1)
422
    )
423
    m_stb_mux
424
    (
425
        .mux_in(m_stb_i_all),
426
        .mux_out(m_grant_stb),
427
        .sel(m_grant_onehot)
428
 
429
    );
430
 
431
 
432
     one_hot_mux #(
433
        .IN_WIDTH(M),
434
        .SEL_WIDTH(M),
435
        .OUT_WIDTH(1)
436
    )
437
     m_cyc_mux
438
    (
439
        .mux_in(m_cyc_i_all),
440
        .mux_out(m_grant_cyc),
441
        .sel(m_grant_onehot)
442
 
443
    );
444
 
445
 
446
 
447
 
448
 
449
generate
450
        if(M > 1) begin
451
                // round roubin arbiter
452
                bus_arbiter # (
453
                        .M (M)
454
                )
455
                arbiter
456
                (
457
                        .request (m_cyc_i_all),
458
                        .grant  (m_grant_onehot),
459
                        .clk (clk),
460
                        .reset (reset)
461
                );
462
        end else begin // if we have just one master there is no needs for arbitration
463
                assign m_grant_onehot = m_cyc_i_all;
464
        end
465
endgenerate
466
 
467
// synthesis translate_off 
468
 
469
    wire sel_is_one_hot;
470
    is_one_hot #(
471
        .INw(S)
472
    )
473
    check_one_hot
474
    (
475
        .in(s_sel_one_hot),
476
        .result(sel_is_one_hot)
477
 
478
    );
479
 
480
 
481
    always @(posedge clk) begin //set error message when a master is seding a request to an unregistered address or multiple slaves match the address range
482
           if (|m_cyc_i_all==1'b1) begin
483
               if (|s_sel_one_hot==1'b0) begin
484
                      $display ("Error: A master is seding a request to an unregistered wishbone address range: %h.  %m",m_grant_addr);
485
               end      else if(sel_is_one_hot==1'b0) begin
486
                  $display ("Error: Multiple slaves match with the given address range: %b.  %m",sel_is_one_hot);
487
           end
488
           end
489
    end
490
 
491
 
492
 
493
 
494
// synthesis translate_on
495
 
496
endmodule
497
 
498
 
499
 
500
 
501
/**************
502
 
503
    bus_arbiter
504
 
505
**************/
506
 
507
module bus_arbiter # (
508
        parameter M = 4
509
)
510
(
511
        request,
512
        grant,
513
        clk,
514
        reset
515
);
516
 
517
    input   [M-1    :       0]  request;
518
    output  [M-1    :       0]  grant;
519
    input                       clk, reset;
520
 
521
    wire                    comreq;
522
    wire    [M-1        :       0]       one_hot_arb_req, one_hot_arb_grant;
523
    reg     [M-1        :       0]       grant_registered;
524
 
525
    assign      one_hot_arb_req =       request  & {M{~comreq}};
526
    assign      grant                                   =       grant_registered;
527
 
528
    assign comreq       =       |(grant & request);
529
 
530
`ifdef SYNC_RESET_MODE
531
    always @ (posedge clk )begin
532
`else
533
    always @ (posedge clk or posedge reset)begin
534
`endif
535
           if (reset) begin
536
                  grant_registered      <= {M{1'b0}};
537
           end else begin
538
                  if(~comreq)   grant_registered        <=      one_hot_arb_grant;
539
           end
540
    end//always
541
 
542
 
543
    arbiter #(
544
           .ARBITER_WIDTH       (M )
545
    )
546
    the_combinational_arbiter
547
    (
548
           .request             (one_hot_arb_req),
549
           .grant               (one_hot_arb_grant),
550
           .any_grant   (),
551
           .clk                 (clk),
552
           .reset               (reset)
553
    );
554
 
555
 
556
endmodule
557
 
558
 
559
 
560
module  is_one_hot #(
561
    parameter INw= 20
562
)
563
(
564
    in,
565
    result
566
);
567
 
568
    function integer log2;
569
      input integer number; begin
570
         log2=(number <=1) ? 1: 0;
571
         while(2**log2<number) begin
572
            log2=log2+1;
573
         end
574
      end
575
    endfunction // log2 
576
 
577
 
578
    input [INw-1  :   0] in;
579
    output result;
580
 
581
    localparam Aw = log2(INw+1);
582
 
583
    reg [Aw-1 :   0] sum;
584
 
585
 
586
  // This is supposed to be synyhesized as "sum=in[0]+in[1]+...in[Num-1]"; 
587
  // It works with Quartus, Verilator and Modelsim compilers  
588
    integer k;
589
    always @(*)begin
590
        sum=0;
591
        for (k=0;k<INw;k=k+1)begin
592
             sum= sum + {{(Aw-1){1'b0}},in[k]};
593
        end
594
    end
595
 
596
    assign result = (sum ==1);
597
 
598
endmodule

powered by: WebSVN 2.1.0

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