CPLDでディジタル電子工作 (CQ文庫), pp.171ff.
テキストは8桁ぶん並べた7セグLEDに測定結果を表示しているが、ここではキャラクターLCDに表示する。SC1602BBWB-XA-LB-Gを使った。フォントが小さいので本当は測定器のディスプレイには適さない。4ビットモードで動かす。
今FGから9.876 kHzの矩形波を入力している。
library ieee; use ieee.std_logic_1164.all; entity LCD_4bits is generic( F_CLK: natural:= 32_768 ); port( clk, rst: in std_logic; bcd_in : in std_logic_vector(31 downto 0); E, RS : out std_logic; DB : out std_logic_vector(7 downto 4); is_ready: out std_logic ); end entity; architecture rtl of LCD_4bits is type state_type is ( power_on_reset1, power_on_reset2, power_on_reset3, power_on_reset4, power_on_reset5, power_on_reset6, power_on_reset7, power_on_reset8, FunctionSet1, FunctionSet2, FunctionSet3, FunctionSet4, FunctionSet5, FunctionSet6, ClearDisplay_H, DisplayControl_H, EntryMode_H, ClearDisplay_L, DisplayControl_L, EntryMode_L, W_10M_H, W_1M_H, W_100k_H, W_10k_H, W_1k_H, W_100_H, W_10_H, W_1_H, W_10M_L, W_1M_L, W_100k_L, W_10k_L, W_1k_L, W_100_L, W_10_L, W_1_L, ReturnHome_H, ReturnHome_L ); signal pr_state, nx_state: state_type; signal E_temp: std_logic; begin -- 周期2 ms以上のクロックを生成する。割に適当でよい。 process(clk) variable count: natural range 0 to F_CLK / 900; begin if rising_edge(clk) then count := count + 1; if count = F_CLK / 900 then count := 0; E <= not E; end if; end if; end process; -- ステートを保存しておくためのレジスタ process(E, rst) begin E_temp <= E; if rst then pr_state <= power_on_reset1; elsif rising_edge(E_temp) then pr_state <= nx_state; end if; E <= E_temp; end process; -- 次のステートを決めるための組み合わせ論理回路 process(all) begin RS <= '0'; DB <= "0011"; is_ready <= '0'; case pr_state is when power_on_reset1 => nx_state <= power_on_reset2; when power_on_reset2 => nx_state <= power_on_reset3; when power_on_reset3 => nx_state <= power_on_reset4; when power_on_reset4 => nx_state <= power_on_reset5; when power_on_reset5 => nx_state <= power_on_reset6; when power_on_reset6 => nx_state <= power_on_reset7; when power_on_reset7 => nx_state <= power_on_reset8; when power_on_reset8 => is_ready <= '1'; nx_state <= FunctionSet1; when FunctionSet1 => nx_state <= FunctionSet2; when FunctionSet2 => nx_state <= FunctionSet3; when FunctionSet3 => nx_state <= FunctionSet4; when FunctionSet4 => DB <= "0010"; nx_state <= FunctionSet5; when FunctionSet5 => DB <= "0010"; nx_state <= FunctionSet6; when FunctionSet6 => DB <= "1000"; nx_state <= ClearDisplay_H; when ClearDisplay_H => DB <= "0000"; nx_state <= ClearDisplay_L; when ClearDisplay_L => DB <= "0001"; nx_state <= DisplayCOntrol_H; when DisplayControl_H => DB <= "0000"; nx_state <= DisplayControl_L; when DisplayControl_L => DB <= "1100"; nx_state <= EntryMode_H; when EntryMode_H => DB <= "0000"; nx_state <= EntryMode_L; when EntryMode_L => DB <= "0110"; nx_state <= W_10M_H; when W_10M_H => RS <= '1'; DB <= "0011" ; nx_state <= W_10M_L; when W_10M_L => RS <= '1'; DB <= bcd_in(31 downto 28); nx_state <= W_1M_H; when W_1M_H => RS <= '1'; DB <= "0011" ; nx_state <= W_1M_L; when W_1M_L => RS <= '1'; DB <= bcd_in(27 downto 24); nx_state <= W_100k_H; when W_100k_H => RS <= '1'; DB <= "0011" ; nx_state <= W_100k_L; when W_100k_L => RS <= '1'; DB <= bcd_in(23 downto 20); nx_state <= W_10k_H; when W_10k_H => RS <= '1'; DB <= "0011" ; nx_state <= W_10k_L; when W_10k_L => RS <= '1'; DB <= bcd_in(19 downto 16); nx_state <= W_1k_H; when W_1k_H => RS <= '1'; DB <= "0011" ; nx_state <= W_1k_L; when W_1k_L => RS <= '1'; DB <= bcd_in(15 downto 12); nx_state <= W_100_H; when W_100_H => RS <= '1'; DB <= "0011" ; nx_state <= W_100_L; when W_100_L => RS <= '1'; DB <= bcd_in(11 downto 8); nx_state <= W_10_H; when W_10_H => RS <= '1'; DB <= "0011" ; nx_state <= W_10_L; when W_10_L => RS <= '1'; DB <= bcd_in( 7 downto 4); nx_state <= W_1_H; when W_1_H => RS <= '1'; DB <= "0011" ; nx_state <= W_1_L; when W_1_L => RS <= '1'; DB <= bcd_in( 3 downto 0); nx_state <= ReturnHome_H; when ReturnHome_H => DB <= "1000"; nx_state <= ReturnHome_L; when ReturnHome_L => DB <= "0000"; nx_state <= W_10M_H; end case; end process; end architecture;