Next: Fetch-Einheit
Up: VHDL-Quellen
Previous: VHDL-Quellen
  Inhalt
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity PriorityManager is
generic (
parameterBreite : integer range 1 to 31 := 31; - Bits fuer Deadline etc.
totalStackNumber : integer range 1 to 127 := 4; - Anzahl der Threads
ld_totalStackNumber : integer range 1 to 7 := 2); - Logarithmus Dualis
port (
clk : in std_logic; - Clock
reset : in std_logic; - Reset (Aktiv High)
signalArrived : in std_logic_vector(totalStackNumber-1 downto 0);
- liegt ein Signal an?
lockNeeded : in std_logic_vector(totalStackNumber-1 downto 0);
- Thread wartet auf Spinlock
swActive : in std_logic_vector(totalStackNumber-1 downto 0);
- Software Aktiv
hwActive : in std_logic_vector(totalStackNumber-1 downto 0);
- Hardware Aktiv (Signal)
opsExecution : in std_logic_vector(totalStackNumber-1 downto 0);
- Es wird gerade MikroCode ausgefuehrt
latency : in std_logic_vector(1 downto 0);
- Der letzte Befehl hatte eine Latenz
fill : in std_logic_vector((4*totalStackNumber)-1 downto 0);
- Fuellstand erster Thread
parameter : in std_logic_vector((parameterBreite*totalStackNumber)-1 downto 0);
- Parameter erster Thread
IdThreadTag : out std_logic_vector(ld_totalStackNumber-1 downto 0);
- Als naechstes auszufuehren
IdInvalid : out std_logic); - Keiner kann ausgefuehrt werden
end PriorityManager;
------------------------------------
------------------------------------
architecture FPP_Scheduler of PriorityManager is
subtype param_int is std_logic_vector(parameterBreite-1 downto 0);
subtype prio_int is std_logic_vector(parameterBreite downto 0);
subtype fi_int is std_logic_vector(3 downto 0);
subtype latenz_int is std_logic_vector(1 downto 0);
type param_int_arr is array(0 to totalStackNumber-1) of param_int;
type prio_int_arr is array(0 to totalStackNumber-1) of prio_int;
type fi_int_arr is array(0 to totalStackNumber-1) of fi_int;
type latenz_int_arr is array(0 to totalStackNumber-1) of latenz_int;
type m_arr is array(0 to totalStackNumber-1) of integer range 0 to totalStackNumber-1;
signal param : param_int_arr; - Parameter array
signal fi : fi_int_arr;
begin - FPP_Scheduler
g: for i in 0 to totalStackNumber-1 generate
param(i) <= parameter((parameterBreite*(i+1))-1 downto parameterBreite*i);
fi(i) <= fill((4*(i+1))-1 downto 4*i);
end generate g;
- purpose: Berechnet den naechsten auszufuehrenden Thread
- Der ausfuehrbare Thread mit der hoechsten prioritaet kommt drann
- type : sequential
- inputs : clk, reset, see entity
- outputs: IdThreadTag, IdInvalid
p: process (clk, reset)
variable params : param_int_arr;
variable priorities : prio_int_arr; - Temporaere Variablen
variable k : integer;
variable full : std_logic;
variable latenzen : latenz_int_arr;
variable m : m_arr;
variable lastScheduled : integer;
variable Invalid : std_logic;
begin - process p
if reset = '1' then - asynchronous reset (active high)
lastScheduled := 0;
k := 0;
IdInvalid <= '0';
Invalid := '0';
for i in 0 to ld_totalStackNumber-1 loop
IdThreadTag(i) <= '0';
end loop;
for i in 0 to totalStackNumber-1 loop
latenzen(i) := conv_std_logic_vector(0,2);
for j in 0 to parameterBreite-1 loop
params(i)(j) := '0';
end loop;
end loop;
elsif clk'event and clk = '1' then - rising clock edge
for i in 0 to totalStackNumber-1 loop
if signalArrived(i) = '1' then
params(i) := param(i);
end if;
end loop; - i
- Latenzen von der Decode-Stufe
if Invalid = '0' and latency /= ``00`` then
latenzen(lastScheduled) := latency;
end if;
for i in 0 to totalStackNumber-1 loop
- Issue Threshold (>=3)
if unsigned(fi(i)) < 3 then
full := '0';
else
full := '1';
end if;
priorities(i)(parameterBreite-1 downto 0) := params(i);
priorities(i)(parameterBreite) := (not (latenzen(i)(0) or latenzen(i)(1))
and hwActive(i) and swActive(i)
and not lockNeeded(i)
and (full or opsExecution(i)));
end loop; - i
- den hoechsten suchen
for i in 0 to totalStackNumber-1 loop
m(i):= i;
end loop;
- Der Vergleicherbaum.
for j in 0 to ld_totalStackNumber-1 loop
for i in 0 to (totalStackNumber/2**(j+1))-1 loop
if priorities(m((2*i+1)*2**j))>priorities(m((2*i)*2**j)) then
m((2*i)*2**j):=m((2*i+1)*2**j);
end if;
end loop;
end loop;
k:=m(0);
- hoechsten oder invalid an decode weitergeben
if priorities(k)(parameterBreite) = '1' then
IdThreadTag <= conv_std_logic_vector(k,ld_totalStackNumber);
IdInvalid <= '0';
Invalid := '0';
lastScheduled := k;
else
IdInvalid <= '1';
Invalid := '1';
end if;
- Latenzen runterzaehlen
for i in 0 to totalStackNumber-1 loop
if unsigned(latenzen(i)) /= 0 then
latenzen(i) := unsigned(latenzen(i)) - 1;
end if;
end loop; - i
end if;
end process p;
end FPP_Scheduler;
------------------------------------
------------------------------------
architecture GP_Scheduler of PriorityManager is
subtype param_int is std_logic_vector(parameterBreite-1 downto 0);
subtype prio_int is std_logic_vector(parameterBreite downto 0);
subtype fi_int is std_logic_vector(3 downto 0);
subtype latenz_int is std_logic_vector(1 downto 0);
subtype remain_int is std_logic_vector(parameterBreite-4 downto 0);
subtype class_int is std_logic_vector(2 downto 0);
type param_int_arr is array(0 to totalStackNumber-1) of param_int;
type prio_int_arr is array(0 to totalStackNumber-1) of prio_int;
type fi_int_arr is array(0 to totalStackNumber-1) of fi_int;
type latenz_int_arr is array(0 to totalStackNumber-1) of latenz_int;
type remain_int_arr is array(0 to totalStackNumber-1) of remain_int;
type class_int_arr is array(0 to totalStackNumber-1) of class_int;
type m_arr is array(0 to totalStackNumber-1) of integer range 0 to totalStackNumber-1;
signal param : param_int_arr; - Parameter array
signal fi : fi_int_arr;
begin - GP_Scheduler
g: for i in 0 to totalStackNumber-1 generate
param(i) <= parameter((parameterBreite*(i+1))-1 downto parameterBreite*i);
fi(i) <= fill((4*(i+1))-1 downto 4*i);
end generate g;
- purpose: Berechnet den naechsten auszufuehrenden Thread
- Die Threads werden in Klassen aufgeteilt:
- 000 : nicht echtzeifaehig: laeuft, wenn nichts anderes geht.
- 001 : minimal: Kann mehr bekommen als seinen Anteil
- 101 : maximal: Kann weniger bekommen als seinen Anteil
- 110 : exakt: Muss genau seinen Anteil bekommen
- 111 : kurz: Wie exakt, wird aber zuerst bedient.
- Der ausfuehrbare Thread mit der hoechsten Klasse und darin
- der hoechsten Resttakte im Intervall kommt dran.
- ACHTUNG: Da min und ex zunaechst gleichzeitig ausgefuehrt werden,
- bekommen minimale auch erstmal 110. Erst wenn sie ihren Anteil
- verbraucht haben, wechseln sie nach 001.
- type : sequential
- inputs : clk, reset, see entity
- outputs: IdThreadTag, IdInvalid
p: process (clk, reset)
constant granularity: std_logic_vector(parameterBreite-4 downto 0) := ``1100100``; - =100
constant gr : integer := 99;
variable params : param_int_arr;
variable remain : remain_int_arr;
variable klasse : class_int_arr;
variable priorities : prio_int_arr; - Temporaere Variablen
variable k : integer;
variable counter : integer range 0 to 100;
variable full : std_logic;
variable darf : std_logic;
variable latenzen : latenz_int_arr;
variable m : m_arr;
variable lastScheduled : integer;
variable Invalid : std_logic;
begin - process p
if reset = '1' then - asynchronous reset (active high)
lastScheduled := 0;
k := 0;
counter := 0;
IdInvalid <= '0';
Invalid := '0';
for i in 0 to ld_totalStackNumber-1 loop
IdThreadTag(i) <= '0';
end loop;
for i in 0 to totalStackNumber-1 loop
latenzen(i) := conv_std_logic_vector(0,2);
remain(i) := granularity;
klasse(i) := ``000``;
for j in 0 to parameterBreite-1 loop
params(i)(j) := '0';
end loop;
end loop;
elsif clk'event and clk = '1' then - rising clock edge
for i in 0 to totalStackNumber-1 loop
if signalArrived(i) = '1' then
params(i) := param(i);
end if;
end loop; - i
- Intervallzaehler
if counter /= 0 then
counter := counter - 1;
else
counter := gr;
for i in 0 to totalStackNumber-1 loop
remain(i) := params(i)(parameterBreite - 1 downto 3);
if params(i)(2 downto 0) = ``001`` then
klasse(i) := ``110``;
else
klasse(i) := params(i)(2 downto 0);
end if;
if klasse(i) = ``000`` then
remain(i) := granularity;
end if;
end loop;
end if;
-Latenzen von Decode?
if Invalid = '0' and latency /= ``00`` then
latenzen(lastScheduled) := latency;
end if;
- Prioritaeten fuer Sortierung vorbereiten
for i in 0 to totalStackNumber-1 loop
- Issue Threashold! (>=3)
if unsigned(fi(i)) < 3 then
full := '0';
else
full := '1';
end if;
- Das erste bit der Klasse sagt, ob mehr als der Anteil erlaubt ist.
- also nicht bei exakt, max, short
if klasse(i)(2) = '1' and unsigned(remain(i)) = 0 then
darf := '0';
else
darf := '1';
end if;
- 1 bit geht|3 bit Klasse|n bit Resttakte
priorities(i)(parameterBreite-4 downto 0) := remain(i);
priorities(i)(parameterBreite-1 downto parameterBreite-3) := klasse(i);
priorities(i)(parameterBreite) := (not (latenzen(i)(0) or latenzen(i)(1))
and hwActive(i) and swActive(i)
and not lockNeeded(i)
and (full or opsExecution(i))
and darf);
end loop; - i
- den groessten suchen
for i in 0 to totalStackNumber-1 loop
m(i):= i;
end loop;
- Der Vergleicherbaum.
for j in 0 to ld_totalStackNumber-1 loop
for i in 0 to (totalStackNumber/2**(j+1))-1 loop
if priorities(m((2*i+1)*2**j))>priorities(m((2*i)*2**j)) then
m((2*i)*2**j):=m((2*i+1)*2**j);
end if;
end loop;
end loop;
k:=m(0);
- den groessten oder invalid weitergeben
if priorities(k)(parameterBreite) = '1' then
IdThreadTag <= conv_std_logic_vector(k,ld_totalStackNumber);
IdInvalid <= '0';
Invalid := '0';
lastScheduled := k;
remain(k) := unsigned(remain(k)) - 1;
else
IdInvalid <= '1';
Invalid := '1';
end if;
- Latenzen werden dem Thread angerechnet
for i in 0 to totalStackNumber-1 loop
if unsigned(latenzen(i)) /= 0 and unsigned(remain(i)) /= 0 then
remain(i) := unsigned(remain(i)) - 1;
end if;
end loop; - i
- Wechsle die Klasse von min,remain>0 (gleich ex) zu min,remain<0
for i in 0 to totalStackNumber-1 loop
if unsigned(remain(i)) = 0 and klasse(i) = ``110`` and params(i)(2 downto 0)= ``001`` then
klasse(i) := ``001``;
remain(i) := granularity;
end if;
end loop; - i
- Latenzen runterzaehlen
for i in 0 to totalStackNumber-1 loop
if unsigned(latenzen(i)) /= 0 then
latenzen(i) := unsigned(latenzen(i)) - 1;
end if;
end loop; - i
end if;
end process p;
end GP_Scheduler;
------------------------------------
------------------------------------
architecture EDF_Scheduler of PriorityManager is
- Typdeklarationen
subtype param_int is std_logic_vector(parameterBreite-1 downto 0);
subtype prio_int is std_logic_vector(parameterBreite downto 0);
subtype fi_int is std_logic_vector(3 downto 0);
subtype latenz_int is std_logic_vector(1 downto 0);
type param_int_arr is array(0 to totalStackNumber-1) of param_int;
type prio_int_arr is array(0 to totalStackNumber-1) of prio_int;
type fi_int_arr is array(0 to totalStackNumber-1) of fi_int;
type latenz_int_arr is array(0 to totalStackNumber-1) of latenz_int;
type m_arr is array(0 to totalStackNumber-1) of integer range 0 to totalStackNumber-1;
- Interne Signale
signal param : param_int_arr;
signal fi : fi_int_arr;
begin - EDF_Scheduler
g: for i in 0 to totalStackNumber-1 generate
param(i) <= parameter((parameterBreite*(i+1))-1 downto parameterBreite*i);
fi(i) <= fill((4*(i+1))-1 downto 4*i);
end generate g;
- purpose: Berechnet den naechsten auszufuehrenden Thread
- Der ausfuehrbare Thread mit den fruehesten Deadline kommt dran
- type : sequential
- inputs : clk, reset, see entity
- outputs: IdThreadTag, IdInvalid
p: process (clk, reset)
variable params : param_int_arr; - Temporaere variablen
variable priorities : prio_int_arr;
variable k : integer range 0 to totalStackNumber-1;
variable full : std_logic;
variable latenzen : latenz_int_arr;
variable m : m_arr;
- ab hier koennen es auch Signale sein
variable lastScheduled : integer range 0 to totalStackNumber-1;
variable Invalid : std_logic;
begin - process p
if reset = '1' then - asynchronous reset (active high)
lastScheduled := 0;
k := 0;
IdInvalid <= '0';
Invalid := '0';
for i in 0 to ld_totalStackNumber-1 loop
IdThreadTag(i) <= '0';
end loop;
for i in 0 to totalStackNumber-1 loop
latenzen(i) := conv_std_logic_vector(0,2);
for j in 0 to parameterBreite-1 loop
params(i)(j) := '0';
end loop;
end loop;
elsif clk'event and clk = '1' then - rising clock edge
- Wenn ein Signal ankommt, wird die Deadline uebernommen.
- Mit jedem Takt wird sie runtergezaehlt, so dass der
- Thread mit der naechsten Deadline die kleinste Zahl
- in parameters hat.
for i in 0 to totalStackNumber-1 loop
if signalArrived(i) = '1' then
params(i) := param(i);
else
if unsigned(params(i)) /= 0 then
params(i) := unsigned(params(i)) - 1;
end if;
end if;
end loop; - i
- Latenz von der decode Stufe gemeldet
if Invalid = '0' and latency /= ``00`` then
latenzen(lastScheduled) := latency;
end if;
- Prioritaeten fuer Sortierung vorbereiten
for i in 0 to totalStackNumber-1 loop
- Issue Threshold (>=3)
if unsigned(fi(i)) < 3 then
full := '0';
else
full := '1';
end if;
priorities(i)(parameterBreite-1 downto 0) := params(i);
priorities(i)(parameterBreite) := not (not (latenzen(i)(0) or latenzen(i)(1))
and hwActive(i) and swActive(i)
and not lockNeeded(i)
and (full or opsExecution(i)));
end loop; - i
- Den niedrigsten! suchen. Hier negative Logik
for i in 0 to totalStackNumber-1 loop
m(i):= i;
end loop;
- Der Vergleicherbaum.
for j in 0 to ld_totalStackNumber-1 loop
for i in 0 to (totalStackNumber/2**(j+1))-1 loop
if priorities(m((2*i+1)*2**j))<priorities(m((2*i)*2**j)) then
m((2*i)*2**j):=m((2*i+1)*2**j);
end if;
end loop;
end loop;
k:=m(0);
- Niedrigsten oder invalid weitergeben zu decode
if priorities(k)(parameterBreite) = '0' then
IdThreadTag <= conv_std_logic_vector(k,ld_totalStackNumber);
IdInvalid <= '0';
Invalid := '0';
lastScheduled := k;
else
IdInvalid <= '1';
Invalid := '1';
end if;
- Alle Threads haben eine Latenz abgesessen
for i in 0 to totalStackNumber-1 loop
if unsigned(latenzen(i)) /= 0 then
latenzen(i) := unsigned(latenzen(i)) - 1;
end if;
end loop; - i
end if;
end process p;
end EDF_Scheduler;
---------------------------------
---------------------------------
- Dies wird einfach ignoriert, er nimmt die letzte architecture
configuration PriorityConfig of PriorityManager is
for EDF_Scheduler
end for;
end PriorityConfig;
Next: Fetch-Einheit
Up: VHDL-Quellen
Previous: VHDL-Quellen
  Inhalt
Alexander Schulz
2000-06-18