Wie erstelle ich ein Lauflicht in VHDL am besten/einfachsten/sinngemässesten? Die Hardware kann ich mir vorstellen (Counter mit D-FlipFlops). Doch um das in VHDL umzusetzen, fehlt mir irgendwie die nötige Kenntnis. Dieses Lauflicht soll dann mal immer laufen. Als Chip habe ich einen XC2C256 und einen 40MHz Clock. Ich möchte keine fixfertige Lösung, eher einen Tipp. Gruss
Verwende ein Schieberegister. Jedes Bit steht für eine LED. So kannst du ein beliebiges Muster durchschieben. Getaktet wird das Schieberegister dann von einem Taktteiler, der die System-Clock auf einen vernünftigen Wert hinunterteilt.
>Verwende ein Schieberegister. Jedes Bit steht für eine LED. So kannst du >ein beliebiges Muster durchschieben. Getaktet wird das Schieberegister >dann von einem Taktteiler, der die System-Clock auf einen vernünftigen >Wert hinunterteilt. So mit dem Schieberegister hab ichs mir überlegt. Nur weiss ich nicht wie programmieren. Den Clock möchte ich nicht mehr teilen (also volle Kanne :)). CLK = 40MHz. Damit das Lauflicht wieder von vorne zu zählen beginnt, muss wohl noch ein Zähler hin. >Das Tutorial/Example zum Webpack? (JohnsonCounter) sorry konnte ich leider nicht finden...ich suchte unter: VHDL\Synthesis Constructs\Cidung Examples\
@ Dave E. (eschlair) >Den Clock möchte ich nicht mehr teilen (also volle Kanne :)). CLK = >40MHz. Und welches Alien soll dann noch ein Lauflicht sehen? Taktung FPGA/CPLD Wobei in diesem Beispiel ein Derived Clock möglich wäre. >Damit das Lauflicht wieder von vorne zu zählen beginnt, muss wohl noch >ein Zähler hin. Richtig. Etwa so.
1 | signal cnt: std_logic_vector(2 downto 0); |
2 | |
3 | process (clk) |
4 | begin
|
5 | if rising_edge(clk) then |
6 | cnt <= cnt+1; |
7 | end if; |
8 | end process; |
9 | |
10 | process(cnt) |
11 | begin
|
12 | case cnt is |
13 | when "000" => led <="00000001"; |
14 | when "000" => led <="00000010"; |
15 | when "000" => led <="00000100"; |
16 | when "000" => led <="00001000"; |
17 | when "000" => led <="00010000"; |
18 | when "000" => led <="00100000"; |
19 | when "000" => led <="01000000"; |
20 | when "000" => led <="10000000"; |
21 | when others => null; |
22 | end case; |
23 | end process; |
MFG Falk
Alternativ: Zähler um den Takt runterzuteilen, und dann ein Ring-Schieberegister.
Aber wie geht so ein Ringschieberegister (nur alternativ - vielen Dank an Falk :)). >Und welches Alien soll dann noch ein Lauflicht sehen? :)) Also ein 'Lauflicht' war nicht korrekt von mir. Es 'läuft', aber ohne Licht :). Ich möchte nur mal wissen, ob ein CPLD 40MHz schalten kann. Und wie dann so die Flanken aussehen... Falls das Resultat nicht befriedigend ist, könnte ich den Takt teilen (hmm wie ging das schon wieder?) oder hätte sonst noch 3MHz aufm Board. Hab kurzerhand beschlossen, einen Print mit D-Sub und Decoder mit 7-Segment zu löten - mit Schalter. Könnte dann externen Print geben; mit Würfelfunktion. Dank dem Decoder wäre dann nur noch ein Counter bis "0111" nötig. Ein CPLD für einen Würfel...naja. dient ja nur Experimentierzwecken.
Beispiel Ringschieberegister für ein Lauflicht mit 10 LEDs:
1 | entity lauflicht is |
2 | port ( |
3 | clk, reset : in std_logic; |
4 | leds : out std_logic_vector (9 downto 0) |
5 | )
|
6 | end entity; |
7 | |
8 | architecture bla of lauflicht is |
9 | signal state : std_logic_vector (9 downto 0); |
10 | begin
|
11 | -- Ausgabe des Zustands auf den LEDs
|
12 | leds <= state; |
13 | |
14 | -- Weiterschalten des Zustands beim Takt
|
15 | process (clk) begin |
16 | if clk'event and clk='1' then |
17 | if reset = '1' then |
18 | -- Startzustand
|
19 | state <= "1000000000"; |
20 | else
|
21 | -- Ring-Schieben
|
22 | state (8 downto 0) <= state (9 downto 1); |
23 | state (9) <= state (0); |
24 | end if; |
25 | end if; |
26 | end process; |
27 | end architecture; |
Das Clock-Runterteilen überlasse ich dir mal als Übung. Tipp: Ein weiteres "if", welches den Schiebeblock nur dann ausführt, wenn der Taktteiler(-Zähler) einmal durch ist. Das entspricht einem Clock-Enable (= sauberer Taktteiler statt Logik im Clock-Pfad).
Hier ist auch noch ein Beispiel. Hab das gestern mal auf mein Spartan3E board geladen und funktioniert super: http://www.obviousobscurity.org/?p=50 Der wesentliche code ist hier:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.STD_LOGIC_ARITH.ALL; |
4 | use IEEE.STD_LOGIC_UNSIGNED.ALL; |
5 | |
6 | entity blinkylights is |
7 | port( led: out std_logic_vector(7 downto 0); |
8 | sw: in std_logic_vector(7 downto 0); |
9 | mclk: in std_logic |
10 | );
|
11 | end blinkylights; |
12 | |
13 | architecture Behavioral of blinkylights is |
14 | signal secclk_c: std_logic_vector(23 downto 0); |
15 | signal secclk: std_logic; |
16 | signal ledreg: std_logic_vector(7 downto 0) := "00000001"; |
17 | begin
|
18 | |
19 | second_clock: process(mclk) |
20 | begin
|
21 | if (mclk = '1' and mclk'Event) then |
22 | secclk_c <= secclk_c + 1; |
23 | if (sw(3) = '1') then |
24 | secclk <= secclk_c(23); |
25 | else
|
26 | secclk <= secclk_c(20); |
27 | end if; |
28 | end if; |
29 | end process; |
30 | |
31 | rotate: process(secclk) |
32 | begin
|
33 | if (secclk = '1' and secclk'Event and sw(0) = '1') then |
34 | if (sw(2) = '1') then |
35 | ledreg <= (ledreg(0) & ledreg(7 downto 1)); |
36 | else
|
37 | ledreg <= (ledreg(6 downto 0) & ledreg(7)); |
38 | end if; |
39 | end if; |
40 | end process; |
41 | |
42 | led <= ledreg; |
43 | end Behavioral; |
Der code erlaubt das Einschalten, Umschalten der Richtung und der Geschwindigkeit mit Hilfe mit Hilfe von switches (sw). Rince
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.