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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : HIBI RX Control
3
-- Project    : Nocbench, Funbase
4
-------------------------------------------------------------------------------
5
-- File       : rx_control.vhd
6
-- Authors    : Lasse Lehtonen
7
-- Company    : Tampere University of Technology
8
-- Created    :
9
-- Last update: 2011-11-28
10
-- Platform   : 
11
-- Standard   : VHDL'93
12
-------------------------------------------------------------------------------
13
-- Description: Receive side control logic
14
-- 
15
-- Main function is to halt bus if getting data that doesn't fit in RX buffers.
16
-- Bus is also halted if configure mem is tried to be read/written and previous
17
-- config mem read hasn't been already replied to or this wrappper is locked
18
-- by exclusive lock and getting something other than exclusive commands.
19
--
20
-------------------------------------------------------------------------------
21
-- Copyright (c) 2010 Tampere University of Technology
22
--
23
-- 
24
-------------------------------------------------------------------------------
25
-- Revisions  :
26
-- Date        Version  Author  Description
27
-- 2010-10-13  1.0      ase     Created
28
-------------------------------------------------------------------------------
29
-- Funbase IP library Copyright (C) 2011 TUT Department of Computer Systems
30
--
31
-- This file is part of HIBI
32
--
33
-- This source file may be used and distributed without
34
-- restriction provided that this copyright statement is not
35
-- removed from the file and that any derivative work contains
36
-- the original copyright notice and the associated disclaimer.
37
--
38
-- This source file is free software; you can redistribute it
39
-- and/or modify it under the terms of the GNU Lesser General
40
-- Public License as published by the Free Software Foundation;
41
-- either version 2.1 of the License, or (at your option) any
42
-- later version.
43
--
44
-- This source is distributed in the hope that it will be
45
-- useful, but WITHOUT ANY WARRANTY; without even the implied
46
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
47
-- PURPOSE.  See the GNU Lesser General Public License for more
48
-- details.
49
--
50
-- You should have received a copy of the GNU Lesser General
51
-- Public License along with this source; if not, download it
52
-- from http://www.opencores.org/lgpl.shtml
53
-------------------------------------------------------------------------------
54
 
55
library ieee;
56
use ieee.std_logic_1164.all;
57
use ieee.numeric_std.all;
58
 
59
use work.hibiv3_pkg.all;
60
 
61
 
62
 
63
entity rx_control is
64
  generic (
65
    data_width_g     : integer;
66
    addr_width_g     : integer;
67
    id_width_g       : integer;
68
    cfg_addr_width_g : integer;
69
    cfg_re_g         : integer;
70
    cfg_we_g         : integer;
71
    separate_addr_g  : integer;
72
    is_bridge_g      : integer
73
    );
74
  port (
75
    clk   : in std_logic;
76
    rst_n : in std_logic;
77
 
78
    -- Bus interface
79
    av_in    : in  std_logic;
80
    data_in  : in  std_logic_vector(data_width_g-1 downto 0);
81
    comm_in  : in  std_logic_vector(comm_width_c-1 downto 0);
82
    full_out : out std_logic;
83
 
84
    -- IP (fifo) side interface
85
    data_0_out : out std_logic_vector(data_width_g-1 downto 0);
86
    comm_0_out : out std_logic_vector(comm_width_c-1 downto 0);
87
    av_0_out   : out std_logic;
88
    we_0_out   : out std_logic;
89
    full_0_in  : in  std_logic;
90
    one_p_0_in : in  std_logic;
91
 
92
    data_1_out : out std_logic_vector(data_width_g-1 downto 0);
93
    comm_1_out : out std_logic_vector(comm_width_c-1 downto 0);
94
    av_1_out   : out std_logic;
95
    we_1_out   : out std_logic;
96
    full_1_in  : in  std_logic;
97
    one_p_1_in : in  std_logic;
98
 
99
    -- Address decoder interface
100
    addr_match_in       : in std_logic;  -- data is for this IP
101
    id_match_in         : in std_logic;  -- Configure data is for this wrapper
102
    norm_cmd_in         : in std_logic;  -- '1' for normal commands
103
    msg_cmd_in          : in std_logic;  -- '1' for normal commands
104
    conf_re_cmd_in      : in std_logic;  -- '1' for conf read
105
    conf_we_cmd_in      : in std_logic;  -- '1' for conf write
106
    excl_lock_cmd_in    : in std_logic;  -- '1' for exclusive lock
107
    excl_data_cmd_in    : in std_logic;  -- '1' for exclusive read/write
108
    excl_release_cmd_in : in std_logic;  -- '1' for exclusive release
109
 
110
    -- Configure memory related (to cfg_mem and tx_control)
111
    cfg_rd_rdy_in    : in  std_logic;
112
    cfg_we_out       : out std_logic;
113
    cfg_re_out       : out std_logic;
114
    cfg_addr_out     : out std_logic_vector(cfg_addr_width_g-1 downto 0);
115
    cfg_data_out     : out std_logic_vector
116
    (data_width_g-1-(separate_addr_g*addr_width_g) downto 0);
117
    cfg_ret_addr_out : out std_logic_vector(addr_width_g-1 downto 0)
118
    );
119
 
120
end rx_control;
121
 
122
 
123
 
124
 
125
architecture rtl of rx_control is
126
 
127
  -----------------------------------------------------------------------------
128
  -- FUNCTIONS
129
  -----------------------------------------------------------------------------
130
  function isBridge(constant is_bridge : integer)
131
    return std_logic is
132
  begin  -- function isBridge
133
    if is_bridge /= 0 then
134
      return '1';
135
    else
136
      return '0';
137
    end if;
138
  end function isBridge;
139
 
140
  -----------------------------------------------------------------------------
141
  -- CONSTANTS
142
  -----------------------------------------------------------------------------
143
  constant is_bridge_c : std_logic := isBridge(is_bridge_g);
144
 
145
  -----------------------------------------------------------------------------
146
  -- OUPUT REGISTERS
147
  -----------------------------------------------------------------------------
148
 
149
  -- Hibi side
150
  -- '1' when block can't accept incoming transfer
151
  signal full_out_r : std_logic;
152
 
153
  -- IP (fifo) side, two priorities
154
  signal data_0_out_r : std_logic_vector(data_width_g-1 downto 0);
155
  signal comm_0_out_r : std_logic_vector(comm_width_c-1 downto 0);
156
  signal av_0_out_r   : std_logic;
157
  signal we_0_out_r   : std_logic;
158
 
159
  signal data_1_out_r : std_logic_vector(data_width_g-1 downto 0);
160
  signal comm_1_out_r : std_logic_vector(comm_width_c-1 downto 0);
161
  signal av_1_out_r   : std_logic;
162
  signal we_1_out_r   : std_logic;
163
 
164
  -- Config mem side (cfg_mem and tx_control)
165
  signal cfg_we_out_r   : std_logic;
166
  signal cfg_re_out_r   : std_logic;
167
  signal cfg_addr_out_r : std_logic_vector(cfg_addr_width_g-1 downto 0);
168
  signal cfg_data_out_r : std_logic_vector
169
    (data_width_g-1-(separate_addr_g*addr_width_g) downto 0);
170
  signal cfg_ret_addr_out_r : std_logic_vector(addr_width_g-1 downto 0);
171
 
172
  -----------------------------------------------------------------------------
173
  -- OTHER REGISTERS
174
  -----------------------------------------------------------------------------
175
 
176
  -- '1' for the first words of config read/write
177
  signal cfg_re_first_r : std_logic;
178
  signal cfg_we_first_r : std_logic;
179
 
180
  -- '1' when rx_control is locked by exclusive access commands
181
  signal excl_locked_r : std_logic;
182
 
183
  -- '1' when output register to fifo should be written to fifo
184
  -- but fifo is full
185
  signal fifo_0_regs_in_use_r : std_logic;
186
  signal fifo_1_regs_in_use_r : std_logic;
187
 
188
  -- '1' when fifo side regs are being emptied
189
  signal fifo_0_regs_we_r : std_logic;
190
  signal fifo_1_regs_we_r : std_logic;
191
 
192
begin
193
 
194
  -----------------------------------------------------------------------------
195
  -- CONNECT OUTPUTS 
196
  -----------------------------------------------------------------------------  
197
  data_0_out       <= data_0_out_r;
198
  comm_0_out       <= comm_0_out_r;
199
  av_0_out         <= av_0_out_r;
200
  we_0_out         <= we_0_out_r;
201
  data_1_out       <= data_1_out_r;
202
  comm_1_out       <= comm_1_out_r;
203
  av_1_out         <= av_1_out_r;
204
  we_1_out         <= we_1_out_r;
205
  cfg_we_out       <= cfg_we_out_r;
206
  cfg_re_out       <= cfg_re_out_r;
207
  cfg_addr_out     <= cfg_addr_out_r;
208
  cfg_data_out     <= cfg_data_out_r;
209
  cfg_ret_addr_out <= cfg_ret_addr_out_r;
210
  full_out         <= full_out_r;
211
 
212
  -----------------------------------------------------------------------------
213
  -- SYNCHRONOUS LOGIC
214
  -----------------------------------------------------------------------------
215
  main_p : process (clk, rst_n) is
216
 
217
    variable full_out_v           : std_logic;
218
    variable cfg_re_out_v         : std_logic;
219
    variable cfg_we_out_v         : std_logic;
220
    variable we_0_out_v           : std_logic;
221
    variable we_1_out_v           : std_logic;
222
    variable fifo_0_regs_in_use_v : std_logic;
223
    variable fifo_1_regs_in_use_v : std_logic;
224
 
225
  begin  -- process main_p
226
    if rst_n = '0' then                 -- asynchronous reset (active low)
227
 
228
      full_out_r <= '0';
229
 
230
      data_0_out_r <= (others => '0');
231
      comm_0_out_r <= (others => '0');
232
      av_0_out_r   <= '0';
233
      we_0_out_r   <= '0';
234
 
235
      data_1_out_r <= (others => '0');
236
      comm_1_out_r <= (others => '0');
237
      av_1_out_r   <= '0';
238
      we_1_out_r   <= '0';
239
 
240
      cfg_we_out_r       <= '0';
241
      cfg_re_out_r       <= '0';
242
      cfg_addr_out_r     <= (others => '0');
243
      cfg_data_out_r     <= (others => '0');
244
      cfg_ret_addr_out_r <= (others => '0');
245
 
246
      excl_locked_r        <= '0';
247
      fifo_0_regs_in_use_r <= '0';
248
      fifo_1_regs_in_use_r <= '0';
249
      cfg_we_first_r       <= '0';
250
      cfg_re_first_r       <= '0';
251
      fifo_0_regs_we_r     <= '0';
252
      fifo_1_regs_we_r     <= '0';
253
 
254
    elsif clk'event and clk = '1' then  -- rising clock edge
255
 
256
 
257
      ------------------------------------------------------------------------
258
      -- Full output
259
      -------------------------------------------------------------------------
260
      -- Block will be or pretend to be full:
261
      -- IF getting normal command and the fifo is (/becoming) full
262
      -- OR getting normal command and locked by exclusive commands
263
 
264
      -- OR getting exclusive commands and full,
265
      --    only bridges pass excl_lock and excl_release
266
 
267
      -- OR being bridge and conf data to the other side
268
      -- OR getting conf command and previous conf mem read is not yet answered
269
      --    unless the previous command was conf read and this cycle is the
270
      --    return address
271
 
272
      full_out_v :=
273
        (((addr_match_in and norm_cmd_in and (full_1_in or one_p_1_in)) or
274
          (addr_match_in and norm_cmd_in and excl_locked_r) or
275
          (addr_match_in and msg_cmd_in and (full_0_in or one_p_0_in)) or
276
          (addr_match_in and msg_cmd_in and excl_locked_r) or
277
 
278
          (addr_match_in and excl_data_cmd_in and (full_0_in or one_p_0_in)) or
279
          (--is_bridge_c and -- forwanding these too
280
            addr_match_in
281
            and (excl_lock_cmd_in or excl_release_cmd_in)
282
            and (full_0_in or one_p_0_in)) or
283
 
284
          (is_bridge_c and addr_match_in and (conf_re_cmd_in or conf_we_cmd_in)
285
           and (full_0_in or one_p_0_in))
286
          ) and
287
         not full_out_r) or
288
 
289
        (id_match_in and (conf_re_cmd_in or conf_we_cmd_in)
290
         and not cfg_rd_rdy_in and not cfg_re_out_r);
291
 
292
      full_out_r <= full_out_v;
293
 
294
      ------------------------------------------------------------------------
295
      -- Configuration
296
      -------------------------------------------------------------------------
297
      -- Conf mem will be read, if not (pretending) full:
298
      -- IF getting read command and previous cycle was not read command
299
      cfg_re_out_v :=
300
        (id_match_in and not full_out_v and conf_re_cmd_in
301
         and not cfg_re_out_r);
302
 
303
      -- Conf mem will be written, when not full:
304
      -- IF getting conf write command
305
      cfg_we_out_v := (id_match_in and not full_out_v and conf_we_cmd_in);
306
 
307
      if separate_addr_g = 0 then
308
 
309
        cfg_we_first_r <= cfg_we_out_v and not cfg_we_first_r;
310
        cfg_we_out_r   <= cfg_we_first_r;
311
 
312
        cfg_re_first_r <= cfg_re_out_v and not cfg_re_first_r;
313
        cfg_re_out_r   <= cfg_re_first_r;
314
 
315
        -- Set conf mem address:
316
        -- IF conf_re or conf_we will go high next cycle
317
        -- ELSE keep the old value
318
        if (cfg_re_out_v = '1' and cfg_re_first_r = '0')
319
          or (cfg_we_out_v = '1' and cfg_we_first_r = '0')
320
        then
321
          cfg_addr_out_r <= data_in(cfg_addr_width_g-1 downto 0);
322
        end if;
323
 
324
        -- Set config data
325
        -- IF writing to conf memory
326
        -- ELSE keep the previous value
327
        if cfg_we_first_r = '1' then
328
          cfg_data_out_r <= data_in;
329
        end if;
330
 
331
        -- Set config return address
332
        -- IF previous cycle was first conf read command
333
        -- ELSE keep the previous value
334
        if cfg_re_first_r = '1' then
335
          cfg_ret_addr_out_r <= data_in(addr_width_g-1 downto 0);
336
        end if;
337
 
338
      else
339
        -- hibi in SAD mode
340
 
341
        cfg_we_out_r <= cfg_we_out_v;
342
        cfg_re_out_r <= cfg_re_out_v;
343
 
344
        if cfg_we_out_v = '1' then
345
          cfg_addr_out_r <=
346
            data_in(data_width_g-addr_width_g+cfg_addr_width_g-1
347
                    downto data_width_g-addr_width_g);
348
          cfg_data_out_r <= data_in(data_width_g-addr_width_g-1 downto 0);
349
        elsif cfg_re_out_v = '1' then
350
          cfg_addr_out_r <=
351
            data_in(data_width_g-addr_width_g+cfg_addr_width_g-1
352
                    downto data_width_g-addr_width_g);
353
          cfg_ret_addr_out_r <= data_in(addr_width_g-1 downto 0);
354
        end if;
355
 
356
      end if;
357
 
358
      ------------------------------------------------------------------------
359
      -- Writing to fifos
360
      -------------------------------------------------------------------------
361
      -- Write to fifo (towards IP), when not full:
362
      -- IF normal commands
363
      -- OR exclusive data commands
364
      -- OR brigde and conf data to forward
365
      -- OR bridge and exclusive lock or release command
366
      -- OR fifo regs contain unwritten data
367
      we_1_out_v :=
368
        (addr_match_in and not full_out_v and not full_out_r and norm_cmd_in) or
369
        (not full_1_in and fifo_1_regs_in_use_r);
370
 
371
      we_1_out_r <= we_1_out_v;
372
 
373
      we_0_out_v :=
374
        (addr_match_in and not full_out_v and not full_out_r and excl_data_cmd_in) or
375
        (addr_match_in and not full_out_v and not full_out_r and msg_cmd_in) or
376
        (--is_bridge_c and -- forwanding these too
377
          addr_match_in and not full_out_v and not full_out_r and
378
          (excl_lock_cmd_in or excl_release_cmd_in)) or
379
        (is_bridge_c and addr_match_in and not full_out_v and not full_out_r and
380
         (conf_re_cmd_in or conf_we_cmd_in)) or
381
        (not full_0_in and fifo_0_regs_in_use_r);
382
 
383
      we_0_out_r <= we_0_out_v;
384
 
385
      -- To mark that last cycle we_out was '1' because fifo regs were
386
      -- being emptied
387
      fifo_0_regs_we_r <= (not full_0_in and fifo_0_regs_in_use_r);
388
      fifo_1_regs_we_r <= (not full_1_in and fifo_1_regs_in_use_r);
389
 
390
      -- Update data_out, comm_out and av_out
391
      -- IF writing to fifo from bus
392
      -- ELSE They all keep their previous values
393
      if (we_0_out_v = '1' or we_0_out_r = '1') and fifo_0_regs_in_use_r = '0' then
394
        data_0_out_r <= data_in;
395
        comm_0_out_r <= comm_in;
396
        av_0_out_r   <= av_in;
397
      end if;
398
 
399
      if (we_1_out_v = '1' or we_1_out_r = '1') and fifo_1_regs_in_use_r = '0' then
400
        data_1_out_r <= data_in;
401
        comm_1_out_r <= comm_in;
402
        av_1_out_r   <= av_in;
403
      end if;
404
 
405
      -- IP side registers are marked as used if fifos are full but
406
      --  these registers contain information not yet written
407
      fifo_0_regs_in_use_v :=
408
        (we_0_out_r and not fifo_0_regs_we_r and full_out_v and not av_in) or
409
        (not we_0_out_v and fifo_0_regs_in_use_r);
410
 
411
      fifo_0_regs_in_use_r <= fifo_0_regs_in_use_v;
412
 
413
      fifo_1_regs_in_use_v :=
414
        (we_1_out_r and not fifo_1_regs_we_r and full_out_v and not av_in) or
415
        (not we_1_out_v and fifo_1_regs_in_use_r);
416
 
417
      fifo_1_regs_in_use_r <= fifo_1_regs_in_use_v;
418
 
419
 
420
 
421
      ------------------------------------------------------------------------
422
      -- Exclusive accesses
423
      -------------------------------------------------------------------------      
424
      -- Block will be locked for exclusive accesses, when not full:
425
      -- IF getting lock command
426
      -- OR if it was already locked and not getting release command
427
      -- ELSE old value stays
428
 
429
      --excl_locked_r <=
430
      --  (addr_match_in and not full_out_v and excl_lock_cmd_in) or
431
      --  (addr_match_in and not full_out_v and excl_locked_r
432
      --   and not excl_release_cmd_in) or
433
      --  ((not addr_match_in or full_out_v) and excl_locked_r);
434
 
435
      if (addr_match_in and
436
          ((not full_out_v and not full_out_r) or
437
           (not fifo_0_regs_in_use_r and fifo_0_regs_in_use_v))) = '1' then
438
 
439
        if excl_lock_cmd_in = '1' then
440
          excl_locked_r <= '1';
441
        elsif excl_release_cmd_in = '1' then
442
          excl_locked_r <= '0';
443
        end if;
444
 
445
      end if;
446
 
447
    end if;
448
  end process main_p;
449
 
450
 
451
 
452
 
453
end rtl;

powered by: WebSVN 2.1.0

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