我的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;
以下是实施和合成给我的所有报告:
我希望有人可以找到问题,并给我一个解决方案或如何调试此问题的方法。
感谢。
答案 0 :(得分:1)
您的FSM的时钟频率为prescaler_clk_out
,而您的计数器的时钟频率为clk
,这是一个红旗。这很容易导致实施失败。
strobe_1024Hz
)clk
,并确保一切都与此时钟同步(换句话说,输入相对于此时钟有足够的设置和保持时间)完成时序图后,编写一个约束文件,告诉合成器你的时钟是什么。 clk_manager
和clk_divider
可能是一个问题,但希望所有内容都只是'clk',而contstraints文件只包含时钟名称和频率。如果您仍然无法使其工作,请提出一个新问题,显示您的时序图以及您对约束文件的尝试。