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

Subversion Repositories nocem

[/] [nocem/] [trunk/] [VHDL/] [ap_exerciser_vc.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: ap_exerciser_vc.vhd
32 4 schelleg
-- 
33 2 schelleg
-- Description: access point exerciser for VC designs
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
use work.pkg_nocem.all;
44
 
45
 
46
entity ap_exerciser_vc is
47 2 schelleg
        Generic(
48
 
49
                DELAY_START_COUNTER_WIDTH               : integer := 32;
50
                DELAY_START_CYCLES                              : integer := 500;
51
                PKT_LENGTH                                                      : integer := 5;
52
                INTERVAL_COUNTER_WIDTH                  : integer := 8;
53 4 schelleg
                DATA_OUT_INTERVAL                               : integer := 16;
54
           INIT_DEST_ADDR                                       : integer := 0;
55
                MY_ADDR                                                                 : integer := 0;
56 2 schelleg
                EXERCISER_MODE                                          : integer := EXERCISER_MODE_SIM
57
                 )      ;
58
    Port (
59
 
60 4 schelleg
                -- arbitration lines (usage depends on underlying network)
61
                arb_req         : out  std_logic;
62
                arb_cntrl_out   : out  arb_cntrl_word;
63
 
64
                arb_grant         : in std_logic;
65
                arb_cntrl_in      : in  arb_cntrl_word;
66
 
67
                datain        : in   data_word;
68
                datain_valid  : in   std_logic;
69
                datain_recvd  : out  std_logic;
70
 
71
                dataout       : out data_word;
72
                dataout_valid : out std_logic;
73
                dataout_recvd : in  std_logic;
74
 
75
                pkt_cntrl_in        : in   pkt_cntrl_word;
76
                pkt_cntrl_in_valid  : in   std_logic;
77
                pkt_cntrl_in_recvd  : out  std_logic;
78
 
79
                pkt_cntrl_out       : out pkt_cntrl_word;
80
                pkt_cntrl_out_valid : out std_logic;
81 2 schelleg
                pkt_cntrl_out_recvd : in  std_logic;
82 4 schelleg
 
83
                clk : in std_logic;
84 2 schelleg
      rst : in std_logic
85
 
86 4 schelleg
                );
87
end ap_exerciser_vc;
88
 
89
architecture Behavioral of ap_exerciser_vc is
90
 
91 2 schelleg
                signal rst_i : std_logic;
92
                signal rst_counter : std_logic_vector(DELAY_START_COUNTER_WIDTH-1 downto 0);
93
                signal interval_counter : std_logic_vector(INTERVAL_COUNTER_WIDTH-1 downto 0);
94
                signal dataout_reg : std_logic_vector(NOCEM_DW-1 downto 0);
95
                signal pkt_cntrl_out_reg : pkt_cntrl_word;
96
 
97
 
98 4 schelleg
                signal burst_counter : std_logic_vector(7 downto 0);
99
 
100
                signal datain_reg : data_word;
101
                signal pkt_cntrl_in_reg : pkt_cntrl_word;
102
 
103
 
104 2 schelleg
                type stateType is (init_st,sending_st,getting_vc_st);
105 4 schelleg
                signal state,nextState : stateType;
106
 
107
                -- determine the next free outgoing VC
108
                signal next_free_vc  : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
109
                signal vc_state : std_logic_Vector(NOCEM_NUM_VC-1 downto 0);   -- 0: free, 1: allocated --
110
                signal vc_allocate : std_logic;
111
                signal free_this_vc      : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
112
                signal vc_mux_wr_reg     : std_logic_vector(NOCEM_VC_ID_WIDTH-1 downto 0);
113
 
114
 
115
                -- data gathering signals
116
                signal  next_vc_with_pkt,finished_pkt,eop_wr_sig,pkt_rdy         : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
117
                signal  recv_idle : std_logic;
118
 
119
                -- arbcntrl out signals used for ORing together
120
                signal  arb_sending_word,arb_receiving_word   :   arb_cntrl_word;
121
 
122
                signal allones_vcwidth : std_logic_vector(NOCEM_NUM_VC-1 downto 0);
123
 
124
                -- any debug signals
125
                signal  debug_vc_mux_wr : std_logic_vector(NOCEM_VC_ID_WIDTH-1 downto 0);
126
 
127
 
128
begin
129
 
130
allones_vcwidth <= (others => '1');
131
 
132
-- arbcntrl out signals used for ORing together
133
arb_cntrl_out <= arb_sending_word or arb_receiving_word;
134
 
135
 
136 2 schelleg
rst_gen : process (clk,rst)
137
begin
138
        if rst='1' then
139
                rst_i <= '1';
140
                rst_counter <= (others => '0');
141
        elsif clk'event and clk ='1' then
142
                rst_counter <= rst_counter+1;
143
                if rst_counter = DELAY_START_CYCLES then
144
                                 rst_i <= '0';
145
                end if;
146
        end if;
147 4 schelleg
end process;
148
 
149
 
150
----------------------------------------------------------------------------------
151
--------KEEPING TRACK OF OUTGOING VC STATES --------------------------------------
152
----------------------------------------------------------------------------------
153
 
154
gen_vc_status_uclkd : process (vc_state)
155
begin
156
 
157
end process;
158
 
159
gen_vc_status_clkd : process (clk,rst)
160
begin
161
 
162
 
163
        if rst='1' then
164
                --next_free_vc <= ('1',others => '0');  
165
                vc_state <= (others => '0');
166
                free_this_vc <= (others => '0');
167
                next_free_vc <= (others => '0');
168
        elsif clk'event and clk='1' then
169
 
170
 
171
                l2: for I in NOCEM_NUM_VC-1 downto 0 loop
172
                        if vc_state(I) = '0' then
173
                                next_free_vc <= CONV_STD_LOGIC_VECTOR(2**I,NOCEM_NUM_VC);
174
                        end if;
175
                end loop;
176
 
177
                if vc_state = allones_vcwidth then
178
                        next_free_vc <= (others => '0');
179
                end if;
180
 
181
 
182
            free_this_vc <= arb_cntrl_in(NOCEM_ARB_CNTRL_VC_EOP_RD_HIX downto NOCEM_ARB_CNTRL_VC_EOP_RD_LIX);
183
 
184
                 -- 0: free, 1: allocated --
185
                 l1: for I in NOCEM_NUM_VC-1 downto 0 loop
186
                        if vc_state(I) = '0' and next_free_vc(I) = '1' and vc_allocate = '1' then -- free going to allocated
187
                                vc_state(I) <= '1';
188
                        elsif vc_state(I) = '1' and free_this_vc(I) = '1' then -- allocated going to free
189
                                vc_state(I) <= '0';
190
                        end if;
191
                 end loop;
192
 
193
        end if;
194
end process;
195
 
196
----------------------------------------------------------------------------------
197
----------------------------------------------------------------------------------
198
----------------------------------------------------------------------------------
199
 
200
 
201 2 schelleg
dataout_gen_clkd : process (clk,rst_i,nextState)
202
begin
203
        if rst_i = '1' then
204
                 state <= init_st;
205 4 schelleg
                 interval_counter               <= (others => '0');
206
                 dataout_reg               <= (others => '0');
207
                 vc_mux_wr_reg             <= (others => '0');
208
                 -- setup pkt_cntrl correctly
209
                 pkt_cntrl_out_reg <= (others => '0');
210
                 pkt_cntrl_out_reg(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX)    <=  addr_gen(INIT_DEST_ADDR,NOCEM_NUM_ROWS,NOCEM_NUM_COLS,NOCEM_AW);
211
 
212
 
213 2 schelleg
                 burst_counter       <= (others => '0');
214
        elsif clk'event and clk='1' then
215
                state <= nextState;
216
        case state is
217 4 schelleg
        when init_st =>
218
                                 interval_counter               <= interval_counter+1;
219
                                 --dataout_reg             <= (others => '0');
220
--                               pkt_cntrl_out_reg(NOCEM_PKTCNTRL_SOP_IX)       <= '1'; 
221
--                               
222
--                               if PKT_LENGTH = 1 then
223
--                                      pkt_cntrl_out_reg(NOCEM_PKTCNTRL_EOP_IX)        <= '1'; 
224
--                               else
225
--                                      pkt_cntrl_out_reg(NOCEM_PKTCNTRL_EOP_IX)        <= '0';
226
--                               end if;                                 
227
                                 vc_mux_wr_reg <= (others => '0');
228
 
229
 
230
 
231
 
232
                                 burst_counter       <= (others => '0');
233 2 schelleg
 
234 4 schelleg
                        when getting_vc_st =>
235 2 schelleg
                                --pkt_cntrl_out_reg <= (others => '0');
236
                                interval_counter <= (others => '0');
237
                                vc_mux_wr_reg <= next_free_vc;
238 4 schelleg
                        when sending_st =>
239
                                -- marking packets with src addrs...
240
                                dataout_reg(NOCEM_DW-1 downto NOCEM_AW) <= dataout_reg(NOCEM_DW-1 downto NOCEM_AW) + 1;
241
                                dataout_reg(NOCEM_AW-1 downto 0)        <= addr_gen(MY_ADDR,NOCEM_NUM_ROWS,NOCEM_NUM_COLS,NOCEM_AW);
242
 
243
                                -- handle the pkt_control reg
244
 
245
                                -- increment the data inside
246 2 schelleg
                                if arb_grant = '1' and dataout_recvd = '1' then
247 4 schelleg
                                        burst_counter <=        burst_counter + 1;
248
                                end if;
249
 
250
                                if nextState = init_st then
251
 
252
                                        -- increment destination field (making sure it doesn't send a packet to myself)                          
253
                                        if pkt_cntrl_out_reg(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX)+1 = addr_gen(MY_ADDR,NOCEM_NUM_ROWS,NOCEM_NUM_COLS,NOCEM_AW) then
254
                                                        pkt_cntrl_out_reg(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX) <= pkt_cntrl_out_reg(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX) + 2;
255
                                        else
256
                                                        pkt_cntrl_out_reg(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX) <= pkt_cntrl_out_reg(NOCEM_PKTCNTRL_DEST_ADDR_HIX downto NOCEM_PKTCNTRL_DEST_ADDR_LIX) + 1;
257
                                        end if;
258
                                end if;
259 2 schelleg
 
260 4 schelleg
 
261
 
262 2 schelleg
                        when others =>
263
                                null;
264
                end case;
265
        end if;
266 4 schelleg
end process;
267 2 schelleg
 
268 4 schelleg
 
269 2 schelleg
dataout_gen_uclkd : process (next_free_vc, vc_mux_wr_reg,pkt_cntrl_out_reg, pkt_cntrl_out_recvd,state, interval_counter, dataout_reg, arb_grant, dataout_recvd, burst_counter)
270
begin
271
 
272 4 schelleg
                 arb_req         <= '0';
273 2 schelleg
                 arb_sending_word <= (others => '0');
274
                 dataout         <= (others => '0');
275
                 dataout_valid   <= '0';
276 4 schelleg
                 --nextState <= init_st;
277 2 schelleg
 
278 4 schelleg
                 pkt_cntrl_out   <= (others => '0');
279
                 pkt_cntrl_out_valid <= '0';
280
                 vc_allocate <= '0';
281
 
282 2 schelleg
                case state is
283 4 schelleg
        when init_st =>
284 2 schelleg
 
285 4 schelleg
                                        if interval_counter = CONV_STD_LOGIC_VECTOR(DATA_OUT_INTERVAL,INTERVAL_COUNTER_WIDTH) then
286
                                                nextState <= getting_vc_st;
287
                                        else
288 2 schelleg
                                                nextState <= init_st;
289 4 schelleg
                                        end if;
290
 
291 2 schelleg
                        when getting_vc_st =>
292
 
293 4 schelleg
                                if next_free_vc /= 0 then
294
                                        vc_allocate <= '1';
295
                                        nextState <= sending_st;
296
                                else
297
                                        nextState <= getting_vc_st;
298
                                end if;
299
 
300
 
301 2 schelleg
                        when sending_st =>
302
 
303 4 schelleg
                                arb_req <= '1';
304
                                arb_sending_word(NOCEM_ARB_CNTRL_VC_MUX_WR_HIX downto NOCEM_ARB_CNTRL_VC_MUX_WR_LIX) <= vc_mux_wr_reg;
305 2 schelleg
 
306
                                dataout <= dataout_reg;
307 4 schelleg
                                dataout_valid <= '1';
308
 
309 2 schelleg
                                pkt_cntrl_out <= pkt_cntrl_out_reg;
310 4 schelleg
                                pkt_cntrl_out_valid <= '1';
311
 
312
 
313
                                if burst_counter = 0 then
314
                                        pkt_cntrl_out(NOCEM_PKTCNTRL_SOP_IX)    <= '1';
315 2 schelleg
                                end if;
316
 
317 4 schelleg
                                if burst_counter = PKT_LENGTH then
318
                                        pkt_cntrl_out(NOCEM_PKTCNTRL_EOP_IX)    <= '1';
319
                                        nextState <= init_st;
320
                                else
321
                                        nextState <= sending_st;
322
                                end if;
323
 
324 2 schelleg
                        when others =>
325
                                null;
326
                end case;
327
end process;
328 4 schelleg
 
329
 
330
 
331
----------------------------------------------------
332
----------------------------------------------------
333
-----------      DATAIN SIGNALLING     -------------
334
----------------------------------------------------
335
----------------------------------------------------
336
 
337
vc_datain_st_gen_clkd : process(clk,rst,arb_cntrl_in)
338
begin
339
 
340
        eop_wr_sig <= arb_cntrl_in(NOCEM_ARB_CNTRL_VC_EOP_WR_HIX downto NOCEM_ARB_CNTRL_VC_EOP_WR_LIX);
341
 
342
        if rst='1' then
343
                pkt_rdy <= (others => '0');
344
                next_vc_with_pkt <= (others => '0');
345
                datain_reg <= (others => '0');
346
                pkt_cntrl_in_reg <= (others => '0');
347
                recv_idle <= '1';
348
        elsif clk'event and clk='1' then
349
 
350
 
351
                l1: for I in NOCEM_NUM_VC-1 downto 0 loop
352
 
353
                        -- is the pkt rdy for reading?
354
                        if eop_wr_sig(I) = '1' then
355
                                pkt_rdy(I) <= '1';
356
                        elsif finished_pkt(I) = '1' then
357
                                pkt_rdy(I) <= '0';
358
                        end if;
359
 
360
                        -- what is the next pkt to read from VCs?
361
                        if pkt_rdy(I) = '1' and recv_idle = '1' then
362
                                next_vc_with_pkt <= CONV_STD_LOGIC_VECTOR(2**I,NOCEM_NUM_VC);
363
                                recv_idle <= '0';
364
                        elsif finished_pkt /= 0 then
365
                                recv_idle <= '1';
366
                        end if;
367
 
368
                end loop;
369
 
370
                if pkt_rdy = 0 then
371
                        next_vc_with_pkt <= (others => '0');
372
                end if;
373
 
374
 
375
        end if;
376
 
377
end process;
378
 
379
 
380
 
381
datain_gather_uclkd : process (next_vc_with_pkt, pkt_cntrl_in,datain_valid,pkt_cntrl_in_valid)
382
begin
383
 
384
        datain_recvd <= '0';
385
        pkt_cntrl_in_recvd <= '0';
386
        finished_pkt <= (others => '0');
387
        arb_receiving_word <= (others => '0');
388
 
389
 
390
        if next_vc_with_pkt /= 0 then
391
                arb_receiving_word(NOCEM_ARB_CNTRL_VC_MUX_RD_HIX downto NOCEM_ARB_CNTRL_VC_MUX_RD_LIX) <= next_vc_with_pkt;
392
                datain_recvd <= '1';
393
        end if;
394
 
395
        if next_vc_with_pkt /= 0 then
396
                pkt_cntrl_in_recvd <= '1';
397
                if pkt_cntrl_in(NOCEM_PKTCNTRL_EOP_IX)  = '1' then
398
                        finished_pkt <= next_vc_with_pkt;
399
                end if;
400
        end if;
401
 
402
 
403
end process;
404
 
405
 
406
 
407
debug_gen : process (arb_sending_word)
408
begin
409
 
410
        debug_vc_mux_wr <= arb_sending_word(NOCEM_ARB_CNTRL_VC_MUX_WR_HIX downto NOCEM_ARB_CNTRL_VC_MUX_WR_LIX);
411
 
412
end process;
413
 
414
 
415
 
416
end Behavioral;

powered by: WebSVN 2.1.0

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