无法为 VHDL 中的整数信号赋值

Can't assign value to integer signal in VHDL

我正在使用可编程逻辑根据摩尔斯电码将一系列长脉冲或短脉冲解码为拉丁字母。我使用 VHDL 来描述我们的设计,准确地说,我使用 Quartus Prime 进行设计,使用 ModelSim 进行仿真。我的 CPLD 是 ALTERA MAX-V 5M160ZE64C5.

这是我的代码:

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

entity SauvezLesMorses is
    port
    (
        -- Input ports
        clk : in std_logic;
        message : in std_logic;
        display : in std_logic;
        start : in std_logic;

        -- Output ports
        seg14 : out std_logic_vector (13 downto 0);
        lengthLED : out std_logic := '0'
    );
end entity SauvezLesMorses;

architecture SauvezLesMorses_arch of SauvezLesMorses is
type state_t is (A, B, C);
signal state : state_t;
signal count : integer range 0 to 4 := 0;   
signal clk_cnt : integer range 0 to 21 := 0;
signal morse : std_logic_vector (3 downto 0);
begin


process (clk, start)
variable vectorDummy : std_logic_vector (3 downto 0);
begin
    if (start = '1') then
        state <= A;
        count <= 0;
        seg14 <= "00000010001000";
        morse <= "0000";
        lengthLED <= '0';

    elsif (rising_edge(clk)) then
        case state is


            -- Idle, listening
            when A =>
                if  (display = '0') then
                    if (message = '1' and count < 4) then
                        state <= B;
                        seg14 <= "00000010001000";
                        count <= count;
                        morse <= morse;
                        lengthLED <= '0';
                        clk_cnt <= 0;
                    else
                        state <= A;
                        seg14 <= "00000010001000";
                        count <= count;
                        morse <= morse;
                        lengthLED <= '0';
                    end if;
                else
                    state <= C;
                    count <= count;
                    morse <= morse;
                    lengthLED <= '0';
                    seg14 <= "00000010001000";
                end if;


            -- Measuring impulse length 
            when B =>
                if (display = '0') then
                    if (message = '1') then
                        state <= B;
                        count <= count;
                        morse <= morse;
                        seg14 <= "00000010001000";
                        if (clk_cnt < 20) then
                            clk_cnt <= (1 + clk_cnt);
                            lengthLED <= '0';
                        else
                            clk_cnt <= 21;
                            lengthLED <= '1';
                        end if;
                    else
                        state <= A;
                        if (clk_cnt < 21) then
                            morse <= morse;
                        else
                            case count is
                                when 0 => vectorDummy := "1000";
                                when 1 => vectorDummy := "0100";
                                when 2 => vectorDummy := "0010";
                                when 3 => vectorDummy := "0001";
                                when others => vectorDummy := "0000";
                            end case;
                            morse <= morse or vectorDummy;
                        end if;
                        count <= count + 1;
                        lengthLED <= '0';
                        seg14 <= "00000010001000";
                    end if;
                else
                    state <= C;
                    count <= count;
                    morse <= morse;
                    lengthLED <= '0';
                    seg14 <= "00000010001000";
                end if;


            -- Displaying converted character to user
            when C =>
                if (display = '0') then
                    state <= A;
                    count <= 0;
                    seg14 <= "00000010001000";
                    lengthLED <= '0';
                    morse <= "0000";
                else
                    state <= C;
                    count <= count;
                    morse <= morse;
                    lengthLED <= '0';
                    if(count = 1) then
                        case morse is
                            when "0000" => seg14 <= "10011110001000"; --E
                            when "1000" => seg14 <= "10000000100010"; --T
                            when others => seg14 <= "11111111111111"; --unknown character
                        end case;
                    elsif(count = 2) then
                        case morse is
                            when "0100" => seg14 <= "11101110001000"; --A
                            when "1000" => seg14 <= "01101101000100"; --N
                            when "1100" => seg14 <= "01101101010000"; --M
                            when "0000" => seg14 <= "00000000100010"; --I
                            when others => seg14 <= "11111111111111"; --unknown character
                        end case;
                    elsif(count = 3) then
                        case morse is
                            when "0000" => seg14 <= "10110110001000"; --S
                            when "0010" => seg14 <= "01111100000000"; --U
                            when "0100" => seg14 <= "11001110001100"; --R
                            when "0110" => seg14 <= "01101100000101"; --W
                            when "1000" => seg14 <= "11110000100010"; --D
                            when "1010" => seg14 <= "00001110010100"; --K
                            when "1100" => seg14 <= "10111100001000"; --G
                            when "1110" => seg14 <= "11111100000000"; --O
                            when others => seg14 <= "11111111111111"; --unknown character
                        end case;
                    elsif(count = 4) then
                        case morse is
                            when "0000" => seg14 <= "01101110001000"; --H
                            when "0001" => seg14 <= "00001100010001"; --V
                            when "0010" => seg14 <= "10001110001000"; --F
                            when "0100" => seg14 <= "00011100000000"; --L
                            when "0110" => seg14 <= "11001110001000"; --P
                            when "0111" => seg14 <= "01111000000000"; --J
                            when "1000" => seg14 <= "11110000101010"; --B
                            when "1001" => seg14 <= "00000001010101"; --X
                            when "1010" => seg14 <= "10011100000000"; --C
                            when "1011" => seg14 <= "00000001010010"; --Y
                            when "1100" => seg14 <= "10010000010001"; --Z
                            when "1101" => seg14 <= "11111100000100"; --Q
                            when others => seg14 <= "11111111111111"; --unknown character
                        end case;
                    else
                        seg14 <= "11111111111111";
                    end if ;
                end if;


        end case;
    end if;
end process;


end architecture SauvezLesMorses_arch ;

带参数的modelsim仿真

force -freeze sim:/sauvezlesmorses/clk 1 0, 0 {25000000000 ps} -r {50 ms}
force -freeze sim:/sauvezlesmorses/display 0 0, 1 {9000000000000 ps} -r {18 sec}
force -freeze sim:/sauvezlesmorses/message 0 0, 1 {3200000000000 ps} -r {6.4 sec}
force -freeze sim:/sauvezlesmorses/start 1 0 -cancel {0.5 sec}
run 40 sec

产生:

Modelsim Simulation

清楚地表明:

你知道为什么吗?


P.S。我知道我绝对不是 运行 合适的测试平台。所以即使我应该,也请不要提醒我,除非你知道这是我问题答案的一部分。

强制更新信号值不会生成事件。

参见 IEEE Std 1076-2008 14.7.3.4 信号更新,第 3 段

... If updating a signal causes the current value of that signal to change, then an event is said to have occurred on the signal, unless the update occurs by application of the vhpi_put_value function with an update mode of vhpiDeposit or vhpiForce to an object that represents the signal. ...

可能与 Modelsim 的力或 FLI 使用的机制相同。

有测试台:

library ieee;
use ieee.std_logic_1164.all;

entity slm_tb is
end entity;

architecture foo of slm_tb is
    -- Input ports
    signal clk:         std_logic := '1';
    signal message:     std_logic := '0';
    signal display:     std_logic := '0';
    signal start:       std_logic := '1';
    -- Output ports
    signal seg14:       std_logic_vector (13 downto 0);
    signal lengthLED:   std_logic;
begin

DUT:
    entity work.sauvezlesmorses
        port map (
            clk => clk,
            message => message,
            display => display,
            start   => start,
            seg14   => seg14,
            lengthLED => lengthLED
        );

-- force -freeze sim:/sauvezlesmorses/clk 1 0, 0 {25000000000 ps} -r {50 ms}
-- force -freeze sim:/sauvezlesmorses/display 0 0, 1 {9000000000000 ps} -r {18 sec}
-- force -freeze sim:/sauvezlesmorses/message 0 0, 1 {3200000000000 ps} -r {6.4 sec}
-- force -freeze sim:/sauvezlesmorses/start 1 0 -cancel {0.5 sec}
-- run 40 sec

-- stimulus generators:
CLOCK:
    process
    begin
        wait for 25 ms;
        clk <= not clk;
        if now > 40 sec then
            wait;
        end if;
    end process;
DISP:
    process
    begin
        wait for 9 sec;
        display <= not display;
        if now > 35 sec then  -- stop simulation at 40 sec
            wait;
        end if;
    end process;
MSG:
    process
    begin
        wait for 3.2 sec;
        message <= not message;
        if now > 35 sec then
            wait;
        end if;
    end process;
ST:
    process
    begin
        wait for 0.5 sec;
        start <= 'U';
        wait;
    end process;
end architecture;

你确实得到了事件: