Skip to content

Instantly share code, notes, and snippets.

@ikwzm
Created March 21, 2012 09:07
Show Gist options
  • Save ikwzm/2145725 to your computer and use it in GitHub Desktop.
Save ikwzm/2145725 to your computer and use it in GitHub Desktop.
Synchronous Dual Port RAM VHDL Behavior Model

Synchronous Dual Port RAM VHDL Behavior Model

単純なシンクロナスデュアルポートRAMのVHDLビヘイビアモデルです。

私がFPGA/ASIC用の回路を設計しているときに比較的多用するデュアルポートメモリのモデルです。

論理合成ツールによってはそのまま合成できる場合がありますが、大抵の場合思うようにいきません。

うまく合成できない場合は、sdpram_model.vhdをFPGA/ASICベンダーが提供するメモリを使ったものに 差し替えて合成します。 Xilinx社FPGA用のモデルはこちらです。( https://gist.github.com/2145736 )

テストベンチを実行するためには、擬似乱数生成パッケージ( https://gist.github.com/2056693 )で 公開している mt19937ar.vhd が必要です。

GHDL=ghdl
GHDLFLAGS =--mb-comments
GHDLRUNFLAGS=--mb-comments
WORK=work
TEST_BENCH = test_bench_depth08_rd3_wd3_we0 \
test_bench_depth08_rd4_wd4_we0 \
test_bench_depth08_rd5_wd5_we0 \
test_bench_depth08_rd6_wd6_we3 \
test_bench_depth08_rd3_wd4_we0 \
test_bench_depth08_rd3_wd5_we0 \
test_bench_depth08_rd4_wd3_we0 \
test_bench_depth08_rd5_wd3_we0 \
$(END_LIST)
all: $(TEST_BENCH)
clean:
rm -f *.o *.cf $(TEST_BENCH)
test_bench_all: test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_depth08_rd3_wd3_we0 : test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_depth08_rd4_wd4_we0 : test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_depth08_rd5_wd5_we0 : test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_depth08_rd6_wd6_we3 : test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_depth08_rd3_wd4_we0 : test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_depth08_rd3_wd5_we0 : test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_depth08_rd4_wd3_we0 : test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench_depth08_rd5_wd3_we0 : test_bench.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench: test_bench.o sdpram_model.o
$(GHDL) -e $(GHDLFLAGS) $@
-$(GHDL) -r $(GHDLRUNFLAGS) $@
test_bench.o: ./test_bench.vhd mt19937ar.o sdpram.o sdpram_model.o
$(GHDL) -a $(GHDLFLAGS) --work=$(WORK) $<
mt19937ar.o: ./mt19937ar.vhd
$(GHDL) -a $(GHDLFLAGS) --work=$(WORK) $<
sdpram.o: ./sdpram.vhd
$(GHDL) -a $(GHDLFLAGS) --work=$(WORK) $<
sdpram_model.o: ./sdpram_model.vhd
$(GHDL) -a $(GHDLFLAGS) --work=$(WORK) $<
-----------------------------------------------------------------------------------
-- --
-- Title : Synchronous Dual Port RAM Entity. --
-- Version : 0.0.1 --
-- Created : 2012/3/18 --
-- File name : SDPRAM.vhd --
-- Module name : SDPRAM --
-- Author : Ichiro Kawazome <ichiro_k@ca2.so-net.ne.jp> --
-- Description : Synchronous Dual Port RAM Entity. --
-- --
-- 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;
entity SDPRAM is
generic (
DEPTH : -- SDPRAM DEPTH :
-- メモリの深さ(ビット単位)を2のべき乗値で指定する.
-- 例 DEPTH=10 => 2**10=1024bit
integer := 10;
RWIDTH : -- SDPRAM READ DATA PORT WIDTH :
-- リードポート(RDATA)の幅(ビット数)を2のべき乗値で指定する.
-- 例 RWIDTH=5 => 2**5=32bit
integer := 5;
WWIDTH : -- SDPRAM WRITE DATA PORT WIDTH :
-- ライトポート(WDATA)の幅(ビット数)を2のべき乗値で指定する.
integer := 6;
WEBIT : -- SDPRAM WRITE ENABLE WIDTH :
-- ライトイネーブル信号(WE)の幅(ビット数)を2のべき乗値で指定する.
-- 例 WEBIT=0 => 2**0=1bit
-- WEBIT=2 => 2**2=4bit
integer := 0;
ID : -- SDPRAM IDENTIFIER :
-- どのモジュールで使われているかを示す識別番号.
integer := 0
);
port (
WCLK : in std_logic;
WE : in std_logic_vector(2**WEBIT-1 downto 0);
WADDR : in std_logic_vector(DEPTH-1 downto WWIDTH);
RCLK : in std_logic;
RADDR : in std_logic_vector(DEPTH-1 downto RWIDTH);
WDATA : in std_logic_vector(2**WWIDTH-1 downto 0);
RDATA : out std_logic_vector(2**RWIDTH-1 downto 0)
);
end SDPRAM;
-----------------------------------------------------------------------------------
-- --
-- Title : Synchronous Dual Port RAM Model. --
-- Version : 0.0.1 --
-- Created : 2012/3/18 --
-- File name : SDPRAM.vhd --
-- Module name : SDPRAM --
-- Author : Ichiro Kawazome <ichiro_k@ca2.so-net.np.jp> --
-- Description : デュアルポートメモリのモデル。 --
-- 実際にASIC/FPGAに実装する時は、このモジュールを --
-- ベンダーに依存したものに置き換える。 --
-- --
-- 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;
use ieee.numeric_std.all;
architecture MODEL of SDPRAM is
signal ram : std_logic_vector(2**DEPTH-1 downto 0);
begin
process (WCLK)
variable w_ptr : integer;
variable w_be : std_logic_vector(WDATA'range);
constant W_BE_SIZE : integer := (2**WWIDTH)/(2**WEBIT);
begin
if (WCLK'event and WCLK = '1') then
w_ptr := TO_INTEGER(unsigned(WADDR)) * (2**WWIDTH);
for i in WE'range loop
for n in 0 to W_BE_SIZE-1 loop
w_be(i*W_BE_SIZE + n) := WE(i);
end loop;
end loop;
for i in WDATA'range loop
if (w_be(i) = '1') then
ram(w_ptr+i) <= WDATA(i);
end if;
end loop;
end if;
end process;
process (RCLK)
variable r_ptr : integer;
begin
if (RCLK'event and RCLK = '1') then
r_ptr := TO_INTEGER(unsigned(RADDR)) * (2**RWIDTH);
for i in RDATA'range loop
RDATA(i) <= ram(r_ptr+i);
end loop;
end if;
end process;
end MODEL;
-----------------------------------------------------------------------------------
-- --
-- Title : SDPRAM TEST BENCH --
-- Version : 0.0.1 --
-- Created : 2012/3/18 --
-- File name : test_bench.vhd --
-- Module name : TEST_BENCH --
-- Author : Ichiro Kawazome <ichiro_k@ca2.so-net.ne.jp> --
-- Description : SDPRAM のテストベンチ。 --
-- --
-- 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;
use ieee.numeric_std.all;
use std.textio.all;
use work.MT19937AR.SEED_TYPE;
use work.MT19937AR.TO_SEED_TYPE;
use work.MT19937AR.PSEUDO_RANDOM_NUMBER_GENERATOR_TYPE;
use work.MT19937AR.NEW_PSEUDO_RANDOM_NUMBER_GENERATOR;
use work.MT19937AR.GENERATE_RANDOM_REAL1;
library ieee;
use ieee.std_logic_1164.all;
entity TEST_BENCH is
generic (
DEPTH : integer := 9;
RWIDTH : integer := 5;
WWIDTH : integer := 6;
WEBIT : integer := 0;
AUTO_FINISH : integer := 1
);
port (
FINISH : out std_logic
);
end TEST_BENCH;
architecture MODEL of TEST_BENCH is
procedure INT_TO_STRING(constant VAL : in integer;
constant LEN : in integer;
variable STR : out STRING )
is
variable buf : string(STR'length downto 1);
variable pos : integer;
variable tmp : integer;
variable digit : integer range 0 to 9;
begin
pos := 1;
tmp := abs(VAL);
for i in 1 to LEN loop
digit := abs(tmp mod 10);
case digit is
when 0 => buf(pos) := '0';
when 1 => buf(pos) := '1';
when 2 => buf(pos) := '2';
when 3 => buf(pos) := '3';
when 4 => buf(pos) := '4';
when 5 => buf(pos) := '5';
when 6 => buf(pos) := '6';
when 7 => buf(pos) := '7';
when 8 => buf(pos) := '8';
when 9 => buf(pos) := '9';
end case;
pos := pos + 1;
tmp := tmp / 10;
end loop;
if (VAL < 0) then
buf(pos) := '-';
else
pos := pos - 1;
end if;
STR(1 to pos) := buf(pos downto 1);
end INT_TO_STRING; -- procedure
function INT_TO_STRING(VAL:integer;LEN:integer) return STRING is
variable str : string(1 to 32);
begin
INT_TO_STRING(VAL, LEN, str);
return str(1 to LEN);
end INT_TO_STRING;
function MAKE_INSTANCE_NAME return STRING is
variable str : string(1 to 19);
begin
str := "DEPTH" & INT_TO_STRING(DEPTH ,2) &
"_RD" & INT_TO_STRING(RWIDTH,1) &
"_WD" & INT_TO_STRING(WWIDTH,1) &
"_WE" & INT_TO_STRING(WEBIT ,1);
return str;
end MAKE_INSTANCE_NAME;
constant INSTANCE_NAME : string(1 to 19) := MAKE_INSTANCE_NAME;
constant PERIOD : time := 10 ns;
constant DELAY : time := 1 ns;
constant HEX : STRING(1 to 16) := "0123456789ABCDEF";
signal SCENARIO : STRING(1 to 5);
signal CLK : std_logic;
signal RST : std_logic;
signal WE : std_logic_vector(2**WEBIT-1 downto 0);
signal WADDR : std_logic_vector(DEPTH-1 downto WWIDTH);
signal RADDR : std_logic_vector(DEPTH-1 downto RWIDTH);
signal WDATA : std_logic_vector(2**WWIDTH-1 downto 0);
signal RDATA : std_logic_vector(2**RWIDTH-1 downto 0);
signal EXP_Q : bit_vector(2**RWIDTH-1 downto 0);
signal EXP_F : bit_vector(2**RWIDTH-1 downto 0);
component SDPRAM
generic (
DEPTH : integer := 6;
RWIDTH : integer := 6;
WWIDTH : integer := 6;
WEBIT : integer := 0;
ID : integer := 0
);
port (
WCLK : in std_logic;
WE : in std_logic_vector(2**WEBIT-1 downto 0);
WADDR : in std_logic_vector(DEPTH-1 downto WWIDTH);
RCLK : in std_logic;
RADDR : in std_logic_vector(DEPTH-1 downto RWIDTH);
WDATA : in std_logic_vector(2**WWIDTH-1 downto 0);
RDATA : out std_logic_vector(2**RWIDTH-1 downto 0)
);
end component;
begin
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
U: SDPRAM
generic map (
DEPTH => DEPTH,
RWIDTH => RWIDTH,
WWIDTH => WWIDTH,
WEBIT => WEBIT,
ID => 0
)
port map(
WCLK => CLK,
WE => WE,
WADDR => WADDR(DEPTH-1 downto WWIDTH),
RCLK => CLK,
RADDR => RADDR(DEPTH-1 downto RWIDTH),
WDATA => WDATA,
RDATA => RDATA
);
-------------------------------------------------------------------------------
--
-------------------------------------------------------------------------------
process begin
CLK <= '1'; wait for PERIOD/2;
CLK <= '0'; wait for PERIOD/2;
end process;
-------------------------------------------------------------------------------
-- 入力側のモデル
-------------------------------------------------------------------------------
process
procedure WAIT_CLK(CNT:integer) is
begin
if (CNT > 0) then
for i in 1 to CNT loop
wait until (CLK'event and CLK = '1');
end loop;
wait for DELAY;
end if;
end WAIT_CLK;
---------------------------------------------------------------------------
-- 乱数生成用変数およびプロシージャ
---------------------------------------------------------------------------
variable prng : PSEUDO_RANDOM_NUMBER_GENERATOR_TYPE
:= NEW_PSEUDO_RANDOM_NUMBER_GENERATOR(1623);
variable count : integer := 0;
variable text_line : LINE;
constant SPACE : STRING(1 to 1) := " ";
procedure GENERATE_UNIFORM_RANDOM(
variable value : out integer;
startpoint : in integer;
endpoint : in integer
) is
variable random_number : real;
variable random_value : integer;
begin
GENERATE_RANDOM_REAL1(prng,random_number);
--WRITE(text_line, count);
--WRITE(text_line, SPACE);
--WRITE(text_line, startpoint);
--WRITE(text_line, SPACE);
--WRITE(text_line, endpoint);
--WRITE(text_line, SPACE);
random_value := startpoint + integer(random_number*real(endpoint-startpoint));
value := random_value;
count := count + 1;
--WRITE(text_line, random_value);
--WRITELINE(OUTPUT, text_line);
end procedure;
---------------------------------------------------------------------------
-- データパターンテーブル/データ書き込みフラグ
---------------------------------------------------------------------------
variable table : bit_vector(2**DEPTH-1 downto 0);
variable w_ok : bit_vector(2**DEPTH-1 downto 0);
---------------------------------------------------------------------------
-- 中間変数
---------------------------------------------------------------------------
variable ptr : integer;
variable len : integer;
---------------------------------------------------------------------------
-- データパターンテーブル//データ書き込みフラグの初期化を行なうサブルーチン
---------------------------------------------------------------------------
procedure INIT_TABLE is
variable pattern : integer;
begin
for i in table'range loop
GENERATE_UNIFORM_RANDOM(pattern,0,2);
if (pattern >= 1) then table(i) := '1';
else table(i) := '0';
end if;
end loop;
w_ok := (others => '0');
WAIT_CLK(1);
end INIT_TABLE;
---------------------------------------------------------------------------
-- RAMにデータを書き込むプロシージャ(WENがbit_vectorの場合)
---------------------------------------------------------------------------
procedure WRITE(PTR:integer;WEN:bit_vector) is
variable w_ptr : integer;
variable w_be : bit_vector(2**WWIDTH-1 downto 0);
constant W_BE_SIZE : integer := (2**WWIDTH)/(2**WEBIT);
begin
w_ptr := PTR * (2**WWIDTH);
for i in WEN'range loop
for n in 0 to W_BE_SIZE-1 loop
w_be(i*W_BE_SIZE + n) := WEN(i);
end loop;
end loop;
for i in 0 to 2**WWIDTH-1 loop
if (w_be(i) = '1') then
if (table(w_ptr+i) = '1') then
WDATA(i) <= '1';
else
WDATA(i) <= '0';
end if;
w_ok(w_ptr+i) := '1';
else
WDATA(i) <= '0';
end if;
end loop;
WADDR <= std_logic_vector(TO_UNSIGNED(PTR,WADDR'length));
for i in WEN'range loop
if (WEN(i) = '1') then WE(i) <= '1';
else WE(i) <= '0';
end if;
end loop;
WAIT_CLK(1);
WE <= (others => '0');
end WRITE;
---------------------------------------------------------------------------
-- RAMにデータを書き込むプロシージャ
---------------------------------------------------------------------------
procedure WRITE(PTR:integer;LEN:integer) is
variable word_ena : bit_vector(2**WEBIT-1 downto 0);
variable word_ptr : integer;
variable word_pos : integer;
variable last_ptr : integer;
variable last_pos : integer;
begin
word_ptr := (PTR ) / (2**WWIDTH);
word_pos := (PTR ) mod (2**WWIDTH);
last_ptr := (PTR+LEN-1) / (2**WWIDTH);
while (word_ptr <= last_ptr) loop
if (word_ptr = last_ptr) then
last_pos := (PTR+LEN-1) mod (2**WWIDTH);
else
last_pos := (2**WWIDTH)-1;
end if;
for i in word_ena'range loop
if (i >= word_pos/(2**(WWIDTH-WEBIT))) and
(i <= last_pos/(2**(WWIDTH-WEBIT))) then
word_ena(i) := '1';
else
word_ena(i) := '0';
end if;
end loop;
WRITE(word_ptr,word_ena);
word_ptr := word_ptr + 1;
word_pos := 0;
exit when (word_ptr*(2**WWIDTH) > (2**(DEPTH-WWIDTH)));
end loop;
end WRITE;
---------------------------------------------------------------------------
-- RAMの内容とデータパターンの照合を行なうプロシージャ
---------------------------------------------------------------------------
procedure VERIFY is
variable d : bit_vector(2**RWIDTH-1 downto 0);
variable w : bit_vector(2**RWIDTH-1 downto 0);
begin
wait until (CLK'event and CLK = '1');
wait for DELAY;
RADDR <= std_logic_vector(TO_UNSIGNED(0,RADDR'length));
wait until (CLK'event and CLK = '1');
for r_ptr in 0 to 2**(DEPTH-RWIDTH)-1 loop
wait for DELAY;
if (r_ptr < 2**(DEPTH-RWIDTH)-1) then
RADDR <= std_logic_vector(TO_UNSIGNED(r_ptr+1,RADDR'length));
end if;
for i in 0 to 2**RWIDTH-1 loop
d(i) := table(r_ptr*(2**RWIDTH)+i);
w(i) := w_ok (r_ptr*(2**RWIDTH)+i);
end loop;
EXP_Q <= d;
EXP_F <= w;
wait until (CLK'event and CLK = '1');
for i in 0 to 2**RWIDTH-1 loop
if (w(i) = '1') and
((d(i) = '1' and RDATA(i) /= '1') or
(d(i) = '0' and RDATA(i) /= '0')) then
assert (false) report "Mismatch..." severity FAILURE;
end if;
end loop;
end loop;
wait for DELAY;
end VERIFY;
begin
---------------------------------------------------------------------------
-- シミュレーションの開始、まずはリセットから。
---------------------------------------------------------------------------
assert(false) report "Starting Run..." severity NOTE;
SCENARIO <= "START";
RST <= '1';
WADDR <= (others => '0');
WE <= (others => '0');
WDATA <= (others => '0');
RADDR <= (others => '0');
WAIT_CLK( 4); RST <= '0';
WAIT_CLK( 4);
---------------------------------------------------------------------------
--
---------------------------------------------------------------------------
SCENARIO <= "1.0.0";
for i in 0 to WEBIT loop
SCENARIO(5) <= HEX(i+1);
INIT_TABLE;
for ptr in 0 to 2**(DEPTH-(WWIDTH-i))-1 loop
WRITE(ptr*(2**(WWIDTH-i)), 2**(WWIDTH-i));
end loop;
VERIFY;
end loop;
---------------------------------------------------------------------------
--
---------------------------------------------------------------------------
SCENARIO <= "2.0.0";
for i in 0 to 9 loop
SCENARIO(5) <= HEX(i+1);
INIT_TABLE;
-- RA <= CONV_STD_LOGIC_VECTOR(1, RA'length);
for n in 0 to 99 loop
GENERATE_UNIFORM_RANDOM(ptr, 0, 2**(DEPTH-(WWIDTH-WEBIT))-1);
GENERATE_UNIFORM_RANDOM(len, 1, 2**(WWIDTH-WEBIT));
WRITE(ptr*(2**(WWIDTH-WEBIT)), len*(2**(WWIDTH-WEBIT)));
end loop;
VERIFY;
end loop;
---------------------------------------------------------------------------
-- シミュレーション終了
---------------------------------------------------------------------------
WAIT_CLK(10);
if (AUTO_FINISH = 0) then
assert(false) report INSTANCE_NAME & " Run complete..." severity NOTE;
FINISH <= 'Z';
else
FINISH <= 'Z';
assert(false) report INSTANCE_NAME & " Run complete..." severity FAILURE;
end if;
wait;
end process;
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチのコンポーネント宣言
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
package COMPONENTS is
component TEST_BENCH is
generic (
DEPTH : integer := 9;
RWIDTH : integer := 5;
WWIDTH : integer := 6;
WEBIT : integer := 0;
AUTO_FINISH : integer := 0
);
port (
FINISH : out std_logic
);
end component;
end COMPONENTS;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_DEPTH08_RD3_WD3_WE0 is
end TEST_BENCH_DEPTH08_RD3_WD3_WE0;
architecture MODEL of TEST_BENCH_DEPTH08_RD3_WD3_WE0 is
signal FINISH : std_logic;
begin
TB:TEST_BENCH generic map (DEPTH=>8,RWIDTH =>3,WWIDTH=>3,WEBIT=>0,AUTO_FINISH => 1)port map (open);
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_DEPTH08_RD4_WD4_WE0 is
end TEST_BENCH_DEPTH08_RD4_WD4_WE0;
architecture MODEL of TEST_BENCH_DEPTH08_RD4_WD4_WE0 is
signal FINISH : std_logic;
begin
TB:TEST_BENCH generic map (DEPTH=>8,RWIDTH =>4,WWIDTH=>4,WEBIT=>0,AUTO_FINISH => 1)port map (open);
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_DEPTH08_RD5_WD5_WE0 is
end TEST_BENCH_DEPTH08_RD5_WD5_WE0;
architecture MODEL of TEST_BENCH_DEPTH08_RD5_WD5_WE0 is
signal FINISH : std_logic;
begin
TB:TEST_BENCH generic map (DEPTH=>8,RWIDTH =>5,WWIDTH=>5,WEBIT=>0,AUTO_FINISH => 1)port map (open);
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_DEPTH08_RD6_WD6_WE3 is
end TEST_BENCH_DEPTH08_RD6_WD6_WE3;
architecture MODEL of TEST_BENCH_DEPTH08_RD6_WD6_WE3 is
signal FINISH : std_logic;
begin
TB:TEST_BENCH generic map (DEPTH=>8,RWIDTH =>6,WWIDTH=>6,WEBIT=>3,AUTO_FINISH => 1)port map (open);
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_DEPTH08_RD3_WD4_WE0 is
end TEST_BENCH_DEPTH08_RD3_WD4_WE0;
architecture MODEL of TEST_BENCH_DEPTH08_RD3_WD4_WE0 is
signal FINISH : std_logic;
begin
TB:TEST_BENCH generic map (DEPTH=>8,RWIDTH =>3,WWIDTH=>4,WEBIT=>0,AUTO_FINISH => 1)port map (open);
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_DEPTH08_RD3_WD5_WE0 is
end TEST_BENCH_DEPTH08_RD3_WD5_WE0;
architecture MODEL of TEST_BENCH_DEPTH08_RD3_WD5_WE0 is
signal FINISH : std_logic;
begin
TB:TEST_BENCH generic map (DEPTH=>8,RWIDTH =>3,WWIDTH=>5,WEBIT=>0,AUTO_FINISH => 1)port map (open);
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_DEPTH08_RD4_WD3_WE0 is
end TEST_BENCH_DEPTH08_RD4_WD3_WE0;
architecture MODEL of TEST_BENCH_DEPTH08_RD4_WD3_WE0 is
signal FINISH : std_logic;
begin
TB:TEST_BENCH generic map (DEPTH=>8,RWIDTH =>4,WWIDTH=>3,WEBIT=>0,AUTO_FINISH => 1)port map (open);
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_DEPTH08_RD5_WD3_WE0 is
end TEST_BENCH_DEPTH08_RD5_WD3_WE0;
architecture MODEL of TEST_BENCH_DEPTH08_RD5_WD3_WE0 is
signal FINISH : std_logic;
begin
TB:TEST_BENCH generic map (DEPTH=>8,RWIDTH =>5,WWIDTH=>3,WEBIT=>0,AUTO_FINISH => 1)port map (open);
end MODEL;
-----------------------------------------------------------------------------------
-- テストベンチ
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use WORK.COMPONENTS.TEST_BENCH;
entity TEST_BENCH_ALL is
end TEST_BENCH_ALL;
architecture MODEL of TEST_BENCH_ALL is
signal FINISH : std_logic;
begin
DEPTH_GEN : for DEPTH in 8 to 12 generate
RWIDTH_GEN: for RWIDTH in 3 to 6 generate
WWIDTH_GEN: for WWIDTH in 3 to 6 generate
WEBIT_GEN : for WEBIT in 0 to 1 generate
TB:TEST_BENCH generic map (
DEPTH => DEPTH,
RWIDTH => RWIDTH,
WWIDTH => WWIDTH,
WEBIT => WEBIT,
AUTO_FINISH => 0
)
port map (
FINISH => FINISH
);
end generate;
end generate;
end generate;
end generate;
FINISH <= 'H' after 1 ns;
process (FINISH) begin
if (FINISH'event and FINISH = 'H') then
assert(false) report "Run complete all." severity FAILURE;
end if;
end process;
end MODEL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment