32ビット値を16進8桁としてキャラクターLCDに表示する

というわけでbufferポートの存在を知った。

VHDL-2008以降、エンティティの内部でもoutポートから値が読み出せるようになったのでbufferポートは用済みになった。だがまだQuartus Prime Liteには実装されていないようである。

ディジタル時計 / VHDLでキャラクターLCD / 8ビットモード -」「ディジタル時計 / VHDLでキャラクターLCD / 4ビットモード -」「周波数カウンターを作る5 / キャラクターLCDに表示する -」のときに假に設けていたシグナルを廃止してbufferポートに置き換える。

VHDL_for_Quartus_Prime/char_LCD_8_digits at main · ti-nspire/VHDL_for_Quartus_Prime · GitHub
example_for_displaying_a_constant.vhdl
ここでは定数を表示した。

library ieee;
use ieee.std_logic_1164.all;
--use ieee.numeric_std.all;

entity example_for_displaying_a_constant is
    port(
        clk   : in std_logic;
        rst_n : in std_logic;
       --bin_in: in std_logic_vector(31 downto 0);
        
        E : out std_logic;
        RS: out std_logic;
        DB: out std_logic_vector(7 downto 4)
    );
end entity;

architecture rtl of example_for_displaying_a_constant is
begin

    c1: entity work.char_LCD_8_digits
        generic map(
            F_CLK => 1_000_000
        )
        port map(
            clk    => clk,
            rst_n  => rst_n,
           --bin_in => bin_in,
            bin_in => x"abef_0189",
            E      => E,
            RS     => RS,
            DB     => DB
        );

end architecture;

char_LCD_8_digits.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity char_LCD_8_digits is
    generic(
        F_CLK : natural := 32_768
    );
    port(
        clk   : in std_logic;
        rst_n : in std_logic;
        bin_in: in std_logic_vector(31 downto 0);
        
        E : buffer std_logic;
        RS: out    std_logic;
        DB: out    std_logic_vector(7 downto 4);
        
        is_ready: out std_logic -- Whether the power_on_reset completed(1) or not(0).
    );
end entity;

architecture rtl of char_LCD_8_digits 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;
    /*
   attribute keep: boolean;
   attribute keep of pr_state, nx_state: signal is true;
   */

    
    function upper_4(num: std_logic_vector(3 downto 0))
        return std_logic_vector is
    begin
        if   unsigned(num) < 10 then return "0011"; -- when 0-9
        else                         return "0100"; -- when A-F
        end if;
    end function;

    function lower_4(num: std_logic_vector(3 downto 0))
        return std_logic_vector  is
    begin
        if   unsigned(num) < 10 then return num;       -- when 0-9
        else return std_logic_vector(unsigned(num)-9); -- when A-F
        end if;
    end function;

begin

   -- generate a clock signal whose period is 2 ms or more.
    process(clk)
        constant count_max: natural := F_CLK / 900;
        variable count: natural range 0 to count_max;
    begin
        if rising_edge(clk) then
            count := count + 1;
            if count = count_max then
                count := 0;
                E <= not E;
            end if;
        end if;
    end process;

   -- a register for keeping a state.
    process(E, rst_n)
    begin
        if    rst_n = '0'    then pr_state <= power_on_reset1;
        elsif rising_edge(E) then pr_state <= nx_state;
        end if;
    end process;

   -- a combinational logic circuit for deciding a next state.
    process(all)
    begin
        RS       <= '0';
        DB       <= "0011";
        is_ready <= '0';
        
        case pr_state is
            when power_on_reset1 =>
                for i in 1 to 7 loop
                    if    i < 7 then nx_state <= power_on_reset1;
                    elsif i = 7 then nx_state <= power_on_reset8;
                    end if;
                end loop;

            /*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<=upper_4(bin_in(31 downto 28));nx_state<=W_10M_L;
            when W_10M_L=>RS<='1';DB<=lower_4(bin_in(31 downto 28));nx_state<=W_1M_H;

            when W_1M_H=>RS<='1';DB<=upper_4(bin_in(27 downto 24));nx_state<=W_1M_L;
            when W_1M_L=>RS<='1';DB<=lower_4(bin_in(27 downto 24));nx_state<=W_100k_H;

            when W_100k_H=>RS<='1';DB<=upper_4(bin_in(23 downto 20));nx_state<=W_100k_L;
            when W_100k_L=>RS<='1';DB<=lower_4(bin_in(23 downto 20));nx_state<=W_10k_H;

            when W_10k_H=>RS<='1';DB<=upper_4(bin_in(19 downto 16));nx_state<=W_10k_L;
            when W_10k_L=>RS<='1';DB<=lower_4(bin_in(19 downto 16));nx_state<=W_1k_H;

            when W_1k_H=>RS<='1';DB<=upper_4(bin_in(15 downto 12));nx_state<=W_1k_L;
            when W_1k_L=>RS<='1';DB<=lower_4(bin_in(15 downto 12));nx_state<=W_100_H;

            when W_100_H=>RS<='1';DB<=upper_4(bin_in(11 downto 8));nx_state<=W_100_L;
            when W_100_L=>RS<='1';DB<=lower_4(bin_in(11 downto 8));nx_state<=W_10_H;

            when W_10_H=>RS<='1';DB<=upper_4(bin_in(7 downto 4));nx_state<=W_10_L;
            when W_10_L=>RS<='1';DB<=lower_4(bin_in(7 downto 4));nx_state<=W_1_H;
                
            when W_1_H=>RS<='1';DB<=upper_4(bin_in(3 downto 0));nx_state<=W_1_L;
            when W_1_L=>RS<='1';DB<=lower_4(bin_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;
            
            when others => nx_state <= power_on_reset1;
        end case;
    end process;

end architecture;

f:id:ti-nspire:20210810072753j:plain:w500