我正在尝试模拟电梯,结果出现错误:
ERROR:Xst:827 = Signal count cannot be synthesized, bad synchronous description
我正在遵循此来源的代码:https://www.youtube.com/watch?v=i03_-NMwmDs,因为我的非常相似,(我有 7 层楼和两部电梯)。首先,我正在使用视频中提到的代码,稍后,我将再实现两个电梯,以便在此模拟中协同工作。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity elevator is
port (clk: in std_logic;
sensors1: out std_logic:='0'; --sensors at each level for elevator 1
a1, a2, a3, a4, a5, a6, a7: out std_logic; -- for LED display at FPGA
insideopendoor, in1, in2, in3, in4, in5, in1up, in2up, in3up, in4up, in5up, in5down, in4down, in3down, in2down, in1down: std_logic; -- input request for each floor
opendoor: out std_logic; -- from inside elevator
closedoor: out std_logic); -- from inside elevator
end elevator;
architecture sequence of elevator is
constant timedoorclose: integer := 3;
constant timedoorclosed: integer := 2;
constant time_nx_state: integer :=4;
signal demand: std_logic_vector(0 to 4) := "00000";
signal direction_of_elevator : integer range 0 to 2 := 0;
signal updownpassenger : std_logic := '0';
signal signalstatus: std_logic := '1';
type status is (L1, L2, L3, L4, L5);
signal pr_state, nx_state: status;
begin
main: process (clk, insideopendoor, in1, in2, in3, in4, in5, in1up, in2up, in3up, in4up, in5up, in5down, in4down, in3down, in2down, in1down)
variable digit1 : std_logic_vector (6 downto 0);
variable count : integer range 0 to (time_nx_state + timedoorclose + timedoorclosed);
variable bufferopendoor : std_logic;
variable position : integer range 0 to 4;
variable tempup : integer range 1 to 2 := 1;
variable tempdown : integer range -4 to 4;
begin
if (clk'event and clk='1') then
demand(0) <= demand(0) or in1 or in1up or in1down;
demand(1) <= demand(1) or in2 or in2up or in2down;
demand(2) <= demand(2) or in3 or in3up or in3down;
demand(3) <= demand(3) or in4 or in4up or in4down;
demand(4) <= demand(4) or in5 or in5up or in5down;
case pr_state is
when L1 => position := 0;
when L2 => position := 1;
when L3 => position := 2;
when L4 => position := 3;
when L5 => position := 4;
end case;
for i in 1 to 4 loop
if demand(i) ='1' then
tempup := i - position;
else null;
end if;
end loop;
for i in 3 downto 0 loop
bufferopendoor := '1';
closedoor <= '0';
count := 0;
end loop; --
elsif (updownpassenger = '1') then
if (count < timedoorclose) then
opendoor <= '1';
bufferopendoor := '1';
elsif count < (timedoorclose + timedoorclosed) then
opendoor <= '0';
bufferopendoor := '0';
else
closedoor <= '0';
end if;
--else null; ------
--end if; ------
-----------part main-----------------
count := count +1;
if insideopendoor = '1' then
opendoor<='1';
bufferopendoor :='1';
closedoor <= '0';
count := 0;
elsif (updownpassenger ='1') then
if (count < timedoorclose) then
opendoor <= '1';
bufferopendoor := '1';
closedoor <= '0';
elsif (count < (timedoorclose + timedoorclosed)) then
opendoor <= '0';
bufferopendoor := '0';
closedoor <= '1';
else
closedoor <= '0';
pr_state <= nx_state;
if signalstatus = '1' then
signalstatus <= '0';
else
signalstatus <= '1';
end if;
count := 0;
end if;
else null; --
end if;--
case nx_state is
when L1 =>
digit1 := "1111001";
if demand(0) = '1' then
demand(0) <= '0';
else null;
end if;
when L2 =>
digit1 := "0100100";
if demand(1) = '1' then
demand(1) <= '0';
else null;
end if;
when L3 =>
digit1 := "0110000";
if demand(3) = '1' then
demand(3) <= '0';
else null;
end if;
when L4 =>
digit1 := "0011001";
if demand(3) = '1' then
demand(3) <= '0';
else null;
end if;
when L5 =>
digit1 := "0010010";
if demand(4) = '1' then
demand(4) <= '0';
else null;
end if;
when others => null;
end case;
a1 <= digit1(0);
a2 <= digit1(1);
a3 <= digit1(2);
a4 <= digit1(3);
a5 <= digit1(4);
a6 <= digit1(5);
a7 <= digit1(6);
end if;
end process main;
step: process (pr_state, signalstatus)
begin
case pr_state is
--end if;
when L1 =>
if (demand(0)='1') then
nx_state <= pr_state;
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <=L2;
elsif direction_of_elevator = 2 then
nx_state <= pr_state;
else
nx_state <= pr_state;
end if;
end if;
when L2 =>
if (demand(1)= '1') then
nx_state <= pr_state;
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <= L3;
elsif direction_of_elevator = 2 then
nx_state <= L1;
else
nx_state <= pr_state;
end if;
end if;
when L3 =>
if (demand(2)= '1') then
nx_state <= pr_state;
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <= L4;
elsif direction_of_elevator = 2 then
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <= L5;
elsif direction_of_elevator = 2 then
end if;
end if;
end if;
when L5 =>
if (demand(4)='1') then
nx_state <= pr_state;
updownpassenger <= '1';
else
updownpassenger <= '0';
if direction_of_elevator = 1 then
nx_state <= L4;
elsif direction_of_elevator = 2 then
nx_state <= L1;
else
nx_state <= pr_state;
end if;
end if;
when others => null;
end case;
end process step;
end sequence;
你的代码看起来很混乱。它不会合成有一个特定的原因:仔细考虑一下紧跟在此处的代码
elsif (updownpassenger = '1') then
将被执行。它将在敏感度列表中任何输入的上升沿或下降沿之后执行,除了
clk
之外,它仅在下降沿之后执行。您将如何设计具有这种行为的逻辑?好吧,你的合成器也做不到。
基本上,您需要重构您的代码。您需要将其分为顺序过程和组合过程。 (组合逻辑是其输出仅取决于其输入的逻辑,因此是不包含锁存器或触发器的逻辑。顺序逻辑是包含锁存器或触发器的逻辑,但通常也包含一些门。不要使用锁存器- 它们不是同步设计。)虽然有很多方法可以对此类流程进行编码,但坚持使用模板来保持一致是明智的。这里有三个模板,如果遵循它们,将为您提供所需的一切,并使您的 VHDL 编码生活变得简单:
这是具有异步复位的时序逻辑模板,所有综合工具都应该理解:
process(clock, async_reset) -- nothing else should go in the sensitivity list
begin
-- never put anything here
if async_reset ='1' then -- or '0' for an active low reset
-- set/reset the flip-flops here
-- ie drive the signals to their initial values
elsif rising_edge(clock) then -- or falling_edge(clock) or clk'event and clk='1' or clk'event and clk='0'
-- put the synchronous stuff here
-- ie the stuff that happens on the rising or falling edge of the clock
end if;
-- never put anything here
end process;
这是没有异步复位的顺序逻辑的模板:
process(clock) -- nothing else should go in the sensitivity list
begin
-- never put anything here
if rising_edge(clock) then -- or falling_edge(clock) or clk'event and clk='1' or clk'event and clk='0'
-- put the synchronous stuff here
-- ie the stuff that happens on the rising or falling edge of the clock
end if;
-- never put anything here
end process;
这是组合过程的相应模板:
process(all inputs in the sensitivity list) -- an 'input' is a signal either on the LHS of an assignment or a signal that is tested
begin
-- combinational logic (with complete assignment and no feedback)
end process;