我正在制作一台饮料自动售货机,其输入为:clk、reset、leu1(1 种货币)、lei5(5 种货币)、10lei(10 种货币)、3 个产品输入:product_3lei(花费 3 种货币)、 Product_5lei(花费 5 货币)、product_7lei(花费 7 货币)和一个要求找零的输入:cerere_rest。它有 3 种状态:累积,它接受最多 10 个最大余额的现金输入;分配,在一个周期内它只发出分配的信号;以及最终确定,在有人要求找零后它会去哪里。首先以尽可能多的 5 列伊钞票形式给出,然后尽可能多地以 1 列伊钞票形式给出,然后当余额为 0 时,它会返回到累积阶段。至少应该是这样。它陷入了最后阶段,看起来 1leu_rest 不断自行触发。我必须将这两个进程分开。这是VHDL代码和仿真图片:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity AutomatBauturi is
Port (
clk : in std_logic;
reset : in std_logic;
leu1 : in std_logic;
lei5 : in std_logic;
lei10 : in std_logic;
product_3lei : in std_logic;
product_5lei : in std_logic;
product_7lei : in std_logic;
cerere_rest : in std_logic;
produs : out std_logic;
leu1_rest : out std_logic;
lei5_rest : out std_logic;
respingere : out std_logic
);
end AutomatBauturi;
architecture Behavioral of AutomatBauturi is
-- States
type state_type is (Accumulating, Dispensing, Finalizing);
signal current_state, next_state : state_type;
-- Internal signals
signal product_price : integer := 0; -- Stores the product price
signal balance : integer := 0;
begin
-- State Transition and Register Update Process
process(clk, reset)
begin
if reset = '1' then
current_state <= Accumulating;
elsif rising_edge(clk) then
current_state <= next_state;
end if;
end process;
-- Combinational Process for FSM Logic
process(current_state, leu1, lei5, lei10, product_3lei, product_5lei, product_7lei, cerere_rest)
begin
-- Default output values
produs <= '0';
leu1_rest <= '0';
lei5_rest <= '0';
respingere <= '0';
next_state <= current_state;
case current_state is
-- State: Accumulating
when Accumulating =>
-- Handle money inputs
if leu1 = '1' then
if balance + 1 > 10 then
respingere <= '1';
else
balance <= balance + 1;
end if;
elsif lei5 = '1' then
if balance + 5 > 10 then
respingere <= '1';
else
balance <= balance + 5;
end if;
elsif lei10 = '1' then
if balance + 10 > 10 then
respingere <= '1';
else
balance <= balance + 10;
end if;
-- Handle product requests
elsif product_3lei = '1' then
if balance >= 3 then
balance <= balance - 3;
next_state <= Dispensing;
end if;
elsif product_5lei = '1' then
if balance >= 5 then
balance <= balance - 5;
next_state <= Dispensing;
end if;
elsif product_7lei = '1' then
if balance >= 7 then
balance <= balance - 7;
next_state <= Dispensing;
end if;
elsif cerere_rest = '1' then
next_state <= Finalizing;
end if;
-- State: Dispensing
when Dispensing =>
produs <= '1'; -- Activate product output
next_state <= Accumulating; -- Return to Accumulating after one cycle
-- State: Finalizing
when Finalizing =>
-- Dispense rest in 5 lei and 1 leu notes
if balance >= 5 then
lei5_rest <= '1';
balance <= balance - 5;
elsif balance >= 1 then
leu1_rest <= '1';
balance <= balance - 1;
else
next_state <= Accumulating;
end if;
end case;
end process;
end Behavioral;
这是我正在使用的测试平台:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity AutomatBauturi_tb is
end AutomatBauturi_tb;
architecture Behavioral of AutomatBauturi_tb is
-- Component Declaration for the Unit Under Test (UUT)
component AutomatBauturi
Port (
clk : in std_logic;
reset : in std_logic;
leu1 : in std_logic;
lei5 : in std_logic;
lei10 : in std_logic;
product_3lei : in std_logic;
product_5lei : in std_logic;
product_7lei : in std_logic;
cerere_rest : in std_logic;
produs : out std_logic;
leu1_rest : out std_logic;
lei5_rest : out std_logic;
respingere : out std_logic
);
end component;
-- Testbench Signals
signal clk : std_logic := '0';
signal reset : std_logic := '0';
signal leu1 : std_logic := '0';
signal lei5 : std_logic := '0';
signal lei10 : std_logic := '0';
signal product_3lei : std_logic := '0';
signal product_5lei : std_logic := '0';
signal product_7lei : std_logic := '0';
signal cerere_rest : std_logic := '0';
signal produs : std_logic;
signal leu1_rest : std_logic;
signal lei5_rest : std_logic;
signal respingere : std_logic;
constant clk_period : time := 10 ns;
begin
-- Instantiate the Unit Under Test (UUT)
uut: AutomatBauturi
Port map (
clk => clk,
reset => reset,
leu1 => leu1,
lei5 => lei5,
lei10 => lei10,
product_3lei => product_3lei,
product_5lei => product_5lei,
product_7lei => product_7lei,
cerere_rest => cerere_rest,
produs => produs,
leu1_rest => leu1_rest,
lei5_rest => lei5_rest,
respingere => respingere
);
-- Clock Generation
clk_process : process
begin
while true loop
clk <= '0';
wait for clk_period / 2;
clk <= '1';
wait for clk_period / 2;
end loop;
end process;
-- Stimulus Process
stimulus_process : process
begin
-- Reset the system
reset <= '1';
wait for clk_period;
reset <= '0';
-- Insert 5 lei
lei5 <= '1';
wait for clk_period;
lei5 <= '0';
wait for clk_period;
-- Insert another 5 lei
lei5 <= '1';
wait for clk_period;
lei5 <= '0';
wait for clk_period;
-- Insert another 5 lei
lei5 <= '1';
wait for clk_period;
lei5 <= '0';
wait for clk_period;
-- Get the 7 lei product
product_7lei <= '1';
wait for clk_period;
product_7lei <= '0';
wait for clk_period;
-- Insert 1 leu
leu1 <= '1';
wait for clk_period;
leu1 <= '0';
wait for clk_period;
-- Insert another 1 leu
leu1 <= '1';
wait for clk_period;
leu1 <= '0';
wait for clk_period;
-- Get the 5 lei product
product_5lei <= '1';
wait for clk_period;
product_5lei <= '0';
wait for clk_period;
-- Insert 5 lei
lei5 <= '1';
wait for clk_period;
lei5 <= '0';
wait for clk_period;
-- Insert 1 leu
leu1 <= '1';
wait for clk_period;
leu1 <= '0';
wait for clk_period;
-- Get rest
cerere_rest <= '1';
wait for clk_period;
cerere_rest <= '0';
wait for clk_period;
-- End simulation
wait;
end process;
end Behavioral;
这是模拟
最后应该返还6个货币。 5 个 1 脉冲,1 也是如此,然后就保持这样。
我尝试将天平的信号切换为变量并使用辅助信号来更新它,但没有成功。
这里有几个问题。 它遇到的问题是
balance
不在敏感度列表中。如果您使用的是VHDL 2008,您只需将敏感度列表替换为process(all)
,编译器将自动确定敏感度列表。
但是在敏感度列表中添加平衡也会导致一个问题 - 你将在硬件中创建一个逻辑循环,并且状态在模拟中会立即发生变化。
您需要确保
balance
仅在时钟进程中修改。您可以通过在异步进程中生成 balance_next
信号并在时钟进程中设置 balance
来实现此目的,与生成 next_state
和 current_state
信号的方式相同。