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/] [rx_ctrl.vhd] - Blame information for rev 159

Go to most recent revision | 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        : rx_control_addr_width_is_1.vhdl
27
-- Description : Control of the receiver for only one cycle long addresses
28
--               Includes two state machines: one for configuration
29
--               one for regular data. No distinction made between data and messages.
30
--
31
--               Needs one_place signal from fifo. Probably this could be
32
--               avoided by having two addr registers. One for decoding and one
33
--               for storing. Store reg  would be used only fifo gets full
34
--
35
-- Author       : Erno Salminen
36
-- e-mail       : erno.salminen@tut.fi
37
-- Date         : 16.12.2002
38
-- Project      
39
-- Design       : Do not use term design when you mean system
40
-- Modified
41
--
42
-- 16.12.02     The earlier versions did not fully work when FIFO got full.
43
--              This is somewhat better.
44
-- 01.04.03     New state Two_Data_Full_New_Addr added
45
-- 13.04.03     message stuff removed, es
46
-- 16.05.03     Config receiving added
47
-- 24.07.03     Target_full logic changed, cleaning
48
-- 07.02.05     ES new generics
49
-- 04.03.05     ES new generics id_width_g and cfg_addr_width_g
50
-- 15.12.05     ES Commented out all (others => rst_valu_arra(dbg_level)
51
--                 => registers keep their old values
52
--                 => 16% reduction in area for 32b rx_ctrl (ST 0.13um)
53
-------------------------------------------------------------------------------
54
library ieee;
55
use ieee.std_logic_1164.all;
56
use ieee.std_logic_arith.all;
57
use ieee.std_logic_unsigned.all;
58
use work.hibiv2_pkg.all;
59
 
60
entity rx_control is
61
  generic (
62
    data_width_g     :    integer := 32;
63
    addr_width_g     :    integer := 25;  -- in bits!
64
    id_width_g       :    integer := 5;   -- 04.03.2005
65
    cfg_addr_width_g :    integer := 16;  -- in bits, smaller than addr_w,  04.03.2005
66
    cfg_re_g         :    integer := 1;   -- 07.02.05
67
    cfg_we_g         :    integer := 1    -- 07.02.05
68
    );
69
  port (
70
    clk              : in std_logic;
71
    rst_n            : in std_logic;
72
 
73
    av_in            : in  std_logic;
74
    data_in          : in  std_logic_vector ( data_width_g-1 downto 0);
75
    comm_in          : in  std_logic_vector ( comm_width_c-1 downto 0);
76
    full_in          : in  std_logic;
77
    one_p_in         : in  std_logic;
78
    cfg_rd_rdy_in    : in  std_logic;   --16.05
79
 
80
    addr_match_in   : in  std_logic;
81
    decode_addr_out : out std_logic_vector ( addr_width_g -1 downto 0);
82
    decode_comm_out : out std_logic_vector ( comm_width_c-1 downto 0);
83
    decode_en_out   : out std_logic;
84
 
85
    data_out         : out std_logic_vector ( data_width_g-1 downto 0);
86
    comm_out         : out std_logic_vector ( comm_width_c-1 downto 0);
87
    av_out           : out std_logic;
88
    we_out           : out std_logic;
89
    full_out         : out std_logic;
90
 
91
    cfg_we_out       : out std_logic;
92
    cfg_re_out       : out std_logic;
93
    cfg_addr_out     : out std_logic_vector ( cfg_addr_width_g -1 downto 0);
94
    cfg_data_out     : out std_logic_vector ( data_width_g -1 downto 0);
95
    cfg_ret_addr_out : out std_logic_vector ( addr_width_g -1 downto 0)
96
    );
97
 
98
end rx_control;
99
 
100
 
101
architecture rtl of rx_control is
102
 
103
  -- Selects if debug prints are used (1-3) or not ('0')
104
  constant dbg_level : integer range 0 to 3 := 0;  -- 0= no debug, use 0 for synthesis
105
 
106
  -- Registers may be reset to 'Z' to 'X' so that reset state is clearly
107
  -- distinguished from active state. Using dbg_level+rst_value_arr array, the rst value may
108
  -- be easily set to '0' for synthesis.
109
  -- 16.12.05 try if "don't care" could reduce area
110
  constant rst_value_arr : std_logic_vector ( 6 downto 0) := 'X' & 'Z' & 'X' & 'Z' & 'X' & 'Z' & '0';
111
 
112
 
113
 
114
  -- Controller has two state machines
115
  --  fsm1 receives redular data (and messages) and requests
116
  --  fsm2 receives configuration data and requests
117
  -- Fsm2 is simpler because confmemory cannot be full like fifo 
118
  type state_type is (Wait_Addr,
119
                      One_Addr, One_Data, One_Data_New_Addr, One_Addr_One_Data,
120
                      Two_Data, Two_Data_Full, Two_Data_Full_New_Addr,
121
                      Reconfiguration);
122
  signal curr_state_r, next_state       : state_type;
123
 
124
  -- attribute enum_encoding : string;
125
  -- attribute enum_encoding of state_type: type is "000000001 000000010 000000100 000001000 000010000 000100000 001000000 010000000 100000000";
126
 
127
 
128
  type conf_state_type is (Conf_Idle, Conf_One_Addr, Conf_Addr_Data);
129
  -- attribute enum_encoding : string;
130
  -- attribute enum_encoding of conf_state_type: type is "001 010 100";
131
 
132
 
133
  signal cfg_curr_state_r, cfg_next_state : conf_state_type;
134
 
135
  -- Registers for receiving data
136
  signal enable_decode_r : std_logic;   -- 04.08.2004
137
  signal addr_r          : std_logic_vector ( addr_width_g-1 downto 0);
138
  signal data_r          : std_logic_vector ( data_width_g-1 downto 0);
139
  signal data_to_fifo_r  : std_logic_vector ( data_width_g-1 downto 0);
140
  signal comm_to_fifo_r  : std_logic_vector ( comm_width_c-1 downto 0);
141
  signal comm_a_r        : std_logic_vector ( comm_width_c-1 downto 0);
142
  signal comm_d_r        : std_logic_vector ( comm_width_c-1 downto 0);
143
  signal av_to_fifo_r    : std_logic;
144
  signal we_to_fifo_r    : std_logic;
145
 
146
  -- Registers for receiving configuration
147
  signal cfg_write_enable_r : std_logic;
148
  signal cfg_read_enable_r  : std_logic;
149
  signal cfg_new_value_r    : std_logic_vector ( data_width_g -1 downto 0);
150
  -- cfg osoitteesta tarvitaan id osoitteen vertailua varten ja cfg_addr_w
151
  -- muistia varten. Addr_w lienee kuitenkin leveämpi kuin id_w + cfg_a_w
152
  -- yhteensä 04.03.05
153
  signal cfg_id_r           : std_logic_vector ( id_width_g -1 downto 0);  -- 04.03.05
154
  signal cfg_addr_r         : std_logic_vector ( cfg_addr_width_g -1 downto 0);  -- 04.03.05
155
  signal cfg_return_addr_r  : std_logic_vector ( addr_width_g -1 downto 0);
156
  signal cfg_comm_r         : std_logic_vector ( comm_width_c -1 downto 0);  -- 15.05
157
 
158
begin
159
 
160
 
161
 
162
  -- Continuous assignments             ---------------------------------------------------
163
  decode_en_out <= enable_decode_r;     -- 04.08.2004
164
  data_out      <= data_to_fifo_r;
165
  comm_out      <= comm_to_fifo_r;
166
  av_out        <= av_to_fifo_r;
167
  we_out        <= we_to_fifo_r;
168
 
169
  cfg_we_out       <= cfg_write_enable_r;
170
  cfg_re_out       <= cfg_read_enable_r;
171
  cfg_data_out     <= cfg_new_value_r;
172
  cfg_addr_out     <= cfg_addr_r;       -- 04.03.05
173
  cfg_ret_addr_out <= cfg_return_addr_r;
174
 
175
 
176
  -----------------------------------------------------------------------------
177
  -- PROCESSES ----------------------------------------------------------------
178
  -----------------------------------------------------------------------------
179
 
180
  -- 04.03.05
181
  assert cfg_addr_width_g < (addr_width_g+1) report "Cfg_addr_w must be smaller than addr_w" severity ERROR;
182
 
183
  -- 1) PROC
184
  -- Synchronous process for state transitions
185
  Sync : process (clk, rst_n)
186
  begin  -- process
187
    if rst_n = '0' then
188
      curr_state_r     <= Wait_Addr;
189
      cfg_curr_state_r <= Conf_Idle;
190
    elsif clk'event and clk = '1' then
191
      curr_state_r     <= next_state;
192
      cfg_curr_state_r <= cfg_next_state;
193
    end if;
194
  end process;
195
 
196
 
197
 
198
 
199
 
200
  -- 2) PROC (ASYNC)
201
  -- Selects which address register is fed to addr decoder 
202
  Select_Decoded_Addr : process (addr_r, comm_a_r, -- cfg_addr_r,
203
                                 cfg_comm_r, cfg_curr_state_r, cfg_id_r)
204
  begin  -- process Select_Decoded_Addr
205
    assert addr_width_g < data_width_g+1 report "addr_width_g must be smaller than data_width_g" severity FAILURE;
206
 
207
    -- modified 2007/04/17
208
    if (cfg_re_g=1
209
        or cfg_we_g=1)
210
        and cfg_curr_state_r = Conf_One_Addr then
211
 
212
      -- Conf addr received
213
      decode_addr_out                                                     <= (others => '0');  --04.03.05
214
      decode_addr_out (addr_width_g -1 downto addr_width_g - id_width_g ) <= cfg_id_r;  -- 04.03.05;
215
      decode_comm_out                                                     <= cfg_comm_r;
216
    else
217
      -- Regular addr received
218
      decode_addr_out                                                     <= addr_r;
219
      decode_comm_out                                                     <= comm_a_r;
220
    end if;  --cfg_curr_state_r
221
  end process Select_Decoded_Addr;
222
 
223
 
224
  -- 3) PROC (ASYNC)
225
  -- Assign output full_out when needed
226
  ControlTargetFull : process (full_in, one_p_in,
227
                               addr_match_in, comm_in,
228
                               curr_state_r)
229
  begin  -- process ControlTargetFull
230
 
231
    -- New version 24.07.03 es
232
    if comm_in /= idle_c then
233
      -- Bus is reserved = some agent is transmitting
234
 
235
 
236
      if full_in = '1' then
237
        -- Fifo full
238
 
239
        if curr_state_r = Wait_Addr
240
          or curr_state_r = One_Data
241
          or curr_state_r = Two_Data_Full
242
        then
243
          -- Some other wrapper is the current receiver
244
          full_out <=  '0';
245
 
246
        elsif curr_state_r = One_Addr
247
          or curr_state_r = One_Data_New_Addr
248
          or curr_state_r = Two_Data_Full_New_Addr
249
        then
250
          -- Addr received and fifo is full
251
          -- Assert target_full only if this wrapper is the receiver (=addr matches)
252
          full_out <= addr_match_in;
253
 
254
        else
255
          -- This wrapper is receiving data and fifo is full
256
          full_out <= '1';
257
        end if;
258
 
259
 
260
      else
261
        if one_p_in = '1' then
262
          -- In some case, there has to be at least two fifo places empty
263
 
264
 
265
          if curr_state_r = One_Addr
266
            or curr_state_r = One_Data_New_Addr
267
            or curr_state_r = Two_Data_Full_New_Addr
268
          then
269
            -- Addr received and only one place left in the fifo
270
            -- Assert target_full only if this wrapper is the receiver (=addr matches)
271
            full_out <=  addr_match_in;
272
            -- This ensures that fifo=1 cannot happen in these states
273
            -- (FSM stays only one cycle in this states)
274
 
275
          else
276
            -- In other FSM states, no need to do anything, one place is enough
277
            full_out <= '0';
278
          end if;                       -- curr_state_r
279
 
280
        elsif curr_state_r = Two_Data_Full_New_Addr then
281
          -- elsif added 2009-07-28, JN
282
          -- Before this fix, in cases where hibi frequency was lower than
283
          -- IP frequency, one_p_in went up and down again within one clk cycle
284
          -- causing full_out to be 0 (the else branch below). This made sender
285
          -- continue transferring even though we didn't have enough space to
286
          -- store the data. This lead to address not being written to the fifo
287
          -- at all. Now we reject the transfer until we have succesfully
288
          -- written old data from data_r to the fifo.
289
          full_out <= addr_match_in;
290
 
291
        else
292
          -- At least two places in the fifo
293
          full_out <= '0';
294
        end if;                         -- one_p_in
295
      end if;                           -- full_in
296
 
297
    else
298
      -- Bus is idle
299
      full_out <= '0';
300
    end if;                             -- comm_in
301
 
302
 
303
  end process ControlTargetFull;
304
 
305
 
306
 
307
 
308
 
309
  -- 4) PROC (ASYNC)
310
  -- Defines the next state of state machine for regular data
311
  -- 
312
  DefNextState : process (curr_state_r, addr_match_in,
313
                          av_in, comm_in,
314
                          full_in, one_p_in)
315
  begin  -- process DefNextState
316
 
317
    case curr_state_r is
318
 
319
      when  Wait_Addr =>
320
        if comm_in /= idle_c and av_in = '1' then
321
          -- There is an addr on the bus
322
 
323
          if comm_in = w_cfg_c or comm_in = r_cfg_c then  --15.05
324
            -- New conf addr, handled elsewhere (see below)
325
            next_state <= curr_state_r; --Wait_Addr;
326
          else
327
            -- New data transfer begins
328
            next_state <= One_Addr;
329
          end if;                       --comm          
330
 
331
        else
332
          next_state <= Wait_Addr;
333
        end if;                         -- comm_in&av_in
334
 
335
 
336
 
337
      when One_Addr =>
338
 
339
        if comm_in /= idle_c
340
          and addr_match_in = '1'
341
          and full_in = '0'
342
          and one_p_in = '0'   -- 1_place added 23.07.03
343
        then
344
          -- Matching addr read on prev cycle.
345
          -- Corresponding data is read to register on this cycle
346
          -- If next_state will be 1a_1d, it is propably necessary to check 1_place_left
347
          -- ( to ensure that it is not possible to have fulll=1 in that state
348
          -- => addr register is freed to be used with next addr on the bus)
349
          next_state <= One_Addr_One_Data;
350
 
351
          -- 24.07 : If it is ensured that addr fits into fifo, it would be
352
          -- possible to have next_state= one_data.
353
          -- However, in other cases that state reached only when transfer has
354
          -- ended. Therefore, it seems safer to go state 1a_1d (if there are
355
          -- at least two places int he fifo) to keep state
356
          -- one_data untouched.
357
 
358
        else
359
          -- Addr does not match or no data after addr
360
          next_state <= Wait_Addr;
361
        end if;                         -- comm_in&full_in
362
 
363
 
364
 
365
      when One_Data =>
366
        if full_in = '1' then
367
          -- Data does not fit into fifo
368
 
369
          if av_in = '1' then
370
            -- New addr on the bus
371
              if comm_in = w_cfg_c or comm_in = r_cfg_c then  --15.05
372
                -- New conf addr, handled elsewhere (see below)
373
                next_state <= curr_state_r;
374
              else
375
                -- New data transfer begins
376
                next_state <= One_Data_New_Addr;
377
              end if;                       -- comm_in          
378
 
379
          else
380
            -- Data that is currently on the bus has to be retransferred by the
381
            -- tx_ctrl
382
            next_state <= One_Data;
383
          end if;                       -- AV
384
 
385
 
386
        else
387
          -- Data goes into fifo i.e. fifo not full          
388
          if av_in = '1'  then
389
 
390
            if comm_in = w_cfg_c or comm_in = r_cfg_c then  --15.05
391
              -- New conf addr, handled elsewhere (see below)
392
              next_state <= curr_state_r;
393
            else
394
              -- New data transfer begins
395
              next_state <= One_Addr;   -- ES 22.7.2003
396
            end if;                     -- comm_in          
397
 
398
          else
399
            next_state <= Wait_Addr;
400
          end if;                       -- AV
401
         end if;                        -- full_in
402
 
403
 
404
 
405
      when One_Addr_One_Data =>
406
 
407
        if full_in = '1' then
408
          -- 23.07.03 This branch should be impossible to reach
409
          -- Otherwise the addr register stays reserved and it is not possible
410
          -- to store next addr on the bus anywhere
411
          next_state <= One_Addr_One_Data;
412
          assert false report "Rec-1d1a Fifo full. Illegal condition, possible deadlock!" severity warning;
413
 
414
        else
415
          -- Addr goes to fifo
416
 
417
          if comm_in = idle_c then
418
            -- Tx ends after first data
419
            next_state <= One_Data;
420
          else
421
            if av_in = '1' then
422
              -- New addr on the bus
423
 
424
              if comm_in = w_cfg_c or comm_in = r_cfg_c then  --15.05
425
                -- New conf addr, handled elsewhere (see below)                
426
                next_state <= One_Data;
427
              else
428
                -- New data transfer begins
429
                next_state <= One_Data_New_Addr;
430
              end if;                       --comm          
431
 
432
            else
433
              -- New data
434
              next_state <= Two_Data;
435
            end if;                     -- AV
436
          end if;                       -- comm_in
437
        end if;                         -- full_in
438
 
439
 
440
 
441
      when One_Data_New_Addr =>
442
        if full_in = '1' then
443
          -- Fifof full, do not accept any new data
444
          -- Store addr so that target_full can be asserted if addr matches
445
          next_state <= One_Data;
446
 
447
        else
448
          -- Data goes into fifo
449
 
450
          if one_p_in = '1' then
451
            -- Only data fits into fifo, do not accept addr or
452
            -- data following it
453
            next_state <= Wait_Addr;
454
 
455
          elsif comm_in = idle_c or addr_match_in = '0' then
456
            -- Addr does not match or transfer ends after the addr
457
            next_state <= Wait_Addr;
458
 
459
          else
460
 
461
            if av_in = '1' then
462
              -- Addr 
463
 
464
              if comm_in = w_cfg_c or comm_in = r_cfg_c then --15.05
465
                -- New conf addr, handled elsewhere (see below)
466
                next_state <= Wait_Addr;
467
              else
468
                -- New data transfer begins
469
                next_state <= One_Addr;
470
              end if;                       --comm          
471
 
472
            else
473
              -- New data
474
              next_state <= One_Addr_One_Data;
475
            end if;  -- AV
476
          end if;  -- comm_in
477
        end if;  -- full_in
478
 
479
 
480
 
481
      when Two_Data =>
482
        if full_in = '1' then
483
          next_state <= Two_Data_Full;
484
        else
485
          -- Another data goes into fifo
486
 
487
          if comm_in = idle_c then
488
            -- Transfer ends
489
            next_state <= One_Data;
490
 
491
          else
492
            if av_in = '1' then
493
 
494
              if comm_in = w_cfg_c or comm_in = r_cfg_c then  --15.05
495
                -- New conf addr, handled elsewhere (see below)
496
                next_state <= One_Data;
497
              else
498
                -- New data transfer begins
499
                next_state <= One_Data_New_Addr;
500
              end if;                       --comm          
501
 
502
            else
503
              -- More data
504
              next_state <= Two_Data;
505
            end if;                     -- AV
506
          end if;                       -- comm_in
507
        end if;                         -- full_in
508
 
509
 
510
 
511
      when Two_Data_Full =>
512
        -- updated 01.04.03
513
        if full_in = '1' then
514
          -- No data can be written to fifo
515
 
516
          if av_in = '1' then
517
            -- New addr = new transfer
518
 
519
            if comm_in = w_cfg_c or comm_in = r_cfg_c then  --15.05
520
              -- New conf addr, handled elsewhere (see below)
521
              next_state <= Two_Data_Full;
522
            else
523
              -- New data transger begins
524
              -- Addr is stored and compared so that target_full can be
525
              -- asserted if needed
526
              next_state <= Two_Data_Full_New_Addr;
527
            end if;                       -- comm_in          
528
 
529
          else
530
            -- Data that is currently on the bus has to be retransferred by the
531
            -- tx_ctrl
532
            next_state <= Two_Data_Full;
533
          end if;                       -- AV
534
 
535
        else
536
          -- Another data goes to fifo
537
 
538
          if av_in = '1' then
539
            -- New addr = new transfer
540
            if comm_in = w_cfg_c or comm_in = r_cfg_c then  --15.05
541
              -- New conf addr, handled elsewhere (see below)
542
              next_state <= curr_state_r;
543
            else
544
              -- Uusi siirto alkaa
545
              next_state <= One_Data_New_Addr;
546
            end if;  -- comm_in          
547
 
548
          else
549
            -- Data that is currently on the bus has to be retransferred by the
550
            -- tx_ctrl
551
            next_state <= One_Data;
552
          end if;                       -- AV
553
        end if;                         -- full_in
554
 
555
 
556
 
557
      when Two_Data_Full_New_Addr =>
558
        -- New state 01.04.03
559
 
560
        if full_in = '1' then
561
          -- Fifo is full, do not accept addr regardless if it matches or not
562
          next_state <= Two_Data_Full;
563
        else
564
 
565
          -- another data went into fifo
566
          -- (Earlier here were all kinds of if clauses, but they all led to
567
          -- state One_Data, so they are removed. In Two_Data_Full_New_Addr
568
          -- nothing can be read, so there is no other state to go.)
569
          next_state <= One_Data;
570
 
571
        end if;         -- full_in
572
 
573
 
574
      when others =>
575
        assert false report "Illegal curr state in rx fsm" severity warning;
576
        next_state <= Wait_Addr;        --12.-4.03
577
    end case;
578
 
579
 
580
  end process DefNextState;
581
 
582
 
583
 
584
 
585
  -- 5) PROC
586
  ControlRegisters : process (clk, rst_n)
587
  begin  -- process ControlRegisters
588
    if rst_n = '0' then                 -- asynchronous reset (active low)
589
      addr_r          <= (others => rst_value_arr (dbg_level* 1));
590
      data_r          <= (others => rst_value_arr (dbg_level* 1));
591
      data_to_fifo_r  <= (others => rst_value_arr (dbg_level* 1));
592
      comm_to_fifo_r  <= (others => rst_value_arr (dbg_level* 1));
593
      av_to_fifo_r    <= '0';
594
      comm_a_r        <= (others => rst_value_arr (dbg_level* 1));
595
      comm_d_r        <= (others => rst_value_arr (dbg_level* 1));
596
      we_to_fifo_r    <= '0';
597
      enable_decode_r <= '1';
598
 
599
 
600
    elsif clk'event and clk = '1' then          -- rising clock edge
601
 
602
      enable_decode_r <= '1';
603
      we_to_fifo_r    <= '0';
604
 
605
 
606
      case curr_state_r is
607
 
608
 
609
        when Wait_Addr              =>
610
          av_to_fifo_r   <= '0';
611
          we_to_fifo_r   <= '0';
612
 
613
          -- 15.05 es
614
          if next_state = One_Addr then
615
            addr_r   <= data_in ( addr_width_g -1 downto 0);  -- 31.01.05
616
            comm_a_r <= comm_in;
617
          end if;
618
 
619
 
620
        when One_Addr                 =>
621
          if next_state = Wait_Addr then
622
            av_to_fifo_r   <= '0';
623
            we_to_fifo_r   <= '0';
624
 
625
          else
626
            -- i.e. next_state = One_Addr_One_Data
627
            data_r                                  <= data_in;
628
            data_to_fifo_r                          <= (others => '0');  -- 31.01.05 jos osoite kapea, nollataan ylimmät bitit
629
            data_to_fifo_r(addr_width_g-1 downto 0) <= addr_r;  --osoite fifolle
630
            comm_to_fifo_r                          <= comm_a_r;
631
            av_to_fifo_r                            <= '1';
632
            comm_d_r                                <= comm_in;
633
            we_to_fifo_r                            <= '1';
634
          end if;
635
 
636
        when One_Data                 =>
637
          if next_state = One_Data then
638
            we_to_fifo_r   <= '1';
639
 
640
          elsif next_state = One_Data_New_Addr then
641
            -- 22.7.2003 : Registers going to fifo cannot reset to zero
642
            -- because fifo is full at the moment. ES
643
            addr_r         <= data_in ( addr_width_g -1 downto 0);  -- 31.01.05  --new addr on bus
644
            comm_a_r       <= comm_in;
645
 
646
            we_to_fifo_r   <= '1';
647
 
648
 
649
          elsif next_state = Wait_Addr then
650
            av_to_fifo_r   <= '0';
651
            we_to_fifo_r   <= '0';
652
 
653
          elsif next_state = One_Addr then
654
            addr_r         <= data_in ( addr_width_g -1 downto 0);  -- 31.01.05;  --new addr on bus
655
            av_to_fifo_r   <= '0';
656
            comm_a_r       <= comm_in;
657
            we_to_fifo_r   <= '0';
658
          else
659
            assert false report "Illegal next state in rx fsm (1D)" severity warning;
660
          end if;
661
 
662
 
663
        when One_Addr_One_Data =>
664
          data_to_fifo_r <= data_r;
665
          comm_to_fifo_r <= comm_d_r;
666
          av_to_fifo_r   <= '0';
667
          we_to_fifo_r <= '1';
668
 
669
          if next_state = One_Data_New_Addr then
670
            addr_r   <= data_in ( addr_width_g -1 downto 0);  -- 31.01.05;        --new addr on bus
671
            comm_a_r <= comm_in;
672
 
673
          elsif next_state = One_Addr_One_Data then
674
            -- Fifo full, cannot receive anything
675
            -- 23.07 This should be impossible branch
676
            assert false report "Rx : 1a1d - > 1a1d, Illegal?" severity warning;
677
 
678
          elsif next_state = Two_Data then
679
            data_r   <= data_in;
680
            comm_d_r <= comm_in;
681
 
682
          elsif next_state /= One_Data then
683
            assert false report "Illegal next state in rx fsm (1A_1D)" severity warning;
684
          end if;
685
 
686
 
687
 
688
        when Two_Data =>
689
          we_to_fifo_r <= '1';
690
 
691
          if next_state = Two_Data then
692
 
693
            if full_in = '1' then
694
              -- 31.03.03 Is this branch ever reached??
695
              -- This may be the same as if the next state is 2d_full
696
              assert dbg_level < 1 report "huhuu? two_d - > two_d?" severity note;
697
 
698
            else
699
              data_r         <= data_in;
700
              data_to_fifo_r <= data_r;
701
              comm_to_fifo_r <= comm_d_r;
702
              av_to_fifo_r   <= '0';
703
              comm_d_r       <= comm_in;
704
            end if;
705
 
706
          elsif next_state = One_Data_New_Addr then
707
            addr_r         <= data_in (addr_width_g-1 downto 0);  -- 31.01.05 --new addr on bus
708
            data_to_fifo_r <= data_r;
709
            comm_to_fifo_r <= comm_d_r;
710
            av_to_fifo_r   <= '0';
711
            comm_a_r       <= comm_in;
712
 
713
          elsif next_state = One_Data then
714
            data_to_fifo_r <= data_r;
715
            comm_to_fifo_r <= comm_d_r;
716
            av_to_fifo_r   <= '0';
717
 
718
          elsif next_state /= Two_Data_Full then
719
            assert false report "Illegal next state in rx fsm (2D)" severity warning;
720
          end if;
721
 
722
 
723
        when One_Data_New_Addr =>
724
 
725
          if next_state = Wait_Addr then
726
            av_to_fifo_r   <= '0';
727
            we_to_fifo_r   <= '0';
728
 
729
          elsif next_state = One_Addr then
730
            addr_r         <= data_in (addr_width_g -1 downto 0); -- 31.01.05  --new addr on bus
731
            av_to_fifo_r   <= '0';
732
            comm_a_r       <= comm_in;
733
            we_to_fifo_r   <= '0';
734
 
735
          elsif next_state = One_Addr_One_Data then
736
            data_r         <= data_in;
737
            data_to_fifo_r <= (others => '0');  -- 31.01.05 jos osoite kapea, nollataan ylimmät bitit
738
            data_to_fifo_r(addr_width_g-1 downto 0) <= addr_r;    -- osoite fifolle
739
            comm_to_fifo_r <= comm_a_r;
740
            av_to_fifo_r   <= '1';
741
            comm_d_r       <= comm_in;
742
            we_to_fifo_r   <= '1';
743
 
744
          elsif next_state = One_Data then
745
            we_to_fifo_r   <= '1';
746
 
747
          else
748
            assert false report "Illegal next state in rx fsm (1D_nA)" severity warning;
749
          end if;
750
 
751
 
752
       when Two_Data_Full =>
753
 
754
          if next_state = Two_Data_Full_New_Addr then
755
            addr_r   <= data_in (addr_width_g -1 downto 0);  -- 31.01.05  --new addr on bus
756
            comm_a_r <= comm_in;
757
            we_to_fifo_r   <= '1';
758
 
759
          elsif next_state = One_Data then
760
            data_to_fifo_r <= data_r;
761
            comm_to_fifo_r <= comm_d_r;
762
            we_to_fifo_r   <= '1';
763
 
764
          elsif next_state = One_Data_New_Addr then
765
            addr_r   <= data_in (addr_width_g -1 downto 0);  --31.01.05  --new addr on bus
766
            comm_a_r <= comm_in;
767
 
768
            data_to_fifo_r <= data_r;
769
            comm_to_fifo_r <= comm_d_r;
770
            we_to_fifo_r   <= '1';
771
 
772
          else
773
            we_to_fifo_r   <= '1';
774
          end if;
775
 
776
 
777
 
778
 
779
      when Two_Data_Full_New_Addr =>
780
        -- New state 01.04.03
781
          if next_state = Two_Data_Full then
782
            -- Fifo still full, everything stays the same
783
            addr_r   <= (others   => '0');  --'Z'); --addr_r;  -- reseting possible ?
784
            we_to_fifo_r   <= '1';
785
 
786
          elsif next_state = One_Data then
787
            -- Another data went into fifo, but the addr cannot be accepted yet
788
            -- due to lack of fifo space
789
            data_to_fifo_r <= data_r;
790
            comm_to_fifo_r <= comm_d_r;
791
            we_to_fifo_r   <= '1';
792
 
793
          else
794
 
795
            assert false report "TwoData -> ?? : Haloo?" severity note;
796
          end if;
797
 
798
 
799
        when others =>
800
          null;
801
      end case;
802
    end if;
803
  end process ControlRegisters;
804
 
805
 
806
 
807
 
808
 
809
  -- 6) PROC (ASYNC)
810
  Def_Conf_next_state : process (cfg_curr_state_r, av_in, comm_in, addr_match_in, cfg_rd_rdy_in)
811
  begin  -- process Def_Conf_next_state
812
      -- if modified 2007/04/17
813
      if cfg_re_g = 1 or cfg_we_g = 1 then
814
 
815
        case cfg_curr_state_r is
816
 
817
          when Conf_Idle =>
818
 
819
            if av_in = '1' then
820
 
821
              if  (comm_in = w_cfg_c or comm_in = r_cfg_c) then
822
                -- New conf addr
823
                cfg_next_state <= Conf_One_Addr;
824
                assert false report "New conf" severity note;
825
              else
826
                cfg_next_state <= Conf_Idle;
827
              end if;
828
            else
829
              cfg_next_state <= Conf_Idle;
830
            end if;                         -- av & comm
831
 
832
 
833
          when Conf_One_Addr =>
834
            if addr_match_in = '1'
835
              and (comm_in = w_cfg_c or comm_in = r_cfg_c) then
836
              -- Conf addr matches and conf transfer continues (either conf value
837
              -- or return addr)
838
              cfg_next_state <= Conf_Addr_Data;
839
            else
840
              -- ConfK addr does not match
841
              cfg_next_state <= Conf_Idle;
842
            end if;                         --am & comm
843
 
844
 
845
 
846
          when Conf_Addr_Data =>
847
 
848
            if cfg_rd_rdy_in = '1' then
849
              --  Current conf data goes into conf_mem/tx_ctrl
850
 
851
              if  (comm_in = w_cfg_c or comm_in = r_cfg_c) then
852
                -- Conf continues
853
 
854
                if av_in = '1' then
855
                  -- New confK addr
856
                  cfg_next_state <= Conf_One_Addr;
857
                else
858
                  -- new conf data
859
                  cfg_next_state <= Conf_Addr_Data;
860
                end if;                       --av
861
 
862
              else
863
                -- Conf ends
864
                cfg_next_state <= Conf_Idle;
865
              end if;                       --comm
866
 
867
            else
868
              -- Cannot forward current conf data
869
              if av_in = '1'
870
                and (comm_in = w_cfg_c or comm_in = r_cfg_c) then
871
                -- New confK addr
872
                cfg_next_state <= Conf_One_Addr;
873
              else
874
                -- Conf transfer ends, cannot forward current conf data
875
                cfg_next_state <= Conf_Addr_Data;
876
              end if;
877
 
878
            end if;                         --cfg_rd_rdy_in
879
 
880
 
881
          when others =>
882
            cfg_next_state <= Conf_Idle;
883
        end case;  --cfg_curr_state_r
884
      end if;                           -- cfg_we_g or cfg_re_g
885
 
886
  end process Def_conf_next_state;
887
 
888
 
889
 
890
 
891
  -- 7) PROC
892
  Control_Conf_registers : process (clk, rst_n)
893
  begin  -- process Control_Conf_registers
894
    if rst_n = '0' then                 -- asynchronous reset (active low)
895
      cfg_comm_r         <= (others => rst_value_arr (dbg_level* 1));
896
      cfg_id_r           <= (others => rst_value_arr (dbg_level* 1));
897
      cfg_addr_r         <= (others => rst_value_arr (dbg_level* 1));
898
      cfg_return_addr_r  <= (others => rst_value_arr (dbg_level* 1));
899
      cfg_new_value_r    <= (others => rst_value_arr (dbg_level* 1));
900
      cfg_read_enable_r  <= '0';
901
      cfg_write_enable_r <= '0';
902
 
903
    elsif clk'event and clk = '1' then  -- rising clock edge
904
 
905
      if cfg_re_g = 1 or cfg_we_g = 1 then
906
 
907
 
908
        case cfg_curr_state_r is
909
 
910
          when Conf_Idle                       =>
911
            -- Wait for conf addr
912
 
913
            if cfg_next_state = Conf_One_Addr then
914
              -- Conf addr on the bus
915
              cfg_id_r         <= data_in ( addr_width_g -1 downto addr_width_g - id_width_g );  -- 04.03.05;
916
              cfg_addr_r       <= data_in (cfg_addr_width_g -1 downto 0);  -- 04.03.05;
917
              cfg_comm_r       <= comm_in;
918
            end if;
919
            cfg_write_enable_r <= '0';
920
            cfg_read_enable_r  <= '0';
921
 
922
 
923
          when Conf_One_Addr =>
924
            -- Coonf addr received
925
 
926
 
927
            case cfg_next_state is
928
              when Conf_Idle                  =>
929
                -- Conf addr does not match
930
                cfg_write_enable_r <= '0';
931
                cfg_read_enable_r  <= '0';
932
 
933
              when Conf_One_Addr =>
934
                -- Illegal next state
935
                assert false report
936
                  "Illegal state transition conf_one_addr -> conf_one_addr" severity warning;
937
 
938
 
939
              when Conf_Addr_Data                   =>
940
                -- Conf addr matches
941
                -- Check whether the command is read or write
942
 
943
                if comm_in = w_cfg_c then
944
                  cfg_new_value_r    <= data_in;
945
                  cfg_write_enable_r <= '1';
946
                  cfg_read_enable_r  <= '0';
947
                else
948
                  cfg_return_addr_r  <= data_in(addr_width_g-1 downto 0);  -- 17.02
949
                  cfg_write_enable_r <= '0';
950
                  cfg_read_enable_r  <= '1';
951
                end if;
952
 
953
            end case;                     --cfg_next_state
954
 
955
 
956
          when Conf_Addr_Data =>
957
            -- Conf addr matched and conf data/return_addr also recieved
958
 
959
            case cfg_next_state is
960
              when Conf_Idle                  =>
961
                -- Conf ends
962
                cfg_write_enable_r <= '0';
963
                cfg_read_enable_r  <= '0';
964
 
965
              when Conf_One_Addr =>
966
                -- New conf immediatley following the previous
967
                -- Take new conf addr
968
                cfg_write_enable_r <= '0';
969
                cfg_read_enable_r  <= '0';
970
                cfg_id_r           <= data_in ( addr_width_g -1 downto addr_width_g - id_width_g );  -- 04.03.05;
971
                cfg_addr_r         <= data_in (cfg_addr_width_g -1 downto 0);  -- 04.03.05;
972
                cfg_comm_r         <= comm_in;
973
 
974
              when Conf_Addr_Data               =>
975
                -- More conf data immediatly, chekc command
976
                if comm_in = w_cfg_c then
977
                  -- Conf write
978
                  cfg_comm_r         <= comm_in;
979
                  cfg_new_value_r    <= data_in;
980
                  cfg_write_enable_r <= '1';
981
                  cfg_read_enable_r  <= '0';
982
 
983
                else
984
                  -- Conf read
985
                  cfg_comm_r         <= comm_in;
986
                  cfg_return_addr_r  <= data_in (addr_width_g -1 downto 0);  -- 31.01.05
987
                  cfg_write_enable_r <= '0';
988
                  cfg_read_enable_r  <= '1';
989
                end if;
990
                -- Increment conf addr
991
                -- NOTE: To make style "1 conf_addr + several conf_data"
992
                -- to work, also the tx_ctrl has to increment conf_addr
993
                -- so that it continues from correct addr if conf transmission is
994
                -- interrupted
995
                cfg_addr_r           <= cfg_addr_r+1;
996
 
997
 
998
            end case;                     -- cfg_next_state          
999
        end case;                         -- cfg_curr_state_r
1000
      end if;
1001
    end if;                             --rst / clk'event
1002
  end process Control_Conf_registers;
1003
end rtl;

powered by: WebSVN 2.1.0

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