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

Subversion Repositories nocem

[/] [nocem/] [trunk/] [VHDL/] [simple_pkt_local_arb.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 schelleg
 
2
-----------------------------------------------------------------------------
3
-- NoCem -- Network on Chip Emulation Tool for System on Chip Research 
4
-- and Implementations
5
-- 
6
-- Copyright (C) 2006  Graham Schelle, Dirk Grunwald
7
-- 
8
-- This program is free software; you can redistribute it and/or
9
-- modify it under the terms of the GNU General Public License
10
-- as published by the Free Software Foundation; either version 2
11
-- of the License, or (at your option) any later version.
12
-- 
13
-- This program is distributed in the hope that it will be useful,
14
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
15
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
-- GNU General Public License for more details.
17
-- 
18
-- You should have received a copy of the GNU General Public License
19
-- along with this program; if not, write to the Free Software
20
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
21
-- 02110-1301, USA.
22
-- 
23
-- The authors can be contacted by email: <schelleg,grunwald>@cs.colorado.edu 
24
-- 
25
-- or by mail: Campus Box 430, Department of Computer Science,
26
-- University of Colorado at Boulder, Boulder, Colorado 80309
27
-------------------------------------------------------------------------------- 
28
 
29
 
30
-- 
31 2 schelleg
-- Filename: simple_pkt_local_arb.vhd
32 4 schelleg
-- 
33 2 schelleg
-- Description: nonVC design arbiter
34 4 schelleg
-- 
35
 
36
 
37
 
38
library IEEE;
39
use IEEE.STD_LOGIC_1164.ALL;
40
use IEEE.STD_LOGIC_ARITH.ALL;
41
use IEEE.STD_LOGIC_UNSIGNED.ALL;
42
 
43
 
44
use work.pkg_nocem.all;
45
 
46
 
47
entity simple_pkt_local_arb is
48
    Port (
49
 
50
                -- local arb info (should be held constant on incoming signal)
51
                local_arb_addr : std_logic_vector(NOCEM_AW-1 downto 0);
52
 
53
                -- needed to mux outputs for the accompanying switch
54
                arb_grant_output : out arb_decision_array(4 downto 0);
55
 
56
 
57
           n_pkt_cntrl_in : in pkt_cntrl_word;
58
           n_pkt_cntrl_out : out pkt_cntrl_word;
59
           n_channel_cntrl_in  : in channel_cntrl_word;
60
           n_channel_cntrl_out : out channel_cntrl_word;
61
 
62
           s_pkt_cntrl_in : in pkt_cntrl_word;
63
           s_pkt_cntrl_out : out pkt_cntrl_word;
64
           s_channel_cntrl_in  : in channel_cntrl_word;
65
           s_channel_cntrl_out : out channel_cntrl_word;
66
 
67
           e_pkt_cntrl_in : in pkt_cntrl_word;
68
           e_pkt_cntrl_out : out pkt_cntrl_word;
69
           e_channel_cntrl_in  : in channel_cntrl_word;
70
           e_channel_cntrl_out : out channel_cntrl_word;
71
 
72
           w_pkt_cntrl_in : in pkt_cntrl_word;
73
           w_pkt_cntrl_out : out pkt_cntrl_word;
74
           w_channel_cntrl_in  : in channel_cntrl_word;
75
           w_channel_cntrl_out : out channel_cntrl_word;
76
 
77
 
78
           ap_pkt_cntrl_in : in pkt_cntrl_word;
79
           ap_pkt_cntrl_out : out pkt_cntrl_word;
80
           ap_channel_cntrl_in  : in channel_cntrl_word;
81
           ap_channel_cntrl_out : out channel_cntrl_word;
82
 
83
                clk : in std_logic;
84
      rst : in std_logic
85
                );
86
end simple_pkt_local_arb;
87
 
88
architecture Behavioral of simple_pkt_local_arb is
89
 
90
 
91
signal local_addr_x : std_logic_vector(NOCEM_AW/2 -1 downto 0);
92
signal local_addr_y : std_logic_vector(NOCEM_AW/2 -1 downto 0);
93
 
94
 
95
 
96
 
97
        -- since much of the work is repetitive, can use looping w/ indexing 
98
        -- to save massive repetitive coding
99
 
100
                --many operations can be easily written if inputs are in array form
101
                signal dest_local_port                          : arb_decision_array(4 downto 0);
102
                signal dest_addr_array                          : node_addr_array(4 downto 0);
103
                signal datain_valid_array                       : std_logic_vector(4 downto 0);
104
                signal pkt_cntrl_valid_array            : std_logic_vector(4 downto 0);
105
                signal pkt_cntrl_data_array      : pkt_cntrl_array(4 downto 0);
106
                signal arb_decision_enum     : arb_decision_array(4 downto 0);
107
                signal channel_cntrl_in_array_i  : channel_cntrl_array(4 downto 0);
108
                signal channel_cntrl_out_array_i : channel_cntrl_array(4 downto 0);
109
 
110
 
111
 --signal srcToDstTimes2 : node_addr_array(4 downto 0);
112
 
113
 
114
 
115
begin
116
 
117
 
118
 
119
        datain_valid_array(NOCEM_NORTH_IX) <= n_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
120
        datain_valid_array(NOCEM_SOUTH_IX) <= s_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
121
        datain_valid_array(NOCEM_EAST_IX)  <= e_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
122
        datain_valid_array(NOCEM_WEST_IX)  <= w_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
123
        datain_valid_array(NOCEM_AP_IX)    <= ap_channel_cntrl_in(NOCEM_CHFIFO_DATA_EMPTY_N_IX);
124
 
125
        channel_cntrl_in_array_i(NOCEM_NORTH_IX) <= n_channel_cntrl_in;
126
        channel_cntrl_in_array_i(NOCEM_SOUTH_IX) <= s_channel_cntrl_in;
127
        channel_cntrl_in_array_i(NOCEM_EAST_IX)  <= e_channel_cntrl_in;
128
        channel_cntrl_in_array_i(NOCEM_WEST_IX)  <= w_channel_cntrl_in;
129
        channel_cntrl_in_array_i(NOCEM_AP_IX)    <= ap_channel_cntrl_in;
130
 
131
        n_channel_cntrl_out  <= channel_cntrl_out_array_i(NOCEM_NORTH_IX);
132
        s_channel_cntrl_out  <= channel_cntrl_out_array_i(NOCEM_SOUTH_IX);
133
        e_channel_cntrl_out  <= channel_cntrl_out_array_i(NOCEM_EAST_IX);
134
        w_channel_cntrl_out  <= channel_cntrl_out_array_i(NOCEM_WEST_IX);
135
        ap_channel_cntrl_out <= channel_cntrl_out_array_i(NOCEM_AP_IX);
136
 
137
        pkt_cntrl_valid_array(NOCEM_NORTH_IX) <= n_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
138
        pkt_cntrl_valid_array(NOCEM_SOUTH_IX) <= s_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
139
        pkt_cntrl_valid_array(NOCEM_EAST_IX)  <= e_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
140
        pkt_cntrl_valid_array(NOCEM_WEST_IX)  <= w_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
141
        pkt_cntrl_valid_array(NOCEM_AP_IX)    <= ap_channel_cntrl_in(NOCEM_CHFIFO_CNTRL_EMPTY_N_IX);
142
 
143
        pkt_cntrl_data_array(NOCEM_NORTH_IX) <= n_pkt_cntrl_in;
144
        pkt_cntrl_data_array(NOCEM_SOUTH_IX) <= s_pkt_cntrl_in;
145
        pkt_cntrl_data_array(NOCEM_EAST_IX)  <= e_pkt_cntrl_in;
146
        pkt_cntrl_data_array(NOCEM_WEST_IX)  <= w_pkt_cntrl_in;
147
        pkt_cntrl_data_array(NOCEM_AP_IX)    <= ap_pkt_cntrl_in;
148
 
149
        arb_decision_enum(NOCEM_AP_IX) <= ARB_AP;
150
        arb_decision_enum(NOCEM_NORTH_IX) <= ARB_NORTH;
151
        arb_decision_enum(NOCEM_SOUTH_IX) <= ARB_SOUTH;
152
        arb_decision_enum(NOCEM_EAST_IX) <= ARB_EAST;
153
        arb_decision_enum(NOCEM_WEST_IX) <= ARB_WEST;
154
 
155
 
156
 
157
 
158
        --local address breakdown for readibility....
159
        local_addr_x <= local_arb_addr(NOCEM_AW-1 downto NOCEM_AW/2);
160
        local_addr_y <= local_arb_addr(NOCEM_AW/2 -1 downto 0);
161
 
162
        -- simply pass on the pkt_cntrl signals to the switch 
163
        -- (may modify in other configs)
164
   n_pkt_cntrl_out <= n_pkt_cntrl_in;
165
        s_pkt_cntrl_out <= s_pkt_cntrl_in;
166
        e_pkt_cntrl_out <= e_pkt_cntrl_in;
167
        w_pkt_cntrl_out <= w_pkt_cntrl_in;
168
        ap_pkt_cntrl_out <= ap_pkt_cntrl_in;
169
 
170
 
171
 
172
 
173
-- process to generate destination address from pkt_cntrl line
174
 
175
dest_addr_gen_process : process (pkt_cntrl_valid_array, pkt_cntrl_data_array)
176
begin
177
 
178
        l1: for I in 4 downto 0 loop
179
                if pkt_cntrl_valid_array(I) = '1' then
180
                         dest_addr_array(I) <= pkt_cntrl_data_array(I)(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX);
181
                else
182
                         dest_addr_array(I) <= (others => '0');
183
                end if;
184
        end loop;
185
 
186
 
187
end process;
188
 
189
 
190
 
191
 
192
 
193
 
194
 
195
-- process to determine routing based on incoming addr and data valid
196
-- decision determined by topology and datain destination address
197
 
198
port_dest_gen_process : process (datain_valid_array, local_addr_x, local_addr_y, dest_addr_array)
199
begin
200
 
201
 
202
 
203
                -- DOUBLE TORUS: north/south have loop around, east/west have looparound....
204
                if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_DTORUS then
205
                        l20 : for I in 4 downto 0 loop
206
                                dest_local_port(I) <= ARB_NODECISION;
207
 
208
                                if datain_valid_array(I) = '1' then
209
 
210
                                        -- src > dst address. go east if ROWS >= 2(SRC-DST) . go west if ROWS < 2(SRC-DST)
211
                                        if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then
212
 
213
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_x - dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2)) sll 1) then
214
                                                                dest_local_port(I) <= ARB_EAST;
215
                                                        else
216
                                                                dest_local_port(I) <= ARB_WEST;
217
                                                        end if;
218
                                        end if;
219
 
220
                                        -- dst > src address. go east if ROWS >= 2(DST-SRC) . go west if ROWS < 2(DST-SRC)
221
                                        if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
222
 
223
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2)- local_addr_x) sll 1) then
224
                                                                dest_local_port(I) <= ARB_EAST;
225
                                                        else
226
                                                                dest_local_port(I) <= ARB_WEST;
227
                                                        end if;
228
 
229
                                        end if;
230
 
231
                                        -- src > dst address. go north if ROWS >= 2(SRC-DST) . go south if ROWS < 2(SRC-DST)  
232
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) < local_addr_y  and
233
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
234
 
235
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_y - dest_addr_array(I)(NOCEM_AW/2 -1 downto 0)) sll 1) then
236
                                                                dest_local_port(I) <= ARB_NORTH;
237
                                                        else
238
                                                                dest_local_port(I) <= ARB_SOUTH;
239
                                                        end if;
240
                                        end if;
241
 
242
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) > local_addr_y and
243
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
244
 
245
                                                        -- dst > src address. go north if ROWS >= 2(DST-SRC) . go south if ROWS < 2(DST-SRC) 
246
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) - local_addr_y) sll 1) then
247
                                                                dest_local_port(I) <= ARB_NORTH;
248
                                                        else
249
                                                                dest_local_port(I) <= ARB_SOUTH;
250
                                                        end if;
251
                                        end if;
252
 
253
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) = local_addr_y and
254
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
255
 
256
                                                        dest_local_port(I) <= ARB_AP;
257
                                        end if;
258
 
259
                                else
260
                                        dest_local_port(I) <= ARB_NODECISION;
261
 
262
                                end if;
263
 
264
                        end loop;
265
 
266
                end if;
267
 
268
                -- TORUS: north/south have loop around, east/west do not....
269
                if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_TORUS then
270
                        l21 : for I in 4 downto 0 loop
271
                                dest_local_port(I) <= ARB_NODECISION;
272
 
273
                                if datain_valid_array(I) = '1' then
274
 
275
                                        if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then
276
                                                dest_local_port(I) <= ARB_WEST;
277
                                        end if;
278
 
279
                                        if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
280
                                                dest_local_port(I) <= ARB_EAST;
281
                                        end if;
282
 
283
                                        -- src > dst address. go north if ROWS >= 2(SRC-DST) . go south if ROWS < 2(SRC-DST)  
284
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) < local_addr_y  and
285
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
286
 
287
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_y - dest_addr_array(I)(NOCEM_AW/2 -1 downto 0)) sll 1) then
288
                                                                dest_local_port(I) <= ARB_NORTH;
289
                                                        else
290
                                                                dest_local_port(I) <= ARB_SOUTH;
291
                                                        end if;
292
                                        end if;
293
 
294
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) > local_addr_y and
295
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
296
 
297
                                                        -- dst > src address. go north if ROWS >= 2(DST-SRC) . go south if ROWS < 2(DST-SRC) 
298
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) - local_addr_y) sll 1) then
299
                                                                dest_local_port(I) <= ARB_NORTH;
300
                                                        else
301
                                                                dest_local_port(I) <= ARB_SOUTH;
302
                                                        end if;
303
                                        end if;
304
 
305
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) = local_addr_y and
306
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
307
 
308
                                                        dest_local_port(I) <= ARB_AP;
309
                                        end if;
310
 
311
                                else
312
                                        dest_local_port(I) <= ARB_NODECISION;
313
 
314
                                end if;
315
 
316
                        end loop;
317
 
318
                end if;
319
 
320
 
321
 
322
                -- MESH: simple deterministic routing....
323
                if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_MESH then
324
                        l22 : for I in 4 downto 0 loop
325
 
326
                                dest_local_port(I) <= ARB_NODECISION;
327
                                if datain_valid_array(I) = '1' then
328
 
329
                                        if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then
330
                                                dest_local_port(I) <= ARB_WEST;
331
                                        end if;
332
 
333
                                        if dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
334
                                                dest_local_port(I) <= ARB_EAST;
335
                                        end if;
336
 
337
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) < local_addr_y  and
338
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
339
 
340
                                                dest_local_port(I) <= ARB_SOUTH;
341
                                        end if;
342
 
343
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) > local_addr_y and
344
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
345
 
346
                                                dest_local_port(I) <= ARB_NORTH;
347
                                        end if;
348
 
349
                                        if dest_addr_array(I)(NOCEM_AW/2 -1 downto 0) = local_addr_y and
350
                                                dest_addr_array(I)(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
351
 
352
                                                dest_local_port(I) <= ARB_AP;
353
                                        end if;
354
 
355
                                else
356
                                        dest_local_port(I) <= ARB_NODECISION;
357
 
358
                                end if;
359
 
360
 
361
                        end loop;
362
 
363
                end if;
364
 
365
 
366
 
367
 
368
 
369
 
370
 
371
 
372
 
373
end process;
374
 
375
 
376
arb_gen_process : process (channel_cntrl_in_array_i, dest_local_port)
377
begin
378
 
379
 
380
 
381
        arb_grant_output <= (others => ARB_NODECISION);
382
        channel_cntrl_out_array_i <= (others => (others => '0'));
383
 
384
 
385
 
386
l3: for I in 4 downto 0 loop
387
 
388
        -- I iterates over the OUTPUT ports
389
        if channel_cntrl_in_array_i(I)(NOCEM_CHFIFO_DATA_FULL_N_IX) = '1' then
390
 
391
                if dest_local_port(NOCEM_AP_IX) = arb_decision_enum(I) then
392
                        --arb grant will push data through switch
393
                        arb_grant_output(I) <= ARB_AP;
394
 
395
                        -- do read enable for selected incoming data
396
                        channel_cntrl_out_array_i(NOCEM_AP_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
397
                        channel_cntrl_out_array_i(NOCEM_AP_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
398
 
399
                        -- do write enable for outgoing port
400
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
401
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
402
 
403
                elsif dest_local_port(NOCEM_NORTH_IX) = arb_decision_enum(I) then
404
                        arb_grant_output(I) <= ARB_NORTH;
405
                        channel_cntrl_out_array_i(NOCEM_NORTH_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
406
                        channel_cntrl_out_array_i(NOCEM_NORTH_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
407
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
408
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
409
 
410
 
411
                elsif dest_local_port(NOCEM_SOUTH_IX) = arb_decision_enum(I) then
412
                        arb_grant_output(I) <= ARB_SOUTH;
413
                        channel_cntrl_out_array_i(NOCEM_SOUTH_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
414
                        channel_cntrl_out_array_i(NOCEM_SOUTH_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
415
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
416
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
417
 
418
                elsif dest_local_port(NOCEM_EAST_IX) = arb_decision_enum(I) then
419
                        arb_grant_output(I) <= ARB_EAST;
420
                        channel_cntrl_out_array_i(NOCEM_EAST_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
421
                        channel_cntrl_out_array_i(NOCEM_EAST_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
422
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
423
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
424
 
425
                elsif dest_local_port(NOCEM_WEST_IX) = arb_decision_enum(I) then
426
                        arb_grant_output(I) <= ARB_WEST;
427
                        channel_cntrl_out_array_i(NOCEM_WEST_IX)(NOCEM_CHFIFO_DATA_RE_IX) <= '1';
428
                        channel_cntrl_out_array_i(NOCEM_WEST_IX)(NOCEM_CHFIFO_CNTRL_RE_IX) <= '1';
429
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_DATA_WE_IX) <= '1';
430
                   channel_cntrl_out_array_i(I)(NOCEM_CHFIFO_CNTRL_WE_IX) <= '1';
431
 
432
                end if;
433
        end if;
434
 
435
 
436
 
437
 
438
end loop;
439
 
440
 
441
 
442
end process;
443
 
444
 
445
end Behavioral;

powered by: WebSVN 2.1.0

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