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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.communication/] [hibi/] [2.0/] [vhd/] [tx_ctrl.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Funbase IP library Copyright (C) 2011 TUT Department of Computer Systems
3
--
4
-- This source file may be used and distributed without
5
-- restriction provided that this copyright statement is not
6
-- removed from the file and that any derivative work contains
7
-- the original copyright notice and the associated disclaimer.
8
--
9
-- This source file is free software; you can redistribute it
10
-- and/or modify it under the terms of the GNU Lesser General
11
-- Public License as published by the Free Software Foundation;
12
-- either version 2.1 of the License, or (at your option) any
13
-- later version.
14
--
15
-- This source is distributed in the hope that it will be
16
-- useful, but WITHOUT ANY WARRANTY; without even the implied
17
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18
-- PURPOSE.  See the GNU Lesser General Public License for more
19
-- details.
20
--
21
-- You should have received a copy of the GNU Lesser General
22
-- Public License along with this source; if not, download it
23
-- from http://www.opencores.org/lgpl.shtml
24
-------------------------------------------------------------------------------
25
-------------------------------------------------------------------------------
26
-- File        : tx_control_addr_width_is_1_muxed_fifos.vhdl
27
-- Description : Control the transmitting of data. Includes
28
--               the priority arbitration. Config mem gives
29
--               the start and end times and owners  of time slots.
30
--
31
--               This version assumes, muxed fifos, i.e. FSM does no
32
--               separation between messages and data, it sees only one fifo.
33
-- Author      : Erno Salminen
34
-- e-mail      : erno.salminen@tut.fi
35
-- Project      huuhaa
36
-- Design      : Do not use term design when you mean system
37
-- Date        : 11.02.2003
38
-- Modified    :
39
--
40
-- 07.01.03     ES:  Next state of Re_tx_data is always idle!
41
--              This way there are less problems with reading the fifo
42
-- 17.03.03     ES: Idle->Write won't work if new addr is coming. Cannot assert
43
--              fifo read enable in time. consequently, tha same is written
44
--              twice on the bus
45
-- 12.04.03     ES: Total_amount, Addr_Amount input ports and Fifo_Depth generic removed
46
-- 13.04.03     ES: Message stuff removed
47
--              Constant print_debug added, selects wheteher assertions are
48
--              used or not
49
-- 04.03.04     ES: two bugs with target_fifo_full
50
--              1) target_fifo_full=1 when next addr coming from fifo
51
--                      => addr stored in data_reg2 and sent as if it was data
52
--                      => add extra reg for that addr and valid_reg for it
53
--                      => values stored in them state 'write'
54
--                      => values read from them when retransfer completes
55
--                      
56
--              2) next addr comes from fifo before retransfer is complete
57
--                      => retransfer goes to 'next addr'
58
--                      => add one confition to if clause in state idle
59
--                      (inside else clause 'not own turn')
60
-- 28.07.2004   ES: cleaning, addr_reg type changed to regular std_logic_vector
61
-- 03.08.2004   ES: Renamed some states to shorter names. New if-branch inside cfg_d
62
--                  Added debug_level and Rst_Value for wave form debugging.
63
--                  Set dbg_level=0 for synthesis.    
64
-- 13.09.2004   ES: Bug found. When target_fifo_full=1 and addr on the bus, the
65
--                  addr will be retransferred as addr (ok) and as data also (not
66
--                  ok). Check addr_valid on state write and assign data_r1 and
67
--                  data_r2 accordingly
68
--
69
-- 15.12.2004   ES names changed
70
--
71
-- 03.01.2005   ES retx_addr: check fo full=1 added
72
-- 14.01.2005      when idle and going to own_slot_reservation, check re
73
-- 15.01.2005   ES idle->own slot res: lock_out must be 1-
74
-- 03.02.05     ES  addr_width_g is now in BITS!
75
-- 07.02.05     ES new generic cfg_re_g
76
-- 15.05.05     AK A bug when writing every other clock cycle, the data after
77
--                 the address vanishes. suspicious state: idle 2d. and write_data 4).
78
--                 corrected, hopefully.
79
--
80
-- 13.07.05     AK A bug which reads out an address but doesn't send it when
81
--                 retransmitting. suspicious state: 1 (under 0a). more
82
--                 explanation there.
83
-- ?????????
84
-- 25.02.2005 Design compiler ei välttämättä syntesoi a_ext-funktiota oikein?
85
-- 2007/04/18   AK/ES Arbitration type voidaan asettaa ajonaikana 4:ään eri arvoon
86
-- 2009/07/31   JN Cleanups + keep_slot_g (lock_out = '1' trough whole time slot)
87
------------------------------------------------------------------------------
88
 
89
library ieee;
90
use ieee.std_logic_1164.all;
91
use ieee.std_logic_arith.all;
92
use ieee.std_logic_unsigned.all;
93
 
94
 
95
entity tx_control is
96
 
97
  generic (
98
    counter_width_g : integer := 8;
99
    id_width_g      : integer := 4;
100
    id_g            : integer := 1;     -- not neede?
101
    data_width_g    : integer := 32;    -- in bits
102
    addr_width_g    : integer := 32;    -- in BITS!
103
    comm_width_g    : integer := 3;
104
    n_agents_g      : integer := 0;      -- 2009-04-08
105
    cfg_re_g        : integer := 0;
106
    keep_slot_g     : integer := 1      -- 2009-07-31
107
    );
108
  port (
109
    clk   : in std_logic;
110
    rst_n : in std_logic;
111
 
112
    lock_in : in std_logic;
113
    full_in : in std_logic;  --nyk. data/osoite ei mennyt perille!
114
 
115
    cfg_ret_addr_in : in std_logic_vector (addr_width_g-1 downto 0);
116
    cfg_data_in     : in std_logic_vector (data_width_g-1 downto 0);
117
    cfg_re_in       : in std_logic;
118
 
119
 
120
    curr_slot_own_in    : in std_logic;
121
    curr_slot_ends_in   : in std_logic;
122
    next_slot_own_in    : in std_logic;
123
    next_slot_starts_in : in std_logic;
124
    max_send_in         : in std_logic_vector (counter_width_g-1 downto 0);
125
    n_agents_in         : in std_logic_vector (id_width_g-1 downto 0);
126
    prior_in            : in std_logic_vector (id_width_g-1 downto 0);
127
    -- *********************************************************
128
    -- new ports: Power_Mode and Competition_Type must be added!
129
    -- *********************************************************
130
    -- 0 round-robin, 1 priority, 2 combined, 3 dyn_arb (rand)
131
    arb_type_in         :    std_logic_vector(1 downto 0);
132
 
133
    av_in    : in std_logic;
134
    data_in  : in std_logic_vector (data_width_g-1 downto 0);
135
    comm_in  : in std_logic_vector (comm_width_g-1 downto 0);
136
    one_d_in : in std_logic;
137
    empty_in : in std_logic;
138
 
139
    av_out         : out std_logic;
140
    data_out       : out std_logic_vector (data_width_g-1 downto 0);
141
    comm_out       : out std_logic_vector (comm_width_g-1 downto 0);
142
    lock_out       : out std_logic;
143
    cfg_rd_rdy_out : out std_logic;
144
    re_out         : out std_logic
145
    );
146
 
147
end tx_control;
148
 
149
 
150
 
151
 
152
 
153
 
154
architecture rtl of tx_control is
155
 
156
 
157
  constant write_command_c : std_logic_vector (2 downto 0) := "010";  -- 03.02.05
158
 
159
 
160
  -- Selects if debug prints are used ('1') or not ('0')
161
  constant dbg_level : integer range 0 to 3 := 0;  -- 0= no debug, use 0 for synthesis
162
 
163
  -- Registers may be reset to 'Z' to 'X' so that reset state is clearly
164
  -- distinguished from active state. Using dbg_level+rst_Value array, the rst value may
165
  -- be easily set to '0' for synthesis.
166
  constant rst_value_arr : std_logic_vector (6 downto 0) := 'X' & 'Z' & 'X' & 'Z' & 'X' & 'Z' & '0';
167
 
168
  -- Combinatorial signals
169
  -- Own_turn_ends is high when own turn ends, i.e.
170
  --  * maximum amount of data sent
171
  --  * own slot ends
172
  --  * other slot starts
173
  --  09.01.04: This seems to be in critical path.
174
  --  If this was register, critical path could be shortened.
175
  --  On the other hand comparison must be changed to drive register one cycle
176
  --  earlier than combinatorial signal. 
177
  signal own_turn_ends  : std_logic;
178
  signal prior_match    : std_logic;
179
  signal max_send_limit : std_logic;
180
 
181
 
182
  -- Define type and signals for state machine
183
  type state_vector is (Idle,
184
                        Own_Slot_Reservation,
185
                        Cfg_A, Cfg_D, Cfg_D_Last,
186
                        Retransfer_Addr, Retransfer_data, Retransfer_Data_Last,
187
                        Write_Data, Write_Last_Data, Error_State);
188
  signal curr_state_r : state_vector;
189
 
190
  -- Counters and signals denoting start and end of the competition reservation
191
  -- Counters do not have to be as wide as data! They generate huge delays
192
  -- and slow down the whole unit if they are unnecessarily wide!
193
  signal prior_counter_r : std_logic_vector (id_width_g -1 downto 0);
194
  signal send_counter_r  : std_logic_vector (counter_width_g -1 downto 0);
195
 
196
 
197
  -- Register, this way the state of the signal 'read enable' can be read
198
  signal fifo_re_r : std_logic;
199
 
200
  signal addr1_r   : std_logic_vector (addr_width_g -1 downto 0);  -- 03.02.05
201
  signal comm_a1_r : std_logic_vector (comm_width_g -1 downto 0);
202
 
203
 
204
  -- Registers needed to continue interrupted transfer
205
  -- When transfer is interrupted, addr and either 1 or 2 data has be trasferred
206
  -- again.
207
  -- (Actually, only one data is retransferered, but have another may already
208
  -- been read from fifo but not transferred. This is data referred as
209
  -- retransferred because it is handled in the sama way as the actually
210
  -- retransferred. It is stored in data_reg2 )
211
  -- When state is write_data
212
  --  * Regular data goes from fifo to output registers
213
  --  * At the same, it is copied ro register data_Reg2
214
  --  * At he same time, previously sent data is copied from data2_r to data1_r
215
  --  data1_r is retransferred after addr (and after that data2_r if needed)
216
  signal data1_r       : std_logic_vector (data_width_g -1 downto 0);
217
  signal data2_r       : std_logic_vector (data_width_g -1 downto 0);
218
  signal comm_d1_r     : std_logic_vector (comm_width_g -1 downto 0);
219
  signal comm_d2_r     : std_logic_vector (comm_width_g -1 downto 0);
220
  signal retx_amount_r : integer range 0 to 2;
221
 
222
  signal addr_valid_r : std_logic;      -- 13.09.04
223
 
224
  -- For storing new addr that comes at the same with full_in=1
225
  signal addr2_r       : std_logic_vector (addr_width_g -1 downto 0);  -- 03.02.05
226
  signal comm_a2_r     : std_logic_vector (comm_width_g -1 downto 0);
227
  signal addr2_valid_r : std_logic;
228
 
229
  -- Signals for configuration read operation
230
  signal cfg_ret_addr_r      : std_logic_vector (addr_width_g-1 downto 0);  -- 03.02.05
231
  signal cfg_read_value_r    : std_logic_vector (data_width_g-1 downto 0);
232
  signal cfg_read_complete_r : std_logic;
233
 
234
 
235
 
236
  -- Muutetaan vertailun tulos reksiteriksi
237
  -- =>  lyhyempi kriittinen polku (toivottavasti)
238
  signal max_send_limit_r : std_logic;
239
 
240
 
241
  -- Katsotaan paljonko tulee viivett�t�� menness�
242
  signal own_turn_ends_r : std_logic;
243
 
244
  -- prior+round-robin countteri
245
  -- after this amount of clock cycles, change the arb type
246
  constant switch_arb_c    : integer := 4096;
247
  signal   switch_arb_r    : integer range 0 to switch_arb_c-1;
248
  signal   arb_type_r      : std_logic_vector(1 downto 0);
249
  signal   curr_arb_type_r : std_logic_vector(1 downto 0);
250
 
251
  -- dynamically adaptive arbitration, enable this for "random arb"
252
  signal   arb_agent_r      : std_logic_vector(id_width_g-1 downto 0);
253
--  constant dyn_arb_enable_c : integer := 0;
254
  constant dyn_arb_enable_c : integer := 1;  -- ES 2009-04-01
255
 
256
 
257
 
258
  signal dyn_arb_prior       : std_logic_vector(id_width_g-1 downto 0);
259
  signal prior_counter_arb_r : std_logic_vector(id_width_g-1 downto 0);
260
 
261
  component dyn_arb
262
    generic (
263
      id_width_g : integer;
264
      n_agents_g : integer
265
      );
266
    port (
267
      clk           : in  std_logic;
268
      rst_n         : in  std_logic;
269
      bus_lock_in   : in  std_logic;
270
      arb_agent_out : out std_logic_vector(id_width_g-1 downto 0));
271
  end component;
272
 
273
 
274
begin  -- rtl
275
 
276
 
277
 
278
  -- Continous assignments to outputs
279
  cfg_rd_rdy_out <= cfg_read_complete_r;
280
  re_out         <= fifo_re_r;
281
  av_out         <= addr_valid_r;       --13.09.04
282
 
283
  -- Sendcounterin vertialu on omalla kellojaksollaan
284
  -- => ei ole en� kriittisell�polulla
285
  -- Laskurin reset-arvosta riippuu mitk�send_maxit on laillisia
286
  -- ja l�etet�nk�tarkalleen se m�r�vai pari enemm�, ao. m�r� sis�t�
287
  -- ekan osoiteen
288
  -----------------------------------------------------------------------------
289
  --   Counterin arvot     L�. m�r�    Sallitus max-sendin arvot
290
  ------------------------------------------------------------------------------
291
  -- jos counter= 0,1,2  max_s+3 kpl      max_s= 2,3+
292
  -- jos counter= 1,2,3  max_s+2 kpl      max_s= 2,3+
293
  -- jos counter= 2,3,4  max_s+1 kpl      max_s= 3,4+
294
  -- jos counter= 3,4,5  max_s   kpl      max_s= 4,5+
295
  -- => ei kannata resetoida ainakaan nollaan!
296
 
297
 
298
  max_send_limit <= max_send_limit_r;
299
 
300
  check_max_send : process (clk, rst_n)
301
  begin  -- process check_max_send
302
    if rst_n = '0' then
303
      max_send_limit_r <= '0';
304
 
305
      own_turn_ends_r <= '0';
306
 
307
    elsif clk'event and clk = '1' then
308
 
309
      if (max_send_in (counter_width_g-1 downto 0) = send_counter_r
310
          or max_send_in = conv_std_logic_vector (0, data_width_g)
311
          or max_send_in = conv_std_logic_vector (1, data_width_g))
312
      then
313
 
314
        if (curr_slot_own_in = '1'
315
            or (next_slot_starts_in = '1' and next_slot_own_in = '1')) then
316
          max_send_limit_r <= '0';
317
        else
318
          max_send_limit_r <= '1';
319
        end if;
320
 
321
      else
322
        max_send_limit_r <= '0';
323
      end if;
324
 
325
      own_turn_ends_r <= own_turn_ends;
326
 
327
    end if;
328
  end process check_max_send;
329
 
330
 
331
 
332
  -- 2) COMB PROC
333
  -- Check if priority matches so that competition reservation may start
334
  Check_Prior : process (prior_in, prior_counter_r)
335
  begin  -- process Check_Send_Limit
336
    if prior_counter_r = prior_in (id_width_g-1 downto 0) then  --22.01.03
337
      prior_match <= '1';
338
    else
339
      prior_match <= '0';
340
    end if;
341
  end process Check_Prior;
342
 
343
 
344
 
345
  -- 3) PROC (ASYNC)
346
  -- Check if bus reservation must be ended
347
  -- Own turn ends, if
348
  -- * max amount data already transferred
349
  -- * or own slot ends
350
  -- * or some other wrapper's slot starts
351
  -- When Own_turn_ends=1, wrapper can transfer one value
352
  Check_Turn : process (max_send_limit,
353
                        curr_slot_own_in, curr_slot_ends_in,
354
                        next_slot_own_in, next_slot_starts_in)
355
  begin  -- process Check_Turn
356
    if max_send_limit = '1'
357
      or ((curr_slot_own_in = '1' and curr_slot_ends_in = '1')
358
          or (next_slot_own_in = '0' and next_slot_starts_in = '1'))then
359
      own_turn_ends <= '1';
360
    else
361
      own_turn_ends <= '0';
362
    end if;
363
  end process Check_Turn;
364
 
365
 
366
 
367
  -- 4) SEQ PROC
368
  -- Count how many data has been transferred
369
  -- Counter is not incremented, if
370
  -- * wrapper is not trasferring
371
  -- * wrapper has a time slot
372
  -- * wrapper is finishing transfer
373
  Count_Sent_Items : process (clk, rst_n)
374
  begin  -- process Count_Sent_Items
375
    if rst_n = '0' then                 -- asynchronous reset (active low)
376
      send_counter_r <= (others => '0');
377
 
378
    elsif clk'event and clk = '1' then  -- rising clock edge
379
 
380
      if curr_state_r = Idle
381
        or curr_slot_own_in = '1'
382
        or curr_state_r = Write_Last_Data
383
        or curr_state_r = Retransfer_Data_Last
384
        or curr_state_r = Cfg_D_Last then
385
 
386
        send_counter_r <= (others => '0');
387
 
388
        send_counter_r(1) <= '1';       -- 12.12.05 reset to 0x002
389
        send_counter_r(0) <= '1';       -- 12.12.05 reset to 0x001
390
 
391
 
392
        -- Counter should be incremented already when moving from idle to
393
        -- some write state (Write_Data / Cfg_A / Retransfer_Addr)!
394
        -- At the moment, counter is started one clock cycle too late
395
        -- => send_max+1 data will be transferred
396
        -- 31.07 can this be fixed, if counter was reset to 1
397
 
398
        else
399
 
400
        if curr_slot_own_in = '1'
401
          or (next_slot_starts_in = '1' and next_slot_own_in = '1') then
402
          send_counter_r <= (others => '0');
403
        else
404
          send_counter_r <= send_counter_r +1;
405
        end if;  -- curr_slot_own_in
406
      end if;  -- Curr_State
407
    end if;  -- rst_n/clk'event
408
  end process Count_Sent_Items;
409
 
410
 
411
 
412
 
413
 
414
  -- 5) SEQ PROC
415
  Define_output : process (clk, rst_n)
416
    variable lock_v : std_logic;
417
  begin  -- process Define_output
418
 
419
    if rst_n = '0' then
420
      lock_out     <= '0';
421
      addr_valid_r <= '0';
422
      comm_out     <= (others => '0');
423
      data_out     <= (others => '0');
424
 
425
      data1_r       <= (others => rst_value_arr (dbg_level* 1));
426
      data2_r       <= (others => rst_value_arr (dbg_level* 1));
427
      comm_d1_r     <= (others => rst_value_arr (dbg_level* 1));
428
      comm_d2_r     <= (others => rst_value_arr (dbg_level* 1));
429
      addr1_r       <= (others => rst_value_arr (dbg_level* 1));
430
      addr2_r       <= (others => rst_value_arr (dbg_level* 1));
431
      comm_a1_r     <= (others => rst_value_arr (dbg_level* 1));
432
      comm_a2_r     <= (others => rst_value_arr (dbg_level* 1));
433
      addr2_valid_r <= '0';
434
 
435
      fifo_re_r           <= '0';
436
      cfg_read_complete_r <= '1';
437
      cfg_read_value_r    <= (others => rst_value_arr (dbg_level* 1));
438
      cfg_ret_addr_r      <= (others => rst_value_arr (dbg_level* 1));
439
 
440
      retx_amount_r <= 0;
441
      curr_state_r  <= Idle;
442
 
443
    elsif clk'event and clk = '1' then
444
      -- checks that the command is being fed with data.
445
      assert (empty_in = '1' or (empty_in = '0' and comm_in /= "000")) report "Comm warning! idle from FIFO" severity error;
446
 
447
 
448
      -- default value, just in case..
449
      lock_v := '0';
450
 
451
      -- Control the configuration registers
452
      -- Read conf value from conf mem to register
453
 
454
      if cfg_re_g = 1
455
        and cfg_re_in = '1' then
456
 
457
        cfg_ret_addr_r      <= cfg_ret_addr_in;
458
        cfg_read_value_r    <= cfg_data_in;
459
        cfg_read_complete_r <= '0';
460
      else
461
 
462
        if curr_state_r = Cfg_D_Last
463
          or curr_state_r = Cfg_D then
464
 
465
          if full_in = '0' then
466
            -- Answering to conf read succeeded
467
            cfg_read_complete_r <= '1';
468
          else
469
            -- Answering did not succeed
470
            cfg_read_complete_r <= '0';
471
 
472
            assert dbg_level < 2 report "Conf (Last) D : Ei onnistunut" severity note;
473
 
474
          end if;
475
        end if;
476
      end if;
477
 
478
 
479
 
480
 
481
      -- Control other registers
482
      -- Register values are updated when state changes
483
      -- (i.e. the assigment clause is in the previous state in the code)
484
      -- => e.g. addr is written when moving idle->Retransfer_Addr
485
      -- => when state=Retransfer_Addr :
486
      --    *  bus=addr and data_out_reg <= next data
487
      case curr_state_r is
488
 
489
 
490
 
491
        --++++++++++++++        
492
        when Idle =>
493
 
494
 
495
          -- (0a Something to transmit, own turn not ending
496
          --  0b Nothing to do)
497
 
498
          -- 1) Own time slot starts
499
          -- 2) Competition 
500
          --    2a) Re_transmit
501
          --    2b) Answer conf read
502
          --    2c) New addr+data
503
          --    2d) New addr but no data, stop. Remove this branch?
504
          --    2e) New data, use old addr
505
          --    2f) Illegal?
506
          -- 3) Not own turn
507
          --
508
 
509
          if own_turn_ends = '0'
510
            and (empty_in = '0'
511
                 or (cfg_re_g = 1 and cfg_read_complete_r = '0')
512
                 or retx_amount_r /= 0) then
513
            -- 0a)
514
 
515
            if next_slot_own_in = '1' and next_slot_starts_in = '1' then
516
              -- 1) Own time slot starts
517
              lock_v       := '1';
518
              addr_valid_r <= '0';
519
              addr_valid_r <= '0';
520
              data_out     <= (others => '0');
521
              comm_out     <= (others => '0');
522
 
523
              assert false report "????????????????????????????????????????" severity warning;
524
              assert false report "tx_ctrl/idle: Suspicious if-elsif branch (own slot starts)" severity warning;
525
 
526
              if (fifo_re_r = '0'
527
                  and retx_amount_r = 0
528
                  and empty_in = '0' and av_in = '1' and one_d_in = '1') then
529
                fifo_re_r    <= '1';            -- 02.06.06 es
530
                addr1_r      <= data_in (addr_width_g -1 downto 0);  -- 02.06.06 es
531
                comm_a1_r    <= comm_in;        -- 02.06.06 es
532
                curr_state_r <= idle;           -- 05.06.2006
533
                assert dbg_level < 1 report "idle : oma aikaslotti alkaa, mutta vain 1 osoite fifossa" severity note;
534
 
535
              elsif (fifo_re_r = '0'
536
                     and retx_amount_r = 0
537
                     and empty_in = '0' and av_in = '1' and one_d_in = '0') then
538
                -- 05.06.06 es
539
                fifo_re_r    <= '1';
540
                addr1_r      <= data_in (addr_width_g -1 downto 0);
541
                comm_a1_r    <= comm_in;
542
                curr_state_r <= Own_Slot_Reservation;
543
                assert dbg_level < 1 report "idle : oma aikaslotti alkaa, 05.06.2006 Brand new!" severity note;
544
 
545
              else
546
                fifo_re_r    <= '0';
547
                assert dbg_level < 1 report "idle : oma aikaslotti alkaa +re = 0" severity note;
548
                curr_state_r <= Own_Slot_Reservation;
549
              end if;
550
 
551
              -- Why did we read out the address? it wasn't even stored anywhere.
552
              -- It seems that address needs to be read in some cases, but in some
553
              -- it must not be! The bug can be seen in the tx control testbench.
554
              -- However, simply setting fifo_re_r <= '0'; doesn't solve the problems;
555
              -- it causes more.
556
              -- Bug was discovered with video system, where (erratically) n_time_slots
557
              -- was one although timeslots are not used.
558
              -- 13.7.05 AK
559
              assert false report "????????????????????????????????????????" severity warning;
560
 
561
 
562
            elsif (next_slot_starts_in = '0' and prior_match = '1'
563
              and (lock_in = '0')) or (keep_slot_g = 1 and curr_slot_own_in = '1')
564
            then
565
              -- 2) Competition
566
              -- Note: Order. 1) retx, 2) cfg and so on
567
 
568
              -- Note! 21.01.2003
569
              -- Comparison (lock_in = '1' and full_in = '1') caused
570
              -- problems, when receiver asserts full=1 during addr phase.
571
              -- (Receiver _should_ assert target_full only during data phase but
572
              -- you never know)
573
              -- Then trasmitter puts data on the bus but the next wrapper may
574
              -- put its own addr on the at same time => conflict
575
 
576
              assert dbg_level < 3 report "Kilpailuvuoro" severity note;
577
 
578
 
579
 
580
              if retx_amount_r /= 0 then
581
                -- 2a) Receiver got full last time
582
                curr_state_r                       <= Retransfer_Addr;
583
                addr_valid_r                       <= '1';
584
                data_out                           <= (others => '0');  -- 01.03.05
585
                data_out (addr_width_g-1 downto 0) <= addr1_r;  -- 01.03.05
586
                comm_out                           <= comm_a1_r;
587
                lock_v                             := '1';
588
                fifo_re_r                          <= '0';
589
 
590
                assert dbg_level < 3 report "Idle : uusiolahetys" severity note;
591
 
592
 
593
 
594
                -- 25.01.05 elsif cfg_read_complete_r = '0' then
595
              elsif cfg_re_g = 1 and cfg_read_complete_r = '0' then
596
                -- 2b) Conf read has not been yet answered
597
                -- Answered conf values don't have to be stored in addr_reg/data_reg
598
                curr_state_r                       <= Cfg_A;
599
                addr_valid_r                       <= '1';
600
                data_out                           <= (others => '0');  -- 01.03.05
601
                data_out (addr_width_g-1 downto 0) <= cfg_ret_addr_r;  -- 01.03.05
602
                comm_out                           <= write_command_c;  -- 03.02.05
603
                lock_v                             := '1';
604
                fifo_re_r                          <= '0';
605
 
606
                assert dbg_level < 3 report "idle : vastataan konf. lukuun" severity note;
607
 
608
 
609
--              elsif (empty_in = '0' and av_in = '1' and one_d_in = '0') then
610
                -- 2c) New addr and data
611
 
612
--                assert dbg_level < 3 report "idle : uusi osoite" severity note;
613
 
614
                -- Take the safe way, stay in idle until addr is read from the
615
                -- fifo 17.03.03
616
--                curr_state_r <= Idle;
617
--                addr_valid_r <= '0';
618
--                data_out     <= (others => '0');
619
--                comm_out     <= (others => '0');
620
--                lock_v       := '0';
621
 
622
--                fifo_re_r    <= '0';
623
 
624
                -- AK 12.05.05
625
              elsif (empty_in = '0' and av_in = '1') then -- and one_d_in = '1') then
626
                -- 2d) Only new addr but no data
627
                curr_state_r <= Idle;
628
                addr_valid_r <= '0';
629
                comm_out     <= (others => '0');
630
                data_out     <= (others => '0');
631
                lock_v       := '0';
632
 
633
                -- 13.05.2005 ES
634
                if fifo_re_r = '0' then
635
                  addr1_r   <= data_in (addr_width_g -1 downto 0);  -- 03.02.05
636
                  comm_a1_r <= comm_in;
637
                  fifo_re_r <= '1';
638
                else
639
                  fifo_re_r <= '0';
640
                end if;
641
 
642
 
643
 
644
                assert dbg_level < 3 report "idle : pelkastaan uusi osoite (ei laheteta)" severity note;
645
 
646
 
647
              elsif (empty_in = '0' and av_in = '0') then
648
                -- 2e) Data coming from fifo
649
                -- Transfer previous addr again
650
                curr_state_r                       <= Retransfer_Addr;
651
                addr_valid_r                       <= '1';
652
                data_out                           <= (others => '0');  -- 01.03.05
653
                data_out (addr_width_g-1 downto 0) <= addr1_r;  -- 01.03.05
654
                comm_out                           <= comm_a1_r;
655
                lock_v                             := '1';
656
                fifo_re_r                          <= '1';
657
                assert dbg_level < 3 report "idle : ed data jatkuu" severity note;
658
 
659
 
660
              else
661
                -- 2f) Illegal (?) branch
662
                curr_state_r <= Error_State;
663
                -- 22.07 Actually this branch may be reached if fifo has one addr
664
                -- but no data
665
                addr_valid_r <= '0';
666
                data_out     <= (others => '0');
667
                comm_out     <= (others => '0');
668
                lock_v       := '0';
669
 
670
                assert false report "Idle => Error_state" severity error;
671
                assert av_in = '1' report "AV on 0" severity note;
672
                assert av_in = '0' report "AV on 1" severity note;
673
                assert empty_in = '1' report "empty_in on 0" severity note;
674
                assert empty_in = '0' report "empty_in on 1" severity note;
675
                assert one_d_in = '1' report "one_d_in on 0" severity note;
676
                assert one_d_in = '0' report "one_d_in on 1" severity note;
677
 
678
 
679
              end if;  -- re_tx_amount
680
 
681
            else
682
              -- 3) Not own turn
683
              curr_state_r <= Idle;
684
              addr_valid_r <= '0';
685
              data_out     <= (others => '0');
686
              comm_out     <= (others => '0');
687
              lock_v       := '0';
688
              assert dbg_level < 3 report "Idle : Odotetaan omaa vuoroa" severity note;
689
 
690
 
691
              -- Read addr already before own turn  19.07 es
692
              -- Keep RE=1 only for one cycle
693
              -- Assure that addr_reg is not reserved, i.e. retransfer is completed
694
              if empty_in = '0'
695
                and retx_amount_r = 0   -- 04.03.04
696
                and av_in = '1'
697
                and fifo_re_r = '0' then
698
 
699
                assert dbg_level < 3 report "Idle : luetaan datafifosta osoite valmiiksi" severity note;
700
 
701
 
702
                fifo_re_r <= '1';
703
                addr1_r   <= data_in (addr_width_g-1 downto 0);  -- 03.02.05
704
                comm_a1_r <= comm_in;
705
              else
706
                fifo_re_r <= '0';
707
              end if;
708
            end if;  --next_slot_own_in etc.
709
 
710
 
711
          else
712
            -- 0b) Nothing to do :
713
            -- * target did not get on previous transfer
714
            -- * conf read has been answered
715
            -- * no data to send
716
            -- * not possible to start on turn (e.g. send_max = 0)
717
 
718
            curr_state_r <= Idle;
719
            addr_valid_r <= '0';
720
            comm_out     <= (others => '0');
721
            data_out     <= (others => '0');
722
            fifo_re_r    <= '0';
723
            lock_v       := '0';
724
 
725
            assert dbg_level < 3 report "Ei ole mitaan sanottavaa kenellekaan" severity note;
726
 
727
          end if;  --own_turn & (empty_in or Cfg_Read or Re_tx_Amount)
728
 
729
 
730
 
731
 
732
 
733
          --++++++++++++++
734
        when Own_Slot_Reservation =>
735
          -- Always move forward from this state. This state lasts only for one cycle
736
          -- By default, reserve bus and write addr
737
          lock_v       := '1';
738
          addr_valid_r <= '1';
739
 
740
          -- Note: Order
741
          -- 0. Own turn ends before it starts. Aargh.
742
          -- 1. retransfer
743
          -- 2. answering conf read
744
          -- 3. data
745
          --  3a) New addr and data
746
          --  3b) New data, use old addr
747
          -- 4) 
748
 
749
          if own_turn_ends = '1' then
750
            -- 0) Own turn ends before it starts. Aargh.
751
            curr_state_r <= Idle;
752
            addr_valid_r <= '0';
753
            data_out     <= (others => '0');
754
            comm_out     <= (others => '0');
755
            lock_v       := '0';
756
            fifo_re_r    <= '0';
757
 
758
            assert dbg_level < 1 report "Own slot : VUORO LOPPUU ENNEN KUIN ALKAAKAAN!" severity note;
759
 
760
          elsif retx_amount_r /= 0 then
761
            -- 1) Receiver got full on previous transfer, try again
762
            curr_state_r                       <= Retransfer_Addr;
763
            data_out                           <= (others => '0');  -- 01.03.05
764
            data_out (addr_width_g-1 downto 0) <= addr1_r;          -- 01.03.05
765
            comm_out                           <= comm_a1_r;
766
            fifo_re_r                          <= '0';
767
            assert dbg_level < 3 report "Own slot : uusiolahetys" severity note;
768
 
769
 
770
          elsif cfg_re_g = 1 and cfg_read_complete_r = '0' then
771
            -- 2) Not yet answered to conf read 
772
            curr_state_r                       <= Cfg_A;
773
            data_out                           <= (others => '0');  -- 01.03.05
774
            data_out (addr_width_g-1 downto 0) <= cfg_ret_addr_r;   -- 01.03.05
775
            comm_out                           <= write_command_c;  -- 03.02.05 
776
            fifo_re_r                          <= '0';
777
            assert dbg_level < 3 report "Own slot : conf return addr" severity note;
778
 
779
          elsif (empty_in = '0' and av_in = '1' and one_d_in = '0') then
780
            -- 3a) New addr and data
781
            curr_state_r <= Write_Data;
782
            data_out     <= data_in;
783
            comm_out     <= comm_in;
784
            addr1_r      <= data_in(addr_width_g-1 downto 0);  -- 17.02
785
            comm_a1_r    <= comm_in;
786
            fifo_re_r    <= '1';
787
 
788
            assert dbg_level < 1 report "Own slot : uusi osoite+dataa." severity note;
789
 
790
 
791
          elsif av_in = '0' and empty_in = '0' then
792
            -- 3b) New data, use old addr
793
            curr_state_r                       <= Retransfer_Addr;
794
            data_out                           <= (others => '0');  -- 01.03.05
795
            data_out (addr_width_g-1 downto 0) <= addr1_r;          -- 01.03.05
796
            comm_out                           <= comm_a1_r;
797
            fifo_re_r                          <= '1';
798
 
799
            assert dbg_level < 1 report "Own slot : Ed data jatkuu" severity note;
800
 
801
 
802
          else
803
            -- 4) Illegal branch
804
            assert false report "Own slot => Error_state" severity error;
805
 
806
 
807
            curr_state_r <= Error_State;
808
            addr_valid_r <= '0';
809
            data_out     <= (others => '0');
810
            comm_out     <= (others => '0');
811
            lock_v       := '0';
812
            fifo_re_r    <= '0';
813
          end if;  --retx_amount_r /= 0
814
 
815
 
816
 
817
          --++++++++++++++
818
 
819
        when Cfg_A =>
820
          -- Return addr of conf read already transferred, write conf value now
821
          -- It is not possible to have Target_Full=1, is it?
822
          -- HUOM! 25.11.04 TK: ainakin mina sain alla olevan tulostuksen
823
          -- tb_tx_rx -testipenkilla aikaiseksi... 
824
 
825
          if cfg_re_g = 1 then
826
            -- if added 25.01.05
827
 
828
            assert not(dbg_level > 0 and full_in = '1') report "tx_ctrl:cfg_a TargetFull=1 unexpectedly" severity warning;
829
 
830
 
831
            if own_turn_ends = '1' or empty_in = '1' then
832
              curr_state_r <= Cfg_D_Last;
833
              lock_v       := '0';
834
              assert dbg_level < 3 report "Conf A : Lopetellaan, (seur Last Conf D)" severity note;
835
            else
836
              curr_state_r <= Cfg_D;
837
              lock_v       := '1';
838
              assert dbg_level < 3 report "Conf A : Jatketaan, (seur Conf D)" severity note;
839
            end if;
840
 
841
            --!!!!!!!!!
842
            -- 19.12.2005
843
            -- Data_out comes from cfg_mem
844
            --!!!!!!!!!
845
 
846
 
847
            addr_valid_r <= '0';
848
            data_out     <= cfg_read_value_r;  -- 19.12.2005 
849
            comm_out     <= write_command_c;
850
            fifo_re_r    <= '0';
851
 
852
            if (empty_in = '0' and av_in = '1') then  -- and one_d_in = '0') then
853
              fifo_re_r <= '1';
854
              addr1_r   <= data_in (addr_width_g -1 downto 0);
855
              comm_a1_r <= comm_in;
856
            else
857
              fifo_re_r <= '0';
858
            end if;
859
            -- else not needed ?            
860
          end if;  --cfg_re_g = 1
861
          --++++++++++++++
862
 
863
 
864
        when Cfg_D =>
865
          -- Conf read answered
866
          -- 1) Not success
867
          -- 2) Success but own turn ends
868
          -- 3) Success + own turn continues
869
          --  3a) New addr+data
870
          --  3b) Only new addr, no data, This added 03.08.2004
871
          --  3c) New data (use old addr)
872
          -- 4)
873
 
874
          if cfg_re_g = 1 then
875
            -- if added 25.01.05
876
 
877
 
878
            if full_in = '1' then
879
              -- 1) Answering to conf read did not succeed because receiver got full
880
              -- Config registers are controlled outside of "switch Curr_State"
881
              -- so nothing has to be done here
882
              curr_state_r <= Idle;
883
              lock_v       := '0';
884
              addr_valid_r <= '0';
885
              data_out     <= (others => '0');
886
              comm_out     <= (others => '0');
887
              fifo_re_r    <= '0';
888
              assert dbg_level < 3 report "Conf D : Lopetellaan koska kohde taysi, (seur idle)" severity note;
889
 
890
 
891
            elsif own_turn_ends = '1' then
892
              -- 2) Cannot continue transferring data after conf value
893
              curr_state_r <= Idle;
894
              lock_v       := '0';
895
              addr_valid_r <= '0';
896
              data_out     <= (others => '0');
897
              comm_out     <= (others => '0');
898
              fifo_re_r    <= '0';
899
              assert dbg_level < 3 report "Conf D : Oma vuoro loppuu, (seur idle)" severity note;
900
 
901
            else
902
              -- 3) Answering conf read succeeded and own turn continues
903
 
904
 
905
              -- If-structure totally new 03.08.2004
906
              if empty_in = '0' then
907
                if av_in = '1' then
908
                  -- New addr
909
                  if one_d_in = '0' then
910
                    -- 3a) Also new data                  
911
                    curr_state_r <= Write_Data;
912
                    addr_valid_r <= '1';
913
                    data_out     <= data_in;
914
                    comm_out     <= comm_in;
915
                    lock_v       := '1';
916
                    addr1_r      <= data_in (addr_width_g -1 downto 0);
917
                    comm_a1_r    <= comm_in;
918
                    fifo_re_r    <= '1';
919
                    assert dbg_level < 1 report "Conf D   : Valmis. Seur uuden datan osoite" severity note;
920
                    assert dbg_level < 2 report "31.03.03 : Tuleeko osoite yhden kerran vai kahdesti vaylalle??" severity note;
921
 
922
                  else
923
                    -- 3b) Addr only, stop tx                  
924
                    curr_state_r <= Idle;
925
                    addr_valid_r <= '0';
926
                    data_out     <= (others => '0');
927
                    comm_out     <= (others => '0');
928
                    lock_v       := '0';
929
                    fifo_re_r    <= '0';
930
                  end if;  -- one_d
931
 
932
                else
933
                  -- 3c) New data, use old addr
934
                  -- i.e. empty=0 and av=0 
935
                  curr_state_r                       <= Retransfer_Addr;
936
                  addr_valid_r                       <= '1';
937
                  data_out                           <= (others => '0');  -- 01.03.05
938
                  data_out (addr_width_g-1 downto 0) <= addr1_r;  -- 01.03.05
939
                  comm_out                           <= comm_a1_r;
940
                  lock_v                             := '1';
941
                  fifo_re_r                          <= '1';
942
                  assert dbg_level < 3 report "Conf D                : Valmis. Ed datan osoite uudestaan" severity note;
943
                  assert dbg_level < 0 report "Conf D - > retx_a     : re = 1. Correct? " severity note;
944
                  assert retx_amount_r < 1 report "Conf D - > retx_a : retx_amount_r > 0 " severity note;
945
 
946
 
947
                end if;  -- av
948
 
949
              else
950
                -- 4) No data, stop tx
951
                curr_state_r <= Idle;
952
                addr_valid_r <= '0';
953
                data_out     <= (others => '0');
954
                comm_out     <= (others => '0');
955
                lock_v       := '0';
956
                fifo_re_r    <= '0';
957
              end if;  -- empty
958
            end if;  -- target_Fifo_Full
959
          end if;  -- cfg_re_g=1?           
960
 
961
 
962
 
963
          --++++++++++++++
964
        when Cfg_D_Last =>
965
          -- Last cycle of own turn.
966
          -- Checking whether the conf read answer succeeded is
967
          -- done elsewhere
968
 
969
          if cfg_re_g = 1 then
970
 
971
 
972
            curr_state_r <= Idle;
973
            addr_valid_r <= '0';
974
            data_out     <= (others => '0');
975
            comm_out     <= (others => '0');
976
            lock_v       := '0';
977
            addr1_r      <= addr1_r;
978
            comm_a1_r    <= comm_a1_r;
979
            fifo_re_r    <= '0';
980
          end if;  -- cfg_re_g=1?           
981
 
982
 
983
 
984
 
985
          --++++++++++++++
986
        when Retransfer_Addr =>
987
          -- At the moment, retransferred addr is on the bus
988
          -- write data now
989
 
990
          -- 1) Addr retransferrred, next data comes from fifo
991
          --    1a) Own turn ends, write one data
992
          --    1b) Own turn continues
993
          --        1ba) Only data in fifo
994
          --        1bb) ??? 
995
          -- 2) At least 1 data must be retransferred
996
          --    2a) Own turn ends, write r1 and stop
997
          --    2b) Own turn continues, write r1
998
 
999
          addr_valid_r <= '0';
1000
 
1001
          -- Check for full=1 added 03.01.2005, ES
1002
          -- This probably caused the Stratix problem with 2*Nios+Sdram
1003
          if full_in = '1' then
1004
 
1005
            curr_state_r <= Idle;
1006
            data_out     <= (others => '0');
1007
            comm_out     <= (others => '0');
1008
            lock_v       := '0';
1009
            fifo_re_r    <= '0';
1010
 
1011
            if fifo_re_r = '1' then
1012
              -- better condition would be retx_amount_r /= 0, perhaps, 28.02.2006
1013
              retx_amount_r <= 1;
1014
              data1_r       <= data_in;
1015
              comm_d1_r     <= comm_in;
1016
            end if;  -- fifo_re_r
1017
 
1018
 
1019
 
1020
 
1021
          else
1022
            -- code inside thi else-branch is the original code (before 03.01.2005)
1023
 
1024
            if retx_amount_r = 0 then
1025
              -- 1) No data has to be retransferred, next data comes from fifo
1026
              retx_amount_r <= 0;
1027
              addr_valid_r  <= '0';
1028
 
1029
              if own_turn_ends = '1' then
1030
                -- 1a) Own turn ends, write one data and then stop
1031
                curr_state_r <= Write_Last_Data;
1032
                data_out     <= data_in;
1033
                comm_out     <= comm_in;
1034
                lock_v       := '0';
1035
                fifo_re_r    <= '0';
1036
                assert dbg_level < 3 report "re tx A : 1 data ja lopetetaan" severity note;
1037
 
1038
                data2_r   <= data_in;
1039
                comm_d2_r <= comm_in;
1040
 
1041
              else
1042
                -- 1b) Own turn continues
1043
                data_out  <= data_in;
1044
                comm_out  <= comm_in;
1045
                data2_r   <= data_in;
1046
                comm_d2_r <= comm_in;
1047
                assert dbg_level < 3 report "re tx A : Jatketaan datalla" severity note;
1048
 
1049
                if one_d_in = '1' and av_in = '0' then
1050
                  -- 1ba) One data left in the fifo, write that and stop
1051
                  curr_state_r <= Write_Last_Data;
1052
                  lock_v       := '0';
1053
                  fifo_re_r    <= '0';  --'1' 31.03.03
1054
 
1055
                  assert dbg_level < 3 report "ReTx_A => Write_last_Data, re <= 0" severity note;
1056
 
1057
 
1058
                else
1059
                  -- 1bb) More than one data (or data+addr etc) in fifo
1060
                  curr_state_r <= Write_Data;
1061
                  lock_v       := '1';
1062
                  fifo_re_r    <= '1';
1063
 
1064
                  assert empty_in = '0' report "ReTx_A : fifossa ei lahetettavaa! APUVA" severity error;
1065
                end if;  -- end 1_d && av
1066
 
1067
              end if;  --own_turn_ends =1
1068
 
1069
            else
1070
              -- 2) At the moment retx_amount_r /= 0
1071
              -- Has to transfer at least one data again
1072
              -- retx_amount_r = 1 or 2
1073
 
1074
              -- send data from reg1 first
1075
              addr_valid_r <= '0';
1076
              data_out     <= data1_r;
1077
              comm_out     <= comm_d1_r;
1078
              fifo_re_r    <= '0';
1079
 
1080
              -- 'Decrement' retx_amount_r
1081
              if retx_amount_r = 1 then
1082
                retx_amount_r <= 0;
1083
              else
1084
                retx_amount_r <= 1;
1085
              end if;
1086
 
1087
 
1088
              if own_turn_ends = '1' then
1089
                -- 2a) Write one data and stop
1090
                curr_state_r <= Retransfer_Data_Last;
1091
                lock_v       := '0';
1092
                assert dbg_level < 3 report "re tx A => re tx D last" severity note;
1093
              else
1094
                -- 2b) Own turn continues
1095
                curr_state_r <= Retransfer_Data;
1096
                lock_v       := '1';
1097
                assert dbg_level < 3 report "re tx A => re tx D" severity note;
1098
              end if;
1099
 
1100
            end if;  --retx_amount_r
1101
 
1102
 
1103
 
1104
          end if;
1105
 
1106
 
1107
          -- State Retransfer_Addr ends ------------------------------------
1108
 
1109
 
1110
 
1111
 
1112
 
1113
          --++++++++++++++
1114
        when Retransfer_Data =>
1115
          -- At the moment, bus data equals to
1116
          --  * reg1, if prev state was ReTx_Addr
1117
          --  * reg2, if prev state was ReTx_Data
1118
 
1119
          -- If writing succeeded, then
1120
          -- max. 1 data (=reg2) has to be retransferred
1121
 
1122
 
1123
          -- 1) target_Full
1124
          -- 2) target not full
1125
          --   2a) Own turn ends
1126
          --       2aa) Retransfer complete, end turn
1127
          --       2ab) Still r2 to retransfer and then end turn
1128
          --   2b) Own turn continues
1129
          --       2ba) Retransfer complete
1130
          --            2baa) Answer cfg read
1131
          --            2bab) Safe way: go to idle
1132
          --       2bb) Retransfer r2    
1133
 
1134
          if full_in = '1' then
1135
            -- 2) Retransfer did not succeed
1136
            curr_state_r <= Idle;
1137
            addr_valid_r <= '0';
1138
            data_out     <= (others => '0');
1139
            comm_out     <= (others => '0');
1140
            lock_v       := '0';
1141
            fifo_re_r    <= '0';
1142
 
1143
            -- 'increment' retx_amount_r back to previous value
1144
            -- No other action is needed, because re_transfer registers
1145
            -- keep their values
1146
            if retx_amount_r = 1 then
1147
              retx_amount_r <= 2;
1148
              assert dbg_level < 2 report "ReTxD : Target full. Retransmit 2" severity note;
1149
            else
1150
              retx_amount_r <= 1;
1151
              assert dbg_level < 2 report "ReTxD : Target full. Retransmit 1" severity note;
1152
            end if;
1153
 
1154
 
1155
          else
1156
            -- Retransfer success
1157
            -- => data2_r has be retransferred if anything
1158
            retx_amount_r <= 0;
1159
 
1160
            if own_turn_ends = '1' then
1161
              -- 2a) Retransfer succes but cannot continue
1162
              lock_v := '0';
1163
 
1164
              if retx_amount_r = 0 then
1165
                -- 2aa) Data currently on the bus was the last one to retransfer
1166
                -- Cannot do anything because own turn ends
1167
                curr_state_r <= Idle;
1168
                addr_valid_r <= '0';
1169
                data_out     <= (others => '0');
1170
                comm_out     <= (others => '0');
1171
 
1172
                assert dbg_level < 3 report "ReTxD =>  idle: Turn ends" severity note;
1173
 
1174
 
1175
                -- 04.03.04             --------------------------------------------------
1176
                if addr2_valid_r = '1' then
1177
                  -- Take addr from extrapextra register into use
1178
                  addr1_r       <= addr2_r;
1179
                  comm_a1_r     <= comm_a2_r;
1180
                  addr2_valid_r <= '0';
1181
                end if;
1182
                -- 04.03.04 ends        ----------------------------------------------
1183
 
1184
              else
1185
                -- 2ab) Still data2_r to retransfer and after that own turn is ends
1186
                curr_state_r <= Retransfer_Data_Last;
1187
                addr_valid_r <= '0';
1188
                data_out     <= data2_r;
1189
                comm_out     <= comm_d2_r;
1190
                data1_r      <= data2_r;
1191
                comm_d1_r    <= comm_d2_r;
1192
 
1193
 
1194
                assert dbg_level < 3 report "ReTxD => ReTx_D_Last : Turn ends" severity note;
1195
 
1196
              end if;  --retx_amount_r
1197
 
1198
 
1199
            else
1200
              -- 2b) This else branch Belongs to "if own_turn_ends = '1'"
1201
              -- Retransfer success and own turn continues
1202
 
1203
              if retx_amount_r = 0 then
1204
                -- 2ba) Data currently on the bus was the last one to retransfer
1205
 
1206
                -- Orig     : Select next state: either Write_D or Conf_A
1207
                -- 07.01.03 : Always go to idle because it simplifies things.
1208
                --            Performance loss is considered negligible (es) 
1209
 
1210
 
1211
                -- 04.03.04             ---------------------------------------------------
1212
                if addr2_valid_r = '1' then
1213
                  -- Take addr from extrapextra register into use
1214
                  addr1_r       <= addr2_r;
1215
                  comm_a1_r     <= comm_a2_r;
1216
                  addr2_valid_r <= '0';
1217
                end if;
1218
 
1219
                -- 04.03.04 ends        ----------------------------------------------
1220
 
1221
 
1222
                -- 25.01.05 if cfg_read_complete_r = '0' then
1223
                if cfg_re_g = 1 and cfg_read_complete_r = '0' then
1224
                  -- 2baa) Nothing to retransfer, but conf read is not yet answered
1225
 
1226
                  -- 07.01.03 Take the safe way, go to Idle
1227
                  curr_state_r <= Idle;
1228
                  lock_v       := '0';
1229
                  fifo_re_r    <= '0';
1230
                  addr_valid_r <= '0';
1231
                  data_out     <= (others => '0');
1232
                  comm_out     <= (others => '0');
1233
 
1234
                  assert dbg_level < 3 report "ReTxD =>  (Conf_Read_A) _idle_" severity note;
1235
 
1236
 
1237
                else
1238
                  -- 2bab) nothing to retransfer and conf read is answered
1239
 
1240
                  -- 07.01.03  Take the safe way, go to Idle
1241
                  curr_state_r <= Idle;
1242
                  lock_v       := '0';
1243
                  data_out     <= (others => '0');
1244
                  comm_out     <= (others => '0');
1245
                  fifo_re_r    <= '0';
1246
 
1247
                  assert dbg_level < 3 report "ReTxD => (write) _idle_" severity note;
1248
 
1249
                end if;  -- cfg_read_complete_r
1250
 
1251
              else
1252
                -- 2bb) Else branch to "if retx_amount_r = 0 then"
1253
                -- means that retx_amount_r > 0
1254
                -- => data2_r has to be retransferred
1255
                -- 31.03.03
1256
                curr_state_r <= Retransfer_Data;  --keep this state for one more cycle
1257
                addr_valid_r <= '0';
1258
                data_out     <= data2_r;
1259
                comm_out     <= comm_d2_r;
1260
                lock_v       := '1';
1261
 
1262
                data1_r   <= data2_r;
1263
                comm_d1_r <= comm_d2_r;
1264
                fifo_re_r <= '0';       -- vaihdettu 07.01.03 oli '1';
1265
 
1266
                assert dbg_level < 3 report "ReTxD => ReTx_D, write reg2 to bus" severity note;
1267
 
1268
 
1269
              end if;  -- retx_amount_r = 0
1270
            end if;  -- own_turn_ends
1271
          end if;  -- full_in
1272
          -- State Retransfer_Data ends --------------------------------------
1273
 
1274
 
1275
 
1276
 
1277
          --++++++++++++++
1278
        when Retransfer_Data_Last =>
1279
          -- Last cycle of own turn
1280
          -- Currently, bus data = retransferred data
1281
          --  a) data1_r, (amount=1)
1282
          --  b) data2_r, (amount=0)
1283
 
1284
          curr_state_r <= Idle;
1285
          addr_valid_r <= '0';
1286
          data_out     <= (others => '0');
1287
          comm_out     <= (others => '0');
1288
          lock_v       := '0';
1289
 
1290
          -- Check if the receiver accepted data
1291
          if full_in = '1' then
1292
            -- 'increment' retx_amount_r back to prev values
1293
            -- No other action needed, because of separate retx registers
1294
            if retx_amount_r = 1 then
1295
              retx_amount_r <= 2;
1296
            else
1297
              retx_amount_r <= 1;
1298
            end if;
1299
 
1300
          else
1301
            -- Retransfer success
1302
 
1303
            -- data1_register succesfully transmitted,
1304
            -- still, value of data2 has to be retrasmitted later
1305
            data1_r   <= data2_r;
1306
            comm_d1_r <= comm_d2_r;
1307
 
1308
            -- Take addr from extrapextra register into use
1309
            -- NOTE: additional condition for amount
1310
            if addr2_valid_r = '1' and retx_amount_r = 0 then
1311
              addr1_r       <= addr2_r;
1312
              comm_a1_r     <= comm_a2_r;
1313
              addr2_valid_r <= '0';
1314
            end if;
1315
 
1316
 
1317
 
1318
          end if;
1319
          -- State Retransfer_Data_Last ends --------------------------------------
1320
 
1321
 
1322
 
1323
 
1324
 
1325
 
1326
 
1327
          --++++++++++++++  
1328
        when Write_Data =>
1329
          -- Regular data goes from fifo to output registers
1330
          -- At the same, the data is copied to register data2_r
1331
          -- At the same, time, previously sent data is copied from data2_r to data1_r
1332
          -- If target got full, the data that was on the bus can be returned
1333
          -- from reg1 and the next data taken away from fifo is in reg2.
1334
 
1335
          -- 1) Receiver got full
1336
          --    1a) tx was reading fifo
1337
          --        1aa) addr coming from fifo, re_tx 1 data
1338
          --        1ab) data coming from fifo, re_tx 2 data
1339
          --    1b) tx was not reading fifo, re_tx 1 data
1340
          --    
1341
          -- 2) Tx success but own turn ends
1342
          --    2a) One can be written, then stop tx
1343
          --    2b) New addr canot be written, stop tx
1344
          --    
1345
          -- 3) Tx success and own turn continues
1346
          --    3a) Finish regular write before conf
1347
          --    3b) Answer conf read
1348
          -- 4)
1349
          --    4a) New addr but no data, stop tx
1350
          --    4b) One data, write it and stop tx
1351
          --    4c) At least one data, continue
1352
          -- 
1353
 
1354
 
1355
          -- Default assignments
1356
          data1_r   <= data2_r;         -- equals to current bus data
1357
          comm_d1_r <= comm_d2_r;
1358
          data2_r   <= data_in;         -- equals to data on the bus on next cycle
1359
          comm_d2_r <= comm_in;
1360
 
1361
 
1362
 
1363
          if full_in = '1' then
1364
            -- 1) Receiver got full, stop
1365
            curr_state_r <= Idle;
1366
            lock_v       := '0';
1367
            addr_valid_r <= '0';
1368
            data_out     <= (others => '0');
1369
            comm_out     <= (others => '0');
1370
            fifo_re_r    <= '0';
1371
 
1372
            -- Transfer did not succeed
1373
            if fifo_re_r = '1' then
1374
              -- 1a) FSM was reading fifo
1375
              -- => has to retransfer data on the bus and the data that came
1376
              -- from fifo
1377
 
1378
              -- 04.03.04 contents 'if fifo_re_r = '1" changed
1379
              -- Originally addr and data from fifo were treated in a same
1380
              -- manner
1381
              -- Now if-else clause is added to make a distinction
1382
              -- Original behavior is now locates inside else-branch
1383
 
1384
              if av_in = '1' then
1385
                -- 1aa) New addr from fifo, that goes to addr_2r
1386
                retx_amount_r <= 1;
1387
                data1_r       <= data2_r;
1388
                comm_d1_r     <= comm_d2_r;
1389
                addr2_r       <= data_in (addr_width_g -1 downto 0);  -- 03.02.05;
1390
                comm_a2_r     <= comm_in;
1391
                addr2_valid_r <= '1';
1392
                assert dbg_level < 2 report "Write_D : target full, re = 1, av_f = 1, av_hibi = ?, retransmit 1" severity note;
1393
 
1394
              else
1395
                -- 1ab) New data from fifo
1396
 
1397
                -- 13.09.04 If clause added to check if addr is currently on the bus
1398
                if addr_valid_r = '0' then
1399
                  -- Data on the bus. 'normal' case
1400
                  retx_amount_r <= 2;
1401
                  data1_r       <= data2_r;
1402
                  comm_d1_r     <= comm_d2_r;
1403
                  data2_r       <= data_in;
1404
                  comm_d2_r     <= comm_in;
1405
                  assert dbg_level < 2 report "Write_D : target full, re = 1, av_f = ?, av_hibi = 0, retransmit 2" severity note;
1406
                else
1407
                  -- Addr on the bus
1408
                  retx_amount_r <= 1;
1409
                  data1_r       <= data_in;
1410
                  comm_d1_r     <= comm_in;
1411
                  assert dbg_level < 2 report "Write_D : target full, re = 1, av_f = ?, av_hibi = 1, retransmit 1" severity note;
1412
                end if;  --addr_valid_r
1413
 
1414
              end if;  -- av_from_fifo
1415
 
1416
 
1417
 
1418
            else
1419
              -- 1b) FSM was not reading fifo
1420
              -- => only one data (=data on the bus) has to retransferred
1421
              retx_amount_r <= 1;
1422
              assert dbg_level < 1 report "Write_D     : target full, retransmit 1. Correct??" severity note;
1423
              assert addr_valid_r = '0' report "WriteD : Propably not correct, av_hibi = 1 - > re_tx_amount should be 0" severity warning;
1424
 
1425
            end if;  -- fifo_re
1426
 
1427
 
1428
 
1429
          elsif own_turn_ends = '1' then
1430
            -- 2) Previous transfer success, but own turn ends
1431
            -- One data can still be written but no new addr
1432
 
1433
            curr_state_r <= Write_Last_Data;
1434
            addr_valid_r <= '0';
1435
            lock_v       := '0';
1436
            fifo_re_r    <= '0';
1437
            assert dbg_level < 3 report "Write : Oma vuoro loppuu" severity note;
1438
 
1439
            -- Siirretaan viim data. Jos fifossa osoite seur, ei siirreta mit'n
1440
            if av_in = '0' and empty_in = '0' then
1441
              -- 2a) Data from coming fifo => write it to bus
1442
              data_out <= data_in;
1443
              comm_out <= comm_in;
1444
            else
1445
              -- 2b) Addr coming from fifo => write nothing
1446
              data_out <= (others => '0');
1447
              comm_out <= (others => '0');
1448
            end if;
1449
 
1450
            --  Addr coming from fifo => store it into register
1451
            if empty_in = '0' and av_in = '1' then
1452
              addr1_r   <= data_in (addr_width_g -1 downto 0);  --03.02.05 
1453
              comm_a1_r <= comm_in;
1454
            end if;
1455
 
1456
 
1457
 
1458
          elsif cfg_re_g = 1 and cfg_read_complete_r = '0' then
1459
            -- 3) Own turn continues, answer conf read. Finish the reading of fifo first.
1460
 
1461
            if (fifo_re_r = '1' and av_in = '0' and empty_in = '0') then
1462
              -- 3a) FSM is reading fifo and data coming from fifo
1463
              -- Transfer that data before answering conf read
1464
              curr_state_r <= Write_Data;
1465
              addr_valid_r <= '0';
1466
              data_out     <= data_in;
1467
              comm_out     <= comm_in;
1468
              lock_v       := '1';
1469
              fifo_re_r    <= '0';
1470
              assert dbg_level < 3 report "Write : viim data ennen kuin => conf return addr" severity note;
1471
 
1472
            else
1473
              -- 3b) Answer conf read
1474
              curr_state_r                       <= Cfg_A;
1475
              addr_valid_r                       <= '1';
1476
              data_out                           <= (others => '0');  -- 01.03.05
1477
              data_out (addr_width_g-1 downto 0) <= cfg_ret_addr_r;  -- 01.03.05
1478
              -- data_out     <= a_ext (cfg_ret_addr_r, data_width_g);  --03.02.05cfg_ret_addr_r;
1479
              comm_out                           <= write_command_c;  -- 03.02.05 "010";
1480
              lock_v                             := '1';
1481
              fifo_re_r                          <= '0';
1482
 
1483
              -- Store addr
1484
              if empty_in = '0' and av_in = '1' then
1485
                addr1_r   <= data_in (addr_width_g-1 downto 0);  -- 03.02.05
1486
                comm_a1_r <= comm_in;
1487
              end if;
1488
 
1489
              assert dbg_level < 3 report "Write => conf return addr" severity note;
1490
            end if;  --(re=1&av=0) || (msg_Re=1&msg_av=0)
1491
 
1492
 
1493
 
1494
 
1495
 
1496
          else
1497
            -- 4) Retransfer ready
1498
            -- Answering conf read complete
1499
            -- Own turn continues
1500
            -- => Transfer data
1501
 
1502
            if empty_in = '0' and av_in = '1' and one_d_in = '1' then
1503
              -- 4a) Stop writing, because only one addr left but no data
1504
              curr_state_r <= Idle;
1505
              lock_v       := '0';
1506
              addr_valid_r <= '0';
1507
              data_out     <= (others => '0');
1508
              comm_out     <= (others => '0');
1509
              fifo_re_r    <= '0';
1510
              assert dbg_level < 3 report "Write (d) : Data loppu" severity note;
1511
              -- 13.05.05 AK The read address have to be stored here! if re = '1'
1512
              if fifo_re_r = '1' then
1513
                addr1_r   <= data_in (addr_width_g -1 downto 0);
1514
                comm_a1_r <= comm_in;  -- 25.02.2006 AK comm has to be stored also..
1515
              end if;
1516
 
1517
            elsif av_in = '0' and one_d_in = '1' then
1518
              -- 4b) One data left in the fifo, write it and stop
1519
              curr_state_r <= Write_Last_Data;
1520
              lock_v       := '0';
1521
              addr_valid_r <= '0';
1522
              data_out     <= data_in;
1523
              comm_out     <= comm_in;
1524
              fifo_re_r    <= '0';
1525
              assert dbg_level < 3 report "Write (d) : Data loppumassa. Viim data kirj" severity note;
1526
 
1527
 
1528
            else
1529
              -- 4c)Continue writing data
1530
              curr_state_r <= Write_Data;
1531
              lock_v       := '1';
1532
              data_out     <= data_in;
1533
              comm_out     <= comm_in;
1534
              fifo_re_r    <= '1';
1535
 
1536
              assert empty_in = '0' report "WriteD -> WriteD: empty_in=1. How can this continue?" severity warning;
1537
 
1538
              if empty_in = '0' and av_in = '1' then
1539
                -- New addr coming from fifo
1540
                -- Store it into addr_reg
1541
                addr1_r      <= data_in (addr_width_g -1 downto 0);  -- 03.02.05
1542
                comm_a1_r    <= comm_in;
1543
                addr_valid_r <= '1';
1544
              else
1545
                -- Data coming from fifo, addr_reg keeps its old value
1546
                addr_valid_r <= '0';
1547
              end if;
1548
            end if;  -- empty & av & one_d            
1549
 
1550
          end if;  -- full_in
1551
          -- State Write_Data ends here----------------------------------------
1552
 
1553
 
1554
 
1555
 
1556
 
1557
 
1558
 
1559
 
1560
 
1561
 
1562
 
1563
          --++++++++++++++
1564
        when Write_Last_Data =>
1565
          -- Last cycle of own turn
1566
          curr_state_r <= Idle;
1567
          data_out     <= (others => '0');
1568
          comm_out     <= (others => '0');
1569
          addr_valid_r <= '0';
1570
          lock_v       := '0';
1571
          fifo_re_r    <= '0';
1572
 
1573
 
1574
          if full_in = '0' then
1575
            -- Last tranfer succeeded, nothing has to be retransferred
1576
            retx_amount_r <= 0;
1577
 
1578
            assert dbg_level < 3 report "Write_D_Last : OK" severity note;
1579
          else
1580
            -- Last transfer did not succeed, have to try again on next turn
1581
            -- Re=0 when coming here => only one data has to be retransferred
1582
            retx_amount_r <= 1;         -- 17.01.03 oli 2;
1583
            data1_r       <= data2_r;
1584
            comm_d1_r     <= comm_d2_r;
1585
 
1586
            assert dbg_level < 2 report "Write_D_Last        : target full, retransmit 1" severity note;
1587
            assert fifo_re_r = '0' report "W_last_D : re should be 0" severity warning;
1588
          end if;
1589
 
1590
 
1591
          --++++++++++++++
1592
        when Error_State =>
1593
          assert false report "INVALid STATE IN TX_CONTROL" severity error;
1594
          curr_state_r <= Error_State;
1595
 
1596
 
1597
        when others =>
1598
          -- Do not write to bus
1599
          lock_v       := '0';
1600
          addr_valid_r <= '0';
1601
          comm_out     <= (others => '0');
1602
          data_out     <= (others => '0');
1603
          fifo_re_r    <= '0';
1604
 
1605
      end case;
1606
 
1607
      if keep_slot_g = 1 then
1608
        -- we keep the slot even if we have nothing to send
1609
        lock_out <= lock_v or (curr_slot_own_in and not curr_slot_ends_in) or next_slot_own_in;
1610
      else
1611
        lock_out <= lock_v;
1612
      end if;
1613
 
1614
 
1615
    end if;  --rst_n
1616
  end process Define_output;
1617
 
1618
 
1619
 
1620
  -- 5) PROC
1621
  Count_Priorities : process (clk, rst_n)
1622
  begin  -- process Count_Priorities
1623
    if rst_n = '0' then                 -- asynchronous reset (active low)
1624
      prior_counter_arb_r <= (others => '0');
1625
      switch_arb_r        <= 0;
1626
      arb_type_r          <= (others => '0');
1627
 
1628
    elsif clk'event and clk = '1' then  -- rising clock edge
1629
 
1630
      -- Assign internal arb_type-register according to ctrl-signal coming from cfg_mem
1631
      if arb_type_in = "00" then
1632
        -- round-robin
1633
        arb_type_r <= "00";
1634
 
1635
      elsif arb_type_in = "01" then
1636
        -- priority, actually 01
1637
        arb_type_r <= "01";
1638
 
1639
      elsif arb_type_in = "10" then
1640
        -- prior+roundrob, "10"
1641
        if switch_arb_r = switch_arb_c-1 then
1642
          switch_arb_r <= 0;
1643
          arb_type_r   <= "0" & not arb_type_r(0);  -- !!!! only when 2 types
1644
 
1645
          else
1646
            switch_arb_r <= switch_arb_r+1;
1647
          arb_type_r <= arb_type_r;
1648
        end if;
1649
 
1650
      else
1651
        arb_type_r <= "11";
1652
      end if;                           -- arb_type_in
1653
 
1654
 
1655
      -- Update priority_counter according to current arb_type
1656
      if lock_in = '0' and arb_type_r /= "11" then
1657
        -- Bus is idle
1658
 
1659
        if prior_counter_arb_r = n_agents_in (id_width_g-1 downto 0) then
1660
          -- Priorities start from 1 (zero is not allowed)
1661
          prior_counter_arb_r <= conv_std_logic_vector (1, id_width_g);
1662
        else
1663
          -- Bus idle, increase current priority
1664
          prior_counter_arb_r <= prior_counter_arb_r +1;
1665
        end if;
1666
 
1667
 
1668
      else
1669
        -- real arbitration types. now only prior + round rob
1670
        if arb_type_r = "00" then
1671
          -- round-robin
1672
          -- Bus reserved, priority remains the same
1673
          prior_counter_arb_r <= prior_counter_arb_r;
1674
 
1675
        elsif arb_type_r = "01" then
1676
          -- priority, actually 01
1677
          prior_counter_arb_r <= conv_std_logic_vector (1, id_width_g);
1678
 
1679
        else
1680
          -- "lottery"
1681
          -- counter is assigned below in separate process (inside if-generate)
1682
          --          prior_counter_arb_r <= arb_agent_r;
1683
        end if;
1684
 
1685
      end if;                           -- lock & arb_type
1686
    end if;  --rst_n      
1687
 
1688
  end process Count_Priorities;
1689
 
1690
  dyn : if dyn_arb_enable_c = 1 generate
1691
    dyn_arb_1 : dyn_arb
1692
      generic map (
1693
        id_width_g => id_width_g,
1694
--        n_agents_g => 22 --6
1695
        n_agents_g => n_agents_g        -- 2009-04-08
1696
        )                --signaali!
1697
      port map (
1698
        clk           => clk,
1699
        rst_n         => rst_n,
1700
        bus_lock_in   => lock_in,
1701
        arb_agent_out => dyn_arb_prior
1702
        );
1703
 
1704
    assign_priocount: process (dyn_arb_prior, arb_type_in, prior_counter_arb_r)
1705
    begin  -- process assign priocount
1706
      if arb_type_in = "11" then
1707
        prior_counter_r <= dyn_arb_prior;
1708
      else
1709
        prior_counter_r <= prior_counter_arb_r;
1710
      end if;
1711
    end process assign_priocount;
1712
  end generate dyn;
1713
 
1714
  notdyn: if dyn_arb_enable_c /= 1 generate
1715
    assert arb_type_in /= "11" report "ERROR! ARB TYPE RANDOM BUT DYN ARB ENABLE = 0" severity failure;
1716
    prior_counter_r <= prior_counter_arb_r;
1717
  end generate notdyn;
1718
 
1719
end rtl;
1720
 
1721
 
1722
 
1723
 

powered by: WebSVN 2.1.0

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