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;