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

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

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : HIBI Address decoder
3
-- Project    : HIBI
4
-------------------------------------------------------------------------------
5
-- File       : addr_decoder.vhd
6
-- Authors    : Lasse Lehtonen
7
-- Company    : Tampere University of Technology
8
-- Created    :
9
-- Last update: 2011-10-07
10
-- Platform   : 
11
-- Standard   : VHDL'93
12
-------------------------------------------------------------------------------
13
-- Description: Address and id decoding logic
14
-- 
15
-- Checks if incoming address or configuration id is for this wrapper.
16
-- This assigns match_out also for configuration commands targeted to ids in range
17
-- [id_min_g, id_max_g], so that they go over the bridge (provided
18
-- that id_max_g is not zero, )
19
--
20
-- Combinatorial block = zero clock cycle latency.
21
--
22
-------------------------------------------------------------------------------
23
-- Notes      :
24
--
25
-- If id_max_g /= 0 then this is assumed to be used inside a HIBI bridge.
26
--
27
-- If addr_limit_g == 0 then the old mask style is used to calculate the upper
28
-- address limit (as in HIBI v.2).
29
--
30
-- Own id_g should not be in range [id_min_g, id_max_g]! (this would prevent
31
-- configuring this side of the bridge) (unless it's inverted)
32
--
33
-------------------------------------------------------------------------------
34
-------------------------------------------------------------------------------
35
-- Revisions  :
36
-- Date        Version  Author  Description
37
-- 2010-10-13  1.0      ase     Created
38
-------------------------------------------------------------------------------
39
-------------------------------------------------------------------------------
40
-- Funbase IP library Copyright (C) 2011 TUT Department of Computer Systems
41
--
42
-- This file is part of HIBI
43
--
44
-- This source file may be used and distributed without
45
-- restriction provided that this copyright statement is not
46
-- removed from the file and that any derivative work contains
47
-- the original copyright notice and the associated disclaimer.
48
--
49
-- This source file is free software; you can redistribute it
50
-- and/or modify it under the terms of the GNU Lesser General
51
-- Public License as published by the Free Software Foundation;
52
-- either version 2.1 of the License, or (at your option) any
53
-- later version.
54
--
55
-- This source is distributed in the hope that it will be
56
-- useful, but WITHOUT ANY WARRANTY; without even the implied
57
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
58
-- PURPOSE.  See the GNU Lesser General Public License for more
59
-- details.
60
--
61
-- You should have received a copy of the GNU Lesser General
62
-- Public License along with this source; if not, download it
63
-- from http://www.opencores.org/lgpl.shtml
64
-------------------------------------------------------------------------------
65
 
66
 
67
 
68
library ieee;
69
use ieee.std_logic_1164.all;
70
use ieee.numeric_std.all;
71
 
72
use work.hibiv3_pkg.all;
73
 
74
entity addr_decoder is
75
  generic (
76
    data_width_g    : integer;
77
    addr_width_g    : integer;
78
    id_width_g      : integer;
79
    id_g            : integer;
80
    id_min_g        : integer;          -- Only for bridges, zero for others!
81
    id_max_g        : integer;          -- Only for bridges, zero for others!
82
    addr_base_g     : integer;
83
    addr_limit_g    : integer;
84
    invert_addr_g   : integer;          -- Only for one half of a bridge
85
    cfg_re_g        : integer;
86
    cfg_we_g        : integer;
87
    separate_addr_g : integer
88
    );
89
  port (
90
    clk                  : in  std_logic;
91
    rst_n                : in  std_logic;
92
    -- from bus
93
    av_in                : in  std_logic;
94
    addr_in              : in  std_logic_vector(addr_width_g-1 downto 0);
95
    comm_in              : in  std_logic_vector(comm_width_c-1 downto 0);
96
    bus_full_in          : in  std_logic;
97
    -- decode results
98
    addr_match_out       : out std_logic;  -- address is (was) in my range
99
    id_match_out         : out std_logic;  -- id is for me
100
    norm_cmd_out         : out std_logic;  -- '1' for normal commands
101
    msg_cmd_out          : out std_logic;  -- '1' for message commands
102
    conf_re_cmd_out      : out std_logic;  -- '1' for conf read
103
    conf_we_cmd_out      : out std_logic;  -- '1' for conf write
104
    excl_lock_cmd_out    : out std_logic;  -- '1' for exclusive lock
105
    excl_data_cmd_out    : out std_logic;  -- '1' for exclusive read/write
106
    excl_release_cmd_out : out std_logic   -- '1' for exclusive release
107
    );
108
 
109
end addr_decoder;
110
 
111
 
112
architecture rtl of addr_decoder is
113
 
114
  -----------------------------------------------------------------------------
115
  -- FUNCTIONS
116
  -----------------------------------------------------------------------------
117
 
118
  -- Calculates the upper address limit
119
  function addressLimit (
120
    constant base_address : unsigned)
121
    return unsigned is
122
    variable idx_found_var      : integer;
123
    variable limit_internal_var : unsigned(addr_width_g-1 downto 0);
124
  begin  -- function addressLimit
125
 
126
    if addr_limit_g = 0 then
127
 
128
      assert false
129
        report "Automagically calculating the upper address limit. "
130
        & "FYI: Upper limit can be also set freely with addr_limit_g "
131
        & "generic"
132
        severity note;
133
 
134
      idx_found_var      := 0;
135
      limit_internal_var := (others => '1');
136
 
137
      parse : for i in 0 to (addr_width_g - 1) loop
138
        if base_address(i) = '0' and idx_found_var = 0 then
139
          limit_internal_var(i) := '1';
140
        else
141
          idx_found_var         := 1;
142
          limit_internal_var(i) := base_address(i);
143
        end if;
144
      end loop;  -- i      
145
 
146
    elsif addr_limit_g >= addr_base_g then
147
 
148
      limit_internal_var := to_unsigned(addr_limit_g, addr_width_g);
149
 
150
    else
151
 
152
      assert false
153
        report "Address limit (upper) is smaller than base address"
154
        severity failure;
155
 
156
    end if;
157
 
158
    report "addr_decoder id(" & integer'image(id_g)
159
      & ") id_min(" & integer'image(id_min_g)
160
      & ") id_max(" & integer'image(id_max_g)
161
      & ") invert(" & integer'image(invert_addr_g)
162
      & ")"
163
      severity note;
164
 
165
    return limit_internal_var;
166
 
167
  end function addressLimit;
168
 
169
  -----------------------------------------------------------------------------
170
  -- CONSTANTS
171
  -----------------------------------------------------------------------------
172
 
173
  constant addr_base_c : unsigned(addr_width_g-1 downto 0) :=
174
    to_unsigned(addr_base_g, addr_width_g);
175
 
176
  constant addr_limit_c : unsigned(addr_width_g-1 downto 0) :=
177
    addressLimit(addr_base_c);
178
 
179
  signal addr_base_dummy  : unsigned(addr_width_g-1 downto 0) := addr_base_c;
180
  signal addr_limit_dummy : unsigned(addr_width_g-1 downto 0) := addr_limit_c;
181
 
182
  -----------------------------------------------------------------------------
183
  -- REGISTERS
184
  -----------------------------------------------------------------------------
185
  signal old_addr_match_r : std_logic;
186
  signal old_id_match_r   : std_logic;
187
 
188
  -----------------------------------------------------------------------------
189
  -- COMBINATORIAL SIGNALS
190
  -----------------------------------------------------------------------------
191
  signal addr_match       : std_logic;
192
  signal id_match         : std_logic;
193
  signal norm_cmd         : std_logic;
194
  signal msg_cmd          : std_logic;
195
  signal conf_re_cmd      : std_logic;
196
  signal conf_we_cmd      : std_logic;
197
  signal excl_lock_cmd    : std_logic;
198
  signal excl_data_cmd    : std_logic;
199
  signal excl_release_cmd : std_logic;
200
 
201
 
202
 
203
begin  -- rtl
204
 
205
  -----------------------------------------------------------------------------
206
  -- OUPUTS
207
  -----------------------------------------------------------------------------
208
  addr_match_out       <= addr_match and not bus_full_in;
209
  id_match_out         <= id_match and not bus_full_in;
210
  norm_cmd_out         <= norm_cmd;
211
  msg_cmd_out          <= msg_cmd;
212
  conf_re_cmd_out      <= conf_re_cmd;
213
  conf_we_cmd_out      <= conf_we_cmd;
214
  excl_lock_cmd_out    <= excl_lock_cmd;
215
  excl_data_cmd_out    <= excl_data_cmd;
216
  excl_release_cmd_out <= excl_release_cmd;
217
 
218
  -----------------------------------------------------------------------------
219
  -- SYNCHRONOUS LOGIC
220
  -----------------------------------------------------------------------------
221
  gen_registers : if separate_addr_g = 0 generate
222
 
223
    -- Only needed if address is multiplexed to same bus as data
224
    -- Used to remember the decoding result from last time av_in was '1'
225
 
226
    old_values_p : process (clk, rst_n) is
227
    begin  -- process old_values_p
228
      if rst_n = '0' then               -- asynchronous reset (active low)
229
 
230
        old_addr_match_r <= '0';
231
        old_id_match_r   <= '0';
232
 
233
      elsif clk'event and clk = '1' then  -- rising clock edge
234
 
235
        old_addr_match_r <= addr_match;
236
        old_id_match_r   <= id_match;
237
 
238
      end if;
239
    end process old_values_p;
240
 
241
  end generate gen_registers;
242
 
243
  -----------------------------------------------------------------------------
244
  -- COMBINATORIAL LOGIC
245
  -----------------------------------------------------------------------------
246
  cmd_type : process (comm_in) is
247
  begin  -- process cmd_type
248
 
249
    -- default
250
    norm_cmd         <= '0';
251
    msg_cmd          <= '0';
252
    conf_re_cmd      <= '0';
253
    conf_we_cmd      <= '0';
254
    excl_data_cmd    <= '0';
255
    excl_lock_cmd    <= '0';
256
    excl_release_cmd <= '0';
257
 
258
    if (comm_in = DATA_WR_c
259
        or comm_in = DATA_RD_c
260
        or comm_in = DATA_RDL_c
261
        or comm_in = DATA_WRNP_c
262
        or comm_in = DATA_WRC_c)
263
    then
264
 
265
      norm_cmd <= '1';
266
 
267
    elsif (comm_in = MSG_WR_c
268
           or comm_in = MSG_RD_c
269
           or comm_in = MSG_RDL_c
270
           or comm_in = MSG_WRNP_c
271
           or comm_in = MSG_WRC_c) then
272
 
273
      msg_cmd <= '1';
274
 
275
    elsif (comm_in = EXCL_WR_c or comm_in = EXCL_RD_c) then
276
 
277
      excl_data_cmd <= '1';
278
 
279
    elsif (comm_in = EXCL_LOCK_c) then
280
 
281
      excl_lock_cmd <= '1';
282
 
283
    elsif (comm_in = EXCL_RELEASE_c) then
284
 
285
      excl_release_cmd <= '1';
286
 
287
    elsif (comm_in = CFG_WR_c) then
288
 
289
      conf_we_cmd <= '1';
290
 
291
    elsif (comm_in = CFG_RD_c) then
292
 
293
      conf_re_cmd <= '1';
294
 
295
    end if;
296
 
297
 
298
  end process cmd_type;
299
 
300
 
301
  current_values_p : process (av_in, addr_in, old_addr_match_r,
302
                              old_id_match_r, norm_cmd, msg_cmd,
303
                              conf_re_cmd, conf_we_cmd, excl_lock_cmd,
304
                              excl_data_cmd, excl_release_cmd, comm_in) is
305
 
306
    variable id_in_v            : unsigned(id_width_g-1 downto 0);
307
    variable is_my_id_range_v   : std_logic;
308
    variable is_my_addr_range_v : std_logic;
309
 
310
  begin  -- process current_values_p
311
 
312
    id_in_v := unsigned(addr_in(addr_width_g-1 downto addr_width_g-id_width_g));
313
 
314
    if ((invert_addr_g = 0
315
         and unsigned(addr_in) >= addr_base_c
316
         and unsigned(addr_in) <= addr_limit_c)
317
        or
318
        (invert_addr_g = 1
319
         and (unsigned(addr_in) < addr_base_c
320
              or unsigned(addr_in) > addr_limit_c))) then
321
 
322
      is_my_addr_range_v := '1';
323
    else
324
      is_my_addr_range_v := '0';
325
    end if;
326
 
327
    if ((invert_addr_g = 0
328
         and id_in_v >= to_unsigned(id_min_g, id_width_g)
329
         and id_in_v <= to_unsigned(id_max_g, id_width_g))
330
        or
331
        (invert_addr_g = 1
332
         and (id_in_v < to_unsigned(id_min_g, id_width_g)
333
              or id_in_v > to_unsigned(id_max_g, id_width_g)))) then
334
 
335
      is_my_id_range_v := '1';
336
    else
337
      is_my_id_range_v := '0';
338
    end if;
339
 
340
    -- defaults
341
    addr_match <= '0';
342
    id_match   <= '0';
343
 
344
    if separate_addr_g = 1 or av_in = '1' then
345
 
346
      -- Address matches if it's normal command and address is in our range
347
      -- or for bridges if the incoming id is in the [id_min_g, id_max_g] range
348
      -- invert_addr_g inverts these conditions
349
      if ((norm_cmd = '1'
350
           or msg_cmd = '1'
351
           or excl_data_cmd = '1'
352
           or excl_lock_cmd = '1'
353
           or excl_release_cmd = '1')
354
          and is_my_addr_range_v = '1')
355
        or
356
        (id_max_g /= 0                  -- This must be bridge
357
         and (conf_re_cmd = '1' or conf_we_cmd = '1')
358
         and is_my_id_range_v = '1') then
359
 
360
        addr_match <= '1';
361
 
362
      elsif (cfg_re_g = 1 or cfg_we_g = 1)
363
        and (conf_re_cmd = '1' or conf_we_cmd = '1')
364
        and (id_in_v = to_unsigned(id_g, id_width_g)
365
             or id_in_v = to_unsigned(0, id_width_g)) then
366
 
367
        -- Id matches for config commands where incoming id is our id_g        
368
        id_match <= '1';
369
 
370
        assert cfg_re_g = 1 or comm_in /= CFG_RD_c
371
          report "Got configure memory read command but reading from it"
372
          & " is not enabled"
373
          severity failure;
374
 
375
        assert cfg_we_g = 1 or comm_in /= CFG_WR_c
376
          report "Got configure memory write command but writing to it"
377
          & " is not enabled"
378
          severity failure;
379
 
380
      end if;
381
 
382
    elsif separate_addr_g = 0 then
383
      -- av_in is '0', use old values
384
 
385
      addr_match <= old_addr_match_r;
386
      id_match   <= old_id_match_r;
387
 
388
    end if;
389
 
390
  end process current_values_p;
391
 
392
 
393
end rtl;

powered by: WebSVN 2.1.0

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