FC2カウンター FPGAの部屋 ModelSimでinit_signal_spyを使ってVHDLの他の階層のsignalをミラーする
fc2ブログ

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

FPGAの部屋

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

ModelSimでinit_signal_spyを使ってVHDLの他の階層のsignalをミラーする

今、ModelSimでCMOSカメラ・ディスプレイ表示回路のシミュレーションをしている。SRAMモデルやCOMSカメラモジュールモデルを接続してテストしている。しかし、CMOSカメラの転送レートはディスプレイ表示回路の半分なので、RGB出力は最初の垂直フレームはずっと0のままになってしまう。そうすると40msくらいシミュレーションしないとだめということになる。それかクロックを驚異的に速めるという方法もあるな~。
そこでSRAMモデルの方でReadの時に、SRAMに書き込まれたデータではなく、自分で生成したデータを出して回路をデバックしようと思った。
つまり通常はこんな風に書いてあるReadの記述を、

    -- Read Upper
    process(n_mem_cs, n_mem_rd, n_mem_upperB, mem_addr_int) begin
        if n_mem_cs='0' and n_mem_rd='0' and n_mem_upperB='0' then
            mem_data_node(15 downto 8) <= To_stdlogicvector(sram_upper(mem_addr_int));
        else
            mem_data_node(15 downto 8) <= (others => 'Z');
        end if;
    end process;
    
    -- Read Lower
    process(n_mem_cs, n_mem_rd, n_mem_lowerB, mem_addr_int) begin
        if n_mem_cs='0' and n_mem_rd='0' and n_mem_lowerB='0' then
            mem_data_node(7 downto 0) <= To_stdlogicvector(sram_lower(mem_addr_int));
        else
            mem_data_node(7 downto 0) <= (others => 'Z');
        end if;
    end process;


下のように、Upperが55から+1、LowerがAAから+1になるように書き直した。

    -- データの流れを見やすいように上位のデータは55から+1, 下位のデータはAAから+1して、出力    process(master_sync, n_mem_we) begin -- Read Upper
        if master_sync='1' then
            mem_data_node2(15 downto 8) <= x"55";
        elsif n_mem_we'event and n_mem_we='1' then
            if n_mem_cs='0' and n_mem_rd='0' and n_mem_upperB='0' then
                mem_data_node2(15 downto 8) <= mem_data_node2(15 downto 8) + 1;
            end if;
        end if;
    end process;
    mem_data_node(15 downto 8) <= mem_data_node2(15 downto 8) when n_mem_cs='0' and n_mem_rd='0' and n_mem_upperB='0' else (others => 'Z');
        
    process(master_sync, n_mem_we) begin -- Read Lower
        if master_sync='1' then
            mem_data_node2(7 downto 0) <= x"AA";
        elsif n_mem_we'event and n_mem_we='1' then
            if n_mem_cs='0' and n_mem_rd='0' and n_mem_lowerB='0' then
                mem_data_node2(7 downto 0) <= mem_data_node2(7 downto 0) + 1;
            end if;
        end if;
    end process;
    mem_data_node(7 downto 0) <= mem_data_node2(7 downto 0) when n_mem_cs='0' and n_mem_rd='0' and n_mem_lowerB='0' else (others => 'Z');


ここで、master_sync はCMOSカメラのVSYNCが来た後で、最初のHREF が来たときに1になる信号だ。この信号は本来SRAMモジュールには来ていないが、最初のデータを決めるために、どうしても使いたい信号だ。以前、”VHDLの共有変数を使用したシミュレーション”をやってみたことがあったが、その時に教えていただいたinit_signal_spy を使ってみようと思った。
このページを見てやり方を学習したが、ModlSim XE3 6.4b Starter のUser's Manual を見るともう1つ引数が増えているようだ。最後の引数は、control_state でinit_signal_spy をenable, disable することができようになるようだ。int_signal_spy の記述をSRAM(IS61LV25616)のモデルに加えた。
まずは、modelsim_libライブラリをuse する。

library modelsim_lib;
use modelsim_lib.util.all;


その後、architecture のbegin の後に下のように記述した。(当然だが、すぐ後に書かなくてもOK)

    -- init_signal_spy でIS61LV25616_instの下にmaster_syncを持ってくる
    process begin
        init_signal_spy("../camdispcntrl_sram_inst/master_sync", "master_sync", 1, -1);
        wait;
    end process;


これで、上のモジュールの下のcamdispcntrl_sram_instモジュールのmaster_sync をSRAMモジュールのmaster_sync にミラーすることができた。なお、master_sync はsignal で定義しておく必要がある。
上は相対パスだが、下のように絶対パスでもOK。

    -- init_signal_spy でIS61LV25616_instの下にmaster_syncを持ってくる
    process begin
        init_signal_spy("/testbench/camdispcntrl_sram_inst/master_sync", "/testbench/is61lv25616_inst/master_sync", 1, -1);
        wait;
    end process;


実際のコード例は”CMOSカメラから画像を入力してディスプレイへ出力9(モデルの説明)”を参照。
  1. 2009年10月10日 17:49 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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