Skip to content

Commit 5ba9072

Browse files
committedDec 10, 2013
initial add
1 parent 419858f commit 5ba9072

File tree

4 files changed

+584
-0
lines changed

4 files changed

+584
-0
lines changed
 

‎Arbiter.vhd

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
library ieee;
2+
use ieee.std_logic_1164.all;
3+
use work.PROTOCOL.all;
4+
use work.FUNCTIONS.all;
5+
use work.ARBITER_CONFIG.all;
6+
use work.GLOBAL_PCI_CONFIG.all;
7+
8+
9+
10+
entity PCI_ARB is
11+
12+
port (
13+
RESET_i, CLOCK : in bit;
14+
FRAME_i, IRDY_i : in std_ulogic;
15+
REQ_i : in std_ulogic_vector
16+
(c_Agents - 1 downto 0);
17+
GNT_o : out std_ulogic_vector
18+
(c_Agents - 1 downto 0)
19+
);
20+
21+
end entity PCI_ARB;
22+
23+
24+
architecture TIME_SLOTS of PCI_ARB is
25+
26+
-- c_Agents is the number of Agents attached to the bus
27+
-- c_AckTimer is the number of clocks a master gets maximal priority
28+
29+
-- Indicate master with maximal priority
30+
signal s_Token : integer range 0 to c_Agents := 0;
31+
32+
-- signal to increment token
33+
signal s_Ack : std_ulogic := '0';
34+
35+
-- timer for token shifting
36+
signal s_AckTimer : integer range 0 to c_AckTimer := 0;
37+
38+
-- counter for master timeout
39+
signal s_MasterTimeout : integer range 0 to 8 := 0;
40+
41+
-- equal to GNT_o
42+
signal s_GntSet : std_ulogic_vector (c_Agents - 1 downto 0) :=
43+
SetBitVector(0, c_Agents-1, '0');
44+
signal s_GntSet_prev : std_ulogic_vector (c_Agents - 1 downto 0);
45+
46+
-- 0 shows that master got problem and will not be granted
47+
signal s_ReqValid : std_ulogic_vector (c_Agents - 1 downto 0) :=
48+
(others => '1');
49+
50+
51+
52+
begin
53+
54+
------------------------------------------------------------------------------------------
55+
---------------------------- Ring Counter ------------------------------------------
56+
------------------------------------------------------------------------------------------
57+
58+
RING_COUNTER : process (CLOCK, RESET_i)
59+
begin -- process RING_COUNTER
60+
if (RESET_i = '0') then
61+
s_Token <= 0;
62+
elsif (s_Ack = '1' and CLOCK'event and CLOCK = '1') then
63+
s_Token <= (s_Token + 1) mod c_Agents;
64+
end if;
65+
end process RING_COUNTER;
66+
67+
------------------------------------------------------------------------------------------
68+
---------------------------- Priority Logic ----------------------------------------
69+
------------------------------------------------------------------------------------------
70+
71+
PRIORITY_LOGIC : process (REQ_i, RESET_i, CLOCK)
72+
73+
variable v_Req : std_ulogic_vector (c_Agents - 1 downto 0);
74+
variable v_Gnt : std_ulogic_vector (c_Agents - 1 downto 0);
75+
76+
begin -- process PRIORITY_LOGIC
77+
if RESET_i = '0' then
78+
GNT_o <= (others => '1');
79+
s_GntSet <= (others => '0');
80+
s_GntSet_prev <= (others => '0');
81+
82+
elsif (CLOCK = '1' and CLOCK'event) then
83+
84+
s_GntSet_prev <= s_GntSet;
85+
86+
-- multiplex request inputs with respect to token position
87+
88+
for j in 0 to c_Agents - 1 loop
89+
v_Req(j) := REQ_i((j + s_Token) mod c_Agents);
90+
if s_ReqValid((j + s_Token) mod c_Agents) = '0' then
91+
v_Req(j) := '1';
92+
end if;
93+
end loop; -- j
94+
95+
-- set v_gnt
96+
97+
for i in 0 to c_Agents - 1 loop
98+
if v_Req(i) = '0' then
99+
v_Gnt(i) := '0';
100+
for j in i+1 to c_Agents - 1 loop
101+
v_Gnt(j) := '1';
102+
end loop; -- j
103+
exit;
104+
else
105+
v_Gnt(i) := '1';
106+
end if;
107+
end loop; -- i
108+
109+
-- Arbitration parking of primary master, if no request is set
110+
111+
for i in 0 to c_Agents -1 loop
112+
if IsEven(v_Gnt) = '1' then
113+
if s_ReqValid((i + s_Token) mod c_Agents) = '1' then
114+
v_Gnt(i) := '0';
115+
exit;
116+
end if;
117+
else
118+
exit;
119+
end if;
120+
end loop; -- i
121+
122+
-- attach v_gnt of Priority Logic to correct GNT_o of the PCI Bus
123+
124+
for i in 0 to c_Agents - 1 loop
125+
--GNT_o((i + s_Token) mod c_Agents) <= v_Gnt(i);
126+
s_GntSet((i + s_Token) mod c_Agents) <= v_Gnt(i);
127+
end loop; -- i
128+
129+
if (FRAME_i /= '0' and IRDY_i /= '0' and
130+
s_GntSet /= s_GntSet_prev) then
131+
GNT_o <= (others => '1');
132+
else
133+
GNT_o <= s_GntSet;
134+
end if;
135+
136+
end if;
137+
138+
end process PRIORITY_LOGIC;
139+
140+
------------------------------------------------------------------------------------------
141+
---------------------------- Ring Counter Timer ------------------------------------
142+
------------------------------------------------------------------------------------------
143+
144+
ACK_TIMER : process(CLOCK, RESET_i, s_AckTimer)
145+
begin
146+
if (RESET_i = '0') then
147+
s_Ack <= '0';
148+
s_AckTimer <= 0;
149+
150+
else
151+
152+
if (CLOCK = '1' and CLOCK'event) then
153+
s_AckTimer <= (s_AckTimer + 1) mod c_AckTimer;
154+
end if;
155+
156+
if (s_AckTimer = c_AckTimer - 1) then
157+
s_Ack <= '1';
158+
else
159+
s_Ack <= '0';
160+
end if;
161+
162+
end if;
163+
end process ACK_TIMER;
164+
165+
------------------------------------------------------------------------------------------
166+
---------------------------- Timeout Detection -------------------------------------
167+
------------------------------------------------------------------------------------------
168+
169+
MASTER_TIMEOUT_DETECTION : process (RESET_i, CLOCK)
170+
begin -- process MASTER_TIMEOUT_DETECTION
171+
172+
if (CLOCK = '1' and CLOCK'event) then
173+
174+
if RESET_i = '0' then
175+
s_MasterTimeout <= 0;
176+
s_ReqValid <= (others => '1');
177+
178+
-- set masters s_ReqValid 0 when master violates time constraints
179+
180+
elsif (s_MasterTimeout = c_MasterTimeOut) then
181+
s_MasterTimeout <= 0;
182+
for i in 0 to c_Agents - 1 loop
183+
if s_GntSet(i) = '0' then
184+
s_ReqValid(i) <= '0';
185+
end if;
186+
end loop; -- i
187+
188+
-- increment and reset Time Out timer
189+
190+
elsif (s_MasterTimeout /= c_MasterTimeOut) then
191+
if (FRAME_i = '0' and IRDY_i = '1') then
192+
s_MasterTimeout <= s_MasterTimeout + 1;
193+
elsif IRDY_i = '0' then
194+
s_MasterTimeout <= 0;
195+
end if;
196+
end if;
197+
198+
-- Reset s_ReqValid to 1 if master removes REQ_i
199+
200+
for j in 0 to c_Agents - 1 loop
201+
if REQ_i(j) = '1' and s_ReqValid(j) = '0' then
202+
s_ReqValid(j) <= '1';
203+
end if;
204+
end loop; -- j
205+
206+
end if;
207+
208+
end process MASTER_TIMEOUT_DETECTION;
209+
210+
211+
end architecture TIME_SLOTS;
212+
213+

‎Config.vhd

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
------------------------------------------------------------------------------------------
2+
---------------------------- Global PCI --------------------------------------------
3+
------------------------------------------------------------------------------------------
4+
5+
6+
package GLOBAL_PCI_CONFIG is
7+
8+
-- Clocks until Master has to assign IRDY after FRAME is set and GNT is given
9+
10+
constant c_MasterTimeOut : integer := 8;
11+
12+
-- Clocks until Target has to assign DEVSEL after FRAME
13+
14+
constant c_DevselTimeOut : integer := 4;
15+
16+
-- Number of 8 Bit Memory Registers that are implemented in the 4kb Memory block.
17+
-- This value may be changed in order to reduce the compilation time in vhdl2gates.
18+
-- It does not affect the functionality.
19+
-- The internal memory address space can access up to 4096 Byte. vhdl2gates will
20+
-- calculate the modulo of the address, if there are not enough memory registers
21+
-- implemented.
22+
23+
constant c_MemoryBlocks : integer := 256;
24+
25+
end GLOBAL_PCI_CONFIG;
26+
27+
28+
------------------------------------------------------------------------------------------
29+
---------------------------- Arbiter -----------------------------------------------
30+
------------------------------------------------------------------------------------------
31+
32+
33+
package ARBITER_CONFIG is
34+
35+
-- number of agents attached to the bus
36+
37+
constant c_Agents : integer := 4;
38+
39+
-- number of clocks master gets maximal priority
40+
41+
constant c_AckTimer : integer := 8;
42+
43+
end ARBITER_CONFIG;

0 commit comments

Comments
 (0)
Please sign in to comment.