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/] [3.0/] [vhd/] [cfg_mem.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- File        : cfg_mem.vhd
3
-- Description : Stores the configuration values. There can be more than one
4
--               configuration pages.
5
-- Author      : Erno Salminen
6
-- Project     : Nocbench, Funbase
7
-- Date        : 29.04.2002
8
-- Modified    :
9
-- 10.05.2002    Vesa Lahtinen  Functionality added
10
--
11
-- 16.12.05       ES Extra parameters are removed
12
--                   Use package for intializing time_slots
13
-------------------------------------------------------------------------------
14
-- Funbase IP library Copyright (C) 2011 TUT Department of Computer Systems
15
--
16
-- This file is part of HIBI
17
--
18
-- This source file may be used and distributed without
19
-- restriction provided that this copyright statement is not
20
-- removed from the file and that any derivative work contains
21
-- the original copyright notice and the associated disclaimer.
22
--
23
-- This source file is free software; you can redistribute it
24
-- and/or modify it under the terms of the GNU Lesser General
25
-- Public License as published by the Free Software Foundation;
26
-- either version 2.1 of the License, or (at your option) any
27
-- later version.
28
--
29
-- This source is distributed in the hope that it will be
30
-- useful, but WITHOUT ANY WARRANTY; without even the implied
31
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
32
-- PURPOSE.  See the GNU Lesser General Public License for more
33
-- details.
34
--
35
-- You should have received a copy of the GNU Lesser General
36
-- Public License along with this source; if not, download it
37
-- from http://www.opencores.org/lgpl.shtml
38
-------------------------------------------------------------------------------
39
library ieee;
40
use ieee.std_logic_1164.all;
41
use ieee.std_logic_arith.all;
42
use ieee.std_logic_unsigned.all;
43
 
44
use work.cfg_init_pkg.all;              -- init values for tiem slots
45
 
46
entity cfg_mem is
47
  generic (
48
    id_width_g       : integer := 4;
49
    id_g             : integer := 5;
50
    data_width_g     : integer := 16;   -- in bits. Obsolete?
51
    counter_width_g  : integer := 8;
52
    cfg_addr_width_g : integer := 7;
53
 
54
    inv_addr_en_g : integer := 0;
55
    addr_g        : integer := 46;
56
    prior_g       : integer := 2;
57
    max_send_g    : integer := 50;
58
 
59
    arb_type_g : integer := 0;
60
 
61
    n_agents_g     : integer := 4;
62
    n_cfg_pages_g  : integer := 1;
63
    n_time_slots_g : integer := 0;
64
    -- n_extra_params_g : integer := 0;
65
    cfg_re_g       : integer := 0;
66
    cfg_we_g       : integer := 0
67
    );
68
 
69
  port (
70
    clk   : in std_logic;
71
    rst_n : in std_logic;
72
 
73
    -- addr_in could be narrower, since id is only in addr decoder
74
    addr_in : in std_logic_vector (cfg_addr_width_g -1 downto 0);
75
    data_in : in std_logic_vector (data_width_g -1 downto 0);
76
    re_in   : in std_logic;
77
    we_in   : in std_logic;
78
 
79
    curr_slot_ends_out   : out std_logic;
80
    curr_slot_own_out    : out std_logic;
81
    next_slot_starts_out : out std_logic;
82
    next_slot_own_out    : out std_logic;
83
    dbg_out              : out integer range 0 to 100;  -- For debug
84
 
85
    data_out     : out std_logic_vector (data_width_g-1 downto 0);
86
    arb_type_out : out std_logic_vector (1 downto 0);
87
    n_agents_out : out std_logic_vector (id_width_g-1 downto 0);
88
    max_send_out : out std_logic_vector (counter_width_g-1 downto 0);
89
    prior_out    : out std_logic_vector (id_width_g-1 downto 0);
90
    pwr_mode_out : out std_logic_vector (1 downto 0)
91
    );
92
end cfg_mem;
93
 
94
 
95
architecture rtl of cfg_mem is
96
 
97
  -- Calculate minimum of 1 and "value"
98
  -- Required for reserving signals for tslots ans extra_params
99
  -- (Design compiler does not handle empty arrays (e.g. 0 downto -1),
100
  -- Precision handles them well)
101
  function max_with_1 (
102
    constant value : integer)
103
    return integer is
104
  begin  -- max_with_1
105
    if value = 0 then
106
      return 1;
107
    else
108
      return value;
109
    end if;
110
  end max_with_1;
111
 
112
  constant n_time_slots_tmp_c : integer := max_with_1 (n_time_slots_g);
113
  -- constant n_extra_params_tmp_c : integer := max_with_1 ( n_extra_params_g);
114
 
115
  function log2 (
116
    constant value : integer)
117
    return integer is
118
    variable temp    : integer := 1;
119
    variable counter : integer := 0;
120
  begin  -- log2
121
    -- Unbounded loops are NOT synthesizable
122
 
123
    --     while temp < value loop
124
    --       temp                     := temp*2;
125
    --       counter                  := counter+1;
126
    --     end loop;
127
 
128
    temp    := 1;
129
    counter := 0;
130
    for i in 0 to 30 loop
131
      if temp < value then
132
        temp    := temp*2;
133
        counter := counter+1;
134
      end if;
135
    end loop;
136
 
137
 
138
    return counter;
139
  end log2;
140
 
141
  constant page_addr_width_c : integer := log2 (n_cfg_pages_g) + 1;
142
 
143
  -- Calculate the maximum size of configuration
144
  -- memory page. There are 8 parameters and  address (which nowadays requires exactly one
145
  -- place in mem), each time slots requires 3 parameters (start, stop, owner),
146
  -- and there may be some application specific parameters as well.
147
  -- E.g. if n_time_slots_g=n_extra_params_g=0 then page_size_c= 8+1+3+1= 13 parameters
148
  constant page_size_c : integer := 8 + 1 + (n_time_slots_tmp_c * 3);  -- + n_extra_params_tmp_c;
149
 
150
  constant param_addr_width_c : integer := log2 (page_size_c);
151
  constant cfg_addr_width_c   : integer := param_addr_width_c + page_addr_width_c;
152
  -- Signals can be viewed from Modelsim. These are not used for any other purpose.
153
  signal   pag                : integer := page_addr_width_c;
154
  signal   par                : integer := param_addr_width_c;
155
  signal   cfg_a              : integer := cfg_addr_width_c;
156
 
157
 
158
 
159
  -- Logic for dbg_out adds roughly 16% to area (at least when 16b data is used) 
160
  constant dbg_level : integer range 0 to 3 := 0;  -- 0= no debug, use 0 for synthesis
161
 
162
  -- Define indexes for parameters
163
  constant ind_cycle_c : integer := 0;
164
  constant ind_prior_c : integer := 1;
165
  constant ind_n_ag_c  : integer := 2;  -- Num of AGents
166
  constant ind_arb_c   : integer := 3;
167
  constant ind_pwr_c   : integer := 4;
168
  constant ind_msend_c : integer := 5;
169
  constant ind_frame_c : integer := 6;  -- ei tarvita ellei ole slotteja!
170
  constant ind_inva_c  : integer := 7;  -- INVert Addr
171
  constant ind_baddr_c : integer := 8;  -- address requires nowadays exactly one memory slot
172
  constant ind_tslot_c : integer := 9;
173
  constant ind_extra_c : integer := ind_tslot_c + (n_time_slots_tmp_c *3);
174
 
175
 
176
 
177
  -- Output registers for time slots
178
  signal curr_slot_ends_r   : std_logic;
179
  signal curr_slot_own_r    : std_logic;
180
  signal next_slot_starts_r : std_logic;
181
  signal next_slot_own_r    : std_logic;
182
 
183
  -- Register for storing current page number,
184
  -- page number zero reserved for special purposes!
185
  signal curr_page_r : integer range 1 to n_cfg_pages_g;
186
 
187
 
188
  -- Own register type for clock cycle counters
189
  type   curr_cycle_array_type is array (1 to n_cfg_pages_g)
190
    of std_logic_vector (counter_width_g-1 downto 0);
191
  signal curr_cycle_r : curr_cycle_array_type;
192
 
193
 
194
 
195
  -- Internal signals for address slices
196
  signal page_num  : integer range 0 to n_cfg_pages_g;
197
  signal param_num : integer range 0 to page_size_c;
198
 
199
  -- Internal write and read enable
200
  -- If page and param numbers are valid, these are identical to inputs
201
  -- Otherwise, they are reset to zero
202
  signal we_int : std_logic;
203
  signal re_int : std_logic;
204
 
205
 
206
 
207
  -- Define type and register for configuration memory
208
  -- Use record instead of array => fields can have different widths
209
  type cfg_page_type is record
210
    Prior : std_logic_vector (id_width_g-1 downto 0);
211
    N_ag  : std_logic_vector (id_width_g-1 downto 0);
212
    Arb   : std_logic_vector (1 downto 0);
213
    Power : std_logic_vector (1 downto 0);
214
    MSend : std_logic_vector (counter_width_g-1 downto 0);
215
    Frame : std_logic_vector (counter_width_g-1 downto 0);
216
    --Inva  : std_logic;
217
  end record;
218
 
219
  type   cfg_array is array (1 to n_cfg_pages_g) of cfg_page_type;
220
  signal memory_r : cfg_array;
221
 
222
 
223
 
224
  -- Own register type for time slots (conf_page, time_slot_param)
225
  -- Note the indexing! This way the incoming addr can be used for indexing without modification..
226
 
227
  type tslot_page_type is array ((ind_tslot_c) to (ind_tslot_c + 3*n_time_slots_tmp_c-1))
228
    of std_logic_vector (counter_width_g-1 downto 0);
229
 
230
  type tslot_page_array_type is array (1 to n_cfg_pages_g) of tslot_page_type;
231
 
232
  signal tslot_r : tslot_page_array_type;
233
 
234
 
235
  -- Slot owner needs (usually) less bits than start and stop times
236
  type tslot_start_type is array ((ind_tslot_c) to (ind_tslot_c + 1*n_time_slots_tmp_c-1))
237
    of std_logic_vector (counter_width_g-1 downto 0);
238
  type tslot_stop_type is array ((ind_tslot_c + 1*n_time_slots_tmp_c) to (ind_tslot_c + 2*n_time_slots_tmp_c-1))
239
    of std_logic_vector (counter_width_g-1 downto 0);
240
  type tslot_id_type is array ((ind_tslot_c + 2*n_time_slots_tmp_c) to (ind_tslot_c + 3*n_time_slots_tmp_c-1))
241
    of std_logic_vector (id_width_g-1 downto 0);
242
 
243
  type tslot_start_array_type is array (1 to n_cfg_pages_g) of tslot_start_type;
244
  type tslot_stop_array_type is array (1 to n_cfg_pages_g) of tslot_stop_type;
245
  type tslot_id_array_type is array (1 to n_cfg_pages_g) of tslot_id_type;
246
 
247
  signal tslot_start_r : tslot_start_array_type;
248
  signal tslot_stop_r  : tslot_stop_array_type;
249
  signal tslot_id_r    : tslot_id_array_type;
250
 
251
 
252
 
253
--   -- Own register type for extra parameters (conf_page, extra_param_num)
254
--   -- Note the indexing! This way the incoming addr can be used for indexing without modification..
255
--   -- type extra_param_page_type is array (ind_extra_c to ind_extra_c + n_extra_params_g-1)
256
--   --  of std_logic_vector ( data_width_g-1 downto 0);
257
--   type extra_param_page_type is array (ind_extra_c to ind_extra_c + n_extra_params_tmp_c-1)
258
--     of std_logic_vector ( data_width_g-1 downto 0);
259
--   type extra_param_array_type is array (1 to n_cfg_pages_g) of extra_param_page_type;
260
--   signal extra_param_r : extra_param_array_type;
261
 
262
 
263
 
264
 
265
 
266
 
267
begin  -- rtl
268
 
269
  -- Continuous assignments
270
  curr_slot_ends_out   <= curr_slot_ends_r;
271
  curr_slot_own_out    <= curr_slot_own_r;
272
  next_slot_starts_out <= next_slot_starts_r;
273
  next_slot_own_out    <= next_slot_own_r;
274
 
275
 
276
  prior_out    <= memory_r (curr_page_r).Prior;  --1
277
  n_agents_out <= memory_r (curr_page_r).N_ag;   --2
278
  arb_type_out <= memory_r (curr_page_r).Arb;    --3
279
  pwr_mode_out <= memory_r (curr_page_r).Power;  --4 
280
  max_send_out <= memory_r (curr_page_r).MSend;  --5
281
 
282
 
283
 
284
  -- Check generic values
285
--   assert (id_width_g + cfg_addr_width_g < addr_width_g+1) report
286
--     "Illegal generic values (Id-, page- or param_addr_width_c" severity error;
287
 
288
--   assert (param_addr_width_c + page_addr_width_c < cfg_addr_width_g+1) report
289
--     "Illegal generic values (Id-, page- or param_addr_width_c" severity error;
290
 
291
 
292
 
293
  -- PROCESSES                          -----------------------------------------------------------------
294
  --
295
  -- 1) PROC
296
  -- Split the incoming config address to separate page and parameter number.
297
  -- Check incoming page and param numbers
298
  -- If they are illegal, internal write and read enbale signals are reset to
299
  -- zero => Nothing happens inside config mem, no checks needed elsewhere than here
300
  -- 
301
  Split_addr_in : process (addr_in,
302
                           we_in,
303
                           re_in
304
                           )
305
  begin  -- process Split_addr_in
306
    if conv_integer (addr_in (page_addr_width_c + param_addr_width_c-1 downto param_addr_width_c)) > n_cfg_pages_g
307
      or conv_integer (addr_in (param_addr_width_c-1 downto 0)) > page_size_c then
308
      -- Illegal page or parameter  number
309
      page_num  <= 0;
310
      param_num <= 0;
311
      we_int    <= '0';
312
      re_int    <= '0';
313
      assert false report "Illegal addr to cfg mem" severity warning;
314
    else
315
      -- Valid page and parameter numbers
316
      page_num  <= conv_integer (addr_in (page_addr_width_c+param_addr_width_c-1 downto param_addr_width_c));
317
      param_num <= conv_integer (addr_in (param_addr_width_c-1 downto 0));
318
      we_int    <= we_in;
319
      re_int    <= re_in;
320
    end if;
321
 
322
  end process Split_addr_in;
323
 
324
 
325
 
326
  -- 2) PROC
327
  -- Write new values to memory if needed, count clock cycles and time slots
328
  Main : process (clk, rst_n)
329
 
330
    variable Start_v            : std_logic_vector(counter_width_g-1 downto 0);
331
    variable Stop_v             : std_logic_vector(counter_width_g-1 downto 0);
332
    variable Owner_v            : std_logic_vector(id_width_g-1 downto 0);
333
    variable curr_slot_own_v    : std_logic;
334
    variable curr_slot_ends_v   : std_logic;
335
    variable next_slot_own_v    : std_logic;
336
    variable next_slot_starts_v : std_logic;
337
 
338
  begin  -- process Main
339
 
340
    if rst_n = '0' then                 -- asynchronous reset (active low)
341
 
342
      -- Reset cycle counter
343
      for i in 1 to n_cfg_pages_g loop
344
        curr_cycle_r (i) <= (others => '0');  -- vai 1?
345
      end loop;  -- i
346
 
347
      -- Reset all values in memory
348
      for i in 1 to n_cfg_pages_g loop
349
        memory_r (i).Arb   <= conv_std_logic_vector(arb_type_g, 2);  -- 3
350
        memory_r (i).Power <= (others => '0');                       -- 4
351
        memory_r (i).Frame <= conv_std_logic_vector (tframe_c (i), counter_width_g);  -- 6
352
        --memory_r (i).Frame <= conv_std_logic_vector (60, counter_width_g); -- (others => '0');  -- 6
353
        --memory_r (i).Inva  <= '0';              -- 7
354
      end loop;  -- i
355
 
356
      -- Assign generic values to memory
357
      for i in 1 to n_cfg_pages_g loop
358
        memory_r (i).Prior <= conv_std_logic_vector (prior_g, id_width_g);
359
        memory_r (i).N_ag  <= conv_std_logic_vector (n_agents_g, id_width_g);
360
        memory_r (i).MSend <= conv_std_logic_vector (max_send_g, counter_width_g);
361
        --if inv_addr_en_g = 0 then
362
        --  memory_r (i).Inva <= '0';
363
        --else
364
        --  memory_r (i).Inva <= '1';
365
        --end if;
366
 
367
      end loop;  -- i
368
 
369
 
370
      if n_time_slots_g > 0 then
371
        for p in 1 to n_cfg_pages_g loop
372
          for s in 0 to n_time_slots_g-1 loop
373
            tslot_r (p) (ind_tslot_c + s*3+0) <= conv_std_logic_vector (9, counter_width_g);
374
            tslot_r (p) (ind_tslot_c + s*3+1) <= conv_std_logic_vector (13, counter_width_g);
375
            tslot_r (p) (ind_tslot_c + s*3+2) <= conv_std_logic_vector (3, counter_width_g);
376
 
377
 
378
            if p < (max_n_cfg_pages_c+1) and s < max_n_tslots_c then
379
 
380
              tslot_start_r (p) (ind_tslot_c + s)                      <= conv_std_logic_vector (tslot_start_c (p) (s), counter_width_g);
381
              tslot_stop_r (p) (ind_tslot_c + n_time_slots_tmp_c + s)  <= conv_std_logic_vector (tslot_stop_c (p) (s), counter_width_g);
382
              tslot_id_r (p) (ind_tslot_c + 2* n_time_slots_tmp_c + s) <= conv_std_logic_vector (tslot_id_c (p) (s), id_width_g);
383
 
384
            else
385
              tslot_start_r (p) (ind_tslot_c + s)                      <= (others => '0');
386
              tslot_stop_r (p) (ind_tslot_c + n_time_slots_tmp_c + s)  <= (others => '0');
387
              tslot_id_r (p) (ind_tslot_c + 2* n_time_slots_tmp_c + s) <= (others => '0');
388
 
389
            end if;
390
 
391
 
392
          end loop;  -- s
393
        end loop;  -- p
394
      end if;
395
 
396
      -- Reset extra parameters
397
--       for p in 1 to n_cfg_pages_g loop
398
--         for e in ind_extra_c to ind_extra_c+ n_extra_params_g-1 loop
399
--           extra_param_r (p) (e) <= (others => '0');
400
--         end loop;  -- e
401
--       end loop;  -- p
402
 
403
      curr_page_r                   <= 1;
404
      curr_slot_own_r               <= '0';
405
      curr_slot_ends_r              <= '0';
406
      next_slot_own_r               <= '0';
407
      next_slot_starts_r            <= '0';
408
      if dbg_level > 0 then dbg_out <= 55; end if;
409
 
410
 
411
 
412
    elsif clk'event and clk = '1' then  -- rising clock edge
413
 
414
      -- default assignments
415
      tslot_r       <= tslot_r;
416
      tslot_start_r <= tslot_start_r;
417
      tslot_stop_r  <= tslot_stop_r;
418
      tslot_id_r    <= tslot_id_r;
419
      curr_cycle_r  <= curr_cycle_r;
420
      -- extra_param_r <= extra_param_r;
421
 
422
 
423
      if cfg_we_g = 1
424
        and we_int = '1'
425
      then
426
 
427
        if page_num = conv_std_logic_vector (0, page_addr_width_c) then
428
          -- Special case when page num is zero
429
 
430
          if param_num = conv_std_logic_vector (0, param_addr_width_c) then
431
            -- Change page when both page and parameter number are zero
432
            -- Check that the new page num is valid (i.e. not zero)
433
            if data_in (page_addr_width_c-1 downto 0) <= n_cfg_pages_g
434
                                                         and data_in (page_addr_width_c-1 downto 0) /= conv_std_logic_vector (0, page_addr_width_c)
435
            then
436
 
437
              curr_page_r                   <= conv_integer (data_in (page_addr_width_c-1 downto 0));
438
              memory_r                      <= memory_r;
439
              --assert false report "Change page number" severity note;
440
              if dbg_level > 0 then dbg_out <= 100; end if;
441
            else
442
              -- Galaxies will explode, if illegal page number is written into
443
              -- curr page register
444
              curr_page_r                   <= curr_page_r;
445
              memory_r                      <= memory_r;
446
              assert false report "Switch to illegal page number cancelled!" severity note;
447
              if dbg_level > 0 then dbg_out <= 80; end if;
448
            end if;  --data_in
449
          else
450
            -- page num zero, but param num is not => do nothing
451
            curr_page_r                   <= curr_page_r;
452
            memory_r                      <= memory_r;
453
            if dbg_level > 0 then dbg_out <= 81; end if;
454
          end if;  -- param_num =0
455
 
456
 
457
        else
458
          -- 0 < page_num < n_cfg_pages_g
459
          -- Write new parameter value
460
          curr_page_r <= curr_page_r;
461
          memory_r    <= memory_r;
462
 
463
          if param_num < ind_tslot_c then
464
            -- if param_num < ind_baddr_c then
465
            case param_num is
466
              when ind_cycle_c =>
467
                -- param=0, different reg for cycle count
468
                -- Updated elsewhere
469
                if dbg_level > 0 then dbg_out <= ind_cycle_c; end if;
470
              when ind_prior_c =>
471
                memory_r (page_num).Prior     <= data_in (id_width_g-1 downto 0);  -- param = 1                  
472
                if dbg_level > 0 then dbg_out <= ind_prior_c; end if;
473
              when ind_n_ag_c =>
474
                memory_r (page_num).N_ag      <= data_in (id_width_g-1 downto 0);  -- param = 2
475
                if dbg_level > 0 then dbg_out <= ind_n_ag_c; end if;
476
              when ind_arb_c =>
477
                memory_r (page_num).Arb       <= data_in (1 downto 0);  -- param = 3
478
                if dbg_level > 0 then dbg_out <= ind_arb_c; end if;
479
              when ind_pwr_c =>
480
                memory_r (page_num).Power     <= data_in (1 downto 0);  -- param = 4 
481
                if dbg_level > 0 then dbg_out <= ind_pwr_c; end if;
482
              when ind_msend_c =>
483
                memory_r (page_num).MSend     <= data_in (counter_width_g-1 downto 0);  -- param = 5  
484
                if dbg_level > 0 then dbg_out <= ind_msend_c; end if;
485
              when ind_frame_c =>
486
                if n_time_slots_g > 0 then
487
                  memory_r (page_num).Frame <= data_in (counter_width_g-1 downto 0);  -- param = 6 
488
                end if;
489
                if dbg_level > 0 then dbg_out <= ind_frame_c; end if;
490
              when ind_inva_c =>
491
                --memory_r (page_num).Inva      <= data_in ( 0);  -- param = 7  
492
                if dbg_level > 0 then dbg_out <= ind_inva_c; end if;
493
                assert false report "Trying to write address invert enable" severity warning;
494
 
495
              when ind_baddr_c =>       -- param = 8
496
                -- moved here 16.12.2005
497
                -- Address is now constant, do not updata
498
                if dbg_level > 0 then dbg_out <= ind_baddr_c; end if;
499
                assert false report "Trying to write address" severity warning;
500
 
501
              when others =>
502
                assert false report "Incorrect parameter number" severity warning;
503
                if dbg_level > 0 then dbg_out <= 99; end if;
504
            end case;
505
 
506
          else
507
            -- 16.12.2005 elsif param_num < ind_extra_c then
508
            -- Assign time slot parameters
509
            if n_time_slots_g > 0 then
510
              tslot_r (page_num) (param_num) <= data_in (counter_width_g-1 downto 0);
511
 
512
              if param_num < (ind_tslot_c + n_time_slots_tmp_c) then
513
                tslot_start_r (page_num) (param_num) <= data_in (counter_width_g-1 downto 0);
514
 
515
              elsif param_num < (ind_tslot_c + 2*n_time_slots_tmp_c) then
516
                tslot_stop_r (page_num) (param_num) <= data_in (counter_width_g-1 downto 0);
517
 
518
              else
519
                tslot_id_r (page_num) (param_num) <= data_in (id_width_g-1 downto 0);
520
              end if;
521
 
522
 
523
 
524
            end if;
525
            assert dbg_level < 1 report "Set time slots" severity note;
526
            if dbg_level > 0 then dbg_out <= ind_tslot_c; end if;
527
 
528
--          else
529
--             -- Assign extra parameters
530
--             if n_extra_params_g > 0 then
531
--               extra_param_r (page_num) (param_num) <= data_in;
532
--             end if;
533
--             assert dbg_level < 1 report "Set extra params" severity note;
534
--             if dbg_level > 0 then dbg_out          <= ind_extra_c; end if;
535
          end if;  -- param_num >= ind_baddr_c                      
536
        end if;  -- page_num =0
537
 
538
      else
539
        -- WE =0 or illegal addr => memory_r remains static
540
        curr_page_r                   <= curr_page_r;
541
        --memory_r      <= memory_r;
542
        if dbg_level > 0 then dbg_out <= 64; end if;
543
      end if;  -- WE =1
544
 
545
 
546
      -- Counters are only needed for time slots
547
      if n_time_slots_g > 0 then
548
 
549
        -- Clock cycle counter (parameter number is 0)
550
        if param_num = conv_std_logic_vector (0, param_addr_width_c)
551
          and page_num /= conv_std_logic_vector (0, page_addr_width_c)
552
          and we_int = '1' then
553
 
554
          -- Write new value to curr cycle register
555
 
556
          if page_num = curr_page_r then
557
            -- Write on current page
558
            curr_cycle_r               <= curr_cycle_r;  --just in case 
559
            curr_cycle_r (curr_page_r) <= data_in (counter_width_g-1 downto 0);
560
          else
561
            -- Write to inactive page, clock cycle on current page is incremented 
562
            curr_cycle_r            <= curr_cycle_r;     --just in case 
563
            curr_cycle_r (page_num) <= data_in (counter_width_g-1 downto 0);
564
 
565
            -- Clock cycle counter goes from 1 to FrameLength
566
            -- counter is reseted to 1
567
            if (curr_cycle_r (curr_page_r) = memory_r (curr_page_r).Frame
568
                and (memory_r (curr_page_r).Frame) /= conv_std_logic_vector (0, counter_width_g)) then
569
              -- and (memory_r (curr_page_r).Frame) /= conv_std_logic_vector (0, data_width_g) ) then
570
              curr_cycle_r (curr_page_r) <= conv_std_logic_vector (1, counter_width_g);
571
            else
572
              curr_cycle_r (curr_page_r) <= curr_cycle_r (curr_page_r) + 1;
573
            end if;
574
          end if;  --page_num = curr_page_r
575
 
576
        else
577
          -- current clock counter is incremented
578
 
579
          curr_cycle_r <= curr_cycle_r;
580
          -- Clock cycle counter goes from 1 to FrameLength
581
          if (curr_cycle_r (curr_page_r) = memory_r (curr_page_r).Frame
582
              and (memory_r (curr_page_r).Frame) /= conv_std_logic_vector (0, counter_width_g)) then
583
            --and (memory_r (curr_page_r).Frame) /= conv_std_logic_vector (0, data_width_g) )then
584
            -- counter is reseted to 1
585
            curr_cycle_r (curr_page_r) <= conv_std_logic_vector(1, counter_width_g);
586
          else
587
            curr_cycle_r (curr_page_r) <= curr_cycle_r (curr_page_r) + 1;
588
          end if;
589
        end if;  --param_num =ind_cycle_c+1
590
 
591
      end if;  -- n_time_slots_g
592
 
593
 
594
 
595
 
596
      -- Time slot signals are produced with a loop
597
 
598
      -- Goal: Bus is reserved one cycle after start=1
599
      --       and start writing on the cycle following reservation
600
      --       However, bus is released (lock=0) on the cycle following end=1
601
      --       The last data is written into bus at the time as lock=0
602
      curr_slot_own_v    := '0';
603
      curr_slot_ends_v   := '0';
604
      next_slot_own_v    := '0';
605
      next_slot_starts_v := '0';
606
 
607
      for i in 0 to n_time_slots_g - 1 loop
608
 
609
        Start_v := tslot_start_r (curr_page_r)(ind_tslot_c + i);
610
        Stop_v  := tslot_stop_r (curr_page_r)(ind_tslot_c + n_time_slots_tmp_c + i);
611
        Owner_v := tslot_id_r (curr_page_r)(ind_tslot_c + 2 * n_time_slots_tmp_c + i);
612
 
613
        --Start_v := tslot_r (curr_page_r)(ind_tslot_c + 3 * i);
614
        --Stop_v  := tslot_r (curr_page_r)(ind_tslot_c + 3 * i + 1);
615
        --Owner_v := tslot_r (curr_page_r)(ind_tslot_c + 3 * i + 2)(id_width_g-1 downto 0);
616
 
617
 
618
 
619
        -- Will current time slot end?
620
        -- elsif makes sure that active bit one is not overwritten
621
        -- (when rest of the time slots are compared)
622
        if (curr_cycle_r (curr_page_r) = Stop_v) then
623
          curr_slot_ends_v := '1';
624
        elsif (curr_slot_ends_v = '1') then
625
          curr_slot_ends_v := '1';
626
        else
627
          curr_slot_ends_v := '0';
628
        end if;
629
 
630
        -- Will own time slot start next?
631
        if ((curr_cycle_r (curr_page_r) = Start_v)
632
             and (Owner_v = conv_std_logic_vector (id_g, id_width_g))) then
633
          next_slot_own_v := '1';
634
        elsif (next_slot_own_v = '1') then
635
          next_slot_own_v := '1';
636
        else
637
          next_slot_own_v := '0';
638
        end if;
639
 
640
        -- Will some other time slot (not own) start next?
641
        if (curr_cycle_r (curr_page_r) = Start_v) then
642
          next_slot_starts_v := '1';
643
        elsif (next_slot_starts_v = '1') then
644
          next_slot_starts_v := '1';
645
        else
646
          next_slot_starts_v := '0';
647
        end if;
648
 
649
        -- current time slot is own, if
650
        -- 1) own time slot starts now
651
        -- 2) already found a matching slot
652
        -- 3) own time slot on the run
653
        -- 4) AND time slot does not stop now
654
        -- 5) AND no other slot will start (see below)
655
        -- During reconfiguration, clock cycle may jump to value
656
        -- that does not belong into any slot. Consequently, the
657
        -- agent initializing reconfiguration may think that it still
658
        -- has the slot (curr_own=1). This 'extra' piece of time slot
659
        -- ends at least when some other agent starts its own slot.
660
        -- It should be noted that stop signal may be absent in such situation
661
        -- (because actually there is no slot)
662
        -- 
663
 
664
        if ((next_slot_starts_r = '1' and next_slot_own_r = '1')   -- 1
665
             or (curr_slot_own_v = '1' or curr_slot_own_r = '1'))  -- 2 & 3
666
          and curr_slot_ends_r = '0'    -- 4
667
          and not (next_slot_starts_r = '1' and next_slot_own_r = '0')  -- 5
668
        then
669
 
670
          curr_slot_own_v := '1';
671
 
672
        else
673
          curr_slot_own_v := '0';
674
        end if;
675
 
676
      end loop;  -- i
677
 
678
      -- Assign output register values
679
      curr_slot_own_r    <= curr_slot_own_v;
680
      curr_slot_ends_r   <= curr_slot_ends_v;
681
      next_slot_own_r    <= next_slot_own_v;
682
      next_slot_starts_r <= next_slot_starts_v;
683
 
684
 
685
    end if;  -- rst_n elsif clk'event
686
  end process Main;
687
 
688
 
689
 
690
  -- 3) PROC
691
  Reading_values : process (re_int, page_num, param_num, memory_r,
692
                            curr_page_r, curr_cycle_r,
693
                            tslot_r,
694
                            tslot_start_r, tslot_stop_r, tslot_id_r  --, extra_param_r                          
695
                            )
696
  begin  -- process Reading_values
697
 
698
    -- 28.02.2005, Design compiler uses latches without this
699
    -- default assignment
700
    data_out <= (others => '0');
701
 
702
    if cfg_re_g = 1 then
703
      if re_int = '1' then
704
 
705
        if page_num = 0 then
706
          if param_num = 0 then
707
            -- Read curr page number        
708
            data_out <= conv_std_logic_vector (curr_page_r, data_width_g);
709
 
710
          elsif param_num = 1 then
711
            -- Read ID
712
            data_out <= conv_std_logic_vector (id_g, data_width_g);
713
 
714
          elsif param_num = 2 then
715
            -- Read base ID
716
            assert false
717
              report "Illegal addres : There's no base_id_g anymore!"
718
              severity warning;
719
            data_out <= (others => '0');
720
            --data_out <= conv_std_logic_vector (base_id_g, data_width_g);
721
          end if;
722
 
723
        elsif page_num > n_cfg_pages_g or param_num > page_size_c then
724
          -- Read either a non-existent param or from non-existent page
725
          data_out <= (others => '0');  -- 'Z'); NOTE:'Z' only for test purposes!
726
          assert false report "Illegal addres : I though this is obsolete line in code" severity warning;
727
          -- Read enable should be reseted to zero, and this branch cannot be reached
728
 
729
        else
730
          -- Read a regular parameter
731
          -- that means 0 < page < n_cfg_pages_g
732
 
733
          if param_num < ind_tslot_c then
734
            -- if param_num < ind_baddr_c then
735
            case param_num is
736
              when ind_cycle_c =>
737
                data_out                              <= (others => '0');
738
                data_out (counter_width_g-1 downto 0) <= curr_cycle_r (page_num);  --param = 0
739
 
740
              when ind_prior_c =>
741
                data_out                         <= (others => '0');
742
                data_out (id_width_g-1 downto 0) <= memory_r (page_num).Prior;  -- param = 1
743
 
744
              when ind_n_ag_c =>
745
                data_out                         <= (others => '0');
746
                data_out (id_width_g-1 downto 0) <= memory_r (page_num).N_ag;  -- param = 2
747
 
748
              when ind_arb_c =>
749
                data_out              <= (others => '0');
750
                data_out (1 downto 0) <= memory_r (page_num).Arb;  -- param = 3
751
 
752
              when ind_pwr_c =>
753
                data_out              <= (others => '0');
754
                data_out (1 downto 0) <= memory_r (page_num).Power;  -- param = 4 
755
 
756
              when ind_msend_c =>
757
                data_out                              <= (others => '0');
758
                data_out (counter_width_g-1 downto 0) <= memory_r (page_num).MSend;  -- param = 5  
759
 
760
              when ind_frame_c =>
761
                data_out                              <= (others => '0');
762
                data_out (counter_width_g-1 downto 0) <= memory_r (page_num).Frame;  -- param = 6
763
 
764
              when ind_inva_c =>
765
                data_out <= (others => '0');
766
                -- data_out ( 0) <= memory_r (page_num).Inva;  -- param = 7  
767
                data_out <= conv_std_logic_vector (inv_addr_en_g, data_width_g);
768
 
769
              when ind_baddr_c =>       --param = 8
770
                -- Read address
771
                assert false report "Read address" severity note;
772
                data_out <= conv_std_logic_vector (addr_g, data_width_g);  --14.04                
773
 
774
              when others =>
775
                data_out <= (others => '0');
776
                assert false report "Incorrect parameter number" severity warning;
777
            end case;
778
 
779
 
780
          else
781
            -- elsif param_num >= ind_tslot_c and param_num < ind_extra_c then
782
            -- Read time slot parameters
783
            -- param = (ind_tslot_c, ind_tslot_c + n_tslots-1)
784
            data_out <= (others => '0');
785
            if n_time_slots_g > 0 then
786
              data_out (counter_width_g-1 downto 0) <= tslot_r (page_num) (param_num);
787
 
788
              if param_num < (ind_tslot_c + n_time_slots_tmp_c) then
789
                data_out (counter_width_g-1 downto 0) <= tslot_start_r (page_num) (param_num);
790
 
791
              elsif param_num < (ind_tslot_c + 2*n_time_slots_tmp_c) then
792
                data_out (counter_width_g-1 downto 0) <= tslot_stop_r (page_num) (param_num);
793
 
794
              else
795
                data_out (id_width_g-1 downto 0) <= tslot_id_r (page_num) (param_num);
796
              end if;
797
 
798
            end if;
799
            assert dbg_level < 1 report "Read time slots" severity note;
800
 
801
 
802
            -- Removed 16.12.2005
803
--           else
804
--             -- Read extra parameters
805
--             -- param = (ind_extra_c, ind_extra_c + n_extra_params_g-1)
806
--             data_out   <= (others => '0');
807
--             if n_extra_params_g > 0 then
808
--               data_out <= extra_param_r (page_num) (param_num);
809
--             end if;
810
--             assert dbg_level < 1 report "Read extra params" severity note;
811
 
812
          end if;  -- param_num < ind_baddr_c          
813
        end if;  -- page_num = 0
814
      else
815
        data_out <= (others => '0');
816
      end if;  --re_int
817
    else
818
      data_out <= (others => '0');
819
    end if;  -- cfg_re_g
820
  end process Reading_values;
821
 
822
 
823
 
824
end rtl;

powered by: WebSVN 2.1.0

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