Skip to content

Instantly share code, notes, and snippets.

@ikwzm
Created April 1, 2012 05:09
Show Gist options
  • Save ikwzm/2271598 to your computer and use it in GitHub Desktop.
Save ikwzm/2271598 to your computer and use it in GitHub Desktop.
Queue Arbiter VHDL RTL MODEL.

Queue Arbiter VHDL RTL MODEL.

キュー(ファーストインファーストアウト)方式の調停回路です.

リクエストを到着順に許可することを特徴とします.

キュー方式が他の一般的な固定優先順位方式やラウンドロビン方式に比べて有利な点は次の二つ.

  • 必ずリクエストはいつかは許可されることが保証されています. 固定優先順位方式の場合、場合によっては永久にリクエストが許可されることがないことが起り得ますが、 キュー方式はそれがありません.
  • リクエストされた順番が変わることがありません. 用途によっては順番が変わることで誤動作する場合がありますが、 キュー方式ではそれに対応できます.

キュー方式が他の一般的な固定優先順位方式やラウンドロビン方式に比べて不利な点は次の二つ.

  • リクエストが到着した順番を記録しているため、回路規模は他の方式に比べて大きい傾向があります. 特にリクエストの数が増えると二乗のオーダーで回路規模が大きくなります.
  • 1クロックで多数の処理を行わなければならないので動作周波数が他の方式に比べて遅い傾向があります. 特にリクエストの数が増えると比例して遅延時間が増大します.

内部でリクエストを保持しておくやり方の違いでアーキテクチャは二つ用意してあります.

  • リクエストを記録しておくのにワンホットを使っているもの(queue_arbiter_one_hot_arch.vhd).

  • リクエストを記録しておくのに単なる整数を使っているもの(queue_arbiter_integer_arch.vhd).

どちらがよいか迷ったのですが、よく分からないので両方アップしました。

実は昔、バスやメモリアクセスの調停がらみでよくトラブルを起しました. 例えば、タイミングによってはある回路からのリクエストが一切処理されずに見掛け上システムがフリーズしてしまうとか、メモリアクセス時にアクセス順が入れ替わってしまって誤動作するなどなど。

その時痛感したのが、調停を甘く見てはいけないということです。これを間違えると、とても分かりにくく且つ致命的なトラブルを起します。

これに懲りて、調停回路には固定優先順位方式やラウンドロビン方式を使うことは止めました。 多少回路規模は不利ですがキュー方式の調停回路を使っています。 優先順位をつけたい場合は、せいぜい2レベルにして、そのレベル間でのみ固定優先順位方式を使い、それぞれのレベルはキュー方式にしています。

二条項BSDライセンス (2-clause BSD license) で公開しています。

GHDL=ghdl
GHDLFLAGS=--mb-comments
GHDLRUNFLAGS=$(GHDLFLAGS)
WORK=work
TEST_BENCH = test_bench_one_hot_arch \
test_bench_integer_arch \
$(END_LIST)
all: $(TEST_BENCH)
clean:
rm -f *.o *.cf $(TEST_BENCH)
test_bench_one_hot_arch: test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_integer_arch: test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench.o: ./test_bench.vhd queue_arbiter.o queue_arbiter_one_hot_arch.o queue_arbiter_integer_arch.o
$(GHDL) -a $(GHDLFLAGS) --work=work $<
queue_arbiter.o: ./queue_arbiter.vhd
$(GHDL) -a $(GHDLFLAGS) --work=$(WORK) $<
queue_arbiter_integer_arch.o: ./queue_arbiter_integer_arch.vhd
$(GHDL) -a $(GHDLFLAGS) --work=$(WORK) $<
queue_arbiter_one_hot_arch.o: ./queue_arbiter_one_hot_arch.vhd
$(GHDL) -a $(GHDLFLAGS) --work=$(WORK) $<
-----------------------------------------------------------------------------------
--! @file queue_arbiter.vhd
--! @brief QUEUE ARBITER MODULE :
--! キュータイプの調停回路
--! @version 1.0.0
--! @date 2012/4/1
--! @author Ichiro Kawazome <ichiro_k@ca2.so-net.ne.jp>
-----------------------------------------------------------------------------------
--
-- Copyright (C) 2012 Ichiro Kawazome
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
--
-- 1. Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
--
-- 2. Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-----------------------------------------------------------------------------------
--! @brief QUEUE ARBITER :
--! キュー(ファーストインファーストアウト)方式の調停回路.
--! * 要求を到着順に許可することを特徴とする調停回路.
--! * キュー方式が他の一般的な固定優先順位方式やラウンドロビン方式に比べて
--! 有利な点は次の二つ.
--! * 必ず要求はいつかは許可されることが保証されている.
--! 固定優先順位方式の場合、場合によっては永久に要求が許可されることが
--! ないことが起り得るが、キュー方式はそれがない.
--! * 要求された順番が変わることがない.
--! 用途によっては順番が変わることで誤動作する場合があるが、
--! キュー方式ではそれに対応できる.
--! * 一般的な固定優先順位方式やラウンドロビン方式の調停回路と異なり、
--! 要求が到着した順番を記録しているため、
--! 回路規模は他の方式に比べて大きい傾向がある.
-----------------------------------------------------------------------------------
entity QUEUE_ARBITER is
generic (
MIN_NUM : --! @brief REQUEST MINIMUM NUMBER :
--! リクエストの最小番号を指定する.
integer := 0;
MAX_NUM : --! @brief REQUEST MAXIMUM NUMBER :
--! リクエストの最大番号を指定する.
integer := 7
);
port (
CLK : --! @brief CLOCK :
--! クロック信号
in std_logic;
RST : --! @brief ASYNCRONOUSE RESET :
--! 非同期リセット信号.アクティブハイ.
in std_logic;
CLR : --! @brief SYNCRONOUSE RESET :
--! 同期リセット信号.アクティブハイ.
in std_logic;
ENABLE : --! @brief ARBITORATION ENABLE :
--! この調停回路を有効にするかどうかを指定する.
--! * 幾つかの調停回路を組み合わせて使う場合、設定によっては
--! この調停回路の出力を無効にしたいことがある.
--! その時はこの信号を'0'にすることで簡単に出来る.
--! * ENABLE='1'でこの回路は調停を行う.
--! * ENABLE='0'でこの回路は調停を行わない.
--! この場合REQUEST信号に関係なREQUEST_OおよびGRANTは'0'になる.
--! リクエストキューの中身は破棄される.
in std_logic := '1';
REQUEST : --! @brief REQUEST INPUT :
--! リクエスト入力.
in std_logic_vector(MIN_NUM to MAX_NUM);
GRANT : --! @brief GRANT OUTPUT :
--! 調停結果出力.
out std_logic_vector(MIN_NUM to MAX_NUM);
GRANT_NUM : --! @brief GRANT NUMBER :
--! 許可番号.
--! * ただしリクエストキューに次の要求が無い場合でも、
--! なんらかの番号を出力してしまう.
out integer range MIN_NUM to MAX_NUM;
REQUEST_O : --! @brief REQUEST OUTOUT :
--! リクエストキューに次の要求があることを示す信号.
--! * VALIDと異なり、リクエストキューに次の要求があっても、
--! 対応するREQUEST信号が'0'の場合はアサートされない.
out std_logic;
VALID : --! @brief REQUEST QUEUE VALID :
--! リクエストキューに次の要求があることを示す信号.
--! * REQUEST_Oと異なり、リスエストキューに次の要求があると
--! 対応するREQUEST信号の状態に関わらずアサートされる.
out std_logic;
SHIFT : --! @brief REQUEST QUEUE SHIFT :
--! リクエストキューの先頭からリクエストを取り除く信号.
in std_logic
);
end QUEUE_ARBITER;
-----------------------------------------------------------------------------------
--! @file queue_arbiter_integer_arch.vhd
--! @brief QUEUE ARBITER INTEGER ARCHITECTURE :
--! キュータイプの調停回路のアーキテクチャ(整数デコード)
--! @version 1.0.0
--! @date 2012/4/1
--! @author Ichiro Kawazome <ichiro_k@ca2.so-net.ne.jp>
-----------------------------------------------------------------------------------
--
-- Copyright (C) 2012 Ichiro Kawazome
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
--
-- 1. Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
--
-- 2. Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-----------------------------------------------------------------------------------
--
-----------------------------------------------------------------------------------
architecture INTEGER_ARCH of QUEUE_ARBITER is
type REQUEST_VECTOR is array(integer range <>) of integer range MIN_NUM to MAX_NUM;
constant QUEUE_TOP : integer := MIN_NUM;
constant QUEUE_END : integer := MAX_NUM;
signal curr_queue : REQUEST_VECTOR (QUEUE_TOP to QUEUE_END);
signal next_queue : REQUEST_VECTOR (QUEUE_TOP to QUEUE_END);
signal curr_valid : std_logic_vector(QUEUE_TOP to QUEUE_END);
signal next_valid : std_logic_vector(QUEUE_TOP to QUEUE_END);
begin
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
process (ENABLE, REQUEST, curr_queue, curr_valid)
variable req_enable : std_logic_vector(MIN_NUM to MAX_NUM);
variable req_num : integer range MIN_NUM to MAX_NUM ;
variable req_new : boolean;
variable temp_queue : REQUEST_VECTOR (QUEUE_TOP to QUEUE_END);
variable temp_valid : std_logic_vector(QUEUE_TOP to QUEUE_END);
variable temp_num : integer range MIN_NUM to MAX_NUM ;
begin
--------------------------------------------------------------------------
-- ENABLE信号がネゲートされている場合.
--------------------------------------------------------------------------
if (ENABLE /= '1') then
next_valid <= (others => '0');
next_queue <= (others => MIN_NUM);
VALID <= '0';
REQUEST_O <= '0';
GRANT_NUM <= MIN_NUM;
GRANT <= (others => '0');
--------------------------------------------------------------------------
-- リクエスト信号が一つしかない場合は話は簡単だ.
--------------------------------------------------------------------------
elsif (MIN_NUM >= MAX_NUM) then
if (REQUEST(MIN_NUM) = '1') then
next_valid <= (others => '0');
next_queue <= (others => MIN_NUM);
VALID <= '1';
REQUEST_O <= '1';
GRANT_NUM <= MIN_NUM;
GRANT <= (others => '1');
else
next_valid <= (others => '0');
next_queue <= (others => MIN_NUM);
VALID <= '0';
REQUEST_O <= '0';
GRANT_NUM <= MIN_NUM;
GRANT <= (others => '0');
end if;
--------------------------------------------------------------------------
-- 複数のリクエスト信号がある場合は調停しなければならない.
-- あたりまえだ. それがこの回路の本来の仕事だ.
--------------------------------------------------------------------------
else
req_enable := (others => '1');
for i in QUEUE_TOP to QUEUE_END loop
if (curr_valid(i) = '1') then
for n in MIN_NUM to MAX_NUM loop
if (n = curr_queue(i)) then
req_enable(n) := '0';
end if;
end loop;
temp_valid(i) := '1';
temp_queue(i) := curr_queue(i);
else
req_new := FALSE;
req_num := MIN_NUM;
for n in MIN_NUM to MAX_NUM loop
if (REQUEST(n) = '1' and req_enable(n) = '1') then
req_new := TRUE;
req_num := n;
req_enable(n) := '0';
exit;
end if;
end loop;
if (req_new) then
temp_valid(i) := '1';
temp_queue(i) := req_num;
else
temp_valid(i) := '0';
temp_queue(i) := MIN_NUM;
end if;
end if;
end loop;
VALID <= temp_valid(QUEUE_TOP);
next_valid <= temp_valid;
next_queue <= temp_queue;
temp_num := temp_queue(QUEUE_TOP);
if (temp_valid(QUEUE_TOP) = '1' and REQUEST(temp_num) = '1') then
REQUEST_O <= '1';
GRANT_NUM <= temp_num;
for i in GRANT'range loop
if (i = temp_num) then
GRANT(i) <= '1';
else
GRANT(i) <= '0';
end if;
end loop;
else
REQUEST_O <= '0';
GRANT_NUM <= temp_num;
GRANT <= (others => '0');
end if;
end if;
end process;
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
process (CLK, RST) begin
if (RST = '1') then
curr_queue <= (others => MIN_NUM);
curr_valid <= (others => '0');
elsif (CLK'event and CLK = '1') then
if (CLR = '1') or
(ENABLE /= '1') then
curr_queue <= (others => MIN_NUM);
curr_valid <= (others => '0');
elsif (SHIFT = '1') then
for i in QUEUE_TOP to QUEUE_END loop
if (i < QUEUE_END) then
curr_queue(i) <= next_queue(i+1);
curr_valid(i) <= next_valid(i+1);
else
curr_queue(i) <= MIN_NUM;
curr_valid(i) <= '0';
end if;
end loop;
else
curr_queue <= next_queue;
curr_valid <= next_valid;
end if;
end if;
end process;
end INTEGER_ARCH;
-----------------------------------------------------------------------------------
--! @file queue_arbiter_one_hot_arch.vhd
--! @brief QUEUE ARBITER ONE HOT ARCHITECTURE :
--! キュータイプの調停回路のアーキテクチャ(ワンホット)
--! @version 1.0.0
--! @date 2012/4/1
--! @author Ichiro Kawazome <ichiro_k@ca2.so-net.ne.jp>
-----------------------------------------------------------------------------------
--
-- Copyright (C) 2012 Ichiro Kawazome
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
--
-- 1. Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
--
-- 2. Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-----------------------------------------------------------------------------------
--
-----------------------------------------------------------------------------------
architecture ONE_HOT_ARCH of QUEUE_ARBITER is
subtype REQUEST_TYPE is std_logic_vector(MIN_NUM to MAX_NUM);
constant REQUEST_NULL : std_logic_vector(MIN_NUM to MAX_NUM) := (others => '0');
type REQUEST_VECTOR is array(integer range <>) of REQUEST_TYPE;
constant QUEUE_TOP : integer := MIN_NUM;
constant QUEUE_END : integer := MAX_NUM;
signal curr_queue : REQUEST_VECTOR (QUEUE_TOP to QUEUE_END);
signal next_queue : REQUEST_VECTOR (QUEUE_TOP to QUEUE_END);
begin
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
process (ENABLE, REQUEST, curr_queue)
variable req_enable : REQUEST_TYPE;
variable req_select : REQUEST_TYPE;
variable temp_queue : REQUEST_VECTOR(QUEUE_TOP to QUEUE_END);
variable temp_num : integer range MIN_NUM to MAX_NUM ;
begin
--------------------------------------------------------------------------
-- ENABLE信号がネゲートされている場合.
--------------------------------------------------------------------------
if (ENABLE /= '1') then
next_queue <= (others => REQUEST_NULL);
VALID <= '0';
REQUEST_O <= '0';
GRANT_NUM <= MIN_NUM;
GRANT <= (others => '0');
--------------------------------------------------------------------------
-- リクエスト信号が一つしかない場合は話は簡単だ.
--------------------------------------------------------------------------
elsif (MIN_NUM >= MAX_NUM) then
if (REQUEST(MIN_NUM) = '1') then
next_queue <= (others => REQUEST_NULL);
VALID <= '1';
REQUEST_O <= '1';
GRANT_NUM <= MIN_NUM;
GRANT <= (others => '1');
else
next_queue <= (others => REQUEST_NULL);
VALID <= '0';
REQUEST_O <= '0';
GRANT_NUM <= MIN_NUM;
GRANT <= (others => '0');
end if;
--------------------------------------------------------------------------
-- 複数のリクエスト信号がある場合は調停しなければならない.
-- あたりまえだ. それがこの回路の本来の仕事だ.
--------------------------------------------------------------------------
else
req_enable := (others => '1');
for i in QUEUE_TOP to QUEUE_END loop
if (curr_queue(i) /= REQUEST_NULL) then
req_select := curr_queue(i);
else
req_select := (others => '0');
for n in MIN_NUM to MAX_NUM loop
if (REQUEST(n) = '1' and req_enable(n) = '1') then
req_select(n) := '1';
exit;
end if;
end loop;
end if;
temp_queue(i) := req_select;
req_enable := req_enable and not req_select;
end loop;
if (temp_queue(QUEUE_TOP) /= REQUEST_NULL) then
VALID <= '1';
else
VALID <= '0';
end if;
if ((temp_queue(QUEUE_TOP) and REQUEST) /= REQUEST_NULL) then
REQUEST_O <= '1';
else
REQUEST_O <= '0';
end if;
GRANT <= temp_queue(QUEUE_TOP) and REQUEST;
next_queue <= temp_queue;
temp_num := MIN_NUM;
for n in MIN_NUM to MAX_NUM loop
if (temp_queue(QUEUE_TOP)(n) = '1') then
temp_num := n;
exit;
end if;
end loop;
GRANT_NUM <= temp_num;
end if;
end process;
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
process (CLK, RST) begin
if (RST = '1') then
curr_queue <= (others => REQUEST_NULL);
elsif (CLK'event and CLK = '1') then
if (CLR = '1') or
(ENABLE /= '1') then
curr_queue <= (others => REQUEST_NULL);
elsif (SHIFT = '1') then
for i in QUEUE_TOP to QUEUE_END loop
if (i < QUEUE_END) then
curr_queue(i) <= next_queue(i+1);
else
curr_queue(i) <= REQUEST_NULL;
end if;
end loop;
else
curr_queue <= next_queue;
end if;
end if;
end process;
end ONE_HOT_ARCH;
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
entity TEST_BENCH is
end TEST_BENCH;
-------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
architecture stimulus of TEST_BENCH is
----------------------------------------------------------------------------
-- 時間の定義
----------------------------------------------------------------------------
constant PERIOD : time := 10 ns;
constant DELAY : time := 1 ns;
----------------------------------------------------------------------------
-- リクエスト/グラント信号のタイプの定義
----------------------------------------------------------------------------
subtype REQUEST_TYPE is std_logic_vector(1 to 4);
----------------------------------------------------------------------------
-- 各種信号の定義
----------------------------------------------------------------------------
signal CLK : std_logic;
signal RST : std_logic;
signal CLR : std_logic;
signal REQ_O : std_logic;
signal VALID : std_logic;
signal REQUEST : REQUEST_TYPE;
signal GRANT : REQUEST_TYPE;
signal SHIFT : std_logic;
signal ENABLE : std_logic := '1';
signal GRANT_NUM : integer;
signal MISMATCH : integer := 0;
----------------------------------------------------------------------------
-- 信号を文字列に変換する関数の定義
----------------------------------------------------------------------------
function BIN_TO_STRING(VALUE:in std_logic_vector) return STRING is
variable bv: std_logic_vector(0 to VALUE'length-1) := VALUE;
variable str: string(1 to VALUE'length);
begin
for i in 0 to VALUE'length-1 loop
case bv(i) is
when '0' => str(i+1) := '0';
when '1' => str(i+1) := '1';
when 'L' => str(i+1) := 'L';
when 'H' => str(i+1) := 'H';
when 'Z' => str(i+1) := 'Z';
when 'U' => str(i+1) := 'U';
when '-' => str(i+1) := '-';
when others => str(i+1) := 'X';
end case;
end loop;
return str;
end BIN_TO_STRING;
function BIN_TO_STRING(BIT:in std_logic) return STRING is
begin
case BIT is
when 'H' => return "H";
when '1' => return "1";
when 'L' => return "L";
when '0' => return "0";
when others => return "X";
end case;
end BIN_TO_STRING;
----------------------------------------------------------------------------
-- メッセージをコンソールに出力する関数の定義
----------------------------------------------------------------------------
procedure REPORT_MESSAGE(MES:in STRING) is
variable str : LINE;
begin
WRITE(str, Now, RIGHT, 9);
WRITE(str, " : " & MES);
WRITELINE(OUTPUT, str);
end REPORT_MESSAGE;
----------------------------------------------------------------------------
-- 整数を文字列に変換する関数の定義
----------------------------------------------------------------------------
function INT_TO_STRING(arg:integer;len:integer;space:character) return STRING is
variable str : STRING(1 to len);
variable value : integer;
begin
value := arg;
for i in str'right downto str'left loop
if (value > 0) then
case (value mod 10) is
when 0 => str(i) := '0';
when 1 => str(i) := '1';
when 2 => str(i) := '2';
when 3 => str(i) := '3';
when 4 => str(i) := '4';
when 5 => str(i) := '5';
when 6 => str(i) := '6';
when 7 => str(i) := '7';
when 8 => str(i) := '8';
when 9 => str(i) := '9';
when others => str(i) := 'X';
end case;
else
if (i = str'right) then
str(i) := '0';
else
str(i) := space;
end if;
end if;
value := value / 10;
end loop;
return str;
end INT_TO_STRING;
----------------------------------------------------------------------------
-- グラント出力値の定義
----------------------------------------------------------------------------
constant GRANT_REQ1 : REQUEST_TYPE := (1 => '1', others => '0');
constant GRANT_REQ2 : REQUEST_TYPE := (2 => '1', others => '0');
constant GRANT_REQ3 : REQUEST_TYPE := (3 => '1', others => '0');
constant GRANT_REQ4 : REQUEST_TYPE := (4 => '1', others => '0');
constant GRANT_NULL : REQUEST_TYPE := (others => '0');
----------------------------------------------------------------------------
-- コンソールに信号の状態を出力する関数の定義
----------------------------------------------------------------------------
procedure REPORT_SIGNALS is
variable str : LINE;
begin
WRITE(str, Now, RIGHT, 9);
WRITE(str, " | REQ(1)=" & BIN_TO_STRING(REQUEST(1)));
WRITE(str, " | REQ(2)=" & BIN_TO_STRING(REQUEST(2)));
WRITE(str, " | REQ(3)=" & BIN_TO_STRING(REQUEST(3)));
WRITE(str, " | REQ(4)=" & BIN_TO_STRING(REQUEST(4)));
WRITE(str, " | SHIFT=" & BIN_TO_STRING(SHIFT));
WRITE(str, " | VALID=" & BIN_TO_STRING(VALID));
WRITE(str, " | REQ_O=" & BIN_TO_STRING(REQ_O));
WRITE(str, " | GRANT=" & BIN_TO_STRING(GRANT));
WRITE(str, " | NUM=" & INT_TO_STRING(GRANT_NUM,1,' '));
WRITELINE(OUTPUT, str);
end REPORT_SIGNALS;
----------------------------------------------------------------------------
-- QUEUE_ARBITERのコンポーネント宣言
----------------------------------------------------------------------------
component QUEUE_ARBITER
generic (
MIN_NUM : integer;
MAX_NUM : integer
);
port (
CLK : in std_logic;
RST : in std_logic;
CLR : in std_logic;
ENABLE : in std_logic;
REQUEST : in std_logic_vector(MIN_NUM to MAX_NUM);
GRANT : out std_logic_vector(MIN_NUM to MAX_NUM);
GRANT_NUM : out integer range MIN_NUM to MAX_NUM;
REQUEST_O : out std_logic;
VALID : out std_logic;
SHIFT : in std_logic
);
end component;
begin
----------------------------------------------------------------------------
-- クロックの生成
----------------------------------------------------------------------------
process begin
CLK <= '1';
wait for PERIOD / 2;
CLK <= '0';
wait for PERIOD / 2;
end process;
CLR <= '0';
----------------------------------------------------------------------------
-- アービターブロック
----------------------------------------------------------------------------
ARB:QUEUE_ARBITER generic map(MIN_NUM=>1, MAX_NUM=>4)
port map (
CLK => CLK,
RST => RST,
CLR => CLR,
ENABLE => ENABLE,
REQUEST => REQUEST,
GRANT => GRANT,
GRANT_NUM => GRANT_NUM,
REQUEST_O => REQ_O,
VALID => VALID,
SHIFT => SHIFT
);
----------------------------------------------------------------------------
-- テスト開始
----------------------------------------------------------------------------
process
variable MISMATCH : integer := 0;
------------------------------------------------------------------------
-- エラーの回数をコンソールに出力する関数の定義
------------------------------------------------------------------------
procedure REPORT_ERROR is
variable str : LINE;
constant tag : STRING(1 to 7) := " *** ";
begin
WRITE(str,tag); WRITELINE(OUTPUT,str);
WRITE(str,tag & "ERROR REPORT"); WRITELINE(OUTPUT,str);
WRITE(str,tag & "Mismatch=");WRITE(str,MISMATCH); WRITELINE(OUTPUT,str);
end REPORT_ERROR;
------------------------------------------------------------------------
-- クロックの立上りまで待って状態をチェックする関数の定義
------------------------------------------------------------------------
procedure WAIT_CLK(
CNT : in integer;
VAL_EXP : in std_logic;
REQ_EXP : in std_logic;
GNT_EXP : in REQUEST_TYPE;
NUM_EXP : in integer
) is
begin
for i in 1 to CNT loop
wait until (CLK'event and CLK = '1');
REPORT_SIGNALS;
if (VALID /= VAL_EXP) then
REPORT_MESSAGE("Mismatch: VAL=" & BIN_TO_STRING(VALID) &
",EXP=" & BIN_TO_STRING(VAL_EXP));
MISMATCH := MISMATCH + 1;
end if;
if (REQ_O /= REQ_EXP) then
REPORT_MESSAGE("Mismatch: REQ=" & BIN_TO_STRING(REQ_O) &
",EXP=" & BIN_TO_STRING(REQ_EXP));
MISMATCH := MISMATCH + 1;
end if;
if (GRANT /= GNT_EXP) then
REPORT_MESSAGE("Mismatch: GNT=" & BIN_TO_STRING(GRANT) &
",EXP=" & BIN_TO_STRING(GNT_EXP));
MISMATCH := MISMATCH + 1;
end if;
if (GRANT_NUM /= NUM_EXP) then
REPORT_MESSAGE("Mismatch: GRANT_NUM=" & INT_TO_STRING(GRANT_NUM,1,' ') &
",EXP=" & INT_TO_STRING(NUM_EXP ,1,' '));
MISMATCH := MISMATCH + 1;
end if;
end loop;
end WAIT_CLK;
procedure WAIT_CLK(CNT:in integer) is
begin
for i in 1 to CNT loop
wait until (CLK'event and CLK = '1');
REPORT_SIGNALS;
end loop;
end WAIT_CLK;
begin
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='1';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='1';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='1';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='1';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="1100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="1100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="1100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1101";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1101";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="1110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0101";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="0101";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="1110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="1000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="0000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="0101";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0101";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0101";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1101";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1101";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="0001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="1010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="1010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="1000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="1000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="0101";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0101";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0101";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="0101";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0000";SHIFT<='1';RST<='0';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,3);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1100";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0000";SHIFT<='1';RST<='0';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="1111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1011";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1010";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0110";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0100";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,4);
wait for DELAY;REQUEST<="0000";SHIFT<='1';RST<='0';WAIT_CLK(1,'0','0',GRANT_NULL,1);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1000";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1001";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1101";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1011";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1111";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="1111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ1,1);
wait for DELAY;REQUEST<="0111";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ4,4);
wait for DELAY;REQUEST<="0110";SHIFT<='0';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ2,2);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','0',GRANT_NULL,2);
wait for DELAY;REQUEST<="0010";SHIFT<='1';RST<='0';WAIT_CLK(1,'1','1',GRANT_REQ3,3);
wait for DELAY;REQUEST<="0000";SHIFT<='0';RST<='0';WAIT_CLK(1,'0','0',GRANT_NULL,1);
REPORT_ERROR;
assert(false) report "Run complete..." severity FAILURE;
wait;
end process;
end stimulus;
configuration TEST_BENCH_ONE_HOT_ARCH of TEST_BENCH is
for stimulus
for ARB : QUEUE_ARBITER
use entity WORK.QUEUE_ARBITER(ONE_HOT_ARCH);
end for;
end for;
end TEST_BENCH_ONE_HOT_ARCH;
configuration TEST_BENCH_INTEGER_ARCH of TEST_BENCH is
for stimulus
for ARB : QUEUE_ARBITER
use entity WORK.QUEUE_ARBITER(INTEGER_ARCH);
end for;
end for;
end TEST_BENCH_INTEGER_ARCH;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment