====== 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