VHDL - 我的代码是可综合的,并且在模拟时可以按照我想要的方式工作,但它并不适用于fpga

时间:2017-12-16 13:15:34

标签: vhdl 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

我希望有人可以找到问题,并给我一个解决方案或如何调试此问题的方法。

感谢。

1 个答案:

答案 0 :(得分:1)

您的FSM的时钟频率为prescaler_clk_out,而您的计数器的时钟频率为clk,这是一个红旗。这很容易导致实施失败。

  • 绘制一个时序图,显示所有时钟和重置,以及您的低频启用(特别是strobe_1024Hz
  • 尝试在同一时钟上计时所有逻辑,大概是clk,并确保一切都与此时钟同步(换句话说,输入相对于此时钟有足够的设置和保持时间)
  • 确保您实际上正在重置芯片

完成时序图后,编写一个约束文件,告诉合成器你的时钟是什么。 clk_managerclk_divider可能是一个问题,但希望所有内容都只是'clk',而contstraints文件只包含时钟名称和频率。如果您仍然无法使其工作,请提出一个新问题,显示您的时序图以及您对约束文件的尝试。