Hallo nochmal!
Ich habe deinen Code ausprobiert. Folgende Beobachtungen:
- beim 1. Einschalten ist das Blinken besonders langsam (ungefähr nur halb so schnell wie die mit sBtn2_i einstellbare Frequenz) - irgendwas mit der initialisierung der Werte?!?
- durch drücken von Taste 4 wird immer gleich auf die schnellste Blinkrate geschaltet - es wird also vermutlich mehrfach subtrahiert
- manchmal dauert es nach Druck einer Taste extra lange bevor die gewünschte Operation ausgeführt wird - vermutlich Überlauf weil svCnt_s schon weiter ist als der neue gewünschte Endwert
Ich vermute die Sache ist vielleicht nicht so synthetisierbar wie beabsichtigt. Der Prozess DetectSpeed ist als kombinatorischer Prozess angegeben aber der Ausdruck
iTimeCnt_s <= iTimeCnt_s - 12500000;
ist wohl nicht rein kombinatorisch sondern bezieht sich auf den eigenen früheren Wert. Wenn ich das richtig verstehe darf sowas nur in getakteten Prozessen vorkommen da nur dann das vorher und nachher eindeutig geregelt ist.
Quelle: Grundregeln für synthetisierbaren VHDL-Code
Wenn man das Ändern der Blinkfrequenz mit in den Clock Prozess stopft wird es zwar unübersichtlich - aber es scheint zu funktionieren..
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity blinky_tast_top is
port (
sClk_i : in std_logic;
sBtn0_i, sBtn1_i, sBtn2_i, sBtn3_i : in std_logic;
sLed_o : out std_logic
);
end;
architecture rtl of blinky_tast_top is
-- signals -------------------------------------------------------------------------
signal svCnt_s : integer range 0 to 99999999 := 0;
signal iTimeCnt_s : integer range 0 to 99999999 := 50000000;
signal sLed_s : std_logic :='0';
signal sBtn3_s : std_logic :='1'; -- remember last state of sBtn3_i in sBtn3_s
begin
---==Toggle the LEDs and change the blinking frequency by Button input==---
Toggle: process(sClk_i) -- sClk_i -> 50Mhz
begin
if rising_edge(sClk_i) then
svCnt_s <= svCnt_s + 1; -- every clock cycle -> increment
if svCnt_s = iTimeCnt_s then -- After several Time (iTimeCnt_s):
svCnt_s <= 0; -- -> reset counter
sLed_s <= not sLed_s; -- -> toggle LED
end if;
-- change the blinking frequency by Button input:
if (sBtn0_i = '0') then
iTimeCnt_s <= 12500000;
elsif (sBtn1_i = '0') then
iTimeCnt_s <= 25000000;
elsif (sBtn2_i = '0') then
iTimeCnt_s <= 50000000;
elsif (sBtn3_i = '0') and (iTimeCnt_s > 12500000) and (sBtn3_s = '1') then
iTimeCnt_s <= iTimeCnt_s - 12500000;
end if;
sBtn3_s <= sBtn3_i; -- remember last state of sBtn3_i
-- fix the issue with casual counter overflow:
if (sBtn3_i and sBtn2_i and sBtn1_i and sBtn0_i) = '0' then
svCnt_s <= 0; -- -> reset counter on any button input
end if;
end if;
end process;
sLed_o <= sLed_s;
end;
Lesezeichen