VHDL - 我的代码是可综合的,并且可以按照我想要的方式在模拟上工作,但它不在 fpga 上
VHDL - My code is synthesizable and works the way i want on simulation, but it doesn't on the fpga
我的 VHDL 代码在功能上是正确的,在模拟中它按照预期的方式工作。我测试了许多变体,代码工作正常。
但是当我对 fpga (Nexyx 4 ddr) 进行编程时,除了计数器的预加载之外,一切都运行良好。
我不知道 fsm 的负载使能 (load_e) 输出是否没有到达计数器,或者表示计数器的输出信号是否已加载 (counter_loaded) '到达 fsm,但是当我对 fpga 进行编程时,它永远不会从状态 C 或 D(等待计数器加载)到状态 E 或 F(它进行倒计时)。
我测试了目标中代码的其他部分并且它工作正常,所以到目前为止唯一的问题是那个,我找不到错误,我正在考虑时间,但我没有如何解决它的想法。
我在这里留下计数器和 fsm 代码,以及 TOP 代码,我是 VHDL 的新手,可能有很多不好的实践错误。
我是西班牙人,这就是我英语不好的原因,也是一些信号的西班牙名称,但我在它们旁边添加了评论。
--------COUNTER---------------------------------------
entity counter is
Generic (NBITS : positive := 15
);
Port (clk : in STD_LOGIC;
rst : in STD_LOGIC;
ce : in STD_LOGIC;
load : in STD_LOGIC_VECTOR (NBITS-1 downto 0);
load_e : in STD_LOGIC;
unit : out STD_LOGIC_VECTOR(3 downto 0);
dec : out STD_LOGIC_VECTOR(3 downto 0);
zero_n : out STD_LOGIC; --true si cuenta = 0
loaded : out STD_LOGIC);
end counter;
architecture Behavioral of counter is
signal q_i : unsigned (NBITS-1 downto 0) := (others => '1');
begin
process(clk,rst)
begin
if rst = '1' then
q_i <= (OTHERS => '1');
loaded <= '0';
elsif rising_edge(clk) then
if CE = '1' then
if load_e = '1' then --ONE OF MY GUESSES OF THE PROBLEM
q_i <= unsigned(load);
loaded <= '1';
else
q_i <= q_i - 1;
loaded <= '0';
end if;
end if;
end if;
end process;
dec <= std_logic_vector(to_unsigned((to_integer(q_i(14 downto 10)) / 10),dec'length)); --first 5 bits are the tens
unit <= std_logic_vector(to_unsigned((to_integer(q_i(14 downto 10)) rem 10),unit'length)); --fist 5 bits are the unit
zero_n <= '1' WHEN q_i < "000010000000000" ELSE '0'; --cout is zero if the first 5 bits are less tan 1 in binary
end Behavioral;
------FINITE STATE MACHINE--------------------------------
entity maquina_estados is
Port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
zero_n : in STD_LOGIC;
counter_loaded : in STD_LOGIC;
load_e : out STD_LOGIC;
load : out STD_LOGIC_VECTOR(14 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end maquina_estados;
architecture Behavioral of maquina_estados is
type state_type is (A, B, C, D, E, F); --define state(A = powered off, B = powered on, C = short coffee preload, D = large coffee preload, E = short coffee, F = large coffee)
signal state, next_state : state_type; --type state signal
begin
process(clk,rst)
begin
if rst = '1' then
state <= A;
elsif rising_edge(clk) then
state <= next_state;
end if;
end process;
process(state, b_on, corto, largo, zero_n, counter_loaded)
begin
CASE state IS
WHEN A => if b_on = '1' then
next_state <= B;
else
next_state <= A;
end if;
WHEN B => if b_on = '0' then
next_state <= A;
elsif corto = '1' then
next_state <= C;
elsif largo = '1' then
next_state <= D;
else
next_state <= B;
end if;
WHEN C => if counter_loaded = '1' then
next_state <= E;
else
next_state <= C;
end if;
WHEN D => if counter_loaded = '1' then
next_state <= F;
else
next_state <= D;
end if;
WHEN E => if zero_n = '1' then
next_state <= B;
else
next_state <= E;
end if;
WHEN F => if zero_n = '1' then
next_state <= B;
else
next_state <= F;
end if;
WHEN OTHERS => next_state <= A;
end case;
end process;
process(state)
begin
CASE state IS
WHEN A => load <= "111111111111111"; --default value of the count
load_e <= '0';
bomba_led <= '0';
indica_on <= '0';
WHEN B => load <= "111111111111111";
load_e <= '0';
bomba_led <= '0';
indica_on <= '1';
WHEN C => load <= "010101111111111"; --10 second, this in addition to a 1024 hz clock made posible to use the first 5 bits as the number
load_e <= '1';
bomba_led <= '0';
indica_on <= '1';
WHEN D => load <= "101001111111111"; --20 seconds
load_e <= '1';
bomba_led <= '0';
indica_on <= '1';
WHEN E => load <= "111111111111111";
load_e <= '0';
bomba_led <= '1';
indica_on <= '1';
WHEN F => load <= "111111111111111";
load_e <= '0';
bomba_led <= '1';
indica_on <= '1';
end case;
end process;
end behavioral;
------TOP-----------------------
entity TOP is
Generic(
FIN : positive := 100000000;
FOUT : positive := 1024);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
display_number : out STD_LOGIC_VECTOR (6 downto 0);
display_selection : out STD_LOGIC_VECTOR (7 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end TOP;
architecture Behavioral of TOP is
--instancies
component clk_divider is
-- Port ( );
generic(
FIN : positive;
FOUT : positive
);
port (
Clk : in STD_LOGIC;
Reset : in STD_LOGIC;
Clk_out : out STD_LOGIC
);
end component;
component maquina_estados is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
zero_n : in STD_LOGIC;
counter_loaded : in STD_LOGIC;
load_e : out STD_LOGIC;
load : out STD_LOGIC_VECTOR(14 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end component;
component counter is
Generic (NBITS : positive
);
Port (clk : in STD_LOGIC;
rst : in STD_LOGIC;
ce : in STD_LOGIC;
load : in STD_LOGIC_VECTOR (NBITS-1 downto 0);
load_e : in STD_LOGIC;
unit : out STD_LOGIC_VECTOR(3 downto 0);
dec : out STD_LOGIC_VECTOR(3 downto 0);
zero_n : out STD_LOGIC;
loaded : out STD_LOGIC);
end component;
component clk_manager is
generic(
CLK_FREQ : positive
);
Port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
strobe_1024Hz : out STD_LOGIC;
strobe_128Hz : out STD_LOGIC
);
end component;
component decoder is
Port ( code : in STD_LOGIC_VECTOR(3 downto 0);
led : out STD_LOGIC_vector(6 downto 0)
);
end component;
component display_refresh is
Port ( clk : in STD_LOGIC;
ce : in STD_LOGIC;
segment_unit : in STD_LOGIC_VECTOR (6 downto 0);
segment_dec : in STD_LOGIC_VECTOR (6 downto 0);
display_number : out STD_LOGIC_VECTOR (6 downto 0);
display_selection : out STD_LOGIC_VECTOR (1 downto 0)); --cada elemento del vector corresponde a un 7 seg, true se ve false no
end component;
-- prescaler signals
signal prescaler_clk_out : STD_LOGIC;
--maquina estados signals
signal zero_n_fsm : STD_LOGIC;
signal load_e_fsm : STD_LOGIC;
signal load_fsm : STD_LOGIC_VECTOR(14 downto 0);
signal bomba_led_fsm: STD_LOGIC;
--counter signals
signal unit : STD_LOGIC_VECTOR(3 downto 0);
signal dec : STD_LOGIC_VECTOR(3 downto 0);
signal zero_n_cntr : STD_LOGIC;
signal load_e_cntr : STD_LOGIC;
signal load_cntr : STD_LOGIC_VECTOR(14 downto 0);
signal counter_loaded : STD_LOGIC;
--clk_manager signals
signal strobe_1024Hz : STD_LOGIC;
signal strobe_128Hz : STD_LOGIC;
signal ce_clkm : STD_LOGIC;
signal rst_clkm : STD_LOGIC;
--decoders signals
signal unit_code : STD_LOGIC_VECTOR(6 downto 0);
signal dec_code : STD_LOGIC_VECTOR(6 downto 0);
--display refresh signals
signal display_refresh_number : STD_LOGIC_VECTOR(6 downto 0);
signal display_refresh_selection : STD_LOGIC_VECTOR(1 downto 0);
begin
prescaler: clk_divider
generic map(
FIN => FIN,
FOUT => FOUT
)
port map(
Clk => clk,
Reset => rst,
Clk_out => prescaler_clk_out
);
sm: maquina_estados
Port map( clk => prescaler_clk_out,
rst => rst,
corto => corto,
largo => largo,
b_on => b_on,
zero_n => zero_n_fsm,
counter_loaded => counter_loaded,
load_e => load_e_fsm,
load => load_fsm,
bomba_led => bomba_led_fsm,
indica_on => indica_on);
cntr: counter
Generic map(NBITS => 15
)
Port map(clk => clk,
rst => rst,
ce => strobe_1024Hz,
load => load_cntr,
load_e => load_e_fsm,
unit => unit,
dec => dec,
zero_n => zero_n_cntr,
loaded => counter_loaded);
clk_m: clk_manager
generic map(
CLK_FREQ => FIN
)
Port map(
clk => clk,
rst => rst,
strobe_1024Hz => strobe_1024Hz,
strobe_128Hz => strobe_128Hz
);
unit_dcd: decoder
Port map(
code => unit,
led => unit_code
);
dec_dcd: decoder
Port map(
code => dec,
led => dec_code
);
dr: display_refresh
Port map(
clk => clk,
ce => strobe_128Hz,
segment_unit => unit_code,
segment_dec => dec_code,
display_number => display_refresh_number,
display_selection => display_refresh_selection);
display_number <= display_refresh_number WHEN bomba_led_fsm = '1' ELSE "1111111";
display_selection <= ("111111" & display_refresh_selection) WHEN bomba_led_fsm = '1' ELSE "11111111";
zero_n_fsm <= zero_n_cntr;
bomba_led <= bomba_led_fsm;
load_cntr <= load_fsm;
end Behavioral;
以下是实施和综合给我的所有报告:
Synthesis reports
implementation reports 1/6
implementation reports 2/6
implementation reports 3/6
implementation reports 4/6
implementation reports 5/6
implementation reports 6/6
我希望有人能找到问题并给我解决方案或调试此问题的方法。
谢谢。
您的 FSM 计时为 prescaler_clk_out
,您的计数器计时为 clk
,这是一个危险信号。这很容易导致实施失败。
- 画一个时序图显示你所有的时钟和复位,以及你的低频使能(特别是,
strobe_1024Hz
)
- 尝试在同一个时钟上为所有逻辑提供时钟,大概
clk
,并确保一切都与这个时钟同步(换句话说,输入相对于这个时钟有足够的建立和保持时间)
- 确保您确实在重置芯片
完成时序图后,编写一个约束文件,告诉合成器您的时钟是什么。 clk_manager
和 clk_divider
可能是这里的一个问题,但希望一切都只在 'clk' 上计时,并且约束文件将仅包含时钟名称和频率。如果您仍然无法让它工作,请提出一个新问题,显示您的时序图,以及您对约束文件的尝试。
我的 VHDL 代码在功能上是正确的,在模拟中它按照预期的方式工作。我测试了许多变体,代码工作正常。
但是当我对 fpga (Nexyx 4 ddr) 进行编程时,除了计数器的预加载之外,一切都运行良好。
我不知道 fsm 的负载使能 (load_e) 输出是否没有到达计数器,或者表示计数器的输出信号是否已加载 (counter_loaded) '到达 fsm,但是当我对 fpga 进行编程时,它永远不会从状态 C 或 D(等待计数器加载)到状态 E 或 F(它进行倒计时)。
我测试了目标中代码的其他部分并且它工作正常,所以到目前为止唯一的问题是那个,我找不到错误,我正在考虑时间,但我没有如何解决它的想法。
我在这里留下计数器和 fsm 代码,以及 TOP 代码,我是 VHDL 的新手,可能有很多不好的实践错误。
我是西班牙人,这就是我英语不好的原因,也是一些信号的西班牙名称,但我在它们旁边添加了评论。
--------COUNTER---------------------------------------
entity counter is
Generic (NBITS : positive := 15
);
Port (clk : in STD_LOGIC;
rst : in STD_LOGIC;
ce : in STD_LOGIC;
load : in STD_LOGIC_VECTOR (NBITS-1 downto 0);
load_e : in STD_LOGIC;
unit : out STD_LOGIC_VECTOR(3 downto 0);
dec : out STD_LOGIC_VECTOR(3 downto 0);
zero_n : out STD_LOGIC; --true si cuenta = 0
loaded : out STD_LOGIC);
end counter;
architecture Behavioral of counter is
signal q_i : unsigned (NBITS-1 downto 0) := (others => '1');
begin
process(clk,rst)
begin
if rst = '1' then
q_i <= (OTHERS => '1');
loaded <= '0';
elsif rising_edge(clk) then
if CE = '1' then
if load_e = '1' then --ONE OF MY GUESSES OF THE PROBLEM
q_i <= unsigned(load);
loaded <= '1';
else
q_i <= q_i - 1;
loaded <= '0';
end if;
end if;
end if;
end process;
dec <= std_logic_vector(to_unsigned((to_integer(q_i(14 downto 10)) / 10),dec'length)); --first 5 bits are the tens
unit <= std_logic_vector(to_unsigned((to_integer(q_i(14 downto 10)) rem 10),unit'length)); --fist 5 bits are the unit
zero_n <= '1' WHEN q_i < "000010000000000" ELSE '0'; --cout is zero if the first 5 bits are less tan 1 in binary
end Behavioral;
------FINITE STATE MACHINE--------------------------------
entity maquina_estados is
Port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
zero_n : in STD_LOGIC;
counter_loaded : in STD_LOGIC;
load_e : out STD_LOGIC;
load : out STD_LOGIC_VECTOR(14 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end maquina_estados;
architecture Behavioral of maquina_estados is
type state_type is (A, B, C, D, E, F); --define state(A = powered off, B = powered on, C = short coffee preload, D = large coffee preload, E = short coffee, F = large coffee)
signal state, next_state : state_type; --type state signal
begin
process(clk,rst)
begin
if rst = '1' then
state <= A;
elsif rising_edge(clk) then
state <= next_state;
end if;
end process;
process(state, b_on, corto, largo, zero_n, counter_loaded)
begin
CASE state IS
WHEN A => if b_on = '1' then
next_state <= B;
else
next_state <= A;
end if;
WHEN B => if b_on = '0' then
next_state <= A;
elsif corto = '1' then
next_state <= C;
elsif largo = '1' then
next_state <= D;
else
next_state <= B;
end if;
WHEN C => if counter_loaded = '1' then
next_state <= E;
else
next_state <= C;
end if;
WHEN D => if counter_loaded = '1' then
next_state <= F;
else
next_state <= D;
end if;
WHEN E => if zero_n = '1' then
next_state <= B;
else
next_state <= E;
end if;
WHEN F => if zero_n = '1' then
next_state <= B;
else
next_state <= F;
end if;
WHEN OTHERS => next_state <= A;
end case;
end process;
process(state)
begin
CASE state IS
WHEN A => load <= "111111111111111"; --default value of the count
load_e <= '0';
bomba_led <= '0';
indica_on <= '0';
WHEN B => load <= "111111111111111";
load_e <= '0';
bomba_led <= '0';
indica_on <= '1';
WHEN C => load <= "010101111111111"; --10 second, this in addition to a 1024 hz clock made posible to use the first 5 bits as the number
load_e <= '1';
bomba_led <= '0';
indica_on <= '1';
WHEN D => load <= "101001111111111"; --20 seconds
load_e <= '1';
bomba_led <= '0';
indica_on <= '1';
WHEN E => load <= "111111111111111";
load_e <= '0';
bomba_led <= '1';
indica_on <= '1';
WHEN F => load <= "111111111111111";
load_e <= '0';
bomba_led <= '1';
indica_on <= '1';
end case;
end process;
end behavioral;
------TOP-----------------------
entity TOP is
Generic(
FIN : positive := 100000000;
FOUT : positive := 1024);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
display_number : out STD_LOGIC_VECTOR (6 downto 0);
display_selection : out STD_LOGIC_VECTOR (7 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end TOP;
architecture Behavioral of TOP is
--instancies
component clk_divider is
-- Port ( );
generic(
FIN : positive;
FOUT : positive
);
port (
Clk : in STD_LOGIC;
Reset : in STD_LOGIC;
Clk_out : out STD_LOGIC
);
end component;
component maquina_estados is
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC;
corto : in STD_LOGIC;
largo : in STD_LOGIC;
b_on : in STD_LOGIC;
zero_n : in STD_LOGIC;
counter_loaded : in STD_LOGIC;
load_e : out STD_LOGIC;
load : out STD_LOGIC_VECTOR(14 downto 0);
bomba_led : out STD_LOGIC;
indica_on : out STD_LOGIC);
end component;
component counter is
Generic (NBITS : positive
);
Port (clk : in STD_LOGIC;
rst : in STD_LOGIC;
ce : in STD_LOGIC;
load : in STD_LOGIC_VECTOR (NBITS-1 downto 0);
load_e : in STD_LOGIC;
unit : out STD_LOGIC_VECTOR(3 downto 0);
dec : out STD_LOGIC_VECTOR(3 downto 0);
zero_n : out STD_LOGIC;
loaded : out STD_LOGIC);
end component;
component clk_manager is
generic(
CLK_FREQ : positive
);
Port (
clk : in STD_LOGIC;
rst : in STD_LOGIC;
strobe_1024Hz : out STD_LOGIC;
strobe_128Hz : out STD_LOGIC
);
end component;
component decoder is
Port ( code : in STD_LOGIC_VECTOR(3 downto 0);
led : out STD_LOGIC_vector(6 downto 0)
);
end component;
component display_refresh is
Port ( clk : in STD_LOGIC;
ce : in STD_LOGIC;
segment_unit : in STD_LOGIC_VECTOR (6 downto 0);
segment_dec : in STD_LOGIC_VECTOR (6 downto 0);
display_number : out STD_LOGIC_VECTOR (6 downto 0);
display_selection : out STD_LOGIC_VECTOR (1 downto 0)); --cada elemento del vector corresponde a un 7 seg, true se ve false no
end component;
-- prescaler signals
signal prescaler_clk_out : STD_LOGIC;
--maquina estados signals
signal zero_n_fsm : STD_LOGIC;
signal load_e_fsm : STD_LOGIC;
signal load_fsm : STD_LOGIC_VECTOR(14 downto 0);
signal bomba_led_fsm: STD_LOGIC;
--counter signals
signal unit : STD_LOGIC_VECTOR(3 downto 0);
signal dec : STD_LOGIC_VECTOR(3 downto 0);
signal zero_n_cntr : STD_LOGIC;
signal load_e_cntr : STD_LOGIC;
signal load_cntr : STD_LOGIC_VECTOR(14 downto 0);
signal counter_loaded : STD_LOGIC;
--clk_manager signals
signal strobe_1024Hz : STD_LOGIC;
signal strobe_128Hz : STD_LOGIC;
signal ce_clkm : STD_LOGIC;
signal rst_clkm : STD_LOGIC;
--decoders signals
signal unit_code : STD_LOGIC_VECTOR(6 downto 0);
signal dec_code : STD_LOGIC_VECTOR(6 downto 0);
--display refresh signals
signal display_refresh_number : STD_LOGIC_VECTOR(6 downto 0);
signal display_refresh_selection : STD_LOGIC_VECTOR(1 downto 0);
begin
prescaler: clk_divider
generic map(
FIN => FIN,
FOUT => FOUT
)
port map(
Clk => clk,
Reset => rst,
Clk_out => prescaler_clk_out
);
sm: maquina_estados
Port map( clk => prescaler_clk_out,
rst => rst,
corto => corto,
largo => largo,
b_on => b_on,
zero_n => zero_n_fsm,
counter_loaded => counter_loaded,
load_e => load_e_fsm,
load => load_fsm,
bomba_led => bomba_led_fsm,
indica_on => indica_on);
cntr: counter
Generic map(NBITS => 15
)
Port map(clk => clk,
rst => rst,
ce => strobe_1024Hz,
load => load_cntr,
load_e => load_e_fsm,
unit => unit,
dec => dec,
zero_n => zero_n_cntr,
loaded => counter_loaded);
clk_m: clk_manager
generic map(
CLK_FREQ => FIN
)
Port map(
clk => clk,
rst => rst,
strobe_1024Hz => strobe_1024Hz,
strobe_128Hz => strobe_128Hz
);
unit_dcd: decoder
Port map(
code => unit,
led => unit_code
);
dec_dcd: decoder
Port map(
code => dec,
led => dec_code
);
dr: display_refresh
Port map(
clk => clk,
ce => strobe_128Hz,
segment_unit => unit_code,
segment_dec => dec_code,
display_number => display_refresh_number,
display_selection => display_refresh_selection);
display_number <= display_refresh_number WHEN bomba_led_fsm = '1' ELSE "1111111";
display_selection <= ("111111" & display_refresh_selection) WHEN bomba_led_fsm = '1' ELSE "11111111";
zero_n_fsm <= zero_n_cntr;
bomba_led <= bomba_led_fsm;
load_cntr <= load_fsm;
end Behavioral;
以下是实施和综合给我的所有报告:
Synthesis reports
implementation reports 1/6
implementation reports 2/6
implementation reports 3/6
implementation reports 4/6
implementation reports 5/6
implementation reports 6/6
我希望有人能找到问题并给我解决方案或调试此问题的方法。
谢谢。
您的 FSM 计时为 prescaler_clk_out
,您的计数器计时为 clk
,这是一个危险信号。这很容易导致实施失败。
- 画一个时序图显示你所有的时钟和复位,以及你的低频使能(特别是,
strobe_1024Hz
) - 尝试在同一个时钟上为所有逻辑提供时钟,大概
clk
,并确保一切都与这个时钟同步(换句话说,输入相对于这个时钟有足够的建立和保持时间) - 确保您确实在重置芯片
完成时序图后,编写一个约束文件,告诉合成器您的时钟是什么。 clk_manager
和 clk_divider
可能是这里的一个问题,但希望一切都只在 'clk' 上计时,并且约束文件将仅包含时钟名称和频率。如果您仍然无法让它工作,请提出一个新问题,显示您的时序图,以及您对约束文件的尝试。