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

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [lib/] [wb_crossbar.v] - Blame information for rev 5

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

Line No. Rev Author Line
1 3 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3 5 dinesha
////  yifive common library Module                                ////
4 3 dinesha
////                                                              ////
5 5 dinesha
////  This file is part of the yifive cores project               ////
6
////  http://www.opencores.org/cores/yifive/                      ////
7 3 dinesha
////                                                              ////
8
////  Description                                                 ////
9 5 dinesha
////     This module  does the WBbone crossbar network            ////
10 3 dinesha
////                                                              ////
11
////  To Do:                                                      ////
12
////    nothing                                                   ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Dinesh Annayya, dinesha@opencores.org                 ////
16
////                                                              ////
17
//////////////////////////////////////////////////////////////////////
18 5 dinesha
////  Revision :                                                  ////
19
////     v0:    Nov 26, 2016, Dinesh A                            ////
20
////            This files copied from my open core               ////
21
////             turbo8051 project                                ////
22 3 dinesha
//////////////////////////////////////////////////////////////////////
23
////                                                              ////
24
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
25
////                                                              ////
26
//// This source file may be used and distributed without         ////
27
//// restriction provided that this copyright statement is not    ////
28
//// removed from the file and that any derivative work contains  ////
29
//// the original copyright notice and the associated disclaimer. ////
30
////                                                              ////
31
//// This source file is free software; you can redistribute it   ////
32
//// and/or modify it under the terms of the GNU Lesser General   ////
33
//// Public License as published by the Free Software Foundation; ////
34
//// either version 2.1 of the License, or (at your option) any   ////
35
//// later version.                                               ////
36
////                                                              ////
37
//// This source is distributed in the hope that it will be       ////
38
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
39
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
40
//// PURPOSE.  See the GNU Lesser General Public License for more ////
41
//// details.                                                     ////
42
////                                                              ////
43
//// You should have received a copy of the GNU Lesser General    ////
44
//// Public License along with this source; if not, download it   ////
45
//// from http://www.opencores.org/lgpl.shtml                     ////
46
////                                                              ////
47
//////////////////////////////////////////////////////////////////////
48
 
49
/**********************************************
50
      Web-bone cross bar M-Master By S-Slave
51
**********************************************/
52
 
53
module wb_crossbar (
54
 
55
              rst_n               ,
56
              clk                 ,
57
 
58
 
59
    // Master Interface Signal
60
              wbd_taddr_master    ,
61
              wbd_din_master      ,
62
              wbd_dout_master     ,
63
              wbd_adr_master      ,
64
              wbd_be_master       ,
65
              wbd_we_master       ,
66
              wbd_ack_master      ,
67
              wbd_stb_master      ,
68
              wbd_cyc_master      ,
69
              wbd_err_master      ,
70
              wbd_rty_master      ,
71
 
72
    // Slave Interface Signal
73
              wbd_din_slave       ,
74
              wbd_dout_slave      ,
75
              wbd_adr_slave       ,
76
              wbd_be_slave        ,
77
              wbd_we_slave        ,
78
              wbd_ack_slave       ,
79
              wbd_stb_slave       ,
80
              wbd_cyc_slave       ,
81
              wbd_err_slave       ,
82
              wbd_rty_slave
83
         );
84
 
85
parameter WB_SLAVE   = 4 ;
86
parameter WB_MASTER  = 4 ;
87
 
88
parameter D_WD    = 16; // Data Width
89
parameter BE_WD   = 2;  // Byte Enable
90
parameter ADR_WD  = 28; // Address Width
91
parameter TAR_WD  = 4;  // Target Width
92
 
93
input                  clk; // CLK_I The clock input [CLK_I] coordinates all activities 
94
                            // for the internal logic within the WISHBONE interconnect. 
95
                            // All WISHBONE output signals are registered at the 
96
                            // rising edge of [CLK_I]. 
97
                            // All WISHBONE input signals must be stable before the 
98
                            // rising edge of [CLK_I]. 
99
input                  rst_n; // RST_I The reset input [RST_I] forces the WISHBONE interface 
100
                            // to restart. Furthermore, all internal self-starting state 
101
                            // machines will be forced into an initial state. 
102
 
103
input [(WB_MASTER *TAR_WD)-1:0] wbd_taddr_master; // target address from master 
104
input [WB_MASTER-1:0]  wbd_stb_master;
105
                    // STB_O The strobe output [STB_O] indicates a valid data 
106
                    // transfer cycle. It is used to qualify various other signals 
107
                    // on the interface such as [SEL_O(7..0)]. The SLAVE must 
108
                    // assert either the [ACK_I], [ERR_I] or [RTY_I] signals in 
109
                    // response to every assertion of the [STB_O] signal. 
110
output [WB_SLAVE-1:0]  wbd_stb_slave;
111
                    // STB_O The strobe output [STB_O] indicates a valid data 
112
                    // transfer cycle. It is used to qualify various other signals 
113
                    // on the interface such as [SEL_O(7..0)]. The SLAVE must 
114
                    // assert either the [ACK_I], [ERR_I] or [RTY_I] signals in 
115
                    // response to every assertion of the [STB_O] signal. 
116
 
117
input [WB_MASTER-1:0]   wbd_we_master;
118
                    // WE_O The write enable output [WE_O] indicates whether the 
119
                    // current local bus cycle is a READ or WRITE cycle. The 
120
                    // signal is negated during READ cycles, and is asserted 
121
                    // during WRITE cycles. 
122
output [WB_SLAVE-1:0]   wbd_we_slave;
123
                    // WE_O The write enable output [WE_O] indicates whether the 
124
                    // current local bus cycle is a READ or WRITE cycle. The 
125
                    // signal is negated during READ cycles, and is asserted 
126
                    // during WRITE cycles. 
127
 
128
output [WB_MASTER-1:0]  wbd_ack_master;
129
                    // The acknowledge input [ACK_I], when asserted, 
130
                    // indicates the termination of a normal bus cycle. 
131
                    // Also see the [ERR_I] and [RTY_I] signal descriptions. 
132
input [WB_SLAVE-1:0]  wbd_ack_slave;
133
                    // The acknowledge input [ACK_I], when asserted, 
134
                    // indicates the termination of a normal bus cycle. 
135
                    // Also see the [ERR_I] and [RTY_I] signal descriptions. 
136
 
137
input [(WB_MASTER *ADR_WD)-1:0] wbd_adr_master;
138
                    // The address output array [ADR_O(63..0)] is used 
139
                    // to pass a binary address, with the most significant 
140
                    // address bit at the higher numbered end of the signal array. 
141
                    // The lower array boundary is specific to the data port size. 
142
                    // The higher array boundary is core-specific. 
143
                    // In some cases (such as FIFO interfaces) 
144
                    // the array may not be present on the interface. 
145
 
146
output [(WB_SLAVE *ADR_WD)-1:0] wbd_adr_slave;
147
                    // The address output array [ADR_O(63..0)] is used 
148
                    // to pass a binary address, with the most significant 
149
                    // address bit at the higher numbered end of the signal array. 
150
                    // The lower array boundary is specific to the data port size. 
151
                    // The higher array boundary is core-specific. 
152
                    // In some cases (such as FIFO interfaces) 
153
                    // the array may not be present on the interface. 
154
 
155
input [(WB_MASTER * BE_WD)-1:0] wbd_be_master; // Byte Enable 
156
                    // SEL_O(7..0) The select output array [SEL_O(7..0)] indicates 
157
                    // where valid data is expected on the [DAT_I(63..0)] signal 
158
                    // array during READ cycles, and where it is placed on the 
159
                    // [DAT_O(63..0)] signal array during WRITE cycles. 
160
                    // Also see the [DAT_I(63..0)], [DAT_O(63..0)] and [STB_O] 
161
                    // signal descriptions.
162
output [(WB_SLAVE * BE_WD)-1:0] wbd_be_slave; // Byte Enable  
163
                    // SEL_O(7..0) The select output array [SEL_O(7..0)] indicates 
164
                    // where valid data is expected on the [DAT_I(63..0)] signal 
165
                    // array during READ cycles, and where it is placed on the 
166
                    // [DAT_O(63..0)] signal array during WRITE cycles. 
167
                    // Also see the [DAT_I(63..0)], [DAT_O(63..0)] and [STB_O] 
168
                    // signal descriptions.
169
 
170
input [WB_MASTER -1:0] wbd_cyc_master;
171
                    // CYC_O The cycle output [CYC_O], when asserted, 
172
                    // indicates that a valid bus cycle is in progress. 
173
                    // The signal is asserted for the duration of all bus cycles. 
174
                    // For example, during a BLOCK transfer cycle there can be 
175
                    // multiple data transfers. The [CYC_O] signal is asserted 
176
                    // during the first data transfer, and remains asserted 
177
                    // until the last data transfer. The [CYC_O] signal is useful 
178
                    // for interfaces with multi-port interfaces 
179
                    // (such as dual port memories). In these cases, 
180
                    // the [CYC_O] signal requests use of a common bus from an 
181
                    // arbiter. Once the arbiter grants the bus to the MASTER, 
182
                    // it is held until [CYC_O] is negated. 
183
output [WB_SLAVE -1:0] wbd_cyc_slave;
184
                    // CYC_O The cycle output [CYC_O], when asserted, 
185
                    // indicates that a valid bus cycle is in progress. 
186
                    // The signal is asserted for the duration of all bus cycles. 
187
                    // For example, during a BLOCK transfer cycle there can be 
188
                    // multiple data transfers. The [CYC_O] signal is asserted 
189
                    // during the first data transfer, and remains asserted 
190
                    // until the last data transfer. The [CYC_O] signal is useful 
191
                    // for interfaces with multi-port interfaces 
192
                    // (such as dual port memories). In these cases, 
193
                    // the [CYC_O] signal requests use of a common bus from an 
194
                    // arbiter. Once the arbiter grants the bus to the MASTER, 
195
                    // it is held until [CYC_O] is negated. 
196
 
197
input [(WB_MASTER * D_WD)-1:0] wbd_din_master;
198
                    // DAT_I(63..0) The data input array [DAT_I(63..0)] is 
199
                    // used to pass binary data. The array boundaries are 
200
                    // determined by the port size. Also see the [DAT_O(63..0)] 
201
                    // and [SEL_O(7..0)] signal descriptions. 
202
 
203
output [(WB_SLAVE * D_WD)-1:0] wbd_din_slave;
204
                    // DAT_I(63..0) The data input array [DAT_I(63..0)] is 
205
                    // used to pass binary data. The array boundaries are 
206
                    // determined by the port size. Also see the [DAT_O(63..0)] 
207
                    // and [SEL_O(7..0)] signal descriptions. 
208
 
209
output [(WB_MASTER * D_WD)-1:0] wbd_dout_master;
210
                    // DAT_O(63..0) The data output array [DAT_O(63..0)] is 
211
                    // used to pass binary data. The array boundaries are 
212
                    // determined by the port size. Also see the [DAT_I(63..0)] 
213
                         // and [SEL_O(7..0)] signal descriptions. 
214
input [(WB_SLAVE * D_WD)-1:0] wbd_dout_slave;
215
                    // DAT_O(63..0) The data output array [DAT_O(63..0)] is 
216
                    // used to pass binary data. The array boundaries are 
217
                    // determined by the port size. Also see the [DAT_I(63..0)] 
218
                    // and [SEL_O(7..0)] signal descriptions. 
219
 
220
output [WB_MASTER -1:0]  wbd_err_master;
221
                    // ERR_I The error input [ERR_I] indicates an abnormal 
222
                    // cycle termination. The source of the error, and the 
223
                    // response generated by the MASTER is defined by the IP core 
224
                    // supplier in the WISHBONE DATASHEET. Also see the [ACK_I] 
225
                    // and [RTY_I] signal descriptions. 
226
input [WB_SLAVE -1:0]  wbd_err_slave;
227
                    // ERR_I The error input [ERR_I] indicates an abnormal 
228
                    // cycle termination. The source of the error, and the 
229
                    // response generated by the MASTER is defined by the IP core 
230
                    // supplier in the WISHBONE DATASHEET. Also see the [ACK_I] 
231
                    // and [RTY_I] signal descriptions. 
232
 
233
output [WB_MASTER -1:0]   wbd_rty_master;
234
                    // RTY_I The retry input [RTY_I] indicates that the indicates 
235
                    // that the interface is not ready to accept or send data, and 
236
                    // that the cycle should be retried. When and how the cycle is 
237
                    // retried is defined by the IP core supplier in the WISHBONE 
238
                    // DATASHEET. Also see the [ERR_I] and [RTY_I] signal 
239
                    // descriptions. 
240
input [WB_SLAVE -1:0]   wbd_rty_slave;
241
                    // RTY_I The retry input [RTY_I] indicates that the indicates 
242
                    // that the interface is not ready to accept or send data, and 
243
                    // that the cycle should be retried. When and how the cycle is 
244
                    // retried is defined by the IP core supplier in the WISHBONE 
245
                    // DATASHEET. Also see the [ERR_I] and [RTY_I] signal 
246
                    // descriptions. 
247
 
248
 
249
reg  [WB_MASTER-1:0]  wbd_ack_master;
250
reg  [WB_MASTER-1:0]  wbd_err_master;
251
reg  [WB_MASTER-1:0]  wbd_rty_master;
252
 
253
 
254
reg  [WB_MASTER-1:0]  master_busy; // master busy flag
255
reg  [WB_SLAVE-1:0]   slave_busy;  // slave busy flag
256
reg  [TAR_WD -1:0]     master_mx_id[WB_MASTER-1:0];
257
reg  [TAR_WD -1:0]     slave_mx_id [WB_SLAVE-1:0];
258
 
259
wire  [TAR_WD-1:0]     wbd_taddr_master_t[WB_MASTER-1:0]; // target address from master 
260
wire  [D_WD-1:0]       wbd_din_master_t[WB_MASTER-1:0]; // target address from master 
261
reg   [D_WD-1:0]       wbd_dout_master_t[WB_MASTER-1:0]; // target address from master 
262
wire  [ADR_WD-1:0]     wbd_adr_master_t[WB_MASTER-1:0]; // target address from master 
263
wire  [BE_WD-1:0]      wbd_be_master_t[WB_MASTER-1:0]; // target address from master 
264
 
265
 
266
reg  [WB_SLAVE-1:0]  wbd_stb_slave;
267
reg  [WB_SLAVE-1:0]  wbd_we_slave;
268
reg  [WB_SLAVE-1:0]  wbd_cyc_slave;
269
wire [D_WD-1:0]      wbd_dout_slave_t[WB_SLAVE-1:0]; // target data towards master 
270
 
271
 
272
reg   [D_WD-1:0]     wbd_din_slave_t[WB_SLAVE-1:0]; // target address from master 
273
reg   [ADR_WD-1:0]    wbd_adr_slave_t[WB_SLAVE-1:0]; // target address from master 
274
reg   [BE_WD-1:0]     wbd_be_slave_t[WB_SLAVE-1:0]; // target address from master 
275
 
276
integer i,k,l,n;
277
 
278
 
279
/**********************************************************
280
   Re-Arraging the array in seperate two dimensional information
281
***********************************************************/
282
 
283
genvar j,m;
284
generate
285
 
286
  // Connect the Master Mux
287
  for(j=0; j < WB_MASTER ; j = j + 1) begin : master_expand
288
     assign wbd_taddr_master_t[j] = wbd_taddr_master[((j+1)*TAR_WD)-1:j * TAR_WD];
289
     assign wbd_din_master_t[j]  = wbd_din_master[((j+1)*D_WD)-1:j * D_WD];
290
     assign wbd_adr_master_t[j]  = wbd_adr_master[((j+1)*ADR_WD)-1:j * ADR_WD];
291
     assign wbd_be_master_t[j]   = wbd_be_master[((j+1)*BE_WD)-1:j * BE_WD];
292
 
293
     assign wbd_dout_master[((j+1)*D_WD)-1:j * D_WD] = wbd_dout_master_t[j];
294
  end
295
 
296
  // Connect the Slave Mux
297
  for(m=0; m < WB_SLAVE ; m = m + 1) begin : slave_expand
298
     assign wbd_din_slave[((m+1)*D_WD)-1:m * D_WD]        = wbd_din_slave_t[m];
299
     assign wbd_adr_slave[((m+1)*ADR_WD)-1:m * ADR_WD]   = wbd_adr_slave_t[m];
300
     assign wbd_be_slave[((m+1)*BE_WD)-1:m * BE_WD]      = wbd_be_slave_t[m];
301
 
302
     assign wbd_dout_slave_t[m]   = wbd_dout_slave[((m+1)*D_WD)-1:m * D_WD];
303
 
304
  end
305
endgenerate
306
 
307
always @*   begin
308
   for(k = 0; k < WB_MASTER; k = k + 1) begin
309
      if(master_busy[k] == 1) begin
310
         wbd_dout_master_t[k] = wbd_dout_slave_t[master_mx_id[k]];
311
         wbd_ack_master[k]    = wbd_ack_slave[master_mx_id[k]];
312
         wbd_err_master[k]    = wbd_err_slave[master_mx_id[k]];
313
         wbd_rty_master[k]    = wbd_rty_slave[master_mx_id[k]];
314
      end else begin
315
         wbd_dout_master_t[k] = 0;
316
         wbd_ack_master[k]    = 0;
317
         wbd_err_master[k]    = 0;
318
         wbd_rty_master[k]    = 0;
319
      end
320
   end
321
   for(l = 0; l < WB_SLAVE; l = l + 1) begin
322
      if(slave_busy[l] == 1) begin
323
         wbd_din_slave_t[l]  = wbd_din_master_t[slave_mx_id[l]];
324
         wbd_adr_slave_t[l]  = wbd_adr_master_t[slave_mx_id[l]];
325
         wbd_be_slave_t[l]   = wbd_be_master_t[slave_mx_id[l]];
326
         wbd_stb_slave[l]    = wbd_stb_master[slave_mx_id[l]];
327
         wbd_we_slave[l]     = wbd_we_master[slave_mx_id[l]];
328
         wbd_cyc_slave[l]    = wbd_cyc_master[slave_mx_id[l]];
329
      end else begin
330
         wbd_din_slave_t[l]  = 0;
331
         wbd_adr_slave_t[l]  = 0;
332
         wbd_be_slave_t[l]   = 0;
333
         wbd_stb_slave[l]    = 0;
334
         wbd_we_slave[l]     = 0;
335
         wbd_cyc_slave[l]    = 0;
336
      end
337
   end
338
end
339
 
340
/*******************************************************
341
   Parsing through the master and deciding on mux connectio
342
   Step-1: analysis the master from 0 to total master
343
   Step-2: If the previously master is not busy,
344
           Then check for any new request from the master and
345
           check corresponding slave is free or not. If there is
346
           master request and requesting slave is free.
347
           Then set the master max id to slave id &
348
           requesting slave to master number & set the master
349
           and slave busy flag
350
   Step-3: If the previous state of master is busy and bus-cycle
351
           is de-asserted, then reset the master and corresponding
352
           slave busy flag
353
 
354
*********************************************************/
355
 
356
always @(negedge rst_n or posedge clk) begin
357
   if(rst_n == 0) begin
358
      master_busy   <= 0;
359
      slave_busy    <= 0;
360
   end else begin
361
      for(i = 0; i < WB_MASTER; i = i + 1) begin
362
         if(master_busy[i] == 0) begin
363
            if(wbd_stb_master[i] & slave_busy[wbd_taddr_master_t[i]] == 0) begin
364
               slave_busy[wbd_taddr_master_t[i]]   <= 1;
365
               master_busy[i]              <= 1;
366
            end
367
         end else if(wbd_cyc_master[i] == 0) begin
368
            master_busy[i]            <= 0;
369
            slave_busy[wbd_taddr_master_t[i]] <= 0;
370
         end
371
      end
372
   end
373
end
374
 
375
// Seperated non resetable two dimensional reg
376
always @(posedge clk) begin
377
      for(n = 0; n < WB_MASTER; n = n + 1) begin
378
         if(master_busy[n] == 0) begin
379
            if(wbd_stb_master[n] & slave_busy[wbd_taddr_master_t[n]] == 0) begin
380
               master_mx_id[n] <= wbd_taddr_master_t[n];
381
               slave_mx_id [wbd_taddr_master_t[n]] <= n;
382
               // synopsys translate_off
383
               // $display("%m:%t: Locking Master : %d with Slave : %d",$time,i,wbd_taddr_master_t[n]);
384
               // synopsys translate_on
385
            end
386
         end else if(wbd_cyc_master[n] == 0) begin
387
            if(master_busy[n] == 1) begin
388
            // synopsys translate_off
389
            //  $display("%m:%t: Releasing Master : %d with Slave : %d",$time,i,wbd_taddr_master_t[n]);
390
            // synopsys translate_on
391
            end
392
         end
393
      end
394
end
395
 
396
 
397
endmodule

powered by: WebSVN 2.1.0

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