FC2カウンター FPGAの部屋 PS/2キーボードインターフェース用テストベンチ(procedure使用)
FC2ブログ

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

FPGAの部屋

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

PS/2キーボードインターフェース用テストベンチ(procedure使用)

procedure文を利用して、”日曜デジタル””PS/2に挑戦”のPS/2キーボード・インターフェースのテストベンチを書いてみた。
procedure文はサブプログラムを書くときに使われる。wait文も書くことができるので、テストベンチでプロセッサのバスプロトコルやシリアルインターフェースの通信手順を書くのも使用することができる。function文とは異なり、複数の出力を持つことができる。
procedureは他でも use して使えるように、package として書くことにした。
procedure文のポート宣言で in で宣言したものはデフォルトでは constant として解釈されるようだ。signal を接続するときには signal を最初につけるようだ。(確かめたことがないので良くわからない。この辺を良く書いてある和書はあまりないようだ)
PS/2のクロックは'1'の期間が40us、'0'の期間が40us のクロックとした。
input_code に8ビットコードを入れると、ps2clk と シリアルデータのps2dataを出力する。そのコードはこれだ。

library ieee;
use ieee.std_logic_1164.all;

package PS2_SigGen_pack is
    procedure PS2_SigGen (
        input_code : in std_logic_vector(7 downto 0); -- constant
        signal clk_out : out std_logic;
        signal data_out : out std_logic
    );
end PS2_SigGen_pack;

package body PS2_SigGen_pack is
    procedure PS2_SigGen (
        input_code : in std_logic_vector(7 downto 0); -- constant
        signal clk_out : out std_logic;
        signal data_out : out std_logic
    ) is
    begin
        clk_out <= '1';
        data_out <= '0'; -- Start bit
        
        wait for 40 us;
        clk_out <= '0'; -- 立下りエッジ
        wait for 40 us;
        
        for i in 0 to 7 loop
            clk_out <= '1'; -- 立ち上がりエッジ
            data_out <= input_code(i); -- シリアルデータ出力
            
            wait for 40 us;
            clk_out <= '0'; -- 立下りエッジ
            wait for 40 us;
        end loop;
        
        clk_out <= '1'; 
        data_out <= not(input_code(0) xor input_code(1) xor input_code(2) xor input_code(3) xor input_code(4) xor input_code(5) xor input_code(6) xor input_code(7)); -- odd parity
        
        wait for 40 us;
        clk_out <= '0'; -- 立下りエッジ
        wait for 40 us;
        
        clk_out <= '1';
        data_out <= '1'; -- Stop bit
        
        wait for 40 us;
        clk_out <= '0'; -- 立下りエッジ
        wait for 40 us;
        
        clk_out <= '1'; -- 元の状態に戻す
    end PS2_SigGen;
end PS2_SigGen_pack;


このパッケージを使ってps2read 用のテストベンチを作る。スキャンコード"1C"('A'キャラクタ)と"32"('B'キャラクタ)を入力するテストベンチだ。
クロックは50MHzとし、80ns リセットをしてから、procedureを2回実行している。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library work;
use work.PS2_SigGen_pack.all;

entity ps2read_tb is
end ps2read_tb;

architecture test_bench of ps2read_tb is
constant CYCLE : time := 20 ns; -- 50MHz

signal clk : std_logic := '1';
signal reset : std_logic := '1';
signal ps2clk : std_logic := '1';
signal ps2data : std_logic := '1';
signal scancode : std_logic_vector(7 downto 0);

component ps2read
    Port ( clk : in  STD_LOGIC;
           reset : in  STD_LOGIC;
           ps2clk : in  STD_LOGIC;
           ps2data : in  STD_LOGIC;
           scancode : out std_logic_vector(7 downto 0)
      );
end component;
begin
    Inst_ps2read : ps2read port map(
        clk => clk,
        reset => reset,
        ps2clk => ps2clk,
        ps2data => ps2data,
        scancode => scancode
    );
    
    clk <= not clk after CYCLE/2;

    process begin
        wait for 80 ns; -- 1クロック分リセット
        
        reset <= '0'; -- リセット解除
        PS2_SigGen(x"1C", ps2clk, ps2data);
        PS2_SigGen(x"32", ps2clk, ps2data);
    end process;
end test_bench;


これで、シミュレーションをしてみる。シミュレーションの仕方は”シミュレーション”の目次を見てください。
2ms ほどシミュレーションすると下の図のようになった。scandataにスキャンコード"1C"('A'キャラクタ)と"32"('B'キャラクタ)が出力されている。
PS2_simulation_1002.png

これでパッケージを use し、プロシージャ PS2_SigGen を使用すると、お手軽にPS/2のプロトコルで出力できる。

宣伝しているわけじゃないですけど、CQ出版社の”HDLサンプル記述集”はテストベンチの書き方がいろいろ載っていて参考になると思います。

2007/10/08 : PS2_SigGen_pack.vhdを変更しました。ps2clkが0で終わるようになっていたので、1に遷移させてから終了するようにしました。以前と動作は変わりません。
2007/10/12 : PS/2インターフェースを偶数パリティと勘違いしていました。奇数パリティに修正しました。
  1. 2007年10月03日 05:01 |
  2. VHDLの書き方
  3. | トラックバック:0
  4. | コメント:2

コメント

なるほど、procedureはこんな目的に向いてますね。
1年半前にこれがあれば、PS/2マウスももう少し楽にできてたかも…。
どうも腑抜けソフト屋としてはついカット&エラーでやっちゃうのですが、
やっぱりテストベンチとシミュレーションは重要なんですね。
  1. 2007/10/03(水) 23:28:38 |
  2. URL |
  3. geeklet #-
  4. [ 編集 ]

geekletさん、ねたに使わせていただいてありがとうございます。

何で、いまさらやりだしたのかといいますと、実験でスパルタン3スタータキットを使って、キーボードから入力した文字をディスプレイに直接出力というのを今年始めました。
それで、PS/2インターフェースはクロックに比べて時間がかかるので、テストベンチを渡すことにしました。それで急遽作りました。私もprocedureの使い方は知ってはいたのですが、実際に書いたのは初めてなので、勉強になりました。今度はVerilogのtaskでテストベンチを書いてみようと思っています。
  1. 2007/10/04(木) 05:11:34 |
  2. URL |
  3. marsee #-
  4. [ 編集 ]

コメントの投稿


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

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