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

Subversion Repositories nocem

[/] [nocem/] [trunk/] [VHDL/] [vc_channel.vhd] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 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
-- Filename: vc_channel.vhd
32
-- 
33
-- Description: toplevel instantion of a virtual channel
34
-- 
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
use work.pkg_nocem.all;
44
 
45
entity vc_channel is
46
generic (
47
                          IS_AN_ACCESS_POINT_CHANNEL : boolean := FALSE
48
                        ) ;
49
port (
50
 
51
                          node_dest_id  : in node_addr_word;
52
                          vc_mux_wr : in std_logic_vector(NOCEM_NUM_VC-1 downto 0);
53
                          vc_mux_rd : in std_logic_vector(NOCEM_NUM_VC-1 downto 0);
54
 
55
           wr_pkt_cntrl : in std_logic_vector(NOCEM_PKT_CNTRL_WIDTH-1 downto 0);
56
           wr_pkt_data  : in std_logic_vector(NOCEM_DW-1 downto 0);
57
 
58
           rd_pkt_cntrl : out std_logic_vector(NOCEM_PKT_CNTRL_WIDTH-1 downto 0);
59
           rd_pkt_data  : out std_logic_vector(NOCEM_DW-1 downto 0);
60
 
61
                          rd_pkt_chdest : out std_logic_vector(NOCEM_ARB_IX_SIZE-1 downto 0);
62
                          rd_pkt_vcdest : out vc_addr_word;
63
                          rd_pkt_vcsrc  : out vc_addr_word;
64
 
65
 
66
                          vc_empty              : out std_logic_vector(NOCEM_NUM_VC-1 downto 0);
67
                          vc_full               : out std_logic_vector(NOCEM_NUM_VC-1 downto 0);
68
 
69
 
70
                          -- VC allocation signals
71
                          vc_allocate_from_node         : in vc_addr_word;
72
                vc_requester_from_node          : in vc_addr_word;
73
 
74
                          vc_allocate_destch_to_node    : out std_logic_vector(NOCEM_ARB_IX_SIZE-1 downto 0);
75
                vc_requester_to_node          : out vc_addr_word;
76
                          vc_eop_rd_status                              : out std_logic_vector(NOCEM_NUM_VC-1 downto 0);
77
                          vc_eop_wr_status                              : out std_logic_vector(NOCEM_NUM_VC-1 downto 0);
78
 
79
                          RE : in std_logic;
80
                          WE : in std_logic;
81
 
82
                          clk : in std_logic;
83
                          rst : in std_logic
84
);
85
 
86
 
87
end vc_channel;
88
 
89
architecture Behavioral of vc_channel is
90
 
91
        signal vc_pkt_cntrl                     : pkt_cntrl_array(NOCEM_NUM_VC-1 downto 0);
92
        signal vc_allocation_req        : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
93
 
94
 
95
        signal vc_req_id                                : vc_addr_array(7 downto 0);
96
        signal channel_dest                     : arb_decision_array(7 downto 0);
97
        signal vc_dest                                  : vc_addr_array(7 downto 0);
98
        signal vc_switch_req            : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
99
 
100
   signal fifo_wr_en            : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
101
   signal fifo_rd_en            : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
102
 
103
        -- pack the data and control lines of the packet into one word
104
   signal datain_packed,dataout_packed : std_logic_vector(NOCEM_DW+NOCEM_PKT_CNTRL_WIDTH-1 downto 0);
105
 
106
        --------------------------------------------------------------------
107
        --------- for the BRAM implementation a 32b line is used -----------
108
        --------------------------------------------------------------------
109
   signal datain_32 : std_logic_vector(31 downto 0);
110
 
111
        subtype slv32 is std_logic_vector(31 downto 0);
112
   type array_slv32 is array(natural range <>) of slv32;
113
 
114
   signal fifo_rd_data_32 : array_slv32(NOCEM_NUM_VC-1 downto 0);
115
        --------------------------------------------------------------------
116
        --------------------------------------------------------------------    
117
 
118
        subtype packedstdlogic is std_logic_vector(NOCEM_DW+NOCEM_PKT_CNTRL_WIDTH-1 downto 0);
119
   type array_packed is array(natural range <>) of packedstdlogic;
120
 
121
   signal fifo_rd_data : array_packed(NOCEM_NUM_VC-1 downto 0);
122
 
123
   signal vc_switch_grant                       : std_logic_vector(7 downto 0);
124
 
125
 
126
   signal vc_alloc_mux_sel : std_logic_vector(7 downto 0);
127
        signal vc_empty_i               : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
128
 
129
        -- needed for Modelsim Simulator ....
130
        signal vc_myid_conv : vc_addr_array(NOCEM_NUM_VC-1 downto 0);
131
 
132
 
133
        -- debug signals
134
        signal db_error    : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
135
        signal db_want_eop : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
136
        signal db_want_sop : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
137
 
138
 
139
begin
140
 
141
 
142
        gen_vcids : process (rst)
143
        begin
144
                lgen : for I in NOCEM_NUM_VC-1 downto 0 loop
145
                          vc_myid_conv(I) <= CONV_STD_LOGIC_VECTOR(2**I,NOCEM_VC_ID_WIDTH);
146
                end loop;
147
        end process;
148
 
149
        datain_packed(NOCEM_DW+NOCEM_PKT_CNTRL_WIDTH-1 downto NOCEM_DW) <= wr_pkt_cntrl;
150
        datain_packed(NOCEM_DW-1 downto 0) <= wr_pkt_data;
151
 
152
 
153
 
154
        vc_read_sel : process (vc_empty_i,vc_mux_rd,rst,RE, vc_mux_wr, WE, dataout_packed,fifo_rd_data)
155
        begin
156
 
157
                vc_pkt_cntrl <= (others => (others => '0'));
158
                fifo_wr_en <= (others => '0');
159
                fifo_rd_en <= (others => '0');
160
                dataout_packed <= (others => '0');
161
                vc_empty <= vc_empty_i;
162
 
163
 
164
 
165
 
166
                -- push dataout from the correct fifo
167
                l1: for I in NOCEM_NUM_VC-1 downto 0 loop
168
 
169
                        fifo_wr_en(I) <= vc_mux_wr(I) and WE;
170
                        fifo_rd_en(I) <= vc_mux_rd(I) and RE;
171
                        vc_pkt_cntrl(I) <=      fifo_rd_data(I)(NOCEM_DW+NOCEM_PKT_CNTRL_WIDTH-1 downto NOCEM_DW);
172
 
173
                        if vc_mux_rd(I) = '1' then
174
                                dataout_packed  <= fifo_rd_data(I);
175
                        end if;
176
                end loop;
177
 
178
        end process;
179
 
180
 
181
        data_packed_handling : process (dataout_packed,datain_packed)
182
        begin
183
 
184
                -- breakout the padded dataout lines
185
                rd_pkt_cntrl <= dataout_packed(NOCEM_DW+NOCEM_PKT_CNTRL_WIDTH-1 downto NOCEM_DW);
186
                rd_pkt_data  <= dataout_packed(NOCEM_DW-1 downto 0);
187
 
188
                datain_32 <= (others => '0');
189
                datain_32(NOCEM_DW+NOCEM_PKT_CNTRL_WIDTH-1 downto 0) <= datain_packed;
190
 
191
 
192
 
193
 
194
        end process;
195
 
196
 
197
        ----------------------------------------------------------------------------
198
        ----------------------------------------------------------------------------
199
        --      GENERATE        THE NEEDED FIFOS AND DATA PADDING AS NEEDED                --
200
        ----------------------------------------------------------------------------
201
        ----------------------------------------------------------------------------
202
 
203
 
204
   g1: for I in NOCEM_NUM_VC-1 downto 0 generate
205
 
206
                -- ONLY difference is:
207
                --              if FIFO is attached to an accesspoint, it must be able to
208
                --    hold an ENTIRE packet, where inside the NoC, this is not the case
209
                g11: if IS_AN_ACCESS_POINT_CHANNEL = FALSE generate
210
 
211
 
212
                        g111: if NOCEM_FIFO_IMPLEMENTATION= NOCEM_FIFO_LUT_TYPE generate
213
 
214
                                I_vc : fifo_allvhdl
215
                                        generic map(
216
                                                WIDTH => NOCEM_DW+NOCEM_PKT_CNTRL_WIDTH,
217
                                                ADDR_WIDTH => Log2(NOCEM_CHFIFO_DEPTH)   -- LENGTH: CHFIFO_DEPTH
218
                                        )
219
                                        PORT MAP(
220
                                                din => datain_packed,
221
                                                clk => clk,
222
                                                rd_en => fifo_rd_en(I),
223
                                                rst => rst,
224
                                                wr_en => fifo_wr_en(I),
225
                                                dout => fifo_rd_data(I),
226
                                                empty => vc_empty_i(I),
227
                                                full =>         vc_full(I)
228
                                        );
229
 
230
                        end generate;
231
 
232
 
233
                end generate;
234
 
235
 
236
 
237
                g12: if IS_AN_ACCESS_POINT_CHANNEL = TRUE generate
238
 
239
 
240
 
241
                        g121: if NOCEM_FIFO_IMPLEMENTATION= NOCEM_FIFO_LUT_TYPE generate
242
 
243
 
244
 
245
                                I_vc : fifo_allvhdl
246
                                        generic map(
247
                                                WIDTH => NOCEM_DW+NOCEM_PKT_CNTRL_WIDTH,
248
                                                ADDR_WIDTH => Log2(NOCEM_MAX_PACKET_LENGTH) -- LENGTH: PACKET LENGTH
249
                                        )
250
                                        PORT MAP(
251
                                                din => datain_packed,
252
                                                clk => clk,
253
                                                rd_en => fifo_rd_en(I),
254
                                                rst => rst,
255
                                                wr_en => fifo_wr_en(I),
256
                                                dout => fifo_rd_data(I),
257
                                                empty => vc_empty_i(I),
258
                                                full =>         vc_full(I)
259
                                        );
260
 
261
                        end generate;
262
 
263
 
264
                end generate;
265
 
266
 
267
                -- generate a virtual FIFO controller.
268
                I_vc_cntrlr : vc_controller PORT MAP(
269
                        vc_my_id => vc_myid_conv(I),
270
                        node_my_id => node_dest_id,
271
                        pkt_cntrl_rd => vc_pkt_cntrl(I),
272
                        pkt_cntrl_wr => wr_pkt_cntrl,
273
                        pkt_re => fifo_rd_en(I),
274
                        pkt_we => fifo_wr_en(I),
275
                        vc_fifo_empty => vc_empty_i(I),
276
                        vc_eop_rd_status => vc_eop_rd_status(I), -- directly outputted to channel_fifo
277
                        vc_eop_wr_status => vc_eop_wr_status(I), -- directly outputted to channel_fifo                  
278
 
279
                        vc_allocation_req => vc_allocation_req(I),
280
                        vc_req_id => vc_req_id(I),
281
                        vc_allocate_from_node => vc_allocate_from_node,
282
                        vc_requester_from_node => vc_requester_from_node,
283
                        channel_dest => channel_dest(I),
284
                        vc_dest => vc_dest(I),
285
                        vc_switch_req =>  vc_switch_req(I),
286
                        rst => rst,
287
                        clk =>  clk
288
                );
289
 
290
 
291
 
292
 
293
  end generate;
294
 
295
-----------------------------------------------------------------------------
296
-----------------------------------------------------------------------------
297
-- VC Allocation muxing, arbitration, marshalling/demarshalling of arguments 
298
-----------------------------------------------------------------------------
299
-----------------------------------------------------------------------------
300
 
301
 
302
--  currently, only 2 and 4 virtual channel per physical channel are implemented
303
--  this is due to needed a power of 2 virtual channel count and with 8 virtual channels
304
--  the design gets very large very fast!
305
 
306
 
307
        I_vc_ch_alloc_arb: xto1_arbiter
308
 
309
        generic map(
310
                NUM_REQS => NOCEM_NUM_VC,
311
                REG_OUTPUT => 0
312
        )
313
        PORT MAP(
314
                arb_req => vc_allocation_req,
315
                arb_grant => vc_alloc_mux_sel(NOCEM_NUM_VC-1 downto 0),
316
                clk => clk,
317
                rst => rst
318
        );
319
 
320
 
321
        vc_alloc_mux4_gen: if NOCEM_NUM_VC = 4 generate
322
 
323
        I_vc_ch_alloc_mux1 : mux4to1
324
        generic map(
325
                DWIDTH => 5,                     -- one hot encoding for ch-dest
326
                REG_OUTPUT => 0
327
        )
328
        PORT MAP(
329
                din0 => channel_dest(0),
330
                din1 => channel_dest(1),
331
                din2 => channel_dest(2),
332
                din3 => channel_dest(3),
333
                sel => vc_alloc_mux_sel(3 downto 0),
334
                dout => vc_allocate_destch_to_node,
335
                clk => clk,
336
                rst => rst
337
        );
338
 
339
        I_vc_ch_alloc_mux2 : mux4to1
340
        generic map(
341
                DWIDTH => NOCEM_VC_ID_WIDTH,
342
                REG_OUTPUT => 0
343
        )
344
        PORT MAP(
345
                din0 => vc_req_id(0),
346
                din1 => vc_req_id(1),
347
                din2 => vc_req_id(2),
348
                din3 => vc_req_id(3),
349
                sel => vc_alloc_mux_sel(3 downto 0),
350
                dout => vc_requester_to_node,
351
                clk => clk,
352
                rst => rst
353
        );
354
 
355
        end generate;
356
 
357
 
358
 
359
        vc_alloc_mux2_gen: if NOCEM_NUM_VC = 2 generate
360
 
361
        I_vc_ch_alloc_mux1 : mux2to1
362
        generic map(
363
                DWIDTH => 5,                     -- one hot encoding for ch-dest
364
                REG_OUTPUT => 0
365
        )
366
        PORT MAP(
367
                din0 => channel_dest(0),
368
                din1 => channel_dest(1),
369
                sel => vc_alloc_mux_sel(1 downto 0),
370
                dout => vc_allocate_destch_to_node,
371
                clk => clk,
372
                rst => rst
373
        );
374
 
375
        I_vc_ch_alloc_mux2 : mux2to1
376
        generic map(
377
                DWIDTH => NOCEM_VC_ID_WIDTH,
378
                REG_OUTPUT => 0
379
        )
380
        PORT MAP(
381
                din0 => vc_req_id(0),
382
                din1 => vc_req_id(1),
383
                sel => vc_alloc_mux_sel(1 downto 0),
384
                dout => vc_requester_to_node,
385
                clk => clk,
386
                rst => rst
387
        );
388
 
389
        end generate;
390
 
391
 
392
 
393
-----------------------------------------------------------------------------
394
-----------------------------------------------------------------------------
395
-- switch allocation muxing, arbitration, marshalling/demarshalling of arguments 
396
-----------------------------------------------------------------------------
397
-----------------------------------------------------------------------------
398
 
399
--  currently, only 2 and 4 virtual channel per physical channel are implemented
400
--  this is due to needed a power of 2 virtual channel count and with 8 virtual channels
401
--  the design gets very large very fast!
402
 
403
 
404
        I_ch_switch_arb: xto1_arbiter
405
 
406
        generic map(
407
                NUM_REQS => NOCEM_NUM_VC,
408
                REG_OUTPUT => 1
409
        )
410
        PORT MAP(
411
                arb_req => vc_switch_req,
412
                arb_grant => vc_switch_grant(NOCEM_NUM_VC-1 downto 0),
413
                clk => clk,
414
                rst => rst
415
        );
416
 
417
 
418
 
419
        ch_alloc_mux4_gen: if NOCEM_NUM_VC = 4 generate
420
 
421
 
422
        I_vc_switch_alloc4_mux1 : mux4to1
423
        generic map
424
        (
425
                DWIDTH => NOCEM_ARB_IX_SIZE,
426
                REG_OUTPUT => 1
427
 
428
        )
429
        PORT MAP(
430
                din0 => channel_dest(0),
431
                din1 => channel_dest(1),
432
                din2 => channel_dest(2),
433
                din3 => channel_dest(3),
434
                sel => vc_switch_grant(3 downto 0),
435
                dout => rd_pkt_chdest,
436
                clk => clk,
437
                rst => rst
438
        );
439
 
440
        I_vc_switch_alloc4_mux2 : mux4to1
441
        generic map(
442
                DWIDTH => NOCEM_VC_ID_WIDTH,
443
                REG_OUTPUT => 1
444
        )
445
        PORT MAP(
446
                din0 => vc_dest(0),
447
                din1 => vc_dest(1),
448
                din2 => vc_dest(2),
449
                din3 => vc_dest(3),
450
                sel => vc_switch_grant(3 downto 0),
451
                dout => rd_pkt_vcdest,
452
                clk => clk,
453
                rst => rst
454
        );
455
 
456
        I_vc_switch_alloc4_mux3 : mux4to1
457
        generic map(
458
                DWIDTH => NOCEM_VC_ID_WIDTH,
459
                REG_OUTPUT => 1
460
        )
461
        PORT MAP(
462
                din0 => "0001",
463
                din1 => "0010",
464
                din2 => "0100",
465
                din3 => "1000",
466
                sel => vc_switch_grant(3 downto 0),
467
                dout => rd_pkt_vcsrc,
468
                clk => clk,
469
                rst => rst
470
        );
471
 
472
        end generate;
473
 
474
 
475
        ch_alloc_mux2_gen: if NOCEM_NUM_VC = 2 generate
476
 
477
 
478
        I_vc_switch_alloc2_mux1 : mux2to1
479
        generic map
480
        (
481
                DWIDTH => NOCEM_ARB_IX_SIZE,
482
                REG_OUTPUT => 1
483
 
484
        )
485
        PORT MAP(
486
                din0 => channel_dest(0),
487
                din1 => channel_dest(1),
488
                sel => vc_switch_grant(1 downto 0),
489
                dout => rd_pkt_chdest,
490
                clk => clk,
491
                rst => rst
492
        );
493
 
494
        I_vc_switch_alloc2_mux2 : mux2to1
495
        generic map(
496
                DWIDTH => NOCEM_VC_ID_WIDTH,
497
                REG_OUTPUT => 1
498
        )
499
        PORT MAP(
500
                din0 => vc_dest(0),
501
                din1 => vc_dest(1),
502
                sel => vc_switch_grant(1 downto 0),
503
                dout => rd_pkt_vcdest,
504
                clk => clk,
505
                rst => rst
506
        );
507
 
508
        I_vc_switch_alloc2_mux3 : mux2to1
509
        generic map(
510
                DWIDTH => NOCEM_VC_ID_WIDTH,
511
                REG_OUTPUT => 1
512
        )
513
        PORT MAP(
514
                din0 => "01",
515
                din1 => "10",
516
                sel => vc_switch_grant(1 downto 0),
517
                dout => rd_pkt_vcsrc,
518
                clk => clk,
519
                rst => rst
520
        );
521
 
522
        end generate;
523
 
524
 
525
---------------------------------------------------------------------------------
526
--debugging process:  simply for debugging purposes.  These signals would get    --
527
--eaten during synthesis as they do not affect downstream logic                                  --
528
--      ....delete if needed....                                                                                                                                         --
529
---------------------------------------------------------------------------------
530
 
531
db_gen : process (clk,rst)
532
begin
533
 
534
 
535
        if rst='1' then
536
                db_error        <= (others => '0');
537
                db_want_eop     <= (others => '0');
538
                db_want_sop     <= (others => '1');
539
        elsif clk='1' and clk'event then
540
 
541
                db_loop: for I in NOCEM_NUM_VC-1 downto 0 loop
542
                        if fifo_wr_en(I)='1' and wr_pkt_cntrl(NOCEM_PKTCNTRL_SOP_IX)='1' then
543
                                db_want_eop(I) <= '1';
544
                                db_want_sop(I) <= '0';
545
 
546
                        elsif fifo_wr_en(I)='1' and wr_pkt_cntrl(NOCEM_PKTCNTRL_EOP_IX)='1' then
547
                                db_want_eop(I) <= '0';
548
                                db_want_sop(I) <= '1';
549
                        end if;
550
 
551
                        if fifo_wr_en(I)='1' and db_want_eop(I)='1' and wr_pkt_cntrl(NOCEM_PKTCNTRL_SOP_IX)='1' then
552
                                db_error(I) <= '1';
553
                        elsif fifo_wr_en(I)='1' and db_want_sop(I)='1' and wr_pkt_cntrl(NOCEM_PKTCNTRL_EOP_IX)='1' then
554
                                db_error(I) <= '1';
555
                        else
556
                                db_error(I) <= '0';
557
                        end if;
558
 
559
                end loop;
560
         end if;
561
 
562
 
563
 
564
end process;
565
 
566
 
567
 
568
 
569
 
570
end Behavioral;

powered by: WebSVN 2.1.0

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