www.mikrocontroller.net

Forum: FPGA, VHDL & Co. VHDL,schieberegister probleme


Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

als anfänger versuche ich ein Signal zu verschieben. Dazu habe ich als 
eingagangsclock 27 Mhz, diese habe ich mittels counter dann 
runtergeteilt habe.

Folgender code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity SCHIEBEREGISTER is
    Port (
       EINGANG   : in   std_logic_vector (3 downto 0);
       RESET     : in     std_logic;
       LED      : out   std_logic;
       AUSGANG   : out   std_logic_vector (3 downto 0);
       SAVE0    : buffer std_logic_vector (3 downto 0);
       SAVE1    : buffer std_logic_vector (3 downto 0);
       SAVE2    : buffer std_logic_vector (3 downto 0);
       SAVE3    : buffer std_logic_vector (3 downto 0);
       SAVE4    : buffer std_logic_vector (3 downto 0);
       SAVE5     : buffer std_logic_vector (3 downto 0);
       clk      : in     std_logic);


end SCHIEBEREGISTER;

architecture Behavioral of SCHIEBEREGISTER is
--signal SAVE0,SAVE1,SAVE2,SAVE3,SAVE4 : std_logic_vector (3 downto 0);
signal clk_2 : std_logic;

COMPONENT TAKT
  PORT  ( clk_in : in std_logic;
        reset   : in std_logic;
        clk_out: out std_logic);
end COMPONENT;


begin

  taktausgabe: TAKT
  PORT MAP (clk_in=> clk, reset => RESET, clk_out=>clk_2 );

  SCHIEBEREGISTER: process (clk_2,reset)
  begin
    if reset = '1' then
      SAVE0    <="0000";
      SAVE1    <="0000";
      SAVE2    <="0000";
      SAVE3    <="0000";
      SAVE4    <="0000";
      SAVE5    <="0000";

    else
      if (clk_2 = '1' and clk_2'event ) then
        SAVE0<= EINGANG;
        SAVE1<= SAVE0;
        SAVE2<= SAVE1;
        SAVE3<= SAVE2;
        SAVE4<= SAVE3;
        SAVE5<= SAVE4;

  else
        SAVE0  <=SAVE0;
        SAVE1  <=SAVE1;
               SAVE3  <=SAVE3;
               SAVE4  <=SAVE4;
        SAVE5 <=SAVE5;
      end if;
    end if;
  end process SCHIEBEREGISTER;

  AUSGANG<=SAVE5;


Das funktioniert aber so nicht, komisch ist das wenn ich das so 
definiere dann kommt am ausgang nach ca. 2 sek. das signal, tue ich aber 
den SAVE5 weg dann kommt das signal nach 6 sek...


Kann mir jemand helfen? ich wollt nur das signal um 4 takte verzögert 
ausgeben?

Eingang ist hier ein switch
Ausgang sind hier 4 LED
LED ist einfach kontrolle für takt.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sollte wenigstens eine saftige Warnung geben:
      if (clk_2 = '1' and clk_2'event ) then
        SAVE0<= EINGANG;
        SAVE1<= SAVE0;
        SAVE2<= SAVE1;
        SAVE3<= SAVE2;
        SAVE4<= SAVE3;
        SAVE5<= SAVE4;
     else
        SAVE0  <=SAVE0;
        SAVE1  <=SAVE1;
        SAVE3  <=SAVE3;
        SAVE4  <=SAVE4;
        SAVE5 <=SAVE5;
     end if;
Zudem wird das hier ausreichen und genau das selbe machen:
      if (clk_2 = '1' and clk_2'event ) then
        SAVE0<= EINGANG;
        SAVE1<= SAVE0;
        SAVE2<= SAVE1;
        SAVE3<= SAVE2;
        SAVE4<= SAVE3;
        SAVE5<= SAVE4;
     end if;

> Dazu habe ich als eingagangsclock 27 Mhz, diese habe ich
> mittels counter dann runtergeteilt habe.
Das ist ein sehr schlechter Designstil.
Ein ideales FPGA-Design hat genau 1 Takt (das gilt besonders für 
Anfänger). Und der Rest wird mit Clock-Enables gemacht.
Siehe Taktung FPGA/CPLD
Was ist dein clk_2? Welche Frequenz hat der?

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein clk_2 kommt von clk_out welches ich hier definiert habe und dann 
als component definiert habe.

Ja ich bin auch anfänger deswegen meine frage, wie sollte ich es  denn 
machen?

Gruss

Mario




entity TAKT is

   Generic (MAXCOUNT,N :integer:= 53999998); -- EINSTELLBARE VARIABLE 
FÜR ZÄHLER!!
   Port ( clk_in   : in  STD_LOGIC;     -- RICHTIGER CLOCKEINGAGN MIT 27 
MHZ
           reset     : in  STD_LOGIC;     -- RESET UM ZÄHLER AUF NULL ZU 
SETZEN
        clk_out   : out  STD_LOGIC);  -- INTERN VERWENDETER 
RUNTERGEDROSSELTER CLOCK -> HIER 1 HZ
end TAKT;


architecture Behavioral of TAKT is

signal cnt: integer range  0 to N ;

begin


  TAKTGEBER: process (reset,clk_in)
  begin
    if (reset = '1') then
      cnt<=0;
    else
      if (clk_in='1' and clk_in'event) then
        cnt<=cnt+1;
      elsif (cnt = MAXCOUNT) then
        cnt<=0;
      end if;
    end if;
  end process TAKTGEBER;

  TAKTOUT: process (cnt)
  begin
    if ((cnt) < (MAXCOUNT/2)) then
      clk_out<= '0';
    else
      clk_out<= '1';
    end if;
  end process TAKTOUT;


end Behavioral;

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
      if (clk_in='1' and clk_in'event) then
        cnt<=cnt+1;
      elsif (cnt = MAXCOUNT) then
        cnt<=0;
      end if;
Das hast du selber erfunden?
Damit beschreibst du Flipflops (cnt), bei denen der Takteingang Vorrang 
vor dem Reseteingang hat. Sowas kannst du nicht kaufen.

Probiers mal so:
entity TAKT is
   Generic (MAXCOUNT,N :integer:= 27000000); -- EINSTELLBARE VARIABLE FÜR ZÄHLER!!
   Port ( clk_in   : in  STD_LOGIC;     -- RICHTIGER CLOCKEINGAGN MIT 27 MHZ
--           reset     : in  STD_LOGIC;     -- RESET nicht nötig.
        clk_out   : out  STD_LOGIC);  -- Clock-Enable -> HIER 1 HZ
end TAKT;

architecture Behavioral of TAKT is
signal cnt: integer range  0 to N-1 ;
begin

  TAKTGEBER: process (reset,clk_in)
  begin
      if (clk_in='1' and clk_in'event) then
        if (cnt = MAXCOUNT) then
           cnt <= 0;
           clk_out <= '1'; -- nur 1 Takt aktiv
        else
           cnt <= cnt+1;
           clk_out <= '0';
        end if;
    end if;
  end process TAKTGEBER;

end Behavioral;

Und dann im Top-Level:
  
  :
  SCHIEBEREGISTER: process (clk,reset)
  begin
    if reset = '1' then
      SAVE0    <="0000";
      SAVE1    <="0000";
      SAVE2    <="0000";
      SAVE3    <="0000";
      SAVE4    <="0000";
      SAVE5    <="0000";
    elsif rising_edge(clk) then
      if (clk_2 = '1') then
        SAVE0<= EINGANG;
        SAVE1<= SAVE0;
        SAVE2<= SAVE1;
        SAVE3<= SAVE2;
        SAVE4<= SAVE3;
        SAVE5<= SAVE4;
      end if;
    end if;
  end process;
  :

Und sowas ist Käse:
SAVE0    : buffer std_logic_vector...
Gewöhne dir besser an, mit lokalen Signalen zu arbeiten und diese dann 
auf einen OUT Port zuzuweisen.

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

danke für die Antwort!!

fürs verständniss: Was passiert jetzt genau bei der änderung von clk 
='1' and clk'event zu rising_edge(clk) then
                           if (clk_2 = '1') then

>> Und sowas ist Käse:
>> SAVE0    : buffer std_logic_vector...

soll ich dann die zwischenspeicherungen SAVE signale nicht in der entity 
sonern als hilfssignal in der architectur definieren?



Gruss

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was passiert jetzt genau bei der änderung von
> clk ='1' and clk'event   zu   rising_edge(clk) then
Nichts, es schreibt sich kürzer.

Der Trick mit dem Clock-Enable liegt darin, dass du vorher clk_2 
verwendet hast:
    if (clk_2 = '1' and clk_2'event ) then
        SAVE0<= EINGANG;
Und ich verwende clk. Und als Clock-Enable den clk_2, der selber aber 
nur 1 clk-Zyklus lang aktiv ist:
    elsif rising_edge(clk) then       -- kompakter
    elsif clk ='1' and clk'event then -- alternativ, aber nicht so schön zu lesen
        if (clk_2 = '1') then -- ist je Sekunde für 1 clk-Zyklus lang '1'
            SAVE0<= EINGANG;


> SAVE signale nicht in der entity
> sonern als hilfssignal in der architectur definieren?
Ja.

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, also so funktioniert das auch irgendwie nicht.

Ich verstehe nicht was am Takt falsch sein soll.

ZUM TAKT:

ich habe 27 Mil. takte in einer sekunde. Ich lasse mit steigender Flanke 
den counter hoch zahlen bis 54 Milund sag das mein neues clocksignal dan 
den wert '1' hat wenn der bei kleiner der hälfte der 54Mil. und 0 wenn 
er mehr als der hälfte der 54 Mil. ist. Also habe ich eine sekunde lang 
eine 1 und eine sekunde lang eine 0 am clk_out. ODER TÄUSCHE ICH MICH 
DA?


und dann schiebe ich das signal mit steigneder flanke dieses clk_out 
signals oder nicht?

Ich verzweifele echt langsam am dem zeug...arrrr



Gruss

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also habe ich eine sekunde lang eine 1 und eine sekunde lang eine 0 am
> clk_out. ODER TÄUSCHE ICH MICH DA?
Was sagt die Simulation?
Was, du simulierst nicht  :-o

Naja, wie auch immer:
1) Es ist schlecht, einen Takt aus Kombinatorik zu erzeugen.
    if ((cnt) < (MAXCOUNT/2)) then
Das Stichwort dazu heißt: Glitches

2) Es ist schlecht, unnötig viele Takte im Design zu haben.
In deinem Design  clk und clk_2
Stichworte hierzu: Taktdomänen und Synchronisation

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok

aber ich verstehe nicht wie du dann mit deinem code dann auf (eine 
sekunde 1 eine sekunde 0) kommen willst?

Und wie gesagt meine clk_in weiße ich der clk von 27 Mhz zu die auch 
wirklich anliegt zu, und mit clk_out erzeuge ich dann meinen neuen takt 
und dann als componente weisse ich clk_out dem hilfssignal clk_2 zu, 
welches ich dann in der architecture verwende verwende....



Gruss

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> aber ich verstehe nicht wie du dann mit deinem code dann auf (eine
> sekunde 1 eine sekunde 0) kommen willst?
Ich will doch gar keinen Takt mit 1:1 Pulspausenverhältnis.
Ich will jede Sekunde 1 Takt lang ein Enable-Signal.

Ich will jede Sekunde um eins weiterschieben. Wenn das nicht passt, dann 
darfst du auch schreiben:
:
   Generic (MAXCOUNT :integer:= 2*27000000); -- 2 Sekunden
:
architecture Behavioral of TAKT is
signal cnt: integer range  0 to MAXCOUNT-1 ;
begin

  TAKTGEBER: process (reset,clk_in)
  begin
      if (clk_in='1' and clk_in'event) then
        if (cnt = MAXCOUNT-1) then
:

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum ich frag ist , weil mit meiner Methode auch eine zustätzliche LED 
zum blinken gebracht hab und somit den Takt kontrolliert hab. Nur wenn 
ich das dann so mache:



LEDBLINKEN : process (clk_2) -- KONTROLLE -> TAKTAUSGABE AN LED
  begin
    if rising_edge(clk) then
      if (clk_2='1' ) then
        LED<='1';
      else
        LED<='0';
      end if;
    end if;
  end process LEDBLINKEN;




Gruss und danke noch mal

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:
  • preview image for WF.gif
    WF.gif
    8,83 KB, 130 Downloads

Bewertung
0 lesenswert
nicht lesenswert
Ich musste kurz weg, aber hier jetzt eine Waveform der Simulation und 
die dazugehörigen VHDL-Dateien.

EDIT:
    if rising_edge(clk) then
      if (clk_2='1' ) then
        LED<='1';
      else
        LED<='0';
      end if;

Damit leuchtet die LED gerade mal 1/27000000 pro Sekunde.
Das ist kurz....

Probiers mal so:
LEDBLINKEN : process (clk_2) -- KONTROLLE -> TAKTAUSGABE AN LED
  begin
    if rising_edge(clk) then
      if (clk_2='1' ) then
        LED <= not LED;
      end if;
    end if;
  end process LEDBLINKEN;
Das Signal LED sollte natürlich wieder lokal sein...

Autor: Mario (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke ich muss das später mal grüdlich durchgehen und dann meld ich mich 
falls ich darf :)


Gruss und danke nochmal

Mario

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.