====== Arbiter(2) ======
===== Parametereinstellung =====
Eine kurze Funktions- und Schnittstellenbeschreibung:
* Das Modell Arbiter2 ist durch die Angabe der Anzahl n der angeschlossenen Module parametrisierbar (@BITBR).
* Die n angeschlossenen Module erhalten jeweils nach spätestens n Taktzyklen einen 'grant' zugeteilt.
* Bei diesem Modell ist zu beachten, daß aufgrund der Parameterroutine n maximal 6 sein kann.
{{:synthesizeable_vhdl-model-library:lib_arbiter_1.svg?nolink&300|Arbiter(2) block diagram}}
===== Schnittstellen =====
* takt : Taktsignal mit dem der zu verwaltende Bus betrieben wird
* bus_request_xp : Eingang für die Anforderung des Moduls Nummer x
* grant : Freigabesignal für die x-te Einheit
===== Model =====
-- ############################################################################
-- # Project : VHDL-Modellbibliothek #
-- # #
-- # Filename : arbiter_2.vhd #
-- # #
-- # Schaltung : parametrierbarer Busarbiter #
-- # #
-- # Modell : arbiter_2 #
-- # #
-- # Designer : Wolfgang Sehr; ueberarbeitet von Stefan Schmechtig #
-- # Abteilung : Lehrstul fuer rechnergestuetzten Schaltungsentwurf #
-- # Datum : 06.02.1995 #
-- ############################################################################
-- ############################################################################
-- # IEEE PACKAGES #
-- ############################################################################
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.math_real.all;
-- ############################################################################
-- ############################################################################
-- # PROJECT - SPEZIFISCHE PACKAGES #
-- ############################################################################
use WORK.local.all;
-- ############################################################################
ENTITY arbiter_2 IS
GENERIC (X : INTEGER := @BITBR); -- Anzahl der zu verwaltenden
-- Einheiten
PORT(reset : IN STD_LOGIC;
takt : IN STD_LOGIC;
${SINGLE_BUSREQUEST}
${SINGLE_GRANT}
);
-- takt : Taktsignal mit dem der zu verwaltende
-- : Bus betrieben wird
-- bus_request : Eingang fuer die Anforderungen der
-- : angeschlossenen Module, wobei die Stellen-Nr.
-- : der Ordnungsnummer des Moduls zugeordnet ist
-- grant : Freigabesignal fuer die jeweilige Einheit
END arbiter_2;
ARCHITECTURE dataflow OF arbiter_2 IS
SIGNAL zustand : UNSIGNED(LOG_2(X) DOWNTO 0);
SIGNAL naechster_zustand : UNSIGNED(LOG_2(X) DOWNTO 0);
SIGNAL bus_request : UNSIGNED((X-1) DOWNTO 0);
SIGNAL grant : UNSIGNED((X-1) DOWNTO 0);
-- zustand : diese Integerzahl stellt den Zustand dar und -- : ist folgendermassen zu interpretieren:
-- : ist zustand=x, so erhaelt die angeschlossene
-- : Einheit x einen Grant zugeteilt. (x=0 be-
-- : deutet, dass keine der angeschlossenen Ein-
-- : heiten einen Grant erhaelt.)
-- naechster_zustand : stellt den, bei der naechsten Taktflanke
-- : gueltigen Zustand dar.
BEGIN
-- Zuweisungen der Eingangsports auf Signale:
${BUSRQ_ZUWEISUNG}
${GRANT_ZUWEISUNG}
komb: PROCESS(bus_request, zustand)
VARIABLE zustand_var : UNSIGNED(LOG_2(X) DOWNTO 0);
VARIABLE zustand_aend_var : UNSIGNED(LOG_2(X) DOWNTO 0);
VARIABLE zustand_aend_eval : STD_LOGIC;
VARIABLE naechster_zustand_var : UNSIGNED((X-1) DOWNTO 0);
VARIABLE bus_request_var : UNSIGNED((X-1) DOWNTO 0);
VARIABLE grant_var : UNSIGNED((X-1) DOWNTO 0);
VARIABLE stelle : INTEGER;
-- zustand_var : ist gleich dem Signal 'zustand'
-- zustands_aend_var : gibt an, um "welchen Betrag sich der
-- : 'zustand' aendern soll"
-- zustand_aend_eval : ist '1', wenn von irgendeinem ange-
-- : schlossenenm Modul eine request-
-- : Anforderung besteht.
-- naechster_zustand_var : beinhaltet dasselbe wie das Signal
-- : 'naechster_zustand' hat aber eine
-- : Stelle mehr
-- bus_request_var : beinhaltet dasselbe, wie das an den
-- : Ports anliegende 'bus_request'-Signal
-- grant_var : gibt den Wert an, der an das 'grant'-
-- : Signal geliefert werden soll
-- stelle : gibt den Index der untersuchten Stelle
-- : des Zustandsvektors an
BEGIN
zustand_var := zustand;
zustand_aend_var := CONV_UNSIGNED(0, zustand_aend_var'LENGTH);
zustand_aend_eval := '0';
grant_var := CONV_UNSIGNED(0, grant_var'LENGTH);
bus_request_var := CONV_UNSIGNED(0, bus_request'LENGTH);
-- ----------------------------------------------------------------
-- Abfangen von unzulaessigen Zustaenden
-- ----------------------------------------------------------------
IF (zustand_var = 0) OR (zustand_var > X) THEN
zustand_var := CONV_UNSIGNED(0, zustand_var'LENGTH);
END IF;
-- ----------------------------------------------------------------
-- ----------------------------------------------------------------
-- Umordnen des urspruenglichen 'bus_request'-Vektors
-- ----------------------------------------------------------------
FOR i IN 0 TO (X-1) LOOP
stelle := (CONV_INTEGER(zustand_var) + i);
IF (stelle > (X-1)) THEN
stelle := stelle - X;
END IF;
bus_request_var(i) := bus_request(stelle);
END LOOP;
-- ----------------------------------------------------------------
-- ----------------------------------------------------------------
-- Bestimmung des naechsten Zustands
-- ----------------------------------------------------------------
FOR i IN 0 TO (X-1) LOOP
IF (bus_request_var(i) = '1') THEN
IF (zustand_aend_eval = '0') THEN
zustand_aend_var := CONV_UNSIGNED(i,
zustand_aend_var'LENGTH);
zustand_aend_eval := '1';
END IF;
END IF;
END LOOP;
IF (zustand_aend_eval = '0') THEN
naechster_zustand_var := CONV_UNSIGNED(0,
naechster_zustand_var'LENGTH);
ELSE
naechster_zustand_var :=
CONV_UNSIGNED(zustand_var,
naechster_zustand_var'LENGTH) +
CONV_UNSIGNED(zustand_aend_var,
naechster_zustand_var'LENGTH) + 1;
END IF;
IF (naechster_zustand_var > X) THEN
naechster_zustand_var := naechster_zustand_var - X;
END IF;
-- ----------------------------------------------------------------
-- ----------------------------------------------------------------
-- Signalzuweisungen
-- ----------------------------------------------------------------
IF (zustand_var /= 0) AND (zustand_var <= X) THEN
grant_var(CONV_INTEGER(zustand_var)-1) := '1';
END IF;
naechster_zustand <= CONV_UNSIGNED(naechster_zustand_var,
naechster_zustand'LENGTH);
grant <= grant_var;
END PROCESS;
sync: PROCESS(takt)
BEGIN
IF ((takt = '1') AND takt'EVENT) THEN
IF (reset = '0') THEN
zustand <= naechster_zustand;
ELSE
zustand <= CONV_UNSIGNED(0, zustand'LENGTH);
END IF;
END IF;
END PROCESS;
END dataflow;
CONFIGURATION CFG_arbiter_2 OF arbiter_2 IS
FOR dataflow
END FOR;
END CFG_arbiter_2;
===== Testbench =====
-- ############################################################################
-- # Project : VHDL-Modellbibliothek #
-- # #
-- # Filename : tb_arbiter_2.vhd #
-- # #
-- # Schaltung : Testbench fuer parametrierbaren Busarbiter #
-- # #
-- # Modell : tb_arbiter_2 #
-- # #
-- # Designer : Wolfgang Sehr; ueberarbeitet von Stefan Schmechtig #
-- # Abteilung : Lehrstul fuer rechnergestuetzten Schaltungsentwurf #
-- # Datum : 01.02.1995 #
-- ############################################################################
-- ############################################################################
-- # IEEE PACKAGES #
-- ############################################################################
Library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
USE IEEE.math_real.all; -- wird fuer die Erzeugung von Zufallszahlen
-- benoetigt
-- ############################################################################
ENTITY TB_arbiter_2 IS
GENERIC (X : INTEGER := @BITBR); -- Anzahl der zu verwaltenden
-- Einheiten
END TB_arbiter_2;
ARCHITECTURE behaviour OF TB_arbiter_2 IS
SIGNAL tb_reset : STD_LOGIC;
SIGNAL tb_takt : STD_LOGIC;
SIGNAL tb_bus_request : UNSIGNED((X-1) DOWNTO 0);
SIGNAL tb_grant : UNSIGNED((X-1) DOWNTO 0);
-- tb_reset : von Testbench erzeugtes Ruecksetzsignal
-- :
-- tb_takt : von Testbench erzeugtes Taktsignal
-- :
-- tb_bus_request : von Testbench erzeugtes 'bus_request' Signal
-- :
-- tb_grant : vom UUT empfangenes 'grant' Signal
-- :
COMPONENT arbiter_2
PORT( reset : IN STD_LOGIC;
takt : IN STD_LOGIC;
${BREQUEST}
${GRANT}
);
END COMPONENT;
BEGIN
UUT: arbiter_2 -- einzige Schaltung
PORT MAP(reset => tb_reset,
takt => tb_takt,
${TB_BREQUEST}
${TB_GRANT}
);
res: PROCESS
BEGIN
tb_reset <= '1';
WAIT FOR 5 ns;
LOOP
tb_reset <= not(tb_reset);
WAIT FOR 300 ns;
tb_reset <= not(tb_reset);
WAIT FOR 10 ns;
END LOOP;
END PROCESS;
clk: PROCESS
BEGIN
tb_takt <= '1';
WAIT FOR 10 ns;
LOOP
tb_takt <= not(tb_takt);
WAIT FOR 5 ns;
END LOOP;
END PROCESS;
stim: PROCESS
VARIABLE bus_request_int : INTEGER;
BEGIN
tb_bus_request <= CONV_UNSIGNED(0, tb_bus_request'LENGTH);
WAIT FOR 10 ns;
LOOP
bus_request_int := RAND;
tb_bus_request <= CONV_UNSIGNED(bus_request_int,
tb_bus_request'LENGTH);
WAIT FOR 50 ns;
END LOOP;
END PROCESS;
END behaviour;
CONFIGURATION CFG_TB_arbiter_2 OF TB_arbiter_2 IS
FOR behaviour
FOR UUT: arbiter_2
USE CONFIGURATION WORK.CFG_arbiter_2;
END FOR;
END FOR;
END CFG_TB_arbiter_2;
===== Synopsys VSS Trace =====
tr tb_reset
tr tb_takt
tr tb_bus_request
tr tb_grant