No entiendo por qué "if" no se activa en modelsim vhdl sim

-1

Estoy usando una lógica programable para decodificar una secuencia de impulsos largos o cortos en letras latinas de acuerdo con el código morse. Estoy usando VHDL para describir nuestro diseño, para ser precisos, estoy usando Quartus Prime para el diseño y ModelSim para las simulaciones. Mi CPLD es un ALTERA MAX-V 5M160ZE64C5.

Estoy usando un interruptor de encendido / apagado que corresponde a "estado" en el código.

  • Cuando está apagado ("estado = '0'"), se supone que el CPLD escucha una secuencia de máximo 4 impulsos largos / cortos (entrada de "mensaje") y los almacena en El vector lógico "morse" para más adelante. Además, tan pronto como se considera que la secuencia es larga, se supone que un LED debe brillar y una pantalla de 14 segmentos debe mostrar el carácter "-".
  • Cuando está activado ("estado = '1'"), el CPLD convierte el vector lógico "morse" previamente almacenado en un carácter latino y lo muestra en la pantalla de 14 semifinales para mientras el "estado" permanezca en '1'. Si cambia a '0', entonces muestra "-" nuevamente.

Como puede ver en la simulación de Modelsim a continuación, la parte brillante del LED se está comportando bastante bien, pero en cuanto al resto, parece que dos de nuestras declaraciones if nunca se activan.

Lasimulaciónseejecutóutilizandolossiguientesparámetros:

force-freezesim:/sauvezlesmorses/clk10,0{25000000000ps}-r{50ms}force-freezesim:/sauvezlesmorses/state00,1{9000000000000ps}-r{18sec}force-freezesim:/sauvezlesmorses/message10,0{3200000000000ps}-r{6.4sec}run40sec

...yaquíestáelcódigo.

libraryieee;useieee.std_logic_1164.all;entitySauvezLesMorsesisport(--Inputportsclk:instd_logic;message:instd_logic;state:instd_logic;--Outputportsseg14:bufferstd_logic_vector(13downto0);lengthLED:bufferstd_logic:='0';stateEvent:bufferstd_logic:='0';messageEvent:bufferstd_logic:='0');endentitySauvezLesMorses;architectureSauvezLesMorses_archofSauvezLesMorsesissignalmorse:std_logic_vector(3downto0):="0000";
begin
    morse2Latin : process(clk, message, state)
    variable count : integer range 0 to 3 := 0;
    variable clk_cnt : integer range 0 to 50 := 0;
    variable first : std_logic := '0';
    begin
        if (rising_edge(clk)) then
            if (first = '0') then
                seg14 <= "00000010001000";
            end if;
            if (stateEvent = '1' and state = '0') then
                seg14 <= "00000010001000";
                first := '1';
                count := 0;
                morse <= "0000";
                stateEvent <= '0';
                messageEvent <= messageEvent;
                lengthLED <= lengthLED;

            elsif (message = '1' and state = '0') then
                if (clk_cnt < 49) then
                    clk_cnt := clk_cnt + 1;
                end if;
                -- Inform user of the length of the current symbol
                if (clk_cnt <= 25) then
                    lengthLED <= '0';
                else
                    lengthLED <= '1';
                end if;
                count := count;
                morse <= morse;
                seg14 <= seg14;
                first := '1';
                stateEvent <= '0';
                messageEvent <= '1';
                clk_cnt := clk_cnt;



            elsif(state = '1') then
                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 ;    
                first := '1';
                stateEvent <= '1';
                lengthLED <= '0';
                count := count;
                morse <= morse;
                clk_cnt := clk_cnt; 
                messageEvent <= '0';


            elsif (messageEvent = '1' and message = '0' and count < 4 and state = '0') then
                if (clk_cnt <= 25) then
                    morse(count) <= '0';
                else
                    morse(count) <= '1';
                end if;
            count := count + 1;
            clk_cnt := 0;
            count := count;
            morse <= morse;
            seg14 <= seg14;
            first := '1';
            stateEvent <= '0';
            messageEvent <= '0';
            lengthLED <= '0';


            else
                seg14 <= seg14;
                first := '1';
                lengthLED <= lengthLED;
                count := count;
                morse <= morse;
                clk_cnt := clk_cnt; 
                stateEvent <= stateEvent;
                messageEvent <= messageEvent;
            end if;
        end if;
    end process morse2Latin;

end architecture SauvezLesMorses_arch ;

Entonces, ¿sabrías por qué esos dos ifs del código indicado arriba

if (stateEvent = '1' and state = '0') then
...
elsif (messageEvent = '1' and message = '0' and count < 4 and state = '0') then
....

nunca son ciertas?

Última actualización del código:

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 <= clk_cnt + 1;
                            lengthLED <= '0';
                        else
                            clk_cnt <= 21;
                            lengthLED <= '1';
                        end if;
                    else
                        state <= A;
                        if (clk_cnt < 25) 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 and 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 ;

Simulación de Modelsim correspondiente:

Entonces, ahora, la pregunta es más bien:

  • ¿Por qué clk_cnt nunca aumenta (cfr estado B)?
  • ¿Por qué count <= 0 no establece realmente count en 0 (cfr estado C)?
pregunta CobaltScales

2 respuestas

0

Bueno, primero mira esta parte

morse2Latin : process(clk)
    variable first : std_logic := '0';
begin
    if (rising_edge(clk)) then
        if (first = '0') then

Cada vez que se desencadena el proceso, first se establece en '0', por lo que la condición if siempre es verdadera.

Entonces realmente deberías separar el proceso en varias partes: preferiblemente una por señal. Combinado así, es difícil de leer y, por lo tanto, difícil de mantener.

Luego está la máquina de estados finitos (FSM) ..., o lo que creo que se supone que es un FSM. Intenté poner algún efecto en la decodificación de los estados de tu máquina, pero es realmente extraño. Vea la imagen:

DeberíaconsiderarescribirunFSMadecuado...connombresdeestadosysimilares.Veauntutorial aquí

    
respondido por el JHBonarius
0

Esto solo parece mostrar las letras E, I, S y H por cierto. Esto podría deberse a esas instrucciones:

if (stateEvent = '1' and state = '0') then
    morse <= "0000";
    stateEvent <= '0';

Causa stateEvent gira a 1 tan pronto como lo hace el estado. Por lo tanto, cuando intente imprimir el texto, solo imprima una de la señal "0000" de morse correspondiente al valor mantenido por recuento

    
respondido por el Bellefroid

Lea otras preguntas en las etiquetas