Sunteți pe pagina 1din 11

Se requiere el diagrama de estados y el código VHDL para una máquina expendedora

que vende barras de chocolate por veinticinco centavos. Las entradas y salidas del
controlador se muestran en la figura. Las señales de entrada nickel_in, dime_in y
quarter_in indican que se ha depositado una moneda correspondiente (1 nickel = 5
centavos, 1 dime = 10 centavos y 1 quarter = 25 centavos). También son necesarias dos
entradas adicionales, clk (reloj) y rst (reset). El controlador responde con tres salidas:
candy_out para dispensar una barra de chocolate, nickel_out y dime_out, confirmados
cuando se debe dar vuelto. Solo se aceptan monedas de cinco centavos, diez centavos y
cuartos). El estado 0 es el estado inactivo. De él, si se deposita una moneda de cinco
centavos, la máquina pasa al estado 5; si es un centavo, para indicar 10; o si es un
cuarto, para indicar 25. Se repiten situaciones similares para todos los estados, hasta el
estado 20. Si se alcanza el estado 25, entonces un se dispensa la barra de caramelo, sin
cambios. Sin embargo, si se alcanza el estado 40, por ejemplo, se entrega una moneda
de cinco centavos, pasando, por lo tanto, el sistema al estado 35, desde el cual se
entrega un centavo y se dispensa una barra de chocolate. Los tres estados marcados con
círculos dobles son aquellos de los que se entrega una barra de caramelo y la máquina
vuelve al estado 0.
library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity vending_machine is

Port ( clk, rst : IN STD_LOGIC;

nickel_in, dime_in, quarter_in : IN BOOLEAN;

candy_out, nickel_out, dime_out, quarter_out: OUT STD_LOGIC);

end vending_machine;

architecture fsm of vending_machine IS

TYPE state IS (st0, st5, st10, st15, st20, st25, st30, st35, st40, st45);

SIGNAL present_state, next_state: STATE;

begin
PROCESS(rst, clk)

BEGIN

IF(rst='1') THEN

present_state <=st0;

ELSIF(clk' EVENT AND clk ='1') THEN

present_state <= next_state;

END IF;

END PROCESS;

PROCESS(present_state, nickel_in, dime_in, quarter_in)

BEGIN

CASE present_state IS

WHEN st0 =>

candy_out <= '0';

nickel_out <='0';

dime_out <= '0';

IF (nickel_in) THEN next_state <= st5;

ELSIF (dime_in) THEN next_state <= st10;

ELSIF (quarter_in) THEN next_state <= st25;

ELSE next_state <=st0;

END IF;

WHEN st5 =>

candy_out <= '0';

nickel_out <='0';

dime_out <= '0';

IF (nickel_in) THEN next_state <= st10;


ELSIF (dime_in) THEN next_state <= st15;

ELSIF (quarter_in) THEN next_state <= st30;

ELSE next_state <=st5;

END IF;

WHEN st10 =>

candy_out <= '0';

nickel_out <='0';

dime_out <= '0';

IF (nickel_in) THEN next_state <= st15;

ELSIF (dime_in) THEN next_state <= st20;

ELSIF (quarter_in) THEN next_state <= st35;

ELSE next_state <=st10;

END IF;

WHEN st15 =>

candy_out <= '0';

nickel_out <='0';

dime_out <= '0';

IF (nickel_in) THEN next_state <= st20;

ELSIF (dime_in) THEN next_state <= st25;

ELSIF (quarter_in) THEN next_state <= st40;

ELSE next_state <=st15;

END IF;

WHEN st20 =>

candy_out <= '0';

nickel_out <='0';

dime_out <= '0';


IF (nickel_in) THEN next_state <= st25;

ELSIF (dime_in) THEN next_state <= st30;

ELSIF (quarter_in) THEN next_state <= st45;

ELSE next_state <=st20;

END IF;

WHEN st25 =>

candy_out <= '1';

nickel_out <='0';

dime_out <= '0';

next_state <= st0;

WHEN st30 =>

candy_out <= '1';

nickel_out <='1';

dime_out <= '0';

next_state <= st0;

WHEN st35 =>

candy_out <= '1';

nickel_out <='0';

dime_out <= '1';

next_state <= st35;

WHEN st45 =>

candy_out <= '0';

nickel_out <='0';

dime_out <= '1';

next_state <= st35;

END CASE;
END PROCESS;

END fsm;
Realizar el código VHDL que defina un circuito secuencial que busca el valor mínimo
presente en la entrada A y cuenta el número de veces que aparece dicho número en cada
período de reloj cuando este valor mínimo está presente. Tiene dos salidas, minVal y
minCount. Entonces, por ejemplo, si el la secuencia de entrada en A es 57, 85, 23, 34, 36,
23, 46, 23 luego las secuencias de valores en las salidas serán 57, 57, 23, 23, 23, 23, 23,
23 y 1,1,1,1,1,2,2,3.

entity minValCount is port (

clk, reset: in std_logic;

A : in std_logic_vector(7 downto 0);

minVal, minCount : out std_logic_vector(7 downto 0));

end minValCount;

architecture a1 of minValCount is

signal val, count: std_logic_vector(7 downto 0);

begin

process (clk) begin

if rising_edge(clk) then

if reset = '1' then

val <= x”FF”; count <= x”00”;

else

if A < val then

val <= A; count <= x”01”;

elsif A = val then

count <= count + 1;

end if;

end if;
end if;

end process;

minVal <= val; minCount <= count;

end a1;

Realizar el diagrama de estados y el código VHDL para contar el número de pulsos impar
que se han observado en la entrada dIn desde la última activación de reset.
entity oddPulseCounter is port(

clk, reset, dIn: in std_logic;

oddCount: out std_logic_vector(7 downto 0));

end oddPulseCounter;

architecture a1 of oddPulseCounter is

type stateType is (resetState, start1, prev0, prev1odd, prev1even);

signal state: stateType;

begin

process(clk) begin

if rising_edge(clk) then

if reset = ‘1’ then state <= resetState;

else case state is

when resetState =>

oddCount <= (others => ‘0’);

if dIn = ‘0’ then state <= prev0;


else state <= start1; end if;

when start1 =>

if dIn = ‘0’ then state <= prev0; end if;

when prev0 =>

if dIn = ‘1’ then state <= prev1odd; end if;

when prev1odd =>

if dIn = ‘0’ then

state <= prev0; oddCount <= oddCount + 1;

else state <= prev1even; end if;

when others =>

if dIn = ‘0’ then state <= prev0;

else state <= prev1odd; end if;

end case; ... end a1;

Realizar el código VHDL que defina un circuito que cuenta el número de veces que la
entrada X es mayor en valor a la entrada Y. Por ejemplo, con la secuencia de pares de
entrada (X, Y) = (7,5), (4,6), (8,6), (9,13), (15, 2) el valor final de la salida, nUpCrossings
debe ser 2.

entity upCross is Port (

clk, reset: in std_logic;

X, Y: in std_logic_vector(3 downto 0);

nUpCrossings: out std_logic_vector(7 downto 0);

end upCross;

architecture a1 of upCross is

signal count: std_logic_vector(7 downto 0);


signal prevCompare: std_logic;

begin

process (clk) begin

if rising_edge(clk) then

if reset = '1' then

count <= (count’range =>’0’);

prevCompare <= ‘1’;

else

if X > Y then prevCompare <= ‘1’;

else prevCompare <= ‘0’;

end if;

if prevCompare = ‘0’ and X > Y then

count <= count + 1;

end if;

end if;

end if;

end process;

nUpCrossings <= count;

end a1;

S-ar putea să vă placă și