1. 電源電圧が1.5V
2. バンク数が8、前のDDR2は4バンクだったのだが、DDR2でも8バンクもあるとのこと。
3. バースト数は当然8だが、4もあるとのこと。4の場合は、残りの4バーストを出さないで待っているようだ(Burst Chop4(BC4))。
4. ZQ Calibration:PVT (プロセス、電圧、温度)による Ron と ODT 値の変動の補正を行うそうだ。DDR2のOCDはオプション機能で肩透かしをくらったが、これは標準機能なのか?なお、Calib.コマンド(ZQCL,ZQCSを発行すると DRAM が自動で調整を行うセルフキャリブレーションだそうだ。DDR3 が正常動作するために必須の機能だそうだ。
5. RL,WLの扱いが変更になっている。この辺の機能はDDR2コントローラでも使っていない。(Posted CAS, Additive Latency)は使っていない。
6. DDR3ではディファレンシャルDQSのみ対応とのこと(DQS, DQS#)
7. /RESETピンが追加された。リセットすることができる。
8. Dynamic ODT:MRSコマンド発行なしにWrite時のODT抵抗値を動的に切り替えることが出来る機能。Write 時の信号品質向上に寄与。だそうです。Asynchoronous ODTも追加されたようだ。
9. DDR3 SDRAMのメモリモジュールでは、CMD/ADDRESS/CLK配線は各DDR3モジュールを一筆書き配線で結ぶとのこと。一筆書きの最初と最後では到達時間差が発生する。DQとDQSはそれぞれのDR3モジュールにつながっているため、CMD/ADDRESS/CLKとの間に時間差が発生する。そこで、 Write levelingモードで、DQ/DQSとCMD/ADDRESS/CLKの到達時間を合わせる。これはDQ/DQSの出力遅延を操作する必要があるので、Virtex-5以上でないと実装出来ないわけだ。
10. Read leveling:DDR3 SDRAM があらかじめ決められたデータパターンを出力してくれるようだ。これで、READデータの取り込みタイミングを最適な位置に調整しやすくなる。
1. コンポーネントのコピーは”C”キー
2. コンポーネントの連続挿入は”insert”キー
3. 回路のコピーは”SHIFT+ドラック”
4. コンポーネントの回転は”R”キー
5. 配線の変形(やってみて下さい)は”CTRL+ドラック”
-- tb_req_ack.vhd
-- OVL_Verilogアサーションを使用する
-- tb_req_ack.vhd本体
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
library accellera_ovl_vhdl;
use accellera_ovl_vhdl.std_ovl.all;
use accellera_ovl_vhdl.std_ovl_procs.all;
-- use accellera_ovl_vhdl.std_ovl_components.all;
library accellera_ovl_vlog;
use accellera_ovl_vlog.all; -- ovl_frameをuse
library work;
use work.proj_pkg.all;
entity tb_req_ack is
end tb_req_ack;
architecture testbench_arch of tb_req_ack is
component ack_sm
port(
clk : in std_logic;
reset : in std_logic;
req0 : in std_logic;
req1 : in std_logic;
ta0 : in std_logic; -- Transfer Acknowledge
ta1 : in std_logic; -- Transfer Acknowledge
ack0 : out std_logic;
ack1 : out std_logic
);
end component;
component req_sm
port(
clk : in std_logic;
reset : in std_logic;
req_start : in std_logic;
ack : in std_logic;
req : out std_logic
);
end component;
component ovl_next
generic (
severity_level : ovl_severity_level := OVL_SEVERITY_LEVEL_NOT_SET;
num_cks : positive := 1;
check_overlapping : ovl_chk_overlap := OVL_CHK_OVERLAP_OFF;
check_missing_start : ovl_ctrl := OVL_OFF;
property_type : ovl_property_type := OVL_PROPERTY_TYPE_NOT_SET;
msg : string := OVL_MSG_NOT_SET;
coverage_level : ovl_coverage_level := OVL_COVERAGE_LEVEL_NOT_SET;
clock_edge : ovl_active_edges := OVL_ACTIVE_EDGES_NOT_SET;
reset_polarity : ovl_reset_polarity := OVL_RESET_POLARITY_NOT_SET;
gating_type : ovl_gating_type := OVL_GATING_TYPE_NOT_SET;
controls : ovl_ctrl_record := OVL_CTRL_DEFAULTS
);
port (
clock : in std_logic;
reset : in std_logic;
enable : in std_logic;
start_event : in std_logic;
test_expr : in std_logic;
fire : out std_logic_vector(OVL_FIRE_WIDTH - 1 downto 0)
);
end component ovl_next;
component ovl_frame
generic (
severity_level : ovl_severity_level := OVL_SEVERITY_DEFAULT;
min_cks : natural := 0;
max_cks : natural := 0;
action_on_new_start : natural := OVL_ACTION_ON_NEW_START_DEFAULT;
property_type : ovl_property_type := OVL_PROPERTY_DEFAULT;
msg : string := OVL_MSG_DEFAULT;
coverage_level : ovl_coverage_level := OVL_COVER_DEFAULT;
clock_edge : ovl_active_edges := OVL_CLOCK_EDGE_DEFAULT;
reset_polarity : ovl_reset_polarity := OVL_RESET_POLARITY_DEFAULT;
gating_type : ovl_gating_type := OVL_GATING_TYPE_DEFAULT;
controls : ovl_ctrl_record := OVL_CTRL_DEFAULTS
);
port (
clock : in std_logic;
reset : in std_logic;
enable : in std_logic;
start_event : in std_logic;
test_expr : in std_logic;
fire : out std_logic_vector(OVL_FIRE_WIDTH - 1 downto 0)
);
end component ovl_frame;
signal clk : std_logic := '1';
signal reset : std_logic := '1';
signal req_start0 : std_logic := '0';
signal req_start1 : std_logic := '0';
signal req0 : std_logic := '0';
signal req1 : std_logic := '0';
signal ta0 : std_logic := '0';
signal ta1 : std_logic := '0';
signal ack0 : std_logic := '0';
signal ack1 : std_logic := '0';
signal fire_ta0_ack0_as, fire_ta1_ack1_as : std_logic_vector(OVL_FIRE_WIDTH - 1 downto 0);
signal fire_req0_ack0_as, fire_req1_ack1_as : std_logic_vector(OVL_FIRE_WIDTH - 1 downto 0);
constant PERIOD : time := 20 ns;
constant DUTY_CYCLE : real := 0.5;
-- req_startとtaを出力するprocedure
procedure REQ_START_TA(
signal clk : in std_logic;
loop_count : in integer;
signal req_start : out std_logic;
signal ta : out std_logic
) is
begin
wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
wait for 1 ns; -- 遅延を挟んで
req_start <= '1';
wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
wait for 1 ns; -- 遅延を挟んで
req_start <= '0';
for n in loop_count to 1 loop
wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
wait for 1 ns; -- 遅延を挟んで
end loop;
ta <= '1';
wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
wait for 1 ns; -- 遅延を挟んで
ta <= '0';
end REQ_START_TA;
begin
-- clkの生成(50MHz)
clk_generate : process begin
clock_loop : loop
clk <= '1';
wait for (PERIOD * DUTY_CYCLE);
clk <= '0';
wait for (PERIOD - (PERIOD * DUTY_CYCLE));
end loop clock_loop;
end process clk_generate;
-- シミュレーション時にOVLチェッカの初期化数を表示
ovl_print_init_count_p : process begin
wait for 0 ns;
ovl_print_init_count_proc(ovl_proj_controls);
wait; -- forever
end process ovl_print_init_count_p;
-- resetの生成
reset_generate : process begin
reset <= '1';
wait for 100 ns;
reset <= '0';
wait; -- forever
end process reset_generate;
ack_sm_inst : ack_sm port map(
clk => clk,
reset => reset,
req0 => req0,
req1 => req1,
ta0 => ta0,
ta1 => ta1,
ack0 => ack0,
ack1 => ack1
);
req_am_inst0 : req_sm port map(
clk => clk,
reset => reset,
req_start => req_start0,
ack => ack0,
req => req0
);
req_am_inst1 : req_sm port map(
clk => clk,
reset => reset,
req_start => req_start1,
ack => ack1,
req => req1
);
-- req_start0 とta0 の関係を生成する
process begin
req_start0 <= '0';
ta0 <= '0';
wait until reset'event and reset='0'; -- resetの立ち下がりまでwait
wait for 100 ns;
REQ_START_TA(clk, 1, req_start0, ta0);
REQ_START_TA(clk, 2, req_start0, ta0);
REQ_START_TA(clk, 3, req_start0, ta0);
REQ_START_TA(clk, 2, req_start0, ta0);
REQ_START_TA(clk, 1, req_start0, ta0);
REQ_START_TA(clk, 3, req_start0, ta0);
REQ_START_TA(clk, 2, req_start0, ta0);
wait for 200 ns;
assert (false) report "Simulation End!" severity failure;
end process;
-- req_start1 とta1 の関係を生成する
process begin
req_start1 <= '0';
ta1 <= '0';
wait until reset'event and reset='0'; -- resetの立ち下がりまでwait
wait for 100 ns;
REQ_START_TA(clk, 2, req_start1, ta1);
REQ_START_TA(clk, 1, req_start1, ta1);
REQ_START_TA(clk, 2, req_start1, ta1);
REQ_START_TA(clk, 3, req_start1, ta1);
REQ_START_TA(clk, 3, req_start1, ta1);
REQ_START_TA(clk, 1, req_start1, ta1);
REQ_START_TA(clk, 2, req_start1, ta1);
wait; -- forever
end process;
-- OVLアサーション
ovl_gen : if (ovl_proj_controls.assert_ctrl = OVL_ON) generate
ta0_ack0_assertion : ovl_next generic map (
severity_level => OVL_ERROR,
num_cks => 1,
check_overlapping => OVL_CHK_OVERLAP_OFF,
check_missing_start => OVL_ON,
property_type => OVL_ASSERT,
msg =>"ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted.",
coverage_level => OVL_COVER_BASIC,
clock_edge => OVL_POSEDGE,
reset_polarity => OVL_ACTIVE_HIGH,
gating_type => OVL_GATE_CLOCK,
controls => OVL_CTRL_DEFAULTS
)port map (
clock => clk,
reset => reset,
enable => '1',
start_event => ta0,
test_expr => ack0,
fire => fire_ta0_ack0_as
);
ta1_ack1_assertion : ovl_next generic map (
severity_level => OVL_ERROR,
num_cks => 1,
check_overlapping => OVL_CHK_OVERLAP_OFF,
check_missing_start => OVL_ON,
property_type => OVL_ASSERT,
msg =>"ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted.",
coverage_level => OVL_COVER_BASIC,
clock_edge => OVL_POSEDGE,
reset_polarity => OVL_ACTIVE_HIGH,
gating_type => OVL_GATE_CLOCK,
controls => OVL_CTRL_DEFAULTS
)port map (
clock => clk,
reset => reset,
enable => '1',
start_event => ta1,
test_expr => ack1,
fire => fire_ta1_ack1_as
);
req0_ack0_assertion : ovl_frame generic map(
severity_level => OVL_ERROR,
min_cks => 2,
max_cks => 4,
action_on_new_start => OVL_IGNORE_NEW_START,
property_type => OVL_ASSERT,
msg => "ERROR: ack0 isn't asserted after 2-4 clocks after req0 was asserted.",
coverage_level => OVL_COVER_BASIC,
clock_edge => OVL_POSEDGE,
reset_polarity => OVL_ACTIVE_HIGH,
gating_type => OVL_GATE_CLOCK,
controls => OVL_CTRL_DEFAULTS
) port map(
clock => clk,
reset => reset,
enable => '1',
start_event => req0,
test_expr => ack0,
fire => fire_req0_ack0_as
);
req1_ack1_assertion : ovl_frame generic map(
severity_level => OVL_ERROR,
min_cks => 2,
max_cks => 4,
action_on_new_start => OVL_IGNORE_NEW_START,
property_type => OVL_ASSERT,
msg => "ERROR: ack1 isn't asserted after 2-4 clocks after req1 was asserted.",
coverage_level => OVL_COVER_BASIC,
clock_edge => OVL_POSEDGE,
reset_polarity => OVL_ACTIVE_HIGH,
gating_type => OVL_GATE_CLOCK,
controls => OVL_CTRL_DEFAULTS
) port map(
clock => clk,
reset => reset,
enable => '1',
start_event => req1,
test_expr => ack1,
fire => fire_req1_ack1_as
);
end generate ovl_gen;
end testbench_arch;
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 260000 : tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 280000 : tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_FRAME : ERROR: ack0 isn't asserted after 2-4 clocks after req0 was asserted. : Test expression is not TRUE within specified maximum max_cks cycles from start event : severity 1 : time 300000 : tb_req_ack.ovl_gen.req0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_FRAME : ERROR: ack1 isn't asserted after 2-4 clocks after req1 was asserted. : Test expression is not TRUE within specified maximum max_cks cycles from start event : severity 1 : time 300000 : tb_req_ack.ovl_gen.req1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expresson is asserted without a corresponding start_event : severity 1 : time 320000 :
tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expresson is asserted without a corresponding start_event : severity 1 : time 320000 :
tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 340000 : tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 340000 : tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 400000 : tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 400000 : tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expresson is asserted without a corresponding start_event : severity 1 : time 440000 :
tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expresson is asserted without a corresponding start_event : severity 1 : time 440000 :
tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 460000 : tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 460000 : tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 520000 : tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 540000 : tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_FRAME : ERROR: ack0 isn't asserted after 2-4 clocks after req0 was asserted. : Test expression is not TRUE within specified maximum max_cks cycles from start event : severity 1 : time 560000 : tb_req_ack.ovl_gen.req0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_FRAME : ERROR: ack1 isn't asserted after 2-4 clocks after req1 was asserted. : Test expression is not TRUE within specified maximum max_cks cycles from start event : severity 1 : time 560000 : tb_req_ack.ovl_gen.req1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expresson is asserted without a corresponding start_event : severity 1 : time 580000 :
tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expresson is asserted without a corresponding start_event : severity 1 : time 580000 :
tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 600000 : tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 600000 : tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 660000 : tb_req_ack.ovl_gen.ta0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 660000 : tb_req_ack.ovl_gen.ta1_ack1_assertion.ovl_error_t
# OVL_ERROR : OVL_FRAME : ERROR: ack0 isn't asserted after 2-4 clocks after req0 was asserted. : Test expression is not TRUE within specified maximum max_cks cycles from start event : severity 1 : time 700000 : tb_req_ack.ovl_gen.req0_ack0_assertion.ovl_error_t
# OVL_ERROR : OVL_FRAME : ERROR: ack1 isn't asserted after 2-4 clocks after req1 was asserted. : Test expression is not TRUE within specified maximum max_cks cycles from start event : severity 1 : time 700000 : tb_req_ack.ovl_gen.req1_ack1_assertion.ovl_error_t
# ** Failure: Simulation End!
# Time: 841 ns Iteration: 0 Process: /tb_req_ack/line__183 File: C:/HDL/OVL/examples/req_ack_test_vhdl_vlog/tb_req_ack.vhd
# Break at C:/HDL/OVL/examples/req_ack_test_vhdl_vlog/tb_req_ack.vhd line 196
-- proj_pkg.vhd
library accellera_ovl_vhdl;
use accellera_ovl_vhdl.std_ovl.all;
use accellera_ovl_vhdl.std_ovl_procs.all;
package proj_pkg is
-- OVL configuration
constant ovl_proj_controls : ovl_ctrl_record := (
-- generate statement controls
xcheck_ctrl => OVL_ON,
implicit_xcheck_ctrl => OVL_ON,
init_msg_ctrl => OVL_ON,
init_count_ctrl => OVL_OFF,
assert_ctrl => OVL_ON,
cover_ctrl => OVL_ON,
global_reset_ctrl => OVL_OFF,
finish_ctrl => OVL_ON,
gating_ctrl => OVL_ON,
-- user configurable library constants
max_report_error => 4,
max_report_cover_point => 15,
runtime_after_fatal => "150 ns ",
-- default values for common generics
severity_level_default => OVL_SEVERITY_DEFAULT,
property_type_default => OVL_PROPERTY_DEFAULT,
--msg_default => OVL_MSG_DEFAULT,
msg_default => ovl_set_msg("Assertion Error"),
coverage_level_default => OVL_COVER_DEFAULT,
clock_edge_default => OVL_CLOCK_EDGE_DEFAULT,
reset_polarity_default => OVL_RESET_POLARITY_DEFAULT,
gating_type_default => OVL_GATING_TYPE_DEFAULT
);
end package proj_pkg;
-- OVLテスト用 req_sm.vhd
-- req_start 信号を受けると、reqを1にアサートする。ackを受け取るとreqを0にディアサートする
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity req_sm is
port(
clk : in std_logic;
reset : in std_logic;
req_start : in std_logic;
ack : in std_logic;
req : out std_logic
);
end req_sm;
architecture RTL of req_sm is
type cs_req_state is (idle_req, assert_req);
signal cs_req : cs_req_state;
begin
process(clk) begin
if clk'event and clk='1' then
if reset='1' then
cs_req <= idle_req;
req <= '0';
else
case cs_req is
when idle_req =>
if req_start='1' then
cs_req <= assert_req;
req <= '1';
end if;
when assert_req =>
if ack='1' then
cs_req <= idle_req;
req <= '0';
end if;
end case;
end if;
end if;
end process;
end RTL;
-- OVLテスト用 ack_sm.vhd
-- 2つのreqを管理して、reqがアサートされている状態で、taがアサートされるとackを返す
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity ack_sm is
port(
clk : in std_logic;
reset : in std_logic;
req0 : in std_logic;
req1 : in std_logic;
ta0 : in std_logic; -- Transfer Acknowledge
ta1 : in std_logic; -- Transfer Acknowledge
ack0 : out std_logic;
ack1 : out std_logic
);
end ack_sm;
architecture RTL of ack_sm is
type cs_main_state is (idle_req, assert_req0, assert_req1, assert_req01, req0_ack, req1_ack, req01_ack);
signal cs_main : cs_main_state;
begin
process(clk) begin
if clk'event and clk='1' then
if reset='1' then
cs_main <= idle_req;
ack0 <= '0'; ack1 <= '0';
else
case cs_main is
when idle_req =>
if req0='1' then
cs_main <= assert_req0;
ack0 <= '0'; ack1 <= '0';
elsif req1='1' then
cs_main <= assert_req1;
ack0 <= '0'; ack1 <= '0';
end if;
when assert_req0 =>
if req1='1' then
cs_main <= assert_req01;
ack0 <= '0'; ack1 <= '0';
elsif ta0='1' then
cs_main <= req0_ack;
ack0 <= '1'; ack1 <= '0';
end if;
when assert_req1 =>
if req0='1' then
cs_main <= assert_req01;
ack0 <= '0'; ack1 <= '0';
elsif ta1='1' then
cs_main <= req1_ack;
ack0 <= '0'; ack1 <= '1';
end if;
when assert_req01 =>
if ta0='1' and ta1='0' then
cs_main <= req0_ack;
ack0 <= '1'; ack1 <= '0';
elsif ta0='0' and ta1='1' then
cs_main <= req1_ack;
ack0 <= '0'; ack1 <= '1';
elsif ta0='1' and ta1='1' then
cs_main <= req01_ack;
ack0 <= '1'; ack1 <= '1';
end if;
when req0_ack =>
if req1='1' then
cs_main <= assert_req1;
ack0 <= '0'; ack1 <= '0';
else
cs_main <= idle_req;
ack0 <= '0'; ack1 <= '0';
end if;
when req1_ack =>
if req0='1' then
cs_main <= assert_req0;
ack0 <= '0'; ack1 <= '0';
else
cs_main <= idle_req;
ack0 <= '0'; ack1 <= '0';
end if;
when req01_ack =>
cs_main <= idle_req;
ack0 <= '0'; ack1 <= '0';
end case;
end if;
end if;
end process;
end RTL;
-- tb_req_ack.vhd
-- tb_req_ack.vhd本体
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
library accellera_ovl_vhdl;
use accellera_ovl_vhdl.std_ovl.all;
use accellera_ovl_vhdl.std_ovl_components.all;
use accellera_ovl_vhdl.std_ovl_procs.all;
library work;
use work.proj_pkg.all;
entity tb_req_ack is
end tb_req_ack;
architecture testbench_arch of tb_req_ack is
component ack_sm
port(
clk : in std_logic;
reset : in std_logic;
req0 : in std_logic;
req1 : in std_logic;
ta0 : in std_logic; -- Transfer Acknowledge
ta1 : in std_logic; -- Transfer Acknowledge
ack0 : out std_logic;
ack1 : out std_logic
);
end component;
component req_sm
port(
clk : in std_logic;
reset : in std_logic;
req_start : in std_logic;
ack : in std_logic;
req : out std_logic
);
end component;
signal clk : std_logic := '1';
signal reset : std_logic := '1';
signal req_start0 : std_logic := '0';
signal req_start1 : std_logic := '0';
signal req0 : std_logic := '0';
signal req1 : std_logic := '0';
signal ta0 : std_logic := '0';
signal ta1 : std_logic := '0';
signal ack0 : std_logic := '0';
signal ack1 : std_logic := '0';
signal fire_ta0_ack0_as, fire_ta1_ack1_as : std_logic_vector(OVL_FIRE_WIDTH - 1 downto 0);
signal fire_req0_ack0_as, fire_req1_ack1_as : std_logic_vector(OVL_FIRE_WIDTH - 1 downto 0);
constant PERIOD : time := 20 ns;
constant DUTY_CYCLE : real := 0.5;
-- req_startとtaを出力するprocedure
procedure REQ_START_TA(
signal clk : in std_logic;
loop_count : in integer;
signal req_start : out std_logic;
signal ta : out std_logic
) is
begin
wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
wait for 1 ns; -- 遅延を挟んで
req_start <= '1';
wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
wait for 1 ns; -- 遅延を挟んで
req_start <= '0';
for n in loop_count to 1 loop
wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
wait for 1 ns; -- 遅延を挟んで
end loop;
ta <= '1';
wait until clk'event and clk='1'; -- clkの立ち上がりまでwait
wait for 1 ns; -- 遅延を挟んで
ta <= '0';
end REQ_START_TA;
begin
-- clkの生成(50MHz)
clk_generate : process begin
clock_loop : loop
clk <= '1';
wait for (PERIOD * DUTY_CYCLE);
clk <= '0';
wait for (PERIOD - (PERIOD * DUTY_CYCLE));
end loop clock_loop;
end process clk_generate;
-- シミュレーション時にOVLチェッカの初期化数を表示
ovl_print_init_count_p : process begin
wait for 0 ns;
ovl_print_init_count_proc(ovl_proj_controls);
wait; -- forever
end process ovl_print_init_count_p;
-- resetの生成
reset_generate : process begin
reset <= '1';
wait for 100 ns;
reset <= '0';
wait; -- forever
end process reset_generate;
ack_sm_inst : ack_sm port map(
clk => clk,
reset => reset,
req0 => req0,
req1 => req1,
ta0 => ta0,
ta1 => ta1,
ack0 => ack0,
ack1 => ack1
);
req_am_inst0 : req_sm port map(
clk => clk,
reset => reset,
req_start => req_start0,
ack => ack0,
req => req0
);
req_am_inst1 : req_sm port map(
clk => clk,
reset => reset,
req_start => req_start1,
ack => ack1,
req => req1
);
-- req_start0 とta0 の関係を生成する
process begin
req_start0 <= '0';
ta0 <= '0';
wait until reset'event and reset='0'; -- resetの立ち下がりまでwait
wait for 100 ns;
REQ_START_TA(clk, 1, req_start0, ta0);
REQ_START_TA(clk, 2, req_start0, ta0);
REQ_START_TA(clk, 3, req_start0, ta0);
REQ_START_TA(clk, 2, req_start0, ta0);
REQ_START_TA(clk, 1, req_start0, ta0);
REQ_START_TA(clk, 3, req_start0, ta0);
REQ_START_TA(clk, 2, req_start0, ta0);
wait for 200 ns;
assert (false) report "Simulation End!" severity failure;
end process;
-- req_start1 とta1 の関係を生成する
process begin
req_start1 <= '0';
ta1 <= '0';
wait until reset'event and reset='0'; -- resetの立ち下がりまでwait
wait for 100 ns;
REQ_START_TA(clk, 2, req_start1, ta1);
REQ_START_TA(clk, 1, req_start1, ta1);
REQ_START_TA(clk, 2, req_start1, ta1);
REQ_START_TA(clk, 3, req_start1, ta1);
REQ_START_TA(clk, 3, req_start1, ta1);
REQ_START_TA(clk, 1, req_start1, ta1);
REQ_START_TA(clk, 2, req_start1, ta1);
wait; -- forever
end process;
-- OVLアサーション
ovl_gen : if (ovl_proj_controls.assert_ctrl = OVL_ON) generate
ta0_ack0_assertion : ovl_next generic map (
severity_level => OVL_ERROR,
num_cks => 1,
check_overlapping => OVL_CHK_OVERLAP_OFF,
check_missing_start => OVL_ON,
property_type => OVL_ASSERT,
msg =>"ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted.",
coverage_level => OVL_COVER_BASIC,
clock_edge => OVL_POSEDGE,
reset_polarity => OVL_ACTIVE_HIGH,
gating_type => OVL_GATE_CLOCK,
controls => OVL_CTRL_DEFAULTS
)port map (
clock => clk,
reset => reset,
enable => '1',
start_event => ta0,
test_expr => ack0,
fire => fire_ta0_ack0_as
);
ta1_ack1_assertion : ovl_next generic map (
severity_level => OVL_ERROR,
num_cks => 1,
check_overlapping => OVL_CHK_OVERLAP_OFF,
check_missing_start => OVL_ON,
property_type => OVL_ASSERT,
msg =>"ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted.",
coverage_level => OVL_COVER_BASIC,
clock_edge => OVL_POSEDGE,
reset_polarity => OVL_ACTIVE_HIGH,
gating_type => OVL_GATE_CLOCK,
controls => OVL_CTRL_DEFAULTS
)port map (
clock => clk,
reset => reset,
enable => '1',
start_event => ta1,
test_expr => ack1,
fire => fire_ta1_ack1_as
);
end generate ovl_gen;
end testbench_arch;
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 260000 ps :tb_req_ack:ovl_gen:ta1_ack1_assertion:
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 280000 ps :tb_req_ack:ovl_gen:ta0_ack0_assertion:
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 400000 ps :tb_req_ack:ovl_gen:ta0_ack0_assertion:
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 400000 ps :tb_req_ack:ovl_gen:ta1_ack1_assertion:
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 520000 ps :tb_req_ack:ovl_gen:ta1_ack1_assertion:
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 540000 ps :tb_req_ack:ovl_gen:ta0_ack0_assertion:
# OVL_ERROR : OVL_NEXT : ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 660000 ps :tb_req_ack:ovl_gen:ta0_ack0_assertion:
# OVL_ERROR : OVL_NEXT : ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted. : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 660000 ps :tb_req_ack:ovl_gen:ta1_ack1_assertion:
# ** Failure: Simulation End!
# Time: 841 ns Iteration: 0 Process: /tb_req_ack/line__133 File: H:/HDL/OVL/example/req_ack_test_vhdl/tb_req_ack.vhd
# Break in Process line__133 at H:/HDL/OVL/example/req_ack_test_vhdl/tb_req_ack.vhd line 146
process begin
wait for 80 ns; -- 1クロック分リセット
reset <= '0'; -- リセット解除
PS2_SigGen(x"1C", ps2clk, ps2data);
PS2_SigGen(x"32", ps2clk, ps2data);
end process;
process begin
wait for 80 ns; -- 1クロック分リセット
reset <= '0'; -- リセット解除
PS2_SigGen(x"1C", ps2clk, ps2data);
PS2_SigGen(x"32", ps2clk, ps2data);
wait for 40 us;
assert (false) report "Simulation End!" severity failure;
end process;
(vcom-1136) Unknown identifier "fatal".
cd H:/HDL/OVL/std_ovl
vlib accellera_ovl_vlog
vlog -work accellera_ovl_vlog +define+OVL_VERILOG +define+OVL_ASSERT_ON +define+OVL_FINISH_OFF +incdir+H:/HDL/OVL/std_ovl ovl_*.v
vlib accellera_ovl_vhdl
vcom -93 -work accellera_ovl_vhdl std_ovl.vhd
vcom -93 -work accellera_ovl_vhdl std_ovl_procs.vhd
vcom -93 -work accellera_ovl_vhdl std_ovl_components_vlog.vhd
vcom -93 -work accellera_ovl_vhdl std_ovl_clock_gating.vhd
vcom -93 -work accellera_ovl_vhdl std_ovl_reset_gating.vhd
vcom -93 -work accellera_ovl_vhdl ovl_*.vhd
vcom -93 -work accellera_ovl_vhdl vhdl93/ovl_*_rtl.vhd
ovl_always : 常に式が成り立つかを見ている(val1 < val2)
ovl_always_on_edge : サンプリングイベントの時に式が成り立つかを見ている(サンプリングイベント=ack, 式=(MAIN_STATE==ACK_STATE))(VHDLは無し)
ovl_change : start_eventが起こった時から、num_cksで示されたクロック以内に出力値が変化すことを保証する(VHDLは無し)
ovl_cycle_sequence : ステートマシンの遷移条件をテストできる。WR→WAIT→(WRまたはDONE)
ovl_decrement : ある値で減算するカウンタ等をテストできる(VHDLは無し)
ovl_delta : 信号がある一定の範囲で変化することをテストできる(VHDLは無し)
ovl_even_parity : 偶数パリティをチェックする(VHDLは無し)
ovl_fifo_index : FIFOのオーバーフローとアンダーフローをチェックする。push,pop条件を監視しdepthを設定することでチェックすることができる(VHDLは無し)
ovl_frame : start_eventとあるtest_exprの関係をテストできる。start_eventが変化してからtest_exprが変化するまでのクロック数を最小値、最大値で表する(VHDLは無し)
ovl_handshake : requestとacknowledgeの関係をovl_frame等よりも詳細にチェックすることができる。req, ackの厳密な関係を記述したい場合はこれを使うべきだと思う(VHDLは無し)
ovl_implication : 原因と結果の関係をテストする。antecedent_exprがアサートされている時に、consequent_exprもアサートされているかをチェックする
ovl_increment:ある値で加算するカウンタ等をテストできる(VHDLは無し)
ovl_never : test_exprが決して真にならないことをチェックする。例えば、サイコロの値をdice_cntとすると、test_exprはdice_cnt>6と表される。dice_cntが7以上になればアサーション・エラーとなる
ovl_never_unkown : qualifierがTRUEの時に、test_exprに不定値を含むかどうかをチェックする
ovl_never_unkown_async : 非同期(クロックイベントがない)のovl_never_unkown
ovl_next : start_eventとtest_expr間のアサートのクロックのタイミングをチェックする。ovl_frameと異なるのは、クロックのタイミングが固定されていること
ovl_no_overflow : test_exprがminとmaxの間にあるかどうかをチェックする(VHDLは無し)
ovl_no_transition : start_stateを指定して、次のステートがnext_stateに遷移しないことをチェックする(VHDLは無し)
ovl_no_underflow : test_exprがminとmaxの間にあるかどうかをチェックする(VHDLは無し)
ovl_odd_parity : test_exprが奇数パリティであることをチェックする(VHDLは無し)
ovl_one_cold : test_exprのステート値などのどれか1ビットが0であることをチェックする(VHDLは無し)
ovl_one_hot : test_exprのどれか1ビットだけが1であることをチェックする
ovl_proposition : test_exprが成立することをチェックする。組み合わせ回路(VHDLは無し)
ovl_quiescent_state : sample_eventがTRUEの時に、state_exprがcheck_valueと同一になっているかをチェックする(VHDLは無し)
ovl_range : test_exprの値がmin値とmax値の間にあることをチェックする
ovl_time : start_eventがTRUEになった次のクロックからnum_cksクロック間、test_exprの条件が成り立つことをチェックする(VHDLは無し)
ovl_transition : test_exprの信号がstart_stateの次のステートがnext_stateであることをチェックする(VHDLは無し)(注:必ずしもステートマシンのステートチェックだけではなく、1つ前の状態と次の状態のチェックをする。enableを使うとクロックが離れていても使える)
ovl_unchange : start_eventがTRUEになってから、test_exprの信号がnum_cksクロック間、変化しないことをチェックする(VHDLは無し)
ovl_width : パルス幅をチェックする。test_exprがTRUEの幅が、min_cksとmax_cksのクロックの間に入っていることをチェックする(VHDLは無し)
ovl_win_change : start_eventがTRUEになってから、end_eventがTRUEになるまでの間(event window)に、test_exprが変化することをチェックする(VHDLは無し)
ovl_win_unchange : start_eventがTRUEになってから、end_eventがTRUEになるまでの間(event window)に、test_exprが変化しないことをチェックする(VHDLは無し)
ovl_window : start_eventがTRUEになってから、end_eventがTRUEになるまでの間(event window)に、test_exprが常にTRUEであることをチェックする(VHDLは無し)
ovl_zero_one_hot : test_exprのどれか1ビットだけが1かまたは、オール0であることをチェックする
ovl_always, ovl_cycle_sequence, ovl_implication, ovl_never, ovl_never_unkown, ovl_next, ovl_one_hot, ovl_range, ovl_win_unchange, ovl_zero_one_hot
// OVLテスト用req_sm.v
// req_start 信号を受けると、reqを1にアサートする。ackを受け取るとreqを0にディアサートする
`default_nettype none
module req_sm (
input wire clk,
input wire reset,
input wire req_start,
input wire ack,
output reg req
);
parameter [1:0] idle_req = 2'b01,
assert_req = 2'b10;
reg [1:0] cs_req;
always @(posedge clk) begin
if (reset) begin
cs_req <= idle_req;
req <= 1'b0;
end else begin
case (cs_req)
idle_req :
if (req_start) begin
cs_req <= assert_req;
req <= 1'b1;
end
assert_req :
if (ack) begin
cs_req <= idle_req;
req <= 1'b0;
end
endcase
end
end
endmodule
`default_nettype wire
// OVLテスト用 ack_sm.v
// 2つのreqを管理して、reqがアサートされている状態で、taがアサートされるとackを返す
`default_nettype none
module ack_sm (
input wire clk,
input wire reset,
input wire req0,
input wire req1,
input wire ta0, // Transfer Acknowledge
input wire ta1, // Transfer Acknowledge
output reg ack0,
output reg ack1
);
parameter [6:0] idle_req = 7'b0000001, // 最初のidle 状態
assert_req0 = 7'b0000010, // req0だけがアサートされている
assert_req1 = 7'b0000100, // req1だけがアサートされている
assert_req01 = 7'b0001000,
req0_ack = 7'b0010000,
req1_ack = 7'b0100000,
req01_ack = 7'b1000000;
reg [6:0] cs_main;
always @(posedge clk) begin
if (reset) begin
cs_main <= idle_req;
ack0 <= 1'b0; ack1 <= 1'b0;
end else begin
case (cs_main)
idle_req : begin
if (req0) begin
cs_main <= assert_req0;
ack0 <= 1'b0; ack1 <= 1'b0;
end else if (req1) begin
cs_main <= assert_req1;
ack0 <= 1'b0; ack1 <= 1'b0;
end
end
assert_req0 : begin
if (req1) begin
cs_main <= assert_req01;
ack0 <= 1'b0; ack1 <= 1'b0;
end else if (ta0) begin
cs_main <= req0_ack;
ack0 <= 1'b1; ack1 <= 1'b0;
end
end
assert_req1 : begin
if (req0) begin
cs_main <= assert_req01;
ack0 <= 1'b0; ack1 <= 1'b0;
end else if (ta1) begin
cs_main <= req1_ack;
ack0 <= 1'b0; ack1 <= 1'b1;
end
end
assert_req01 : begin
if (ta0 & ~ta1) begin
cs_main <= req0_ack;
ack0 <= 1'b1; ack1 <= 1'b0;
end else if (~ta0 & ta1) begin
cs_main <= req1_ack;
ack0 <= 1'b0; ack1 <= 1'b1;
end else if (ta0 & ta1) begin
cs_main <= req01_ack;
ack0 <= 1'b1; ack1 <= 1'b1;
end
end
req0_ack : begin
if (req1) begin
cs_main <= assert_req1;
ack0 <= 1'b0; ack1 <= 1'b0;
end else begin
cs_main <= idle_req;
ack0 <= 1'b0; ack1 <= 1'b0;
end
end
req1_ack : begin
if (req0) begin
cs_main <= assert_req0;
ack0 <= 1'b0; ack1 <= 1'b0;
end else begin
cs_main <= idle_req;
ack0 <= 1'b0; ack1 <= 1'b0;
end
end
req01_ack : begin
cs_main <= idle_req;
ack0 <= 1'b0; ack1 <= 1'b0;
end
endcase
end
end
endmodule
`default_nettype wire
// tb_req_ack.v
`default_nettype none
`timescale 1ns / 10ps
`include "std_ovl_defines.h"
module tb_req_ack;
reg clk;
reg reset;
reg req_start0, req_start1;
wire req0, req1;
wire ack0, ack1;
reg ta0, ta1;
wire [`OVL_FIRE_WIDTH-1:0] fire_ta0_ack0_as, fire_ta1_ack1_as;
wire [`OVL_FIRE_WIDTH-1:0] fire_req0_ack0_as, fire_req1_ack1_as;
parameter CLK_PERIOD = 20;
// 50MHzクロック
always begin
#(CLK_PERIOD/2) clk = 1'b1 ;
#(CLK_PERIOD/2) clk = 1'b0 ;
end
// reset
initial begin
reset = 1'b1;
#100 reset = 1'b0;
end
req_sm req_sm0 (
.clk(clk),
.reset(reset),
.req_start(req_start0),
.ack(ack0),
.req(req0)
);
req_sm req_sm1 (
.clk(clk),
.reset(reset),
.req_start(req_start1),
.ack(ack1),
.req(req1)
);
ack_sm ack_sm_i (
.clk(clk),
.reset(reset),
.req0(req0),
.req1(req1),
.ta0(ta0),
.ta1(ta1),
.ack0(ack0),
.ack1(ack1)
);
// req_start0とta0の関係を生成する
initial begin
req_start0 <= 1'b0;
ta0 <= 1'b0;
@(negedge reset); // リセットが0になるのを待つ
#100;
REQ_START_TA0(3'd1);
REQ_START_TA0(3'd2);
REQ_START_TA0(3'd3);
REQ_START_TA0(3'd2);
REQ_START_TA0(3'd1);
REQ_START_TA0(3'd3);
REQ_START_TA0(3'd2);
#200 $stop;
end
// req_start1とta1の関係を生成する
initial begin
req_start1 <= 1'b0;
ta1 <= 1'b0;
@(negedge reset); // リセットが0になるのを待つ
#100;
REQ_START_TA1(3'd2);
REQ_START_TA1(3'd1);
REQ_START_TA1(3'd2);
REQ_START_TA1(3'd3);
REQ_START_TA1(3'd3);
REQ_START_TA1(3'd1);
REQ_START_TA1(3'd2);
end
// task REQ_START_TA0
task REQ_START_TA0;
input [2:0] loop_count;
begin :REQ_START_TA0_PROCESS
integer i;
@(posedge clk); // clkの立ち上がりまでwait
#1 ; // 遅延を挟んで
req_start0 = 1'b1;
@(posedge clk); // clkの立ち上がりまでwait
#1; // 遅延を挟んで
req_start0 = 1'b0;
for(i=loop_count; i>0; i=i-1) begin
@(posedge clk);
#1;
end
ta0 = 1'b1;
@(posedge clk); // clkの立ち上がりまでwait
#1 ; // 遅延を挟んで
ta0 = 1'b0;
end
endtask
// task REQ_START_TA1
task REQ_START_TA1;
input [2:0] loop_count;
begin :REQ_START_TA1_PROCESS
integer i;
@(posedge clk); // clkの立ち上がりまでwait
#1 ; // 遅延を挟んで
req_start1 = 1'b1;
@(posedge clk); // clkの立ち上がりまでwait
#1; // 遅延を挟んで
req_start1 = 1'b0;
for(i=loop_count; i>0; i=i-1) begin
@(posedge clk);
#1;
end
ta1 = 1'b1;
@(posedge clk); // clkの立ち上がりまでwait
#1 ; // 遅延を挟んで
ta1 = 1'b0;
end
endtask
// アサーション
// ta0がアサートされた次のクロックでack0がアサートされる
ovl_next #(
`OVL_ERROR, // severity_level
1, // num_cks(1クロック後にアサート)
1, // check_overlapping (off)
1, // check_missing_start (on)
`OVL_ASSERT, // property_type
// "ERROR: ta0がアサートされた次のクロックでack0がアサートされていない",
"ERROR: ack0 isn't asserted of with the next clock that ta0 was asserted.",
`OVL_COVER_BASIC, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ta0_ack0_assertion (
clk,
reset,
1'b1, // enable
ta0, // start event
ack0, // test_expr
fire_ta0_ack0_as // fire
);
// ta1がアサートされた次のクロックでack1がアサートされる
ovl_next #(
`OVL_ERROR, // severity_level
1, // num_cks(1クロック後にアサート)
1, // check_overlapping (off)
1, // check_missing_start (on)
`OVL_ASSERT, // property_type
// "ERROR: ta1がアサートされた次のクロックでack1がアサートされていない",
"ERROR: ack1 isn't asserted of with the next clock that ta1 was asserted.",
`OVL_COVER_BASIC, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ta1_ack1_assertion (
clk,
reset,
1'b1, // enable
ta1, // start event
ack1, // test_expr
fire_ta1_ack1_as // fire
);
// req0アサートされた後で、ack0 が2~4クロックの間に1になる
ovl_frame #(
`OVL_ERROR, // severity_level
2, // min_cks
4, // max_cks
`OVL_IGNORE_NEW_START, // action_on_new_start
`OVL_ASSERT, // property_type
// "ERROR: req0がアサートされた後の2~4クロック後にack0が1にならない",
"ERROR: ack0 isn't asserted after 2-4 clocks after req0 was asserted.",
`OVL_COVER_BASIC, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) req0_ack0_assertion (
clk,
reset,
1'b1, // enable
req0, // start event
ack0, // test_expr
fire_req0_ack0_as // fire
);
// req1アサートされた後で、ack1 が2~4クロックの間に1になる
ovl_frame #(
`OVL_ERROR, // severity_level
2, // min_cks
4, // max_cks
`OVL_IGNORE_NEW_START, // action_on_new_start
`OVL_ASSERT, // property_type
// "ERROR: req1がアサートされた後の2~4クロック後にack1が1にならない",
"ERROR: ack1 isn't asserted after 2-4 clocks after req1 was asserted.",
`OVL_COVER_BASIC, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) req1_ack1_assertion (
clk,
reset,
1'b1, // enable
req1, // start event
ack1, // test_expr
fire_req1_ack1_as // fire
);
endmodule
`default_nettype wire
OVL_ERROR : OVL_NEXT : ERROR: ta0がアサートされた次のクロックでack0がアサートされていない : Test expression is not asserted after elapse of num_cks cycles from start event : severity 1 : time 29000 : tb_req_ack.ta0_ack0_assertion.ovl_error_t
OVL_ERROR : OVL_FRAME : ERROR: req0がアサートされた後の2~4クロック後にack0が1にならない : Test expression is not TRUE within specified maximum max_cks cycles from start event : severity 1 : time 33000 : tb_req_ack.req0_ack0_assertion.ovl_error_t
// ta0がアサートされた次のクロックでack0がアサートされる
ovl_next #(
`OVL_ERROR, // severity_level
1, // num_cks(1クロック後にアサート)
1, // check_overlapping (off)
1, // check_missing_start (on)
`OVL_ASSERT, // property_type
"ERROR: ta0がアサートされた次のクロックでack0がアサートされていない",
`OVL_COVER_BASIC, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ta0_ack0_assertion (
clk,
reset,
1'b1, // enable
ta0, // start event
ack0, // test_expr
fire_ta0_ack0_as // fire
);
// req0アサートされた後で、ack0 が2~4クロックの間に1になる
ovl_frame #(
`OVL_ERROR, // severity_level
2, // min_cks
4, // max_cks
`OVL_IGNORE_NEW_START, // action_on_new_start
`OVL_ASSERT, // property_type
"ERROR: req0がアサートされた後の2~4クロック後にack0が1にならない",
`OVL_COVER_BASIC, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) req0_ack0_assertion (
clk,
reset,
1'b1, // enable
req0, // start event
ack0, // test_expr
fire_req0_ack0_as // fire
);
assert_range #(
/*severity_level*/`OVL_FATAL,
/*width*/ 4,
/*min */ 0,
/*max */ 9,
/*property_type */`OVL_ASSERT,
/*msg*/ "The counter arrived at invalid range.",
/*coverage_level*/`OVL_COVER_CORNER)
counter_checker_inst (
.clk(ICLK),
.reset_n(~IRST),
.test_expr(OCOUT));
ovl_range #(
`OVL_FATAL, // severity_level
4, // width
0, // min
9, // max
`OVL_ASSERT, // property_type
"The counter arrived at invalid range.",
`OVL_COVER_CORNER, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK) // gating type
counter_checker_inst (
.clock(ICLK),
.reset(IRST),
.enable(1'b1),
.test_expr(OCOUT),
.fire(fire)
);
// アサーション
// synthesis translate_off
always @ (posedge clk_ddr2) begin
if (reset_ddr2)
;
else
if (afifo_underflow) begin
$display("%m: at time %t ERROR : FIFOが空なのにリードした",$time);
$stop;
end
if (afifo_overflow) begin
$display("%m: at time %t ERROR : FIFOがフルなのにライトした",$time);
$stop;
end
end
// synthesis translate_on
// アサーション
// synthesis translate_off
assert_never #(`OVL_FATAL, 0, "ERROR : FIFOが空なのにリードした") fifo_underflow_assertion(clk_ddr2, ~reset_ddr2, afifo_underflow);
assert_never #(`OVL_FATAL, 0, "ERROR : FIFOがフルなのにライトした") fifo_overflow_assertion(clk_ddr2, ~reset_ddr2, afifo_overflow);
// synthesis translate_on
ovl_example/sim/compile.f-------------------------------------
1 +define+OVL_ASSERT_ON
2 +define+OVL_COVER_ON
3 +define+OVL_MAX_REPORT_ERROR=1
4 +define+OVL_INIT_MSG
5 +libext+.v+.vlib
6 -y ../std_ovl
7 +incdir+../std_ovl
8 +incdir+../tb
9 ../tb/top.v
10 +incdir+../rtl
11 ../rtl/decimal_counter.v
-----------------------------------------------------------
do all.do
# ** Warning: (vlib-34) Library already exists at "work".
# Model Technology ModelSim ALTERA vlog 6.5b Compiler 2009.10 Oct 1 2009
# -- Compiling module clkgen
# -- Compiling module control
# -- Compiling module top
# -- Compiling module decimal_counter
# -- Scanning library directory '../std_ovl'
# -- Compiling module assert_range
#
# Top level modules:
# top
# vsim -do wave.do -l transcript.log -c top
# Loading work.top
# Loading work.clkgen
# Loading work.control
# Loading work.decimal_counter
# Loading work.assert_range
# do wave.do
# OVL_NOTE: V2.4: ASSERT_RANGE initialized @ top.counter_checker_inst.ovl_init_msg_t Severity: 0, Message: The counter arrived at invalid range.
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 105 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 115 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 125 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_max covered : time 235 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 245 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 255 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_max covered : time 415 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 425 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 435 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 445 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 455 : top.counter_checker_inst.ovl_cover_t
# OVL_COVER_POINT : ASSERT_RANGE : test_expr_at_min covered : time 465 : top.counter_checker_inst.ovl_cover_t
module avalon_cpu (
input wire clk,
input wire reset,
output wire [31:0] avm_address,
output wire [2:0] avm_burstcount,
input wire [31:0] avm_readdata,
output wire [31:0] avm_writedata,
input wire avm_waitrequest,
output wire avm_write,
output wire avm_read,
output wire [3:0] avm_byteenable,
input wire avm_readdatavalid,
input wire [31:0] irq
);
altera_avalon_mm_master_bfm #(
.AV_ADDRESS_W (32),
.AV_SYMBOL_W (8),
.AV_NUMSYMBOLS (4),
.AV_BURSTCOUNT_W (3),
.USE_READ (1),
.USE_WRITE (1),
.USE_ADDRESS (1),
.USE_BYTE_ENABLE (1),
.USE_BURSTCOUNT (1),
.USE_READ_DATA (1),
.USE_READ_DATA_VALID (1),
.USE_WRITE_DATA (1),
.USE_BEGIN_TRANSFER (0),
.USE_BEGIN_BURST_TRANSFER (0),
.USE_WAIT_REQUEST (1),
.AV_BURST_LINEWRAP (1),
.AV_BURST_BNDR_ONLY (1),
.AV_MAX_PENDING_READS (1),
.AV_FIX_READ_LATENCY (1)
)
cpu (
.clk (clk),
.reset (reset),
.avm_address (avm_address),
.avm_burstcount (avm_burstcount),
.avm_readdata (avm_readdata),
.avm_writedata (avm_writedata),
.avm_waitrequest (avm_waitrequest),
.avm_write (avm_write),
.avm_read (avm_read),
.avm_byteenable (avm_byteenable),
.avm_readdatavalid (avm_readdatavalid),
.avm_begintransfer (),
.avm_beginbursttransfer ()
);
`define BFM cpu
`ifdef DPI_C
// =========================================================================
// DPI-C
// =========================================================================
`ifndef TEST_BFM
import "DPI-C" context task dpi_main();
`endif // TEST_BFM
export "DPI-C" task bfm_write32;
export "DPI-C" task bfm_read32;
export "DPI-C" task bfm_write16;
export "DPI-C" task bfm_read16;
export "DPI-C" task bfm_write8;
export "DPI-C" task bfm_read8;
export "DPI-C" task bfm_nop;
export "DPI-C" task wait_for_interrupt;
// =========================================================================
// Main
// =========================================================================
initial begin
`BFM.init();
`ifdef TEST_BFM
test_bfm;
`else
dpi_main();
`endif // TEST_BFM
#100;
$finish(2);
end
// =========================================================================
// Task
// =========================================================================
import avalon_mm_pkg::*;
task wait_for_interrupt( output int unsigned status );
status = 0;
wait( irq != 0 );
status = irq;
endtask : wait_for_interrupt
task automatic bfm_run( Request_t request, int addr, int byte_enable, inout int data );
.......................
end module;
alias _vsim {vsim -t ps +nowarnTFMPC -sv_root prog -sv_lib dpi_main_dma -L lpm_ver -L sgate_ver -L altera_mf_ver -L altgxb_ver -L stratixiigx_hssi_ver -L stratixgx_ver -L stratixgx_gxb_ver -L stratixiigx -L altera_ver -L stratixiii_ver -L stratixii_ver -L cycloneii_ver -L cycloneiii_ver -L stratixiv_hssi_ver -L arriaii_ver -L arriaii_pcie_hip_ver -L arriaii_hssi_ver -L stratixiv_pcie_hip_ver -L cycloneiv_pcie_hip_ver -L cycloneiv_hssi_ver -L hardcopyiv_pcie_hip_ver -L hardcopyiv_hssi_ver test_bench} } else {
alias _vsim {vsim -t ps +nowarnTFMPC -sv_root prog -sv_lib dpi_main_dma test_bench } }
gcc -c dpi_main_dma.c
// dma_define.h
#define DMA_STATUS_REG 0x10000000
#define DMA_READ_REG 0x10000004
#define DMA_WRITE_REG 0x10000008
#define DMA_LENGTH_REG 0x1000000c
#define DMA_CONTROL_REG 0x10000018
// DMA_CONTROL_REGの値の定義
#define DMA_CONTROL_SOFTWARERESET 0x1000
#define DMA_CONTROL_QUADWORD 0x800
#define DMA_CONTROL_DOUBLEWORD 0x400
#define DMA_CONTROL_WCON 0x200
#define DMA_CONTROL_RCON 0x100
#define DMA_CONTROL_LEEN 0x80
#define DMA_CONTROL_WEEN 0x40
#define DMA_CONTROL_REEN 0x20
#define DMA_CONTROL_I_EN 0x10
#define DMA_CONTROL_GO 0x8
#define DMA_CONTROL_WORD 0x4
#define DMA_CONTROL_HW 0x2
#define DMA_CONTROL_BYTE 0x1
// DMA_STATUS_REGの値の定義
#define DMA_STATUS_LEN 0x10
#define DMA_STATUS_WEOP 0x8
#define DMA_STATUS_REOP 0x4
#define DMA_STATUS_BUSY 0x2
#define DMA_STATUS_DONE 0x1
#include "dma_define.h"
do setup_sim_dma.do
s
vsim -c -dpiexportobj prog/exportobj.obj test_bench
gcc -shared -o dpi_main_dma.dll dpi_mai_dma.o exportobj.obj \/c/altera/91/modelsim_ase/win32aloem/mtipli.dll
run -all
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - Hello from altera_avalon_mm_master_bfm
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - $Revision: #2 $
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - $Date: 2009/08/28 $
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - AV_ADDRESS_W = 32
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - AV_SYMBOL_W = 8
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - AV_NUMSYMBOLS = 4
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - AV_BURSTCOUNT_W = 3
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_READ = 1
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_WRITE = 1
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_ADDRESS = 1
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_BYTE_ENABLE = 1
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_BURSTCOUNT = 1
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_READ_DATA = 1
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_READ_DATA_VALID = 1
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_WRITE_DATA = 1
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_BEGIN_TRANSFER = 0
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_BEGIN_BURST_TRANSFER = 0
# 0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - USE_WAIT_REQUEST = 1
# 0: INFO: ------------------------------------------------------------
# bfm_write32 : addr = 0x00000000, data = 0x12345678
# bfm_write32 : addr = 0x00000004, data = 0x12345678
# bfm_write32 : addr = 0x00000008, data = 0x12345678
# bfm_write32 : addr = 0x0000000c, data = 0x12345678
# bfm_write32 : addr = 0x00000010, data = 0x12345678
# bfm_write32 : addr = 0x00000014, data = 0x12345678
# bfm_write32 : addr = 0x00000018, data = 0x12345678
# bfm_write32 : addr = 0x0000001c, data = 0x12345678
# bfm_write32 : addr = 0x00000020, data = 0x12345678
# bfm_write32 : addr = 0x00000024, data = 0x12345678
# bfm_write32 : addr = 0x00000028, data = 0x12345678
# bfm_write32 : addr = 0x0000002c, data = 0x12345678
# bfm_write32 : addr = 0x00000030, data = 0x12345678
# bfm_write32 : addr = 0x00000034, data = 0x12345678
# bfm_write32 : addr = 0x00000038, data = 0x12345678
# bfm_write32 : addr = 0x0000003c, data = 0x12345678
# bfm_write32 : addr = 0x10000004, data = 0x00000000
# bfm_write32 : addr = 0x10000008, data = 0x00000800
# bfm_write32 : addr = 0x1000000c, data = 0x00000040
# bfm_write32 : addr = 0x10000018, data = 0x0000009c
# Interrput = 0x1
# bfm_read32 : addr = 0x10000000, data = 0x00000011
# bfm_write32 : addr = 0x10000000, data = 0x00000011
# bfm_read32 : addr = 0x00001000, data = 0x12345678
# bfm_read32 : addr = 0x00001004, data = 0x12345678
# bfm_read32 : addr = 0x00001008, data = 0x12345678
# bfm_read32 : addr = 0x0000100c, data = 0x12345678
# bfm_read32 : addr = 0x00001010, data = 0x12345678
# bfm_read32 : addr = 0x00001014, data = 0x12345678
# bfm_read32 : addr = 0x00001018, data = 0x12345678
# bfm_read32 : addr = 0x0000101c, data = 0x12345678
# bfm_read32 : addr = 0x00001020, data = 0x12345678
# bfm_read32 : addr = 0x00001024, data = 0x12345678
# bfm_read32 : addr = 0x00001028, data = 0x12345678
# bfm_read32 : addr = 0x0000102c, data = 0x12345678
# bfm_read32 : addr = 0x00001030, data = 0x12345678
# bfm_read32 : addr = 0x00001034, data = 0x12345678
# bfm_read32 : addr = 0x00001038, data = 0x12345678
# bfm_read32 : addr = 0x0000103c, data = 0x12345678
# ** Note: Data structure takes 7471320 bytes of memory
# Process time 0.12 seconds
# $finish : ../avalon_bfm_sim/avalon_cpu.sv(88)
# Time: 3490100 ps Iteration: 0 Instance: /test_bench/DUT/the_avalon_cpu_0/avalon_cpu_0
# 1
# Break in Module avalon_cpu at ../avalon_bfm_sim/avalon_cpu.sv line 88
module avalon_cpu (
input wire clk,
input wire reset,
output wire [31:0] avm_address,
output wire [2:0] avm_burstcount,
input wire [31:0] avm_readdata,
output wire [31:0] avm_writedata,
input wire avm_waitrequest,
output wire avm_write,
output wire avm_read,
output wire [3:0] avm_byteenable,
input wire avm_readdatavalid
);
altera_avalon_mm_master_bfm #(
)
.............. // AV_ADDRESS_W 等の定義
cpu (
.clk (clk),
.reset (reset),
.address (avm_address),
.avm_burstcount (avm_burstcount),
.avm_readdata (avm_readdata),
.avm_writedata (avm_writedata),
.avm_waitrequest (avm_waitrequest),
.avm_write (avm_write),
.avm_read (avm_read),
.avm_byteenable (avm_byteenable),
.avm_readdatavalid (avm_readdatavalid),
.avm_begintransfer (),
.avm_beginbursttransfer ()
);
`define BFM cpu
// =========================================================================
// DPI-C
// =========================================================================
`ifndef TEST_BFM
import "DPI-C" context task dpi_main();
`endif // TEST_BFM
export "DPI-C" task bfm_write32;
export "DPI-C" task bfm_read32;
export "DPI-C" task bfm_write16;
export "DPI-C" task bfm_read16;
export "DPI-C" task bfm_write8;
export "DPI-C" task bfm_read8;
export "DPI-C" task bfm_nop;
// =========================================================================
// Main
// =========================================================================
initial begin
`BFM.init();
`ifdef TEST_BFM
test_bfm;
`else
dpi_main();
`endif // TEST_BFM
#100;
$finish(2);
end
............ // tb_prog.svの残り
endmodule : avalon_cpu
module avalon_cpu (
input wire clk,
input wire reset,
output wire [31:0] avm_address,
output wire [2:0] avm_burstcount,
input wire [31:0] avm_readdata,
output wire [31:0] avm_writedata,
input wire avm_waitrequest,
output wire avm_write,
output wire avm_read,
output wire [3:0] avm_byteenable,
input wire avm_readdatavalid
);
altera_avalon_mm_master_bfm #(
.AV_ADDRESS_W (32),
.AV_SYMBOL_W (8),
.AV_NUMSYMBOLS (4),
.AV_BURSTCOUNT_W (3),
.USE_READ (1),
.USE_WRITE (1),
.USE_ADDRESS (1),
.USE_BYTE_ENABLE (1),
.USE_BURSTCOUNT (1),
.USE_READ_DATA (1),
.USE_READ_DATA_VALID (1),
.USE_WRITE_DATA (1),
.USE_BEGIN_TRANSFER (0),
.USE_BEGIN_BURST_TRANSFER (0),
.USE_WAIT_REQUEST (1),
.AV_BURST_LINEWRAP (1),
.AV_BURST_BNDR_ONLY (1),
.AV_MAX_PENDING_READS (1),
.AV_FIX_READ_LATENCY (1)
)
cpu (
.clk (clk),
.reset (reset),
.address (avm_address),
.avm_burstcount (avm_burstcount),
.avm_readdata (avm_readdata),
.avm_writedata (avm_writedata),
.avm_waitrequest (avm_waitrequest),
.avm_write (avm_write),
.avm_read (avm_read),
.avm_byteenable (avm_byteenable),
.avm_readdatavalid (avm_readdatavalid),
.avm_begintransfer (),
.avm_beginbursttransfer ()
);
`define BFM cpu
`ifdef DPI_C
// =========================================================================
// DPI-C
// =========================================================================
`ifndef TEST_BFM
import "DPI-C" context task dpi_main();
`endif // TEST_BFM
export "DPI-C" task bfm_write32;
export "DPI-C" task bfm_read32;
export "DPI-C" task bfm_write16;
export "DPI-C" task bfm_read16;
export "DPI-C" task bfm_write8;
export "DPI-C" task bfm_read8;
export "DPI-C" task bfm_nop;
// =========================================================================
// Main
// =========================================================================
initial begin
`BFM.init();
`ifdef TEST_BFM
test_bfm;
`else
dpi_main();
`endif // TEST_BFM
#100;
$finish(2);
end
// =========================================================================
// Task
// =========================================================================
import avalon_mm_pkg::*;
task automatic bfm_run( Request_t request, int addr, int byte_enable, inout int data );
`BFM.set_command_request(request);
`BFM.set_command_address(addr);
`BFM.set_command_byte_enable(byte_enable,0);
`BFM.set_command_idle(0,0);
`BFM.set_command_init_latency(0);
`BFM.set_command_burst_count(1);
`BFM.set_command_burst_size(1);
if( request == REQ_WRITE )
`BFM.set_command_data(data, 0);
`BFM.push_command();
while(1) begin
@(posedge `BFM.clk);
if(`BFM.get_response_queue_size() > 0)
break;
end
`BFM.pop_response();
if( request == REQ_READ )
data = `BFM.get_response_data(0);
endtask : bfm_run
task automatic bfm_read32( int unsigned addr, output int unsigned data );
int byte_enable;
if( addr & 'h3 ) begin // address check
data = 'hffff_ffff;
return;
end
byte_enable = 'hf;
bfm_run( REQ_READ, addr, byte_enable, data );
$display("bfm_read32 : addr = 0x%h, data = 0x%x", addr, data );
endtask : bfm_read32
task automatic bfm_write32( int unsigned addr, input int unsigned data );
int byte_enable;
if( addr & 'h3 ) begin // address check
return;
end
byte_enable = 'hf;
bfm_run( REQ_WRITE, addr, byte_enable, data );
$display("bfm_write32 : addr = 0x%h, data = 0x%x", addr, data );
endtask : bfm_write32
task automatic bfm_read16( int unsigned addr, output shortint unsigned data );
int byte_enable;
int unsigned word;
if( addr & 'h1 ) begin // address check
data = 'hffff;
return;
end
case ( addr & 'h2 )
0 : byte_enable = 'h3;
2 : byte_enable = 'hc;
endcase
bfm_run( REQ_READ, addr, byte_enable, word );
case( addr & 'h2 )
0 : data = (word & 'h0000_ffff) >> 0;
2 : data = (word & 'hffff_0000) >> 16;
endcase
$display("bfm_read16 : addr = 0x%h, data = 0x%x", addr, data );
endtask : bfm_read16
task automatic bfm_write16( int unsigned addr, input shortint unsigned data );
int byte_enable;
int unsigned word;
if( addr & 'h1 ) begin // address check
return;
end
case ( addr & 'h2 )
0 : begin byte_enable = 'h3; word = (data << 0) & 'h0000_ffff; end
2 : begin byte_enable = 'hc; word = (data << 16) & 'hffff_0000; end
endcase
bfm_run( REQ_WRITE, addr, byte_enable, word );
$display("bfm_write16 : addr = 0x%h, data = 0x%x", addr, data );
endtask : bfm_write16
task automatic bfm_read8( int unsigned addr, output byte unsigned data );
int byte_enable;
int unsigned word;
case ( addr & 'h3 )
0 : byte_enable = 'h1;
1 : byte_enable = 'h2;
2 : byte_enable = 'h4;
3 : byte_enable = 'h8;
endcase
bfm_run( REQ_READ, addr, byte_enable, word );
case ( addr & 'h3 )
0 : data = (word & 'h0000_00ff) >> 0;
1 : data = (word & 'h0000_ff00) >> 8;
2 : data = (word & 'h00ff_0000) >> 16;
3 : data = (word & 'hff00_0000) >> 24;
endcase
$display("bfm_read8 : addr = 0x%h, data = 0x%x", addr, data );
endtask : bfm_read8
task automatic bfm_write8( int unsigned addr, input byte unsigned data );
int byte_enable;
int unsigned word;
case ( addr & 'h3 )
0 : begin byte_enable = 'h1; word = (data << 0) & 'h0000_00ff; end
1 : begin byte_enable = 'h2; word = (data << 8) & 'h0000_ff00; end
2 : begin byte_enable = 'h4; word = (data << 16) & 'h00ff_0000; end
3 : begin byte_enable = 'h8; word = (data << 24) & 'hff00_0000; end
endcase
bfm_run( REQ_WRITE, addr, byte_enable, word );
$display("bfm_write8 : addr = 0x%h, data = 0x%x", addr, data );
endtask : bfm_write8
task automatic bfm_nop( int no );
for( int n=0 ; n<no ; n++ )
@(posedge `BFM.clk);
endtask : bfm_nop
task test_bfm;
int unsigned addr;
addr = 'h0000_0000;
for ( int n=0 ; n<4 ; n+=4 ) begin : int_loop
int unsigned a, b;
a = 'h1234_5678;
bfm_write32( addr, a );
bfm_read32 ( addr, b );
$display("addr = 0x%h, exp = 0x%h, data = 0x%h", addr, b, a );
end
addr = 'h0000_1000;
for ( int n=0 ; n<4 ; n+=2 ) begin : short_loop
shortint unsigned a, b;
a = 'h4567 + n*2;
bfm_write16( addr + n, a );
bfm_read16 ( addr + n, b );
$display("addr = 0x%h, exp = 0x%h, data = 0x%h", addr, b, a );
a += a;
end
addr = 'h0000_2000;
for ( int n=0 ; n<4 ; n++ ) begin : byte_loop
byte unsigned a, b;
a = 'h12 + n*4;
bfm_write8( addr + n, a );
bfm_read8 ( addr + n, b );
$display("addr = 0x%h, exp = 0x%h, data = 0x%h", addr, b, a );
a += a;
end
endtask : test_bfm
`else // DPI_C
`endif // DPI_C
endmodule : avalon_cpu
alias _vsim {vsim -t ps +nowarnTFMPC -sv_root prog -sv_lib dpi_main -L lpm_ver -L sgate_ver -L altera_mf_ver -L altgxb_ver -L stratixiigx_hssi_ver -L stratixgx_ver -L stratixgx_gxb_ver -L stratixiigx -L altera_ver -L stratixiii_ver -L stratixii_ver -L cycloneii_ver -L cycloneiii_ver -L stratixiv_hssi_ver -L arriaii_ver -L arriaii_pcie_hip_ver -L arriaii_hssi_ver -L stratixiv_pcie_hip_ver -L cycloneiv_pcie_hip_ver -L cycloneiv_hssi_ver -L hardcopyiv_pcie_hip_ver -L hardcopyiv_hssi_ver test_bench} } else {
alias _vsim {vsim -t ps +nowarnTFMPC -sv_root prog -sv_lib dpi_main test_bench } }
vlog -sv +incdir+.. ../avalon_bfm.v;
do setup_sim_lib.do
_vsim
を行っても、信号はwaveウインドウに表示されなかったので、Simウインドウのtest_bench -> DUT -> the_avalon_cpu_0 -> avalon_cpu_0 を選択して、Objectウインドウに表示された信号をwaveにドラックアンドドロップした。do wave.do
をしてRUNするが、finishしない。run -all
vlog -sv +define+DPI_C +incdir+.. ../avalon_bfm.v;
do setup_sim_lib.do
s
run -all
do setup_sim.do
を実行すると、シミュレーションがスタートした。_vsim
を実行すると、ModelSimにwaveペインが追加され、信号がロードされた。do wave.do
を実行すると、下に示すように、シミュレーションが終了し、Write3回、Read3回実行されているのが見えた(波形が見えないので、waveウインドウをアンドックしました)。run -All
alias _vsim {vsim -t ps +nowarnTFMPC -sv_root prog -sv_lib dpi_main ...
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | - | - | - |