VHDLの文法が酷い

Twitterで、「このくらいにしておく」と宣言したので蒸し返すようですが、ちょっと調べたことを書いておきます。VHDLの文法が酷いです。というか、これは80年代前半頃のアメリカコンピュータ科学がいかにコンピュータ言語の文法に無頓着だったかという話です。

例をお見せしましょう、これはVHDL-2008のentity宣言の文法です。

entity_declaration ::=
    entity identifier is
        entity_header
        entity_declarative_part
    [ begin
        entity_statement_part ]
    end [ entity ] [ entity_simple_name ] ;

ちょっと違和感を感じます。endの後のentityを省略可能にしている点。あまりいい気持ちはしませんが、まあわからなくはありません。しかし、続くentity名も省略してもよい、しかもどちらかだけでも両方でも省略していいというのは、文法としてかなり異常です。

そして、この文法とcomponent宣言の文法を並べるとさらに違和感が増します。

component_declaration ::=
    component identifier [ is ]
        [ local_generic_clause ]
        [ local_port_clause ]
    end component [ component_simple_name ] ;

どうしてこちらだけisが省略可能なのでしょうか。また、どうしてこちらだけendの次の予約後が省略不可能なのでしょうか。

結論から言えば、このようないびつな形になっているのは、VHDL-1987でいい加減な文法を決めてしまい、各方面からの意見を元にVHDL-1993で改訂を行ったことに起因します。当初entityとcomponentはよく似た違う形だったのが、苦情を受けて同じ形に書くことができるよう改訂したわけですね。

VHDLにはこのようなちゃらんぽらんな文法がいくつかあります。理解した上でなるべく綺麗に書いていくしかありません。

と、言うわけで先日のVHDLコードの清書版。

-- LED display demo on BeMicro MAX10
-- Shifting LED pattern every second. 

library ieee;
use ieee.std_logic_1164.all;

entity blink_slide is 
    generic(	period : integer := 50000000 );
    port ( 	reset : in std_logic;
                clock : in std_logic;	-- assign 50Mhz clock.
                led : out std_logic_vector( 7 downto 0 ) );
end entity blink_slide;


architecture rtl of blink_slide is 
    signal count : integer;										-- 50Mhz divider
    signal pattern : std_logic_vector( 15 downto 0 );	-- LED internal pattern.
    
    type stateType is ( counting, saturated );			-- for State machine
    signal state : stateType ;
begin
    process ( clock, reset ) is
    begin
        if reset = '1' then
                -- async reset the internal state and signals; 
            led <= ( others => '0' );
            pattern <= "0000000011111111";
            count <= 1;
            state <= saturated;
        elsif clock'event and clock = '1' then
                -- State transition
            case state is
                        -- count up till 50M 
                when counting =>
                    count <= count + 1;
                    
                    if count > period then
                        state <= saturated;
                    end if;
                    
                        -- output the display pattern to LED, then, rotate the pattern
                        -- initialize the counter 
                when saturated =>
                    led <= pattern( 15 downto 8 );							-- output to LED
                    pattern <= pattern( 14 downto 0 ) & pattern(15);	-- rotate pattern
                    count <= 1;														-- reset counter
                    
                    state <= counting;
            end case;
        
        end if;
    end process;
end architecture rtl;

 

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください