Forum: FPGA, VHDL & Co. Lauflicht mit CPLD


von D. E. (eschlair)


Lesenswert?

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

von mr.chip (Gast)


Lesenswert?

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.

von Rick Dangerus (Gast)


Lesenswert?

Das Tutorial/Example zum Webpack? (JohnsonCounter)

Rick

von D. E. (eschlair)


Lesenswert?

>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\

von Falk B. (falk)


Lesenswert?

@ 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

von Morin (Gast)


Lesenswert?

Alternativ: Zähler um den Takt runterzuteilen, und dann ein 
Ring-Schieberegister.

von D. E. (eschlair)


Lesenswert?

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.

von Morin (Gast)


Lesenswert?

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;

von Morin (Gast)


Lesenswert?

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).

von Michael E. (rince)


Lesenswert?

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
Noch kein Account? Hier anmelden.