FC2カウンター FPGAの部屋 ブロック文
fc2ブログ

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

FPGAの部屋

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

ブロック文

VHDLの本を読んでいたら、便利に使えそうなブロック文を見つけた。
いままで、1つのVHDLファイルに2つ以上のステートマシンを記述する際には、ステート名を変えていた。例えば下のように。

type STATE is (idle, active, holdoff);
type STATE2 is (idle2, active2);


block文を使うと、block文の中はカプセル化されて、type宣言もローカルになるので、同じVHDLファイルの違うステートマシンのステートに同じ名前のステートや、同じ名前のsignalを宣言できるはずだ。
ちょっとやってみることにした。1つのVHDLファイルの中に、block文を使って、2つのステートマシンを記述してみた。

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

entity block_check is
    Port ( reset : in  STD_LOGIC;
           clk : in  STD_LOGIC;
           in_sig1 : in  STD_LOGIC;
           in_sig2 : in  STD_LOGIC;
           pulse : out  STD_LOGIC;
           active_sig : out  STD_LOGIC);
end block_check;

architecture RTL of block_check is
begin
    STATE_MACHINE1 : block
        type STATE is (idle, active, holdoff);
        signal c_state, n_state : STATE;
    begin
        process(reset, clk) begin
            if reset='1' then
                c_state <= idle;
            elsif clk'event and clk='1' then
                c_state <= n_state;
            end if;
        end process;
        process(c_state, in_sig1) begin
            case c_state is
                when idle =>
                    pulse <= '0';
                    if in_sig1='1' then
                        n_state <= active;
                    else
                        n_state <= idle;
                    end if;
                when active =>
                    pulse <= '1';
                    n_state <= holdoff;
                when holdoff =>
                    pulse <= '0';
                    if in_sig1='0' then
                        n_state <= idle;
                    else 
                        n_state <= holdoff;
                    end if;
            end case;
        end process;
    end block STATE_MACHINE1;
    
    STATE_MACHINE2 : block
        type STATE is (idle, active);
        signal c_state, n_state : STATE;
    begin
        process(reset, clk) begin
            if reset='1' then
                c_state <= idle;
            elsif clk'event and clk='1' then
                c_state <= n_state;
            end if;
        end process;
        process(c_state, in_sig2) begin
            case c_state is
                when idle =>
                    active_sig <= '0';
                    if in_sig2='1' then
                        n_state <= active;
                    else
                        n_state <= idle;
                    end if;
                when active =>
                    active_sig <= '1';
                    if in_sig2='1' then
                        n_state <= idle;
                    else
                        n_state <= active;
                    end if;
            end case;
        end process;
    end block STATE_MACHINE2;

end RTL;


最初のブロックはin_sig1が1になったときにpulseを1クロックだけ1にするためのステートマシン。次はin_sig2が1の時にactive_sigが1,0を繰り返すためのステートマシン。
2つともblock文の中で、同じidle, activeステートを使っているが、論理合成してもエラーが出ていない。今度から、こういう方式でも書けそうだ。
block_check_070907.png


block文でカプセル化するのも良いのだが、signalごとにスコープされたtypeが使えると一番良いのだが。。。
  1. 2007年09月07日 05:22 |
  2. VHDLの書き方
  3. | トラックバック:0
  4. | コメント:8

コメント

block文というのがあるのですか
その処理の中で閉じた使用をするsignalにうまく使えそうですね
テンポラリとして使用することがあるので、さっそく使って見たいと思います

signalって、日頃文中に宣言できたら書き易いのにと思っています
architecture内ではグローバルになるので、先頭宣言の明示性は意味はわかりますが。
旧のCで、変数宣言が先頭だけだったのが、現在のCは、文中宣言が許可になっていますが。VHDLにも必要を感じています。

process ...
...
end process;

signal mode :std_logic; --コメント

process ( CK, RST ) begin
if (RST = SETX) then
mode <= CLR;
elsif (CK'event and CK = '1') then
if(status = SET) then
mode <= SET;
else
mode <= mode;
end if;
end if;
end process;

みたいな
  1. 2007/09/09(日) 00:09:57 |
  2. URL |
  3. NSX #-
  4. [ 編集 ]

スペースによるインデントは無効でしたか、見にくくなってしまいました
どうやって入れたらいいのでしょうか
  1. 2007/09/09(日) 00:13:46 |
  2. URL |
  3. NSX #-
  4. [ 編集 ]

block文は、中をカプセル化して、他に影響を与えないようにするために使えそうです。ステートの情報を他で使っている場合には使えないでしょうが。。。
signal はだめだと思いますが、variableはprocess文で定義できます。
下のような感じです。
process(read_port_no, read_data_enable) -- 読み出しポートへのreの通知、読み出しポート以外は0とすること
variable no : integer;
begin
no := CONV_INTEGER(read_port_no);
for i in recv_re'range loop
if i = no then -- 読み込みポートの番号と一致したときのみCH IDを出力
recv_re(i) <= read_data_enable;
else
recv_re(i) <= '0';
end if;
end loop;
end process;
VHDLコードなどはSourceConverterでHTMLに変換しています。
これは後でブログに書きます。
  1. 2007/09/09(日) 08:31:23 |
  2. URL |
  3. marsee #-
  4. [ 編集 ]

コメントはHTMLにしてもだめなようです。
  1. 2007/09/09(日) 08:43:07 |
  2. URL |
  3. marsee #-
  4. [ 編集 ]

これならどうなる?
全角
process
 if

全角+半角
process
  if

"絵文字:v-32"
process
v-32if
  1. 2007/09/09(日) 13:28:23 |
  2. URL |
  3. NSX #-
  4. [ 編集 ]

さっそく移植しました
微分パルス用のコンポーネントがあり気に入らなかったので、block文にしました
(動作は信用しないで下さい)

B_PULS: block
  signal pw,pw1,pw2 :std_logic;   -- tmp

begin
 puls_o <= pw;            -- 微分パルス出力
 pw <= pw1 and pw2;

 process ( CLK, RST ) begin
  if (RST = SETX) then
   pw1 <= CLR;
   pw2 <= CLR;
  elsif (CLK'event and CLK = '1') then
   pw1 <= flg_i;          -- 起動フラグ 入力
   pw2 <= not pw1;
  end if;
 end process;

end block B_PULS;

今まで、テンポラリとして、signal pw,pw1,pw2 を先頭宣言していたのをblock内に入れました
これで、カプセル化ができてスコープが完璧になりました
なんかとても気に入りました

紹介頂いたvariableですが、適切な使用例ですね。
他の使用例で、variableは、人によっては、同期レジスタとして使用するようですが、
私は、signal派なので使用しません
そのため最初に書いた件はあって欲しいわけです。
(文中宣言のsignalの話は、外部processでの参照をするので、このblock文の話とは別です)
ieee.std_logic_200x.all とかで追加されるのを期待しているし可能性あると思っています
  1. 2007/09/09(日) 19:45:05 |
  2. URL |
  3. NSX #-
  4. [ 編集 ]

すみません。variableは釈迦に説法だったようですね。
variableは全ビットXORを取るときのようなテンポラリの変数として使っています。
signaについては、文中に書くと、書いたことを忘れやすいため、追加されても私は使わないと思います。グローバル信号は最初に全部宣言するのが好きです。

ところで、話はぜんぜん違うのですが、NSXさんは、車はホンダのNSXに乗っておられるんでしょうか?
  1. 2007/09/09(日) 20:47:05 |
  2. URL |
  3. marsee #-
  4. [ 編集 ]

>釈迦に説法だったようですね
と、とんでもございません。
HDL技術は、かなり平均以下で間違いないです。ブログ内容も、ついてけないものはよくパスします。(本業はシステムの方なので)
ですので、ここで勉強させてもらってます

質問の件ですが、誤解まねくといけませんので過去の適当な別スレに紛らせてコメントしておきます。管理人さんには新規コメントのスレは確定できるのだと思いますので。
  1. 2007/09/10(月) 16:36:09 |
  2. URL |
  3. NSX #-
  4. [ 編集 ]

コメントの投稿


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

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