这段代码应该(而且)非常简单,我不知道我做错了什么。 以下是它应该做的描述:
它应该在一个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启动板上尝试过这种设计并且它无法工作......每次按下按钮,我都会疯狂(随机)值。重置按钮工作正常。 谢谢!!!!
答案 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;
我知道我没有尝试过代码(只是在这里编写),但我认为没问题。