Skip to content

Commit 5c135db

Browse files
Formatting output
1 parent a986260 commit 5c135db

35 files changed

+2140
-1970
lines changed

hdl/ip/vhd/arb_mux_demux/arbiter.vhd

100755100644
Lines changed: 116 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,116 @@
1-
-- This Source Code Form is subject to the terms of the Mozilla Public
2-
-- License, v. 2.0. If a copy of the MPL was not distributed with this
3-
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.
4-
--
5-
-- Copyright 2024 Oxide Computer Company
6-
7-
-- Note: Documentation can be rendered in VSCode using the TerosHDL
8-
-- plugin: https://terostechnology.github.io/terosHDLdoc/
9-
--! A simple request arbiter that can do priority or round-robbin arbitration
10-
--! Built generically using unconstrained arrays.
11-
--! In Priority mode, the LSB (0) gets the highest priority.
12-
--! In round-robbin mode, the LSB gets the priority only when there was not a grant in the previous
13-
--! cycle and two requests occur simultaneously.
14-
--! A goal is to do this in a single cycle, without having to scan the request bits so that
15-
--! this scales well with increasing vectors.
16-
--! This arbiter uses the fact that <number> AND <two's complement of number> gives
17-
--! you a vector with the lowest (right-most) bit of <number> set
18-
library ieee;
19-
use ieee.std_logic_1164.all;
20-
use ieee.numeric_std.all;
21-
22-
use work.arbiter_pkg.arbiter_mode;
23-
24-
entity arbiter is
25-
generic
26-
(
27-
--! Using arbiter_pkg.arbiter_mode enum, choose
28-
--! arbiter type
29-
MODE : arbiter_mode
30-
);
31-
port
32-
(
33-
clk : in std_logic;
34-
reset : in std_logic;
35-
--! Request vector blocks requesting arbitration must
36-
--! assert their request until grant has been asserted
37-
--! grant remains until request is de-asserted.
38-
requests : in std_logic_vector;
39-
--! This block asserts grant signals, and holds them
40-
--! until the the associated request signal drops.
41-
grants : out std_logic_vector
42-
);
43-
end entity;
44-
architecture rtl of arbiter is
45-
constant ZEROS : unsigned(requests'range) := (others => '0');
46-
signal requests_int : unsigned(requests'range);
47-
signal requests_masked_twos : unsigned(requests'range);
48-
signal requests_masked : unsigned(requests'range);
49-
signal requests_last : unsigned(requests'range);
50-
signal grants_int : unsigned(requests'range);
51-
signal grants_last : unsigned(requests'range);
52-
signal grants_mask : unsigned(requests'range);
53-
signal req_vec_f_edge : unsigned(requests'range);
54-
signal req_f_edge : std_logic;
55-
begin
56-
requests_int <= unsigned(requests);
57-
round_robin_mode : if MODE = ROUND_ROBIN generate
58-
-- This uses a grant-masking scheme to generate round-robin grant behavior.
59-
-- We want to mask off the previous granted channel and any lower bits
60-
-- so the upper bits get a round-robin chance.
61-
grants_mask <= not (grants_last or (grants_last - 1));
62-
63-
-- Mask the requests based on the current grant mask, unless we have no active requests or grants, in
64-
-- which case, pass the unmasked vector through
65-
requests_masked <= requests_int and grants_mask when (requests_int and grants_mask) /= 0 else
66-
requests_int;
67-
else generate
68-
-- In priority mode, we needn't mask grants since the priority encoder takes over
69-
-- and we will allow multiple grants to the same requester to the exclusion of others
70-
-- given the desired priority.
71-
grants_mask <= (others => '0');
72-
requests_masked <= requests_int;
73-
end generate;
74-
75-
-- Build two's complement, remember basic boolean math? 2's complement = (not <dat>) + 1
76-
requests_masked_twos <= (not requests_masked) + 1;
77-
78-
fedge_detects : for i in requests_int'range generate
79-
req_vec_f_edge(i) <= '1' when requests_int(i) = '0' and requests_last(i) = '1' else
80-
'0';
81-
end generate;
82-
--Unary OR reduction, active when any bit is active
83-
req_f_edge <= or req_vec_f_edge;
84-
85-
the_arbiter : process (clk)
86-
begin
87-
if reset then
88-
grants_int <= ZEROS;
89-
grants_last <= (others => '0');
90-
requests_last <= (others => '0');
91-
elsif rising_edge(clk) then
92-
-- Store history for edge detector
93-
requests_last <= requests_int;
94-
-- To determine a grant, we take the currently active requests vector,
95-
-- which is masked by the allowable requests in round-robbin mode, and then
96-
-- bitwise AND that with it's two's complement
97-
-- to get 1 bit active as our active grant.
98-
grants_int <= requests_masked and requests_masked_twos;
99-
if req_f_edge then
100-
-- Note: we expect requesters of this to hold request high until they both have the grant,
101-
-- and are finished with their current transaction. This means that falling edges of
102-
-- requests cause arbitration updates and we save the current grant for use in round-robin
103-
-- arbitration next time.
104-
grants_last <= grants_int;
105-
end if;
106-
end if;
107-
end process;
108-
109-
grants <= std_logic_vector(grants_int);
110-
111-
end architecture;
1+
-- This Source Code Form is subject to the terms of the Mozilla Public
2+
-- License, v. 2.0. If a copy of the MPL was not distributed with this
3+
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
--
5+
-- Copyright 2024 Oxide Computer Company
6+
7+
-- Note: Documentation can be rendered in VSCode using the TerosHDL
8+
-- plugin: https://terostechnology.github.io/terosHDLdoc/
9+
--! A simple request arbiter that can do priority or round-robbin arbitration
10+
--! Built generically using unconstrained arrays.
11+
--! In Priority mode, the LSB (0) gets the highest priority.
12+
--! In round-robbin mode, the LSB gets the priority only when there was not a grant in the previous
13+
--! cycle and two requests occur simultaneously.
14+
--! A goal is to do this in a single cycle, without having to scan the request bits so that
15+
--! this scales well with increasing vectors.
16+
--! This arbiter uses the fact that <number> AND <two's complement of number> gives
17+
--! you a vector with the lowest (right-most) bit of <number> set
18+
19+
library ieee;
20+
use ieee.std_logic_1164.all;
21+
use ieee.numeric_std.all;
22+
use work.arbiter_pkg.arbiter_mode;
23+
24+
entity arbiter is
25+
generic (
26+
27+
--! Using arbiter_pkg.arbiter_mode enum, choose
28+
--! arbiter type
29+
mode : arbiter_mode
30+
);
31+
port (
32+
clk : in std_logic;
33+
reset : in std_logic;
34+
--! Request vector blocks requesting arbitration must
35+
--! assert their request until grant has been asserted
36+
--! grant remains until request is de-asserted.
37+
requests : in std_logic_vector;
38+
--! This block asserts grant signals, and holds them
39+
--! until the the associated request signal drops.
40+
grants : out std_logic_vector
41+
);
42+
end entity;
43+
44+
architecture rtl of arbiter is
45+
46+
constant zeros : unsigned(requests'range) := (others => '0');
47+
signal requests_int : unsigned(requests'range);
48+
signal requests_masked_twos : unsigned(requests'range);
49+
signal requests_masked : unsigned(requests'range);
50+
signal requests_last : unsigned(requests'range);
51+
signal grants_int : unsigned(requests'range);
52+
signal grants_last : unsigned(requests'range);
53+
signal grants_mask : unsigned(requests'range);
54+
signal req_vec_f_edge : unsigned(requests'range);
55+
signal req_f_edge : std_logic;
56+
57+
begin
58+
59+
requests_int <= unsigned(requests);
60+
61+
round_robin_mode : if mode = ROUND_ROBIN generate
62+
-- This uses a grant-masking scheme to generate round-robin grant behavior.
63+
-- We want to mask off the previous granted channel and any lower bits
64+
-- so the upper bits get a round-robin chance.
65+
grants_mask <= not (grants_last or (grants_last - 1));
66+
67+
-- Mask the requests based on the current grant mask, unless we have no active requests or grants, in
68+
-- which case, pass the unmasked vector through
69+
requests_masked <= requests_int and grants_mask when (requests_int and grants_mask) /= 0 else
70+
requests_int;
71+
else generate
72+
-- In priority mode, we needn't mask grants since the priority encoder takes over
73+
-- and we will allow multiple grants to the same requester to the exclusion of others
74+
-- given the desired priority.
75+
grants_mask <= (others => '0');
76+
requests_masked <= requests_int;
77+
end generate;
78+
79+
-- Build two's complement, remember basic boolean math? 2's complement = (not <dat>) + 1
80+
requests_masked_twos <= (not requests_masked) + 1;
81+
82+
fedge_detects : for i in requests_int'range generate
83+
req_vec_f_edge(i) <= '1' when requests_int(i) = '0' and requests_last(i) = '1' else
84+
'0';
85+
end generate;
86+
87+
-- Unary OR reduction, active when any bit is active
88+
req_f_edge <= or req_vec_f_edge;
89+
90+
the_arbiter : process (clk)
91+
begin
92+
if reset then
93+
grants_int <= zeros;
94+
grants_last <= (others => '0');
95+
requests_last <= (others => '0');
96+
elsif rising_edge(clk) then
97+
-- Store history for edge detector
98+
requests_last <= requests_int;
99+
-- To determine a grant, we take the currently active requests vector,
100+
-- which is masked by the allowable requests in round-robbin mode, and then
101+
-- bitwise AND that with it's two's complement
102+
-- to get 1 bit active as our active grant.
103+
grants_int <= requests_masked and requests_masked_twos;
104+
if req_f_edge then
105+
-- Note: we expect requesters of this to hold request high until they both have the grant,
106+
-- and are finished with their current transaction. This means that falling edges of
107+
-- requests cause arbitration updates and we save the current grant for use in round-robin
108+
-- arbitration next time.
109+
grants_last <= grants_int;
110+
end if;
111+
end if;
112+
end process;
113+
114+
grants <= std_logic_vector(grants_int);
115+
116+
end rtl;

hdl/ip/vhd/arb_mux_demux/arbiter_pkg.vhd

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
--
55
-- Copyright 2024 Oxide Computer Company
66

7-
87
--! Common shared information for arbiters
98
package arbiter_pkg is
109

11-
type arbiter_mode is (PRIORITY, ROUND_ROBIN);
10+
type arbiter_mode is (priority, round_robin);
1211

13-
end package;
12+
end package;

hdl/ip/vhd/arb_mux_demux/sims/arbiter_sim_pkg.vhd

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,56 @@
55
-- Copyright 2024 Oxide Computer Company
66

77
library ieee;
8-
use ieee.std_logic_1164.all;
9-
use ieee.numeric_std.all;
8+
use ieee.std_logic_1164.all;
9+
use ieee.numeric_std.all;
1010

1111
library vunit_lib;
12-
context vunit_lib.vunit_context;
13-
context vunit_lib.com_context;
14-
12+
context vunit_lib.vunit_context;
13+
context vunit_lib.com_context;
1514
use work.gpio_msg_pkg.all;
1615

1716
package arbiter_sim_pkg is
1817

19-
procedure set_arb(
20-
signal net : inout network_t;
18+
procedure set_arb (
19+
signal net : inout network_t;
2120
variable msg_target :in actor_t;
22-
variable data: in std_logic_vector
21+
variable data : in std_logic_vector
2322
);
24-
procedure get_grant(
25-
signal net : inout network_t;
23+
24+
procedure get_grant (
25+
signal net : inout network_t;
2626
variable msg_target :in actor_t;
27-
variable data: out std_logic_vector
27+
variable data : out std_logic_vector
2828
);
2929

3030
end package;
3131

3232
package body arbiter_sim_pkg is
3333

34-
procedure set_arb(
35-
signal net : inout network_t;
34+
procedure set_arb (
35+
signal net : inout network_t;
3636
variable msg_target :in actor_t;
37-
variable data: in std_logic_vector
37+
variable data : in std_logic_vector
3838
) is
39-
variable send_data: std_logic_vector(GPIO_MESAGE_DATA_WDITH - 1 downto 0) := (others => '0');
39+
40+
variable send_data : std_logic_vector(GPIO_MESAGE_DATA_WDITH - 1 downto 0) := (others => '0');
41+
4042
begin
4143
send_data(data'range) := data;
4244
set_gpio(net, msg_target, send_data);
4345
end;
44-
procedure get_grant(
45-
signal net : inout network_t;
46+
47+
procedure get_grant (
48+
signal net : inout network_t;
4649
variable msg_target :in actor_t;
47-
variable data: out std_logic_vector
50+
variable data : out std_logic_vector
4851
) is
49-
variable get_data: std_logic_vector(GPIO_MESAGE_DATA_WDITH - 1 downto 0) := (others => '0');
52+
53+
variable get_data : std_logic_vector(GPIO_MESAGE_DATA_WDITH - 1 downto 0) := (others => '0');
54+
5055
begin
5156
get_gpio(net, msg_target, get_data);
5257
data := get_data(data'range);
5358
end;
54-
end package body;
59+
60+
end package body;

0 commit comments

Comments
 (0)