【问题标题】:Can anyone help me with this VHDL code (currently malfunctioning)?谁能帮我处理这个 VHDL 代码(目前出现故障)?
【发布时间】:2012-02-20 18:12:14
【问题描述】:

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

它应该在一个 7 段显示器上显示一个数字。每当有人按下按钮时,该数字应增加一。还有一个重置按钮,将数字设置为 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 Started 板上尝试过这种设计,但它不起作用......每次按下按钮时,我都会得到疯狂的(随机)值。重置按钮工作正常。 谢谢!!!!

【问题讨论】:

  • 你没有提供“djelitelj”,但是你已经粘贴了两次PWM。

标签: vhdl


【解决方案1】:

我猜问题出在这里:

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

【讨论】:

    【解决方案2】:

    同意前面的回答。

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

    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;
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 2011-05-03
      • 2019-08-28
      • 2015-08-28
      • 2022-11-21
      相关资源
      最近更新 更多