todo
17.09.2009, 11:22
Hallo Leute,
ich habe hier meine ersten Schritte in VHDL gepostet. Das Programm lässt eine LED mit verschiedenen Frequenzen (je nach Tastereingabe blinken).
Drückt man Taster 1 (sBtn0_i), Taster 2 (sBtn1_i) oder Taster 3 (sBtn2_i), dann blinkt die LED entweder mit 0,125Hz, 0,25Hz, oder 0,5 Hz.
Haupt-Entity mit eigentlichem Blink-Prozess ganz am Ende ist:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity blinky_tast_top is
generic (
iTWaitDebounce : integer range 0 to 99999999 := 50000
);
port (
sClk_i : in std_logic;
sBtn0_i, sBtn1_i, sBtn2_i : in std_logic;
sLed_o : out std_logic
);
end;
architecture rtl of blinky_tast_top is
-- components -----------------------------------------------------------------------
component debouncer
generic (
iTWait : integer range 0 to 99999999
);
port (
sClk_i, sRst_i : in std_logic;
sPb_i : in std_logic;
sPb_debounced_o : out std_logic
);
end component;
-- signals -------------------------------------------------------------------------
signal sCnt_s : std_logic_vector(27 downto 0) := x"0000000";
signal sLed_s : std_logic :='0';
signal iTimeCnt_s : integer range 0 to 99999999 := 50000000;
signal sBtn0_s, sBtn1_s, sBtn2_s : std_logic := '1';
begin
---===============================Debounce Button 1===============================---
DebounceBtn0: debouncer
generic map (
iTWait => iTWaitDebounce
)
port map (
sClk_i => sClk_i,
sRst_i => 'L', -- Reset not required -> always "low"
sPb_i => sBtn0_i,
sPb_debounced_o => sBtn0_s
);
---===============================Debounce Button 2===============================---
DebounceBtn1: debouncer
generic map (
iTWait => iTWaitDebounce
)
port map (
sClk_i => sClk_i,
sRst_i => 'L', -- Reset not required -> always "low"
sPb_i => sBtn1_i,
sPb_debounced_o => sBtn1_s
);
---===============================Debounce Button 3===============================---
DebounceBtn2: debouncer
generic map (
iTWait => iTWaitDebounce
)
port map (
sClk_i => sClk_i,
sRst_i => 'L', -- Reset not required -> always "low"
sPb_i => sBtn2_i,
sPb_debounced_o => sBtn2_s
);
---================Change the blinking frequency by Button input==================---
DetectSpeed: process(sClk_i)
begin
if (sBtn0_s = '0') then
iTimeCnt_s <= 12500000;
elsif (sBtn1_s = '0') then
iTimeCnt_s <= 25000000;
elsif (sBtn2_s = '0') then
iTimeCnt_s <= 50000000;
end if;
end process;
---===============================Toggle the LEDs=================================---
Toggle: process(sClk_i) -- sClk_i -> 50Mhz
begin
if rising_edge(sClk_i) then
sCnt_s <= sCnt_s + 1; -- every clock cycle -> increment
if sCnt_s = iTimeCnt_s then -- increment until count = 12500000 (Btn0)or 25000000 (Btn1) or 50000000 (Btn2)
sCnt_s <= (others=>'0'); -- reset counter
sLed_s <= not sLed_s; -- toggle LED
end if;
end if;
end process;
sLed_o <= sLed_s;
end;
Und die Entity der Entprell-Routine:
library ieee;
use ieee.std_logic_1164.all;
entity debouncer is
generic (
iTWait : integer range 0 to 99999999
);
port (
sClk_i, sRst_i : in std_logic; -- clk frequency = 50Mhz
sPb_i : in std_logic;
sPb_debounced_o : out std_logic
);
end entity debouncer;
architecture rtl of debouncer is
-- signals ------------------------------------------------------------------------
signal iCntWait_s : integer range 0 to 99999999;
signal sClkDiv_s : std_logic;
signal sPb_sampled_s : std_logic;
begin
---===============================Divide Frequency===============================---
DivideFrequency: process(sClk_i, sRst_i)
begin
if sRst_i = '1' then
sClkDiv_s <= '0';
iCntWait_s <= 0;
elsif rising_edge(sClk_i) then
if iCntWait_s = iTWait then
iCntWait_s <= 0;
sClkDiv_s <= '1';
else
iCntWait_s <= iCntWait_s + 1;
sClkDiv_s <= '0';
end if;
end if;
end process DivideFrequency;
---============================Debounce Push Button===============================---
debounce_pb: process(sClk_i) is
begin
if rising_edge(sClk_i) then
if sClkDiv_s='1' then
if sPb_i = sPb_sampled_s then
sPb_debounced_o <= sPb_i;
end if;
end if;
sPb_sampled_s <= sPb_i;
end if;
end process debounce_pb;
end architecture rtl;
Wenn ich den Button 3 (sBtn2_i) drücke, verharrt die LED 5 s (also eine Ewigkeit, wenn man bedenkt, dass der Eingangstakt 50 MHz beträgt) in ihrem Zustand, bevor sie die Dem Knopfdruck entsprechende Frequenz annimmt. Dies passiert aber nur wenn ich gerade diesen Button drücke. Bei den anderen kommt dies nicht vor und ich kann mir dieses Verhalten nicht erklären.
Weiß jemand, woran dies liegen könnte, oder wo ich nach dem Fehler suchen kann.
Ich würde mich freuen, wenn vielleicht ein erfahrener VHDL-Programmierer prinzipiell seine Meinung zum Code abgeben könnte. Wie gesagt, es ist mein erster!
ich habe hier meine ersten Schritte in VHDL gepostet. Das Programm lässt eine LED mit verschiedenen Frequenzen (je nach Tastereingabe blinken).
Drückt man Taster 1 (sBtn0_i), Taster 2 (sBtn1_i) oder Taster 3 (sBtn2_i), dann blinkt die LED entweder mit 0,125Hz, 0,25Hz, oder 0,5 Hz.
Haupt-Entity mit eigentlichem Blink-Prozess ganz am Ende ist:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity blinky_tast_top is
generic (
iTWaitDebounce : integer range 0 to 99999999 := 50000
);
port (
sClk_i : in std_logic;
sBtn0_i, sBtn1_i, sBtn2_i : in std_logic;
sLed_o : out std_logic
);
end;
architecture rtl of blinky_tast_top is
-- components -----------------------------------------------------------------------
component debouncer
generic (
iTWait : integer range 0 to 99999999
);
port (
sClk_i, sRst_i : in std_logic;
sPb_i : in std_logic;
sPb_debounced_o : out std_logic
);
end component;
-- signals -------------------------------------------------------------------------
signal sCnt_s : std_logic_vector(27 downto 0) := x"0000000";
signal sLed_s : std_logic :='0';
signal iTimeCnt_s : integer range 0 to 99999999 := 50000000;
signal sBtn0_s, sBtn1_s, sBtn2_s : std_logic := '1';
begin
---===============================Debounce Button 1===============================---
DebounceBtn0: debouncer
generic map (
iTWait => iTWaitDebounce
)
port map (
sClk_i => sClk_i,
sRst_i => 'L', -- Reset not required -> always "low"
sPb_i => sBtn0_i,
sPb_debounced_o => sBtn0_s
);
---===============================Debounce Button 2===============================---
DebounceBtn1: debouncer
generic map (
iTWait => iTWaitDebounce
)
port map (
sClk_i => sClk_i,
sRst_i => 'L', -- Reset not required -> always "low"
sPb_i => sBtn1_i,
sPb_debounced_o => sBtn1_s
);
---===============================Debounce Button 3===============================---
DebounceBtn2: debouncer
generic map (
iTWait => iTWaitDebounce
)
port map (
sClk_i => sClk_i,
sRst_i => 'L', -- Reset not required -> always "low"
sPb_i => sBtn2_i,
sPb_debounced_o => sBtn2_s
);
---================Change the blinking frequency by Button input==================---
DetectSpeed: process(sClk_i)
begin
if (sBtn0_s = '0') then
iTimeCnt_s <= 12500000;
elsif (sBtn1_s = '0') then
iTimeCnt_s <= 25000000;
elsif (sBtn2_s = '0') then
iTimeCnt_s <= 50000000;
end if;
end process;
---===============================Toggle the LEDs=================================---
Toggle: process(sClk_i) -- sClk_i -> 50Mhz
begin
if rising_edge(sClk_i) then
sCnt_s <= sCnt_s + 1; -- every clock cycle -> increment
if sCnt_s = iTimeCnt_s then -- increment until count = 12500000 (Btn0)or 25000000 (Btn1) or 50000000 (Btn2)
sCnt_s <= (others=>'0'); -- reset counter
sLed_s <= not sLed_s; -- toggle LED
end if;
end if;
end process;
sLed_o <= sLed_s;
end;
Und die Entity der Entprell-Routine:
library ieee;
use ieee.std_logic_1164.all;
entity debouncer is
generic (
iTWait : integer range 0 to 99999999
);
port (
sClk_i, sRst_i : in std_logic; -- clk frequency = 50Mhz
sPb_i : in std_logic;
sPb_debounced_o : out std_logic
);
end entity debouncer;
architecture rtl of debouncer is
-- signals ------------------------------------------------------------------------
signal iCntWait_s : integer range 0 to 99999999;
signal sClkDiv_s : std_logic;
signal sPb_sampled_s : std_logic;
begin
---===============================Divide Frequency===============================---
DivideFrequency: process(sClk_i, sRst_i)
begin
if sRst_i = '1' then
sClkDiv_s <= '0';
iCntWait_s <= 0;
elsif rising_edge(sClk_i) then
if iCntWait_s = iTWait then
iCntWait_s <= 0;
sClkDiv_s <= '1';
else
iCntWait_s <= iCntWait_s + 1;
sClkDiv_s <= '0';
end if;
end if;
end process DivideFrequency;
---============================Debounce Push Button===============================---
debounce_pb: process(sClk_i) is
begin
if rising_edge(sClk_i) then
if sClkDiv_s='1' then
if sPb_i = sPb_sampled_s then
sPb_debounced_o <= sPb_i;
end if;
end if;
sPb_sampled_s <= sPb_i;
end if;
end process debounce_pb;
end architecture rtl;
Wenn ich den Button 3 (sBtn2_i) drücke, verharrt die LED 5 s (also eine Ewigkeit, wenn man bedenkt, dass der Eingangstakt 50 MHz beträgt) in ihrem Zustand, bevor sie die Dem Knopfdruck entsprechende Frequenz annimmt. Dies passiert aber nur wenn ich gerade diesen Button drücke. Bei den anderen kommt dies nicht vor und ich kann mir dieses Verhalten nicht erklären.
Weiß jemand, woran dies liegen könnte, oder wo ich nach dem Fehler suchen kann.
Ich würde mich freuen, wenn vielleicht ein erfahrener VHDL-Programmierer prinzipiell seine Meinung zum Code abgeben könnte. Wie gesagt, es ist mein erster!