任何人都可以帮我解决这个VHDL代码(目前出现故障)?

时间:2012-02-20 18:12:15

标签: vhdl

这段代码应该(而且)非常简单,我不知道我做错了什么。 以下是它应该做的描述:

它应该在一个7段显示器上显示一个数字。每当有人按下按钮时,该数字应增加1。还有重置按钮,将数字设置为0.就是这样。这是VHDL代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity PWM is
    Port ( cp_in : in  STD_LOGIC;
           inc : in  STD_LOGIC;
              rst: in std_logic;
           AN : out  STD_LOGIC_VECTOR (3 downto 0);
           segments : out  STD_LOGIC_VECTOR (6 downto 0));
end PWM;

architecture Behavioral of PWM is
    signal cp: std_logic;

    signal CurrentPWMState: integer range 0 to 10;
    signal inco: std_logic;
    signal temp: std_logic_vector (3 downto 0);
begin
    --cp = 100 Hz
    counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp);
    debounce: entity debounce port map (inc, cp, inco);
    temp <= conv_std_logic_vector(CurrentPWMState, 4);
    ss: entity decoder7seg port map (temp, segments);

    process (inco, rst)
    begin
        if inco = '1' then
            CurrentPWMState <= CurrentPWMState + 1;
        elsif rst='1' then
            CurrentPWMState <= 0;
        end if;
    end process;

    AN <= "1110";
end Behavioral;

实体djelitelj(用于划分50MHz时钟的计数器):

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity PWM is
    Port ( cp_in : in  STD_LOGIC;
           inc : in  STD_LOGIC;
              rst: in std_logic;
           AN : out  STD_LOGIC_VECTOR (3 downto 0);
           segments : out  STD_LOGIC_VECTOR (6 downto 0));
end PWM;

architecture Behavioral of PWM is
    signal cp: std_logic;

    signal CurrentPWMState: integer range 0 to 10;
    signal inco: std_logic;
    signal temp: std_logic_vector (3 downto 0);
begin
    --cp = 100 Hz
    counter: entity djelitelj generic map (CountTo => 250000) port map (cp_in, cp);
    debounce: entity debounce port map (inc, cp, inco);
    temp <= conv_std_logic_vector(CurrentPWMState, 4);
    ss: entity decoder7seg port map (temp, segments);

    process (inco, rst)
    begin
        if inco = '1' then
            CurrentPWMState <= CurrentPWMState + 1;
        elsif rst='1' then
            CurrentPWMState <= 0;
        end if;
    end process;

    AN <= "1110";
end Behavioral;

辩论实体:

library IEEE;
use  IEEE.STD_LOGIC_1164.all;
use  IEEE.STD_LOGIC_ARITH.all;
use  IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY debounce IS
    PORT(pb, clock_100Hz : IN    STD_LOGIC;
         pb_debounced     : OUT    STD_LOGIC);
END debounce;

ARCHITECTURE a OF debounce IS
    SIGNAL SHIFT_PB : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN

-- Debounce Button: Filters out mechanical switch bounce for around 40Ms.
-- Debounce clock should be approximately 10ms
process 
begin
  wait until (clock_100Hz'EVENT) AND (clock_100Hz = '1');
      SHIFT_PB(2 Downto 0) <= SHIFT_PB(3 Downto 1);
      SHIFT_PB(3) <= NOT PB;
      If SHIFT_PB(3 Downto 0)="0000" THEN
        PB_DEBOUNCED <= '1';
      ELSE 
        PB_DEBOUNCED <= '0';
      End if;
end process;
end a;

这是BCD到7段解码器:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity decoder7seg is
    port (
        bcd: in std_logic_vector (3 downto 0);
        segm: out std_logic_vector (6 downto 0));
end decoder7seg;

architecture Behavioral of decoder7seg is
begin
    with bcd select
        segm<= "0000001" when "0000", -- 0
        "1001111" when "0001",        -- 1
        "0010010" when "0010",        -- 2
        "0000110" when "0011",        -- 3
        "1001100" when "0100",        -- 4
        "0100100" when "0101",        -- 5
        "0100000" when "0110",        -- 6
        "0001111" when "0111",        -- 7
        "0000000" when "1000",        -- 8
        "0000100" when "1001",        -- 9
        "1111110" when others;        -- just - character

end Behavioral;

有没有人知道我犯了哪些错误? 我在Spartan-3启动板上尝试过这种设计并且它无法工作......每次按下按钮,我都会疯狂(随机)值。重置按钮工作正常。 谢谢!!!!

2 个答案:

答案 0 :(得分:2)

我想问题出在这里:

process (inco, rst)
begin
    if inco = '1' then
        CurrentPWMState <= CurrentPWMState + 1;
    elsif rst='1' then
        CurrentPWMState <= 0;
    end if;
end process;

rst='1'时,您将重置CurrentPWMState。但是当inco='1'时,您无休止地将1添加到CurrentPWMState。这就像通过锁存器的异步反馈循环。你应该在这里做一些边缘敏感的事。您可能应该使用时钟信号捕获inco,检测0-> 1更改,然后添加1

答案 1 :(得分:1)

同意之前的回答。

这样的代码可以解决这个问题:

process (inco, ps, rst)
begin
  if rst='1' then
    CurrentPWMState <= '0';
    prev_inco <= inco; -- This signal captures the previous value of inco
  elsif ps'event and ps='1' then
    if inco='1' and prev_inco='0' then -- Capture the flank rising.
      CurrentPWMState <= CurrentPWMState + 1;
    end if;
    prev_inco <= inco;
  end if;
end process;

我知道我没有尝试过代码(只是在这里编写),但我认为没问题。