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

Subversion Repositories sd_mmc_emulator

[/] [sd_mmc_emulator/] [trunk/] [rtl/] [bus_arbiter_pack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jclaytons
--------------------------------------------------------------------------
2
-- Package
3
--
4
 
5
library IEEE;
6
use IEEE.STD_LOGIC_1164.ALL;
7
use IEEE.NUMERIC_STD.ALL;
8
use IEEE.MATH_REAL.ALL;
9
 
10
package bus_arbiter_pack is
11
 
12
  component bus_arbiter_N_way
13
    generic(
14
      LOCKING : integer; -- Nonzero to hold until ack_i is received.
15
      N_VALUE : integer; -- Number of bus requestors.
16
      LOG2_N  : integer  -- Bit width of msel_o
17
    );
18
    port (
19
      -- System Clock and Clock Enable
20
      sys_rst_n   : in  std_logic;
21
      sys_clk     : in  std_logic;
22
      sys_clk_en  : in  std_logic;
23
 
24
      -- Bus Access Request Inputs
25
      req_i       : in  unsigned(N_VALUE-1 downto 0);
26
 
27
      -- Status
28
      cyc_o       : out std_logic;
29
      hold_o      : out std_logic; -- Bus lock
30
 
31
      -- Ram Access Acknowledge
32
      ack_i       : in  std_logic; -- Releases lock
33
 
34
      -- Ram Selection (Use to control external muxes)
35
      msel_o      : out unsigned(LOG2_N-1 downto 0);
36
      msel_new_o  : out std_logic
37
    );
38
  end component;
39
 
40
  component bus_arbiter_dataflow_N_way
41
    generic(
42
      LOCKING : integer; -- Nonzero to hold until ack_i is received.
43
      N_VALUE : integer; -- Number of bus requestors.
44
      LOG2_N  : integer  -- Bit width of msel_o
45
    );
46
    port (
47
      -- System Clock and Clock Enable
48
      sys_rst_n   : in  std_logic;
49
      sys_clk     : in  std_logic;
50
      sys_clk_en  : in  std_logic;
51
 
52
      -- Bus Access Request Inputs
53
      req_i       : in  unsigned(N_VALUE-1 downto 0);
54
 
55
      -- Status
56
      cyc_o       : out std_logic;
57
      hold_o      : out std_logic; -- Bus lock
58
 
59
      -- Ram Access Acknowledge
60
      ack_i       : in  std_logic; -- Releases lock
61
 
62
      -- Ram Selection (Use to control external muxes)
63
      msel_o      : out unsigned(LOG2_N-1 downto 0);
64
      msel_new_o  : out std_logic
65
    );
66
  end component;
67
 
68
  component bus_requester_N_way
69
    generic(
70
      N_VALUE : integer -- Number of bus requestors.
71
    );
72
    port (
73
      -- System Clock and Clock Enable
74
      sys_rst_n   : in  std_logic;
75
      sys_clk     : in  std_logic;
76
      sys_clk_en  : in  std_logic;
77
 
78
      -- Single "master" Bus Access Request and acknowledge
79
      req_i       : in  std_logic;
80
      ack_o       : out std_logic;
81
 
82
      -- A multiplicity of subordinate bus requests
83
      n_req_o     : out unsigned(N_VALUE-1 downto 0);
84
 
85
      -- A multiplicity of subordinate Bus Access Acknowledge signals
86
      n_ack_i     : in  unsigned(N_VALUE-1 downto 0)
87
 
88
    );
89
  end component;
90
 
91
 
92
end bus_arbiter_pack;
93
 
94
-------------------------------------------------------------------------------
95
-- Bus Access Arbitration Module
96
-------------------------------------------------------------------------------
97
--
98
-- Author: John Clayton
99
-- Date  : July 13, 2011 Copied code from "bus_arbiter_4_way" to begin.
100
--                       I am hoping to derive a more parameterized
101
--                       module.
102
--         Sept 11, 2012 After much successful use in hardware, I have
103
--                       revisited this module and simplified it so that
104
--                       requests are immediately driven out to msel.
105
--                       The intent is to eliminate wasted clock cycles.
106
--         Nov. 21, 2012 I have discovered that I was using an external
107
--                       mux for the bus_cyc signal, which is fairly
108
--                       understandable, since I'm using external muxes
109
--                       for nearly everything...  However, in the case
110
--                       of the bys_cyc signal, there is an unnecessary
111
--                       "opportunity for error" since bus_cyc is always
112
--                       set to the currently selected request line. It
113
--                       occurred to me that this can be moved inside
114
--                       the module, thereby eliminating the possibility
115
--                       of connecting it up incorrectly outside the
116
--                       module.  Thus, I'm adding the cyc_o signal.
117
--         May  15, 2013 While simulating a design, I discovered that
118
--                       while one request is active, another request
119
--                       may arrive which alters the state of msel_next,
120
--                       thus altering the output msel_o.  This is a flaw
121
--                       since requesters may be depending on the value
122
--                       of msel_o in order to receive acknowledgments,
123
--                       and could therefore erroneously see a ack when
124
--                       msel_o changed.  A new statement was added to
125
--                       "lock out" changes to msel_next while the current
126
--                       request is still active.
127
--         May  23, 2013 Because accesses through multiple arbiters using
128
--                       a single cycle seemed "aggressive" I put in a
129
--                       one cycle delay here.  This arbiter has the
130
--                       advantage now of not synthesizing any latches...
131
--                       The "dataflow" version could still be used, perhaps,
132
--                       reliably with a delayed acknowledge signal!
133
--         Feb.  6, 2014 Added cyc_l for fast clearing of cyc_o.
134
--         Feb. 11, 2014 Added LOCKING generic and hold_o output, to
135
--                       permit locking the arbiter until ack_i is
136
--                       received.
137
--                 
138
--
139
-- Description
140
-------------------------------------------------------------------------------
141
-- This module is an N way request arbitration unit.  There are N high
142
-- asserted request inputs.  When any subset of these is asserted, the arbitrator
143
-- causes its "msel" (multiplexer select address) output to control muxes that
144
-- route the appropriate request to the bus.
145
--
146
-- This unit is meant to coordinate access to a single resource bus, by N requesters.
147
-- The access is not exactly fair, since there is no timeout implemented here.
148
-- Thus, a requester must implement its own timeout, and if it never receives
149
-- an acknoledge signal, and never deasserts its request line, then the bus
150
-- will be "hogged" by that requester for ever.  The purpose of this module
151
-- is not to rip away the bus from a misbehaving or irresponsible requester.
152
-- Rather, this module gives out access to the bus in turns.  Each turn must
153
-- be fairly conducted by the requester.
154
--
155
-- There is a single acknowledge signal from the single bus.  The assertion of
156
-- the ack_i signal for one sys_clk edge is sufficient to terminate the current
157
-- access cycle, and cause this unit to change the msel_o output to route signals
158
-- from the next requester to the memory bus.  This same termination condition
159
-- should be respected by all requesters using this module.
160
--
161
-- The reason that external muxes are used to send the bus signals to the RAM is
162
-- to enable other muxes to be controlled for additional processing, e.g. an
163
-- offset engine which modifies the address presented to the bus, with the offset
164
-- being different depending on which requester is using the bus.
165
--
166
-- The policy of "fairness" followed by this module is of the "round robin" type.
167
-- In other words, each request when completed, is followed by a grant to the next
168
-- request, in order 0,1,2,...N-1,0,1...  There is no requirement for the request
169
-- lines to be returned to the inactive state before they can be asserted and
170
-- recognized again as valid requests.
171
--
172
-- There is a "parking" philosophy implemented in this module, which works in the
173
-- following way:  Whenever a request is completed, if there are no other pending
174
-- requests, the msel_o output remains in its current state.  This is probably
175
-- not an important fact, except to note that the most recent requester, already
176
-- having control of the memory bus, gets its next request granted one cycle faster
177
-- than usual, since its new request doesn't need to cause any change in the muxes
178
-- to grant it access to the memory bus.
179
--
180
-- Following reset, the msel_o output is set to zero, meaning that the bus is parked
181
-- for quickest access by requester zero.  Note that it is the user's responsibility
182
-- to ensure that the connections to the external muxes are made in such a way as to
183
-- correspond to the request inputs, according to this mapping:
184
--
185
--      Request Input         Corresponding msel_o output
186
--      -------------         ---------------------------
187
--        req_i(0)                       00b
188
--        req_i(1)                       01b
189
--         .....                         ...
190
--        req_i(N-1)                     unsigned(N-1)
191
--
192
-- All storage elements within this module are clocked according to the positive edge
193
-- of the sys_clk input, qualified by the sys_clk_en input being asserted high.  In
194
-- this way, sys_clk_en can be used to run this module at slower rates than sys_clk.
195
--
196
-- The sys_rst_n input is an asynchronous reset.
197
 
198
library IEEE;
199
use IEEE.STD_LOGIC_1164.ALL;
200
use IEEE.NUMERIC_STD.ALL;
201
use IEEE.MATH_REAL.ALL;
202
 
203
entity bus_arbiter_N_way is
204
    generic(
205
      LOCKING : integer := 0; -- Nonzero to hold until ack_i is received.
206
      N_VALUE : integer := 4; -- Number of bus requestors.
207
      LOG2_N  : integer := 2  -- Bit width of msel_o
208
    );
209
    port (
210
      -- System Clock and Clock Enable
211
      sys_rst_n   : in  std_logic;
212
      sys_clk     : in  std_logic;
213
      sys_clk_en  : in  std_logic;
214
 
215
      -- Access Request Inputs
216
      req_i       : in  unsigned(N_VALUE-1 downto 0);
217
 
218
      -- Status
219
      cyc_o       : out std_logic;
220
      hold_o      : out std_logic; -- Bus lock
221
 
222
      -- Ram Access Acknowledge
223
      ack_i       : in  std_logic; -- Releases lock
224
 
225
      -- Selection (Use to control external muxes)
226
      msel_o      : out unsigned(LOG2_N-1 downto 0);
227
      msel_new_o  : out std_logic
228
    );
229
end bus_arbiter_N_way;
230
 
231
architecture beh of bus_arbiter_N_way is
232
 
233
  -- Constants
234
 
235
  -- Functions & associated types
236
 
237
  -- Signal Declarations
238
  signal msel_l        : unsigned(LOG2_N-1 downto 0);
239
  signal msel_prior    : unsigned(LOG2_N-1 downto 0);
240
  signal req_asserted  : std_logic;
241
  signal cyc_l         : std_logic;
242
  signal hold_l        : std_logic;
243
 
244
begin
245
 
246
-- Combine all incoming request signals into a single signal indicating
247
-- there is at least one request active.
248
req_asserted <= '1' when (req_i/=0) else '0';
249
 
250
process (sys_clk, sys_clk_en, sys_rst_n)
251
variable l : integer := 0;
252
variable k : integer := 0;
253
begin
254
  if (sys_rst_n='0') then
255
    msel_l     <= (others=>'0');
256
    msel_prior <= (others=>'0');
257
    cyc_l  <= '0';
258
    hold_l <= '0';
259
  elsif (sys_clk'event and sys_clk='1') then
260
    if (sys_clk_en='1') then
261
      for j in 0 to N_VALUE-1 loop
262
        l := j+to_integer(msel_l);
263
        -- Use an if statement to apply "modulo N_VALUE"
264
        if (l>=N_VALUE) then
265
          k := l-N_VALUE;
266
        else
267
          k := l;
268
        end if;
269
        if (req_i(k)='1') then
270
          msel_l <= to_unsigned(k,LOG2_N);
271
        end if;
272
      end loop;
273
      -- Lock out changes to msel_l when current request is still active
274
      if LOCKING=0 then
275
        if req_i(to_integer(msel_l))='1' then
276
          msel_l <= msel_l;
277
        end if;
278
      else
279
        if hold_l='1' and ack_i='0' then
280
          msel_l <= msel_l;
281
        end if;
282
      end if;
283
      -- Handle hold_l signal
284
      if LOCKING=1 then
285
        -- clear hold
286
        if (hold_l='1' and ack_i='1') then
287
          hold_l <= '0';
288
        end if;
289
        -- Setting hold has higher priority than clearing hold
290
        if req_i(to_integer(msel_l))='1' and (hold_l='0' or (hold_l='1' and ack_i='1')) then
291
          hold_l <= '1';
292
        end if;
293
      end if;
294
      -- Save previous msel_l value, to support msel_new_o
295
      msel_prior <= msel_l;
296
      -- Provide the currently selected request line as an
297
      -- arbiter-wide bus cycle signal
298
      cyc_l <= req_i(to_integer(msel_l));
299
    end if; -- sys_clk_en
300
  end if; -- sys_clk
301
end process;
302
 
303
msel_o <= msel_l;
304
msel_new_o <= '1' when (msel_prior/=msel_l) else '0';
305
 
306
-- Clear the bus cycle output immediately upon removal of request.
307
cyc_o <= cyc_l and req_asserted;
308
 
309
-- Provide hold output
310
hold_o <= hold_l;
311
 
312
end beh;
313
 
314
-------------------------------------------------------------------------------
315
-- Bus Access Arbitration Module - Dataflow version
316
-------------------------------------------------------------------------------
317
--
318
-- Author: John Clayton
319
-- Date  : July 13, 2011 Copied code from "bus_arbiter_4_way" to begin.
320
--                       I am hoping to derive a more parameterized
321
--                       module.
322
--         Sept 11, 2012 After much successful use in hardware, I have
323
--                       revisited this module and simplified it so that
324
--                       requests are immediately driven out to msel.
325
--                       The intent is to eliminate wasted clock cycles.
326
--         Nov. 21, 2012 I have discovered that I was using an external
327
--                       mux for the bus_cyc signal, which is fairly
328
--                       understandable, since I'm using external muxes
329
--                       for nearly everything...  However, in the case
330
--                       of the bys_cyc signal, there is an unnecessary
331
--                       "opportunity for error" since bus_cyc is always
332
--                       set to the currently selected request line. It
333
--                       occurred to me that this can be moved inside
334
--                       the module, thereby eliminating the possibility
335
--                       of connecting it up incorrectly outside the
336
--                       module.  Thus, I'm adding the cyc_o signal.
337
--         May  15, 2013 While simulating a design, I discovered that
338
--                       while one request is active, another request
339
--                       may arrive which alters the state of msel_next,
340
--                       thus altering the output msel_o.  This is a flaw
341
--                       since requesters may be depending on the value
342
--                       of msel_o in order to receive acknowledgments,
343
--                       and could therefore erroneously see a ack when
344
--                       msel_o changed.  A new statement was added to
345
--                       "lock out" changes to msel_next while the current
346
--                       request is still active.
347
--         Feb. 11, 2014 Added LOCKING generic and hold_o output, to
348
--                       permit locking the arbiter until ack_i is
349
--                       received.
350
--                 
351
--
352
-- Description
353
-------------------------------------------------------------------------------
354
-- This module is an N way request arbitration unit.  There are N high
355
-- asserted request inputs.  When any subset of these is asserted, the arbitrator
356
-- causes its "msel" (multiplexer select address) output to control muxes that
357
-- route the appropriate request to the bus.
358
--
359
-- This unit is meant to coordinate access to a single resource bus, by N requesters.
360
-- The access is not exactly fair, since there is no timeout implemented here.
361
-- Thus, a requester must implement its own timeout, and if it never receives
362
-- an acknoledge signal, and never deasserts its request line, then the bus
363
-- will be "hogged" by that requester for ever.  The purpose of this module
364
-- is not to rip away the bus from a misbehaving or irresponsible requester.
365
-- Rather, this module gives out access to the bus in turns.  Each turn must
366
-- be fairly conducted by the requester.
367
--
368
-- There is a single acknowledge signal from the single bus.  The assertion of
369
-- the ack_i signal for one sys_clk edge is sufficient to terminate the current
370
-- access cycle, and cause this unit to change the msel_o output to route signals
371
-- from the next requester to the memory bus.  This same termination condition
372
-- should be respected by all requesters using this module.
373
--
374
-- The reason that external muxes are used to send the bus signals to the RAM is
375
-- to enable other muxes to be controlled for additional processing, e.g. an
376
-- offset engine which modifies the address presented to the bus, with the offset
377
-- being different depending on which requester is using the bus.
378
--
379
-- The policy of "fairness" followed by this module is of the "round robin" type.
380
-- In other words, each request when completed, is followed by a grant to the next
381
-- request, in order 0,1,2,...N-1,0,1...  There is no requirement for the request
382
-- lines to be returned to the inactive state before they can be asserted and
383
-- recognized again as valid requests.
384
--
385
-- There is a "parking" philosophy implemented in this module, which works in the
386
-- following way:  Whenever a request is completed, if there are no other pending
387
-- requests, the msel_o output remains in its current state.  This is probably
388
-- not an important fact, except to note that the most recent requester, already
389
-- having control of the memory bus, gets its next request granted one cycle faster
390
-- than usual, since its new request doesn't need to cause any change in the muxes
391
-- to grant it access to the memory bus.
392
--
393
-- Following reset, the msel_o output is set to zero, meaning that the bus is parked
394
-- for quickest access by requester zero.  Note that it is the user's responsibility
395
-- to ensure that the connections to the external muxes are made in such a way as to
396
-- correspond to the request inputs, according to this mapping:
397
--
398
--      Request Input         Corresponding msel_o output
399
--      -------------         ---------------------------
400
--        req_i(0)                       00b
401
--        req_i(1)                       01b
402
--         .....                         ...
403
--        req_i(N-1)                     unsigned(N-1)
404
--
405
-- All storage elements within this module are clocked according to the positive edge
406
-- of the sys_clk input, qualified by the sys_clk_en input being asserted high.  In
407
-- this way, sys_clk_en can be used to run this module at slower rates than sys_clk.
408
--
409
-- The sys_rst_n input is an asynchronous reset.
410
--
411
-- This version of the bus arbiter is a "dataflow" version in the sense that the
412
-- msel_o outputs change immediately upon a request input going high, thus allowing
413
-- for a bus cycle to be arbitrated and acknowledged in fewer sys_clk periods.
414
--
415
-- However, it synthesizes a latch in the msel_next process.  If this is nettlesome,
416
-- then do not use it...
417
 
418
library IEEE;
419
use IEEE.STD_LOGIC_1164.ALL;
420
use IEEE.NUMERIC_STD.ALL;
421
use IEEE.MATH_REAL.ALL;
422
 
423
entity bus_arbiter_dataflow_N_way is
424
    generic(
425
      LOCKING : integer := 0; -- Nonzero to hold until ack_i is received.
426
      N_VALUE : integer := 4; -- Number of bus requestors.
427
      LOG2_N  : integer := 2  -- Bit width of msel_o
428
    );
429
    port (
430
      -- System Clock and Clock Enable
431
      sys_rst_n   : in  std_logic;
432
      sys_clk     : in  std_logic;
433
      sys_clk_en  : in  std_logic;
434
 
435
      -- Ram Access Request Inputs
436
      req_i       : in  unsigned(N_VALUE-1 downto 0);
437
 
438
      -- Status
439
      cyc_o       : out std_logic;
440
      hold_o      : out std_logic; -- Bus lock
441
 
442
      -- Ram Access Acknowledge
443
      ack_i       : in  std_logic; -- Releases lock
444
 
445
      -- Ram Selection (Use to control external muxes)
446
      msel_o      : out unsigned(LOG2_N-1 downto 0);
447
      msel_new_o  : out std_logic
448
    );
449
end bus_arbiter_dataflow_N_way;
450
 
451
architecture beh of bus_arbiter_dataflow_N_way is
452
 
453
  -- Constants
454
 
455
  -- Functions & associated types
456
 
457
  -- Signal Declarations
458
  -- type msel_type is integer range 0 to N_VALUE-1; -- changed to integer for the simulator...
459
  -- signal msel_l        : msel_type := 0;
460
  -- signal msel_prev     : msel_type := 0;
461
  signal msel_next     : unsigned(LOG2_N-1 downto 0);
462
  signal msel_l        : unsigned(LOG2_N-1 downto 0);
463
  signal msel_prior    : unsigned(LOG2_N-1 downto 0);
464
  signal req_asserted  : std_logic;
465
  signal hold_l        : std_logic;
466
 
467
begin
468
 
469
-- Combine all incoming request signals into a single signal indicating
470
-- there is at least one request active.
471
req_asserted <= '1' when (req_i/=0) else '0';
472
 
473
process (msel_l,req_i)
474
-- type msel_modulo_type is integer range 0 to 2*N_VALUE-1; -- changed to integer, to satisfy simulator...
475
-- variable l : msel_modulo_type := 0;
476
-- variable k : msel_type := 0;
477
variable l : integer := 0;
478
variable k : integer := 0;
479
begin
480
  -- Change mux selections based on request and ack inputs.
481
  msel_next <= msel_l; -- Default value, prevents latch formation
482
  for j in 0 to N_VALUE-1 loop
483
    l := j+to_integer(msel_l);
484
    -- Use an if statement to apply "modulo N_VALUE"
485
    if (l>=N_VALUE) then
486
      k := l-N_VALUE;
487
    else
488
      k := l;
489
    end if;
490
    if (req_i(k)='1') then
491
      msel_next <= to_unsigned(k,LOG2_N);
492
    end if;
493
  end loop;
494
  -- Lock out changes to msel_next when current request is still active
495
  if LOCKING=0 then
496
    if req_i(to_integer(msel_l))='1' then
497
      msel_next <= msel_next;
498
    end if;
499
  else
500
    if (hold_l='1' and ack_i='0') then
501
      msel_next <= msel_next;
502
    end if;
503
  end if;
504
end process;
505
 
506
process (sys_clk, sys_clk_en, sys_rst_n)
507
begin
508
  if (sys_rst_n='0') then
509
    msel_l     <= (others=>'0');
510
    msel_prior <= (others=>'0');
511
    hold_l <= '0';
512
  elsif (sys_clk'event and sys_clk='1') then
513
    if (sys_clk_en='1') then
514
      msel_prior <= msel_next;
515
      if LOCKING=0 then
516
        if req_asserted='1' then
517
          msel_l <= msel_next;
518
        end if;
519
      else
520
        if req_asserted='1' and (hold_l='0' or (hold_l='1' and ack_i='1')) then
521
          msel_l <= msel_next;
522
        end if;
523
      end if;
524
 
525
      -- Handle the hold_l signal
526
        -- clear hold
527
      if (hold_l='1' and ack_i='1') then
528
        hold_l <= '0';
529
      end if;
530
        -- Setting hold has higher priority than clearing hold
531
      if req_i(to_integer(msel_l))='1' and LOCKING=1 then
532
        if (hold_l='0' or (hold_l='1' and ack_i='1')) then
533
          hold_l <= '1';
534
        end if;
535
      end if;
536
 
537
    end if; -- sys_clk_en
538
  end if; -- sys_clk
539
end process;
540
 
541
msel_o <= msel_next;
542
msel_new_o <= '1' when (msel_prior/=msel_next) else '0';
543
 
544
-- Provide the currently selected request line as an
545
-- arbiter-wide bus cycle signal
546
cyc_o <= req_i(to_integer(msel_next));
547
 
548
hold_o <= '0';
549
 
550
end beh;
551
 
552
-------------------------------------------------------------------------------
553
-- Multiple Bus Access Request Module
554
-------------------------------------------------------------------------------
555
--
556
-- Author: John Clayton
557
-- Date  : Feb.  3, 2014 Copied code from "bus_arbiter_N_way" to begin.
558
--
559
-- Description
560
-------------------------------------------------------------------------------
561
-- This module is an N way bus request unit.  It is meant for those rare days
562
-- when a single bus cycle is issued to multiple buses, all of which must
563
-- acknowledge the cycle before the request can be considered fulfilled.
564
--
565
-- Asserting a single "master" req_i signal gives rise to the assertion of a
566
-- multiplicity of bus request req_o signals.  Each of these is then used to
567
-- generate a bus cycle, with its associated acknowledge ack_i handshake signal
568
-- in return.  When each ack_i handshake is received, the associated request
569
-- line is deasserted.  However, the main "master" acknowledge is not given
570
-- until all the ack_i inputs have been received.
571
--
572
-- This module does not implement a cycle timeout of any kind.  Therefore, if
573
-- any of the multiple requested cycles does not complete, the master cycle
574
-- will remain unacknowledged, and it can "hang" forever in this state.  You
575
-- have been warned!
576
--
577
-- This is a "dataflow" unit in the sense that asserting req_i immediately
578
-- asserts the req_o signals, without any clock delays.  The acknowledge
579
-- ack_i inputs do not, however, immediately deassert the req_o outputs.
580
-- Instead, the req_o outputs are deasserted after one clock cycle.
581
--
582
-- Isn't that just as "clear as mud?"
583
--
584
-- The sys_rst_n input is an asynchronous reset.
585
 
586
library IEEE;
587
use IEEE.STD_LOGIC_1164.ALL;
588
use IEEE.NUMERIC_STD.ALL;
589
use IEEE.MATH_REAL.ALL;
590
 
591
entity bus_requester_N_way is
592
    generic(
593
      N_VALUE : integer := 2 -- Number of bus requestors.
594
    );
595
    port (
596
      -- System Clock and Clock Enable
597
      sys_rst_n   : in  std_logic;
598
      sys_clk     : in  std_logic;
599
      sys_clk_en  : in  std_logic;
600
 
601
      -- Single "master" Bus Access Request and acknowledge
602
      req_i       : in  std_logic;
603
      ack_o       : out std_logic;
604
 
605
      -- A multiplicity of subordinate bus requests
606
      n_req_o     : out unsigned(N_VALUE-1 downto 0);
607
 
608
      -- A multiplicity of subordinate Bus Access Acknowledge signals
609
      n_ack_i     : in  unsigned(N_VALUE-1 downto 0)
610
 
611
    );
612
end bus_requester_N_way;
613
 
614
architecture beh of bus_requester_N_way is
615
 
616
  -- Constants
617
 
618
  -- Functions & associated types
619
 
620
  -- Signal Declarations
621
  signal req_l    : unsigned(N_VALUE-1 downto 0);
622
  signal req_msk  : unsigned(N_VALUE-1 downto 0);
623
 
624
begin
625
 
626
process (sys_clk, sys_clk_en, sys_rst_n)
627
variable k : integer := 0;
628
begin
629
  if (sys_rst_n='0') then
630
    req_l      <= (others=>'1');
631
  elsif (sys_clk'event and sys_clk='1') then
632
    if (sys_clk_en='1') then
633
      -- Clear internal request bits when acknowledged
634
      for k in 0 to N_VALUE-1 loop
635
        if (n_ack_i(k)='1') then
636
          req_l(k) <= '0';
637
        end if;
638
      end loop;
639
      -- Reset the internal request bits
640
      if (req_i='0') then
641
        req_l <= (others=>'1');
642
      end if;
643
    end if; -- sys_clk_en
644
  end if; -- sys_clk
645
end process;
646
 
647
n_req_gen : for i in 0 to N_VALUE-1 generate
648
  n_req_o(i) <= '1' when req_i='1' and req_l(i)='1' else '0';
649
end generate n_req_gen;
650
 
651
-- The masked version of req_l proleptically reflects the request
652
-- bits which are about to be cleared.
653
req_msk <= req_l and (not n_ack_i);
654
 
655
ack_o <= '1' when req_i='1' and req_msk=0 else '0';
656
 
657
end beh;
658
 
659
 

powered by: WebSVN 2.1.0

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