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

Subversion Repositories nocem

[/] [nocem/] [trunk/] [VHDL/] [vc_controller.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: vc_controller.vhd
32 4 schelleg
-- 
33 2 schelleg
-- Description: vc controller -- state, allocation status, etc.
34 4 schelleg
-- 
35
 
36
 
37
--The VC controller is instantiated on a per VC basis and keeps track 
38
--of the state of the VC and outputs the appropriate signals to the node 
39
--that is switching this data and the node that originally provided the data.
40
 
41
library IEEE;
42
use IEEE.STD_LOGIC_1164.ALL;
43
use IEEE.STD_LOGIC_ARITH.ALL;
44
use IEEE.STD_LOGIC_UNSIGNED.ALL;
45
 
46
use work.pkg_nocem.all;
47
 
48
entity vc_controller is
49
    Port (
50
 
51
                -- id's for this vc and its node (for routing)
52
                vc_my_id : in std_logic_vector(NOCEM_VC_ID_WIDTH-1 downto 0); -- should be tied to constant
53
                node_my_id : in std_logic_vector(NOCEM_AW-1 downto 0);
54
 
55
                -- packet fields from/to FIFO that are being snooped 
56
                pkt_cntrl_rd : in pkt_cntrl_word;
57
                pkt_cntrl_wr : in pkt_cntrl_word;
58
                pkt_re : in std_logic;
59
                pkt_we : in std_logic;
60
                vc_fifo_empty : in std_logic;
61
 
62
                -- this VC's status
63
                vc_eop_rd_status : out std_logic;                 -- 0: no eop with rden, 1: eop and rden
64
                vc_eop_wr_status  : out std_logic;                -- 0: no eop with wren, 1: eop and wren
65
 
66
 
67
                -- requesting a outgoing VC
68
                vc_allocation_req : out std_logic;
69
                vc_req_id : out std_logic_vector(NOCEM_VC_ID_WIDTH-1 downto 0);
70
 
71
                -- virtual channel request RESPONSE SIGNALS
72
                vc_allocate_from_node : in std_logic_vector(NOCEM_VC_ID_WIDTH-1 downto 0);
73
                vc_requester_from_node : in std_logic_vector(NOCEM_VC_ID_WIDTH-1 downto 0);
74
 
75
                -- destination signals (channel,VC) for packet transmission
76
                channel_dest : out arb_decision;
77
                vc_dest : out std_logic_vector(NOCEM_VC_ID_WIDTH-1 downto 0);
78
                vc_switch_req : out std_logic;
79
 
80
                rst : in std_logic;
81
                clk : in std_logic
82
         );
83
end vc_controller;
84
 
85
architecture Behavioral of vc_controller is
86
 
87
--STATE MACHINE SUMMARY --
88
--
89
--will see the SOP and then attempt to get a virtual channel on 
90
--the outgoing physical CHANNEL.  Once we have a vc, we can start 
91
--to send the packet, waiting for a EOP to show up/be read out.  Once we do, 
92
--will signal back to previous router that channel is now deallocated.
93
--
94
 
95 2 schelleg
  type stateType is (idle_st,getting_vc_st,sending_st);
96 4 schelleg
  signal state,nextState : stateType;
97
 
98
        signal local_addr_x : std_logic_vector(NOCEM_AW/2 -1 downto 0);
99
        signal local_addr_y : std_logic_vector(NOCEM_AW/2 -1 downto 0);
100
 
101
        signal channel_dest_routed,channel_dest_reg  : arb_decision;
102
 
103
        signal final_dest_addr : std_logic_vector(NOCEM_AW-1 downto 0);
104
 
105
        signal vc_allocated_reg : std_logic_vector(NOCEM_VC_ID_WIDTH-1 downto 0);
106
        signal sop_wr : std_logic;
107
        signal eop_rd,eop_wr : std_logic;
108
 
109
   -- register the incoming cntrl_wr signal for performance reasons (higher clock speed)
110
        signal pkt_cntrl_wr_1stword : pkt_cntrl_word;
111
 
112
 
113
begin
114
 
115
        -- setup signals coming/going to FIFO
116
        sop_wr  <= pkt_cntrl_wr(NOCEM_PKTCNTRL_SOP_IX) when pkt_we = '1' else '0';
117
        eop_wr  <= pkt_cntrl_wr(NOCEM_PKTCNTRL_EOP_IX) when pkt_we = '1' else '0';
118
        eop_rd  <= pkt_cntrl_rd(NOCEM_PKTCNTRL_EOP_IX) when pkt_re = '1' else '0';
119
 
120
 
121
        vc_eop_rd_status <= eop_rd;               -- 0: no eop with rden, 1: eop and rden
122
        vc_eop_wr_status <= eop_wr;
123
 
124
 
125
        --local address breakdown for readibility....
126
        local_addr_x <= node_my_id(NOCEM_AW-1 downto NOCEM_AW/2);
127
        local_addr_y <= node_my_id(NOCEM_AW/2 -1 downto 0);
128
        final_dest_addr <= pkt_cntrl_wr_1stword(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX);
129
 
130
 
131 2 schelleg
        state_clkd : process (clk,rst,nextState)
132
        begin
133
                if rst = '1' then
134
                         state                                          <= idle_st;
135 4 schelleg
                         channel_dest_reg               <= ARB_NODECISION;
136
                         vc_allocated_reg               <= (others => '0');
137 2 schelleg
                         pkt_cntrl_wr_1stword   <= (others => '0');
138
                elsif clk'event and clk='1' then
139
                        state <= nextState;
140 4 schelleg
                case state is
141
 
142
                                when idle_st =>
143
 
144
                                        vc_allocated_reg                <= (others => '0');
145
 
146
                                        if sop_wr='1' then
147
                                                pkt_cntrl_wr_1stword <= pkt_cntrl_wr;
148
                                        end if;
149
                                when getting_vc_st =>
150
                                        channel_dest_reg <= channel_dest_routed;
151
                                        if vc_allocate_from_node /= 0 and vc_requester_from_node = vc_my_id then
152
                                                vc_allocated_reg <= vc_allocate_from_node;
153
                                        else
154
                                                null;
155
                                        end if;
156
                                when sending_st =>
157
                                when others =>
158
                                        null;
159
 
160
 
161
                        end case;
162
                end if;
163
        end process;
164
 
165
 
166
 
167 2 schelleg
        state_uclkd : process (vc_fifo_empty,eop_rd,state, sop_wr, vc_my_id, channel_dest_routed, vc_requester_from_node, channel_dest_reg, vc_allocate_from_node, pkt_re, eop_wr, vc_allocated_reg)
168 4 schelleg
        begin
169
 
170
                        vc_allocation_req        <= '0';
171
                        vc_switch_req <= '0';
172
                        vc_dest <= (others => '0');
173
                        channel_dest <= ARB_NODECISION;
174
                        vc_req_id       <= (others => '0');
175
 
176
 
177
                case state is
178
 
179
                                when idle_st =>
180
                                        vc_dest <= (others => '0');
181
                                        if sop_wr = '1' then
182
                                                nextState <= getting_vc_st;
183
                                        else
184
                                                nextState <= idle_st;
185
                                        end if;
186
 
187
                                when getting_vc_st =>
188
 
189
                                        channel_dest <= channel_dest_routed;
190
                                        vc_dest <= vc_allocate_from_node;
191
 
192
                                        if vc_allocate_from_node /= 0 and vc_requester_from_node = vc_my_id then
193
 
194
                                                -- requesting switch signals
195
                                                if vc_fifo_empty='0' then
196
                                                        vc_switch_req <= '1';
197
                                                end if;
198
 
199
                                                -- single word packet handling
200
                                                if eop_rd = '1' then
201
                                                        nextState <= idle_st;
202
                                                else
203
                                                        nextState <= sending_st;
204
                                                end if;
205
 
206
 
207
                                        else
208
 
209
                                                -- requesting vc signals...
210
                                                vc_allocation_req <= '1';
211
                                                vc_req_id <= vc_my_id;
212
 
213
                                                nextState <= getting_vc_st;
214
                                        end if;
215
 
216
 
217
 
218
 
219
                                when sending_st =>
220
 
221
                                                channel_dest <= channel_dest_routed;
222
                                                vc_dest <= vc_allocated_reg;
223
                                                -- requesting switch signals
224
                                                if vc_fifo_empty = '0' then
225
                                                        vc_switch_req <= '1';
226
                                                end if;
227
 
228
                                                -- waiting for packet to be completed read
229
                                                if eop_rd = '1' then
230
                                                        nextState <= idle_st;
231
                                                else
232
                                                        nextState <= sending_st;
233
                                                end if;
234
 
235
                                when others =>
236
                                        null;
237
 
238
 
239
                        end case;
240
        end process;
241
 
242
 
243
 
244
 
245
 
246
-- process to determine routing based on incoming addr 
247
-- decision determined by topology and datain destination address
248
        channel_dest_gen : process (pkt_cntrl_wr,final_dest_addr, local_addr_x, local_addr_y)
249
        begin
250
 
251
 
252
 
253
 
254
                -- DOUBLE TORUS: north/south have loop around, east/west have looparound....
255
                if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_DTORUS then
256
 
257
                                channel_dest_routed <= ARB_NODECISION;
258
 
259
 
260
 
261
                                        -- src > dst address. go east if ROWS >= 2(SRC-DST) . go west if ROWS < 2(SRC-DST)
262
                                        if final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then
263
 
264
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_x - final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2)) sll 1) then
265
                                                                channel_dest_routed <= ARB_EAST;
266
                                                        else
267
                                                                channel_dest_routed <= ARB_WEST;
268
                                                        end if;
269
                                        end if;
270
 
271
                                        -- dst > src address. go east if ROWS >= 2(DST-SRC) . go west if ROWS < 2(DST-SRC)
272
                                        if final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
273
 
274
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2)- local_addr_x) sll 1) then
275
                                                                channel_dest_routed <= ARB_EAST;
276
                                                        else
277
                                                                channel_dest_routed <= ARB_WEST;
278
                                                        end if;
279
 
280
                                        end if;
281
 
282
                                        -- src > dst address. go north if ROWS >= 2(SRC-DST) . go south if ROWS < 2(SRC-DST)  
283
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) < local_addr_y  and
284
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
285
 
286
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_y - final_dest_addr(NOCEM_AW/2 -1 downto 0)) sll 1) then
287
                                                                channel_dest_routed <= ARB_NORTH;
288
                                                        else
289
                                                                channel_dest_routed <= ARB_SOUTH;
290
                                                        end if;
291
                                        end if;
292
 
293
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) > local_addr_y and
294
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
295
 
296
                                                        -- dst > src address. go north if ROWS >= 2(DST-SRC) . go south if ROWS < 2(DST-SRC) 
297
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(final_dest_addr(NOCEM_AW/2 -1 downto 0) - local_addr_y) sll 1) then
298
                                                                channel_dest_routed <= ARB_NORTH;
299
                                                        else
300
                                                                channel_dest_routed <= ARB_SOUTH;
301
                                                        end if;
302
                                        end if;
303
 
304
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) = local_addr_y and
305
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
306
 
307
                                                        channel_dest_routed <= ARB_AP;
308
                                        end if;
309
 
310
 
311
                end if; -- DTORUS
312
 
313
 
314
                -- TORUS: north/south have loop around, east/west do not....
315
                if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_TORUS then
316
 
317
                                channel_dest_routed <= ARB_NODECISION;
318
 
319
 
320
                                        if final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then
321
                                                channel_dest_routed <= ARB_WEST;
322
                                        end if;
323
 
324
                                        if final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
325
                                                channel_dest_routed <= ARB_EAST;
326
                                        end if;
327
 
328
                                        -- src > dst address. go north if ROWS >= 2(SRC-DST) . go south if ROWS < 2(SRC-DST)  
329
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) < local_addr_y  and
330
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
331
 
332
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(local_addr_y - final_dest_addr(NOCEM_AW/2 -1 downto 0)) sll 1) then
333
                                                                channel_dest_routed <= ARB_NORTH;
334
                                                        else
335
                                                                channel_dest_routed <= ARB_SOUTH;
336
                                                        end if;
337
                                        end if;
338
 
339
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) > local_addr_y and
340
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
341
 
342
                                                        -- dst > src address. go north if ROWS >= 2(DST-SRC) . go south if ROWS < 2(DST-SRC) 
343
                                                        if NOCEM_NUM_ROWS >= TO_STDLOGICVECTOR(TO_BITVECTOR(final_dest_addr(NOCEM_AW/2 -1 downto 0) - local_addr_y) sll 1) then
344
                                                                channel_dest_routed <= ARB_NORTH;
345
                                                        else
346
                                                                channel_dest_routed <= ARB_SOUTH;
347
                                                        end if;
348
                                        end if;
349
 
350
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) = local_addr_y and
351
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
352
 
353
                                                        channel_dest_routed <= ARB_AP;
354
                                        end if;
355
 
356
 
357
                end if;
358
 
359
 
360
 
361
 
362
                -- MESH: simple deterministic routing....
363
                if NOCEM_TOPOLOGY_TYPE = NOCEM_TOPOLOGY_MESH then
364
 
365
 
366
                                channel_dest_routed <= ARB_NODECISION;
367
 
368
 
369
                                        if final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) < local_addr_x then
370
                                                channel_dest_routed <= ARB_WEST;
371
                                        end if;
372
 
373
                                        if final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) > local_addr_x then
374
                                                channel_dest_routed <= ARB_EAST;
375
                                        end if;
376
 
377
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) < local_addr_y  and
378
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
379
 
380
                                                channel_dest_routed <= ARB_SOUTH;
381
                                        end if;
382
 
383
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) > local_addr_y and
384
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
385
 
386
                                                channel_dest_routed <= ARB_NORTH;
387
                                        end if;
388
 
389
                                        if final_dest_addr(NOCEM_AW/2 -1 downto 0) = local_addr_y and
390
                                                final_dest_addr(NOCEM_AW-1 downto NOCEM_AW/2) = local_addr_x then
391
 
392
                                                channel_dest_routed <= ARB_AP;
393
                                        end if;
394
 
395
 
396
                end if;
397
 
398
 
399
 
400
end process;
401
 
402
 
403
 
404
 
405
 
406
 
407
 
408
 
409
 
410
 
411
end Behavioral;

powered by: WebSVN 2.1.0

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