VHDL - XULA,有限状态机

时间:2016-08-09 21:43:33

标签: warnings vhdl state-machine

我有一个XULA2并且正在学习一些教程,并且已成功开启和关闭LED闪光灯。现在我正在尝试继续前进并实现一个状态机(基本上做同样的事情 - 现在)并且收到一些警告,最终构建无法生成输出文件。

错误的形式(为清楚起见,删除了一些类似的警告):

WARNING:Xst:1710 - FF/Latch <wait_time_msec_7> (without init value) has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1710 - FF/Latch <wait_time_msec_8> (without init value) has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process...
WARNING:Xst:1710 - FF/Latch <wait_time_msec_15> (without init value) has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1293 - FF/Latch <fsm_display_1> has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1293 - FF/Latch <fsm_display_0> has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1293 - FF/Latch <cntr_time_delay_19> has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process....
WARNING:Xst:1293 - FF/Latch <cntr_time_delay_0> has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1710 - FF/Latch <wait_time_msec_9> (without init value) has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process....
WARNING:Xst:1710 - FF/Latch <wait_time_msec_0> (without init value) has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <blinker_o> (without init value) has a constant value of 0 in block <BigDisplayMain>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1898 - Due to constant pushing, FF/Latch <return_state_0> is unconnected in block <BigDisplayMain>.

我粗略地理解为什么未使用的值可能会产生一些修剪过的FF,所以那些不会打扰我......很多(我确实对此有疑问,但后来我的主要问题解决了)

我的代码的快速解释是它是一个状态机,有4个状态 - INIT, START0, START1 and DELAY。我想要发生的是设备从INIT开始,然后继续从START0DELAYSTART1DELAY然后返回到START0等,沿途切换信号到LED(通过blinker_o)。当然,这是一种比试图使LED闪烁所必需的更复杂的方法,但这是一个学术练习,因为我学习如何做一个更复杂的任务,围绕使用DELAY状态。

无论如何,编译器总结blinker_o被硬连线到'0'(在WARNING:Xst:1895)。当然这不是我想要的!

我尽可能地删除了我的代码以说明问题(除了留下“重置”信号)

感谢您的时间和帮助!

以下是代码:

----------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity BigDisplayMain is
    port (         clk_i : in   std_logic;
               blinker_o : out  std_logic
         );
end BigDisplayMain;

architecture Behavioral of BigDisplayMain is

signal       clk_1MHZ  : std_logic;
signal           reset : std_logic := '0';
signal  wait_time_msec : natural range 0 to 1_000_000;
signal cntr_time_delay : natural range 0 to 1_000_000;

type fsmA is (
FSM_INIT, FSM_STATE_DISPLAY_START0, FSM_STATE_DISPLAY_START1, FSM_STATE_DELAY
);
signal fsm_display  : fsmA;
signal return_state : fsmA;

begin
   -- DCM_CLKGEN: Frequency Aligned Digital Clock Manager
   --             Spartan-6
   -- Xilinx HDL Language Template, version 14.7

   reset <= '0';

   DCM_CLKGEN_inst : DCM_SP
   generic map (
      CLKFX_DIVIDE => 24,        -- Divide value - D - (1-256)
      CLKFX_MULTIPLY => 2       -- Multiply value - M - (2-256)
   )
   port map (
      CLKFX => clk_1MHZ,         -- 1-bit output: Generated clock output
      CLKIN => clk_i,         -- 1-bit input: Input clock
      RST => '0'              -- 1-bit input: Reset input pin
   );

   -- End of DCM_CLKGEN_inst instantiation

process(clk_1MHz, reset) is
begin
    if reset = '1' then
        cntr_time_delay <= 0;
        fsm_display <= FSM_INIT;
        wait_time_msec <= 0;
        blinker_o <= '0';

    elsif rising_edge(clk_1MHZ) then
        case fsm_display is
            when FSM_INIT => 
                cntr_time_delay <= 0;
                wait_time_msec <= 0;
                return_state <= FSM_STATE_DISPLAY_START0;

            when FSM_STATE_DISPLAY_INIT_START0 =>
                blinker_o <= '0';
                wait_time_msec <= 1_000_000;
                return_state <= FSM_STATE_DISPLAY_START1;
                fsm_display <= FSM_STATE_DELAY;

            when FSM_STATE_DISPLAY_INIT_START1 =>
                blinker_o <= '1';
                wait_time_msec <= 999_999;
                return_state <= FSM_STATE_DISPLAY_START0;
                fsm_display <= FSM_STATE_DELAY;

            when FSM_STATE_DELAY =>
                if cntr_time_delay >= wait_time_msec then
                    fsm_display <= return_state;
                    cntr_time_delay <= 0;
                else
                    cntr_time_delay <= cntr_time_delay + 1;
                    fsm_display <= FSM_STATE_DELAY;
                end if;

            when others =>
                null;
        end case;

    end if;     
end process;
end Behavioral;

1 个答案:

答案 0 :(得分:1)

您似乎没有模拟此设计。

我在选项中分析了它和枚举名称:

            when FSM_STATE_DISPLAY_INIT_START0 =>

            when FSM_STATE_DISPLAY_INIT_START1 =>

不在fsma类型的声明中:

type fsmA is (
FSM_INIT, FSM_STATE_DISPLAY_START0, FSM_STATE_DISPLAY_START1,  FSM_STATE_DELAY
);

我更正了选择以匹配声明的fsma状态并注释掉实例化的组件,将clk_i分配给clk_1MHZ并编写了一个小型测试平台:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- use IEEE.NUMERIC_STD.ALL;
--
-- library UNISIM;
-- use UNISIM.VComponents.all;

entity BigDisplayMain is
    port ( 
        clk_i:      in   std_logic;
        -- reset:      in   std_logic;
        blinker_o:  out  std_logic
         );
end BigDisplayMain;

architecture Behavioral of BigDisplayMain is

signal       clk_1MHZ:   std_logic;
signal           reset:  std_logic := '0'; -- COMMENT out if driven by testbench
signal  wait_time_msec:  natural range 0 to 1_000_000;
signal cntr_time_delay:  natural range 0 to 1_000_000;

type fsmA is (
    FSM_INIT, 
    FSM_STATE_DISPLAY_START0, 
    FSM_STATE_DISPLAY_START1, 
    FSM_STATE_DELAY
);
signal fsm_display:   fsmA;
signal return_state:  fsmA;

begin
   -- DCM_CLKGEN: Frequency Aligned Digital Clock Manager
   --             Spartan-6
   -- Xilinx HDL Language Template, version 14.7

   reset <= '0';  -- COMMENT out if driven by test bench

   -- DCM_CLKGEN_inst:  DCM_SP
   -- generic map (
   --    CLKFX_DIVIDE => 24,        -- Divide value - D - (1-256)
   --    CLKFX_MULTIPLY => 2       -- Multiply value - M - (2-256)
   -- )
   -- port map (
   --    CLKFX => clk_1MHZ,         -- 1-bit output: Generated clock output
   --    CLKIN => clk_i,         -- 1-bit input: Input clock
   --    RST => '0'              -- 1-bit input: Reset input pin
   -- );

   -- End of DCM_CLKGEN_inst instantiation

   clk_1MHZ <= clk_i;  -- ADDED debug

    process(clk_1MHz, reset) is
    begin
        if reset = '1' then
            cntr_time_delay <= 0;
            fsm_display <= FSM_INIT;
            wait_time_msec <= 0;
            blinker_o <= '0';

        elsif rising_edge(clk_1MHZ) then
            case fsm_display is
                when FSM_INIT => 
                    cntr_time_delay <= 0;
                    wait_time_msec <= 0;
                    return_state <= FSM_STATE_DISPLAY_START0;
                    fsm_display <= FSM_STATE_DELAY; -- ADDED branch

                when FSM_STATE_DISPLAY_START0 => -- REMOVED _INIT
                    blinker_o <= '0';
                    wait_time_msec <= 10; -- 1_000_000; -- FOR SIMULATION
                    return_state <= FSM_STATE_DISPLAY_START1;
                    fsm_display <= FSM_STATE_DELAY;

                when FSM_STATE_DISPLAY_START1 => -- REMOVED _INIT
                    blinker_o <= '1';
                    wait_time_msec <= 9; -- 999_999;  -- FOR SIMULTION
                    return_state <= FSM_STATE_DISPLAY_START0;
                    fsm_display <= FSM_STATE_DELAY;

                when FSM_STATE_DELAY =>
                    if cntr_time_delay >= wait_time_msec then
                        fsm_display <= return_state;
                        cntr_time_delay <= 0;
                    else
                        cntr_time_delay <= cntr_time_delay + 1;
                        fsm_display <= FSM_STATE_DELAY;
                    end if;
                when others =>
                    null;
            end case;
        end if;     
    end process;
end architecture Behavioral;

library ieee;
use ieee.std_logic_1164.all;

entity bigdisplaymain_tb is
end entity;

architecture foo of bigdisplaymain_tb is
    signal clk_i:       std_logic := '0';
    -- signal reset:       std_logic := '0';
    signal blinker_o:   std_logic;
begin
CLOCK:
    process
    begin
        wait for 500 ns;
        clk_i <= not clk_i;
        if now > 120 us then
            wait;
        end if;
    end process;

    DUT:
        entity work.bigdisplaymain 
            port map (
                clk_i => clk_i,
                -- reset => reset,
                blinker_o => blinker_o
            );

-- STIMULI:
--     process
--     begin
--         wait for 1 us;
--         reset <= '1';
--         wait for 1 us;
--         reset <= '0';
--         wait;
--     end process;

end architecture;

最重要的是,我将状态FSM_INIT的分支添加到STATE_DELAY:

                when FSM_INIT => 
                    cntr_time_delay <= 0;
                    wait_time_msec <= 0;
                    return_state <= FSM_STATE_DISPLAY_START0;
                    fsm_display <= FSM_STATE_DELAY; -- ADDED branch

如果没有这个分支,它就会坐在那里。

将时间延迟缩短为9和10会产生:

bigdisplaymain_tb.png

状态FSM_INIT可能缺少的分支负责所有综合警告和触发器被吃掉。它们都没有被使用,blinker_o将是重置值(假设实际使用了重置)。