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;