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 realmentecount
en 0 (cfr estado C)?