contador simple en VHDL

0

Estoy tratando de escribir un pequeño contador en VHDL usando la metodología de los dos procesos. Sin embargo no está funcionando. ¿Podría alguien explicarme por qué?

   library IEEE;
   use IEEE.std_logic_1164.all;
   use IEEE.std_logic_arith.all;
   USE ieee.numeric_std.ALL;
   use IEEE.std_logic_unsigned.all;


   entity myCounter is
   port(
    clk: in std_logic;
    clkEnable:in std_logic;
    reset:in std_logic;
   );
   end myCounter;


   architecture Behavioral of myCounteris

   TYPE STATE_TYPE IS (counterDecr, countIncr, resetCounter);

   signal stateMachine: STATE_TYPE:=counterDecr;
   signal nextState: STATE_TYPE:=counterDecr;

   signal counter: integer:=15;

   signal test: std_logic:='0';

   begin

synchronous: process(clk)begin
        if(clkEnable='1')then
            if(rising_edge(clk))then
                if(reset='1')then
                    stateMachine<=counterDecr;                      
                else 
                    stateMachine<=nextState;
                end if;

            end if;
        end if; 
end process;

combin:process(stateMachine)begin
            counter<=counter-1;
            nextState<=counterDecr;
            test<= not test;
end process;
   end;
    
pregunta J.Doe

2 respuestas

1

El problema principal es que StateMachine siempre tiene el valor de counterDecr . Como nunca cambia, el proceso combin nunca se activa.

El proceso combin debe tener todas las señales en el RHS (lado derecho) de cualquiera de sus asignaciones, y ninguna otra, en su lista de sensibilidad. No tiene sentido que sea activado por alguna otra señal.

Pero un problema mayor es que un proceso combinatorio no puede tener asignaciones en las cuales las señales en el LHS también aparecen en el RHS. Declaraciones como counter <= counter - 1; y test <= not test; no tienen ningún sentido, nunca se conformarían con un valor final.

EDITAR: No puedo decir cuáles son tus intenciones con tu código, pero si necesitara un contador arriba / abajo, escribiría algo como esto:

architecture Behavioral of myCounter is
  signal counter: std_logic_vector (3 downto 0);
begin
  process (clk) begin
    if rising_edge(clk) then
      if reset = '1' then
        counter <= (others => '0');
      elsif clkEnable = '1' then
        if updown = '1' then
          counter <= counter + 1;
        else
          counter <= counter - 1;
        end if;
      end if;
    end if;
  end process;
end Behavioral;

Tenga en cuenta que el único "estado" es el propio contador. Si quisiera tener una máquina de estado que controlara el modo de conteo del contador, sería un módulo separado.

No me suscribo al método de "dos procesos" para máquinas de estado; es simplemente más detallado y propenso a errores, como lo ha encontrado.

EDITAR: En respuesta a su último comentario, haría una división entre diez y algo como esto:

architecture Behavioral of myCounter is
  signal counter: std_logic_vector (3 downto 0);
begin
  process (clk) begin
    if rising_edge(clk) then
      if reset = '1' then
        counter <= (others => '0');
        output_pulse <= '0';
      elsif clkEnable = '1' then
        if counter = "1001" then
          counter <= (others => '0');
          output_pulse <= '1';
        else
          counter <= counter + 1;
          output_pulse <= '0';
        end if;
      end if;
    end if;
  end process;
end Behavioral;
    
respondido por el Dave Tweed
0

Su código tiene varios errores y problemas. Ver mis anotaciones en línea.

library IEEE;
use IEEE.std_logic_1164.all;
-- use IEEE.std_logic_arith.all;     -- don't use this
use ieee.numeric_std.all;            -- use this package, it comes with new types for signed and unsigned operations
-- use IEEE.std_logic_unsigned.all;  -- don't use this either

entity myCounter is                  -- there was a space missing
  port (
    clk       : in std_logic;
    clkEnable : in std_logic;
    reset     : in std_logic   --;   -- ";"-signs are no line end signs like in C, they are list element delimiters, so no ";" on the port
                                     -- btw. entities with no output signal are considered empty or useless design units and get trimmed in many tools
  );
end entity;

architecture Behavioral of myCounter is -- there was a space missing
  type STATE_TYPE is (counterDecr, countIncr, resetCounter);

  signal stateMachine : STATE_TYPE := counterDecr;  -- space characters around operators do no harm, but increase readability
  signal nextState    : STATE_TYPE;        -- don't initialize combinatoric signals

  signal counter      : integer   := 15;   -- this is a 32-bit integer, you could constrain the range to 0..15

  signal test         : std_logic := '0';  -- this signal maps to a register, so an init value is 'correct'

begin
  synchronous: process(clk)
  begin
    --if(clkEnable='1')then         -- clock enables must be placed 'inside' of a rising_edge, see the HDL coding guide of you vendor tool, what patterns are supported
    if rising_edge(clk) then
      if (reset = '1') then
        stateMachine <= counterDecr;
      elsif (clkEnable = '1') then  -- note that ce (clock enable) signals usually have a lower priority than resets
        stateMachine <= nextState;
      end if;
    end if; 
  end process;

  combin: process(stateMachine)     -- your FSM has less events then your counter should have, so this sensitivity list will not work as expected
  begin
    counter   <= counter - 1;       -- this generates a combinatoric loop, such statement makes only sense in a sequential process
    nextState <= counterDecr;
    test      <= not test;          -- this generates a combinatoric loop
  end process;
end architecture;
    
respondido por el Paebbels

Lea otras preguntas en las etiquetas