无法在VHDL

时间:2017-05-02 18:26:56

标签: 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

清楚地表明:

  • clk_cnt永远不会增加,而是在40秒内保持为零
  • count既未通过激活start也未设置为0,也未设置为停用显示(即stateC转换为A )。

你知道为什么吗?

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

1 个答案:

答案 0 :(得分:1)

更新信号值的力量不会产生事件。

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

  

...如果更新信号导致该信号的当前值发生变化,则表示信号上发生了事件,除非通过应用{{1更新模式为vhpi_put_valuevhpiDeposit的函数,用于表示信号的对象。 ...

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

使用测试平台:

vhpiForce

你确实得到了一些事件:

slm_tb.png