FC2カウンター FPGAの部屋 VHDLでOVLアサーションを使用する3(VHDLからVerilog OVLを使用する)
fc2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

VHDLでOVLアサーションを使用する3(VHDLからVerilog OVLを使用する)

VHDLでOVLアサーションを使用する2(VHDLライブラリを使用)”でVHDL OVLを使用したが、今度はVerilogのOVLを使用して、VHDLソースにOVLアサーションを挿入しようと思う。前回のOVLアサーションはovl_nextだけだったが、Verilog OVLにしかないovl_frameを使用する。

proj_pkg.vhd, req_sm.vhd, ack_sm は”VHDLでOVLアサーションを使用する2(VHDLライブラリを使用)”と同じだ。
テストベンチのtb_req_ack.vhd を示す。

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


std_ovlフォルダのstd_ovl_components.vhdとstd_ovl_components_vlog.vhdのパッケージ名がstd_ovl_componentsで同じなので、これらのパッケージはuseしないで、component文をソース上に書くことにした。ModelSim Altera Starter Editon 6.5b では、VHDLとVerilogの混在シミュレーションが出来ないため、ModelSim SE 6.1eでシミュレーションを行った。
前と同様に、accellera_ovl_vhdlとaccellera_ovl_vlogライブラリをリンクして、VHDLファイルをコンパイルし、シミュレーションをスタートする。run -allコマンドでシミュレーションを行った。そのModelSimの図を下に示す。
OVL_VHDL_7_100329.png

ログを下に示す。

# 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


これで、混在シミュレーションができるシミュレーターがあれば、VHDLでも種類の豊富なVerilog OVLを使うことができた。
  1. 2010年03月29日 19:53 |
  2. アサーション事始め
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
https://marsee101.blog.fc2.com/tb.php/1419-e6ca90c5
この記事にトラックバックする(FC2ブログユーザー)