www.mikrocontroller.net

Forum: FPGA, VHDL & Co. 4bit ladbarer Zähler


Autor: Matthias Hanske (prahlehans)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, also ich will sowas machen, wie einen 4 bit Zähler, bei dem man 
anfangs einstellen kann, bei welchem Startwert er beginnen soll. Achso, 
muss dazu sagen, ich arbeite mit Quartus II 9.0 sp2. Ich hab dort ein 
Problem bei der Simulation damit. Denn, sobald die clk das erste mal 1 
annimmt, wird mein IN-Port auf 0 gesetzt. Wie kann das zu so einer 
Reaktion kommen? Ich meine, wie kann die clk in der architecture 
Einfluss auf den Port nehmen? Ich poste mal meinen bisherigen code.
library ieee;
use ieee.std_logic_1164.all,
  ieee.numeric_std.all;

entity counter is
port (  start : in std_logic_vector(3 downto 0);
    clk,reset: in std_logic;
    output: out std_logic_vector(6 downto 0)
    );
end counter;

architecture logik of counter is
  signal result_next: std_logic_vector(3 downto 0);
  signal result_reg: std_logic_vector(3 downto 0) := start;
begin
  result_next <= std_logic_vector(unsigned(result_reg) + 1);    
  count: process(clk,reset)
    begin if reset = '1' then result_reg <= start;
      elsif (clk'event and clk = '1') then result_reg <= result_next;
      end if;
    end process;  
  ausgabe: entity work.count_muxer(logik) port map (input=>result_next,segment=>output);
  
end logik;

Achso, noch dazu: das Ergebnis soll auf nem 7-Segmenter in hex 
ausgegeben werden. Deswegen hat der Output nur 7 bits. Und diesen 
count_muxer braucht ihr glaub ich nich beachten. Der setzt einfach nur 
die Ausgaben auf dem 7-Segmenter.

Autor: Thomas Reinemann (Firma: abaxor engineering) (abaxor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias Hanske schrieb:

>
> 
> entity counter is
> port (  start : in std_logic_vector(3 downto 0);

...

>   signal result_reg: std_logic_vector(3 downto 0) := start;
> 

Die Initialisierung eines Signals mit dem Wert eines Eingangssignals ist 
nicht gerade sinnvoll.

Tom

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

Bewertung
0 lesenswert
nicht lesenswert
>   signal result_reg: std_logic_vector(3 downto 0) := start;
So geht das nicht, weil zum Synthesezeitpunkt start nicht bekannt 
ist...
An dieser Stelle kann für die Synthese nur eine Konstante angegeben 
werden. Und zwar deshalb, weil zum Initialisierungszeitpunkt 
(Einschalten) das Signal start auch noch nicht bekannt ist (das ginge 
bestenfalls über ein Generic, aber das ist auch wieder "nur" eine 
Konstante).

BTW:
Du solltest das Laden des Werts synchron machen:
:
architecture logik of counter is
  signal result_reg: std_logic_vector(3 downto 0) := "0000"; -- hier gehen in der Realitiät nur Konstanten
begin
  count: process(clk) begin 
      if (clk'event and clk = '1') then 
         result_reg <= std_logic_vector(unsigned(result_reg) + 1);
         if reset = '1' then 
            result_reg <= start; 
         end if;
      end if;
  end process;  
:

> Denn, sobald die clk das erste mal 1 annimmt,
> wird mein IN-Port auf 0 gesetzt.
Das ist nicht so kritisch. Denn in der Realität wird dein Clock ein 
paar mal kommen, bis du endlich alles initialisiert hast und loslegst...

Autor: Matthias Hanske (prahlehans)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja. wenn ich aber  "0000" setze, dann isses ja nur ein stinknormaler 
Zähler. Der soll ja grade bei start anfangen zu zählen.

>> Denn, sobald die clk das erste mal 1 annimmt,
>> wird mein IN-Port auf 0 gesetzt.
>Das ist nicht so kritisch.

Hmm. vllt doch, denn ich weiß noch nicht so genau, ob später beim reset 
auf "0000" gesetzt werden soll, oder auf start.

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

Bewertung
0 lesenswert
nicht lesenswert
> Hmm. vllt doch, denn ich weiß noch nicht so genau, ob später beim reset
> auf "0000" gesetzt werden soll, oder auf start.
Dann braucht du eben ein load und ein reset Signal.

Autor: Matthias Hanske (prahlehans)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu deinem Quelltext oben. Das is doch ein wenig unlogisch, da doch das 
reset asynchron kommen kann. Also darf das reset doch nicht von der clk 
abhängig sein. Das würde ja bedeuten, dass das reset auch nur synchron 
auftreten kann.

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

Bewertung
0 lesenswert
nicht lesenswert
> Das würde ja bedeuten, dass das reset auch nur synchron auftreten kann.
Besser wäre das wirklich...
Denn wenn dein Reset wirklich asynchron kommen kann, dann kann er auch 
asynchron wieder weggehen. Und dann wird es kritisch, denn der geht 
garantiert nicht bei jedem Zählerflipflop gleichzeitig weg. Was dann 
passieren kann, das kannst du dir ohne Probleme selber denken   :-o

Zum heissen Thema Reset gibts auch was im 
Beitrag "Xilinx und die Resets"

Autor: Matthias Hanske (prahlehans)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, ich hab jetz zwarr nochwas verändert, aber das Verhalten beim 
simulieren hat sich trotzdem nicht verändert...Was mach ich nur falsch? 
Im Prozess soll das Verhalten erstmal vom Reset abhängig sein, dann, 
falls ein load-Signal kommt, der counter auf meinen Eingangs-start 
gesetzt werden und gar nicht weiterzählen, und erst dann, soll bei 
steigender Taktflanke hoch gezählt werden...Aber es passiert im Ausgang 
gar nix...Hier nochmal mein Text
library ieee;
use ieee.std_logic_1164.all,
  ieee.numeric_std.all;

entity counter is
port (  start : in std_logic_vector(3 downto 0);
    clk,reset,load: in std_logic;
    output: out std_logic_vector(6 downto 0)
    );
end counter;

architecture logik of counter is
  signal result_next: std_logic_vector(3 downto 0);
  signal result_reg: std_logic_vector(3 downto 0);
begin
  
  result_next <= std_logic_vector(unsigned(result_reg) + 1);    
  count: process(clk,reset)
    begin if reset = '1' then result_reg <= (others=>'0');
      elsif load = '1' then result_reg <= start;
      elsif (clk'event and clk = '1') then result_reg <= result_next;
      end if;
    end process;  
  ausgabe: entity work.count_muxer(logik) port map (input=>result_next,segment=>output);
  
end logik;

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

Bewertung
0 lesenswert
nicht lesenswert
> Was mach ich nur falsch?
Du bist offenbar lernresistent  :-/
Hast du meine Beiträge ernsthaft angesehen und verstanden?

> dann, falls ein load-Signal kommt, der counter auf meinen
> Eingangs-start gesetzt werden
Mal abgesehen davon, dass dein Quelltext (immer noch) unschön formatiert 
ist, ist die Sensitivliste unvollständig. Eine Änderung von load bewirkt 
bei der Simulation daher nichts:
  count: process(clk,reset) begin -- hier fehlt load

Damit beschreibst du einen asynchron setz- und ladbaren Zähler:
      if reset = '1' then 
         result_reg <= (others=>'0');
      elsif load = '1' then 
         result_reg <= start;
      elsif (clk'event and clk = '1') then 
         result_reg <= result_next;
      end if;
    end process;  
Können deine FFs im FPGA sowas überhaupt?
Bei Xilinx gibt es sowas nicht.
Hast du dir mal das Syntheseergebnis im RTL-Viewer angesehen?

Um mich selber zu zitieren:
> Du solltest das Laden des Werts synchron machen:
:
architecture logik of counter is
  signal result_reg: std_logic_vector(3 downto 0) := "0000"; 
begin
  count: process(clk) begin -- diese Sensitivliste ist vollständig, weil der Prozess auf clk synchron ist
      if (clk'event and clk = '1') then 
         if reset = '1' then 
            result_reg <= "0000"; 
         elsif load = '1' then 
            result_reg <= start; 
         else
            result_reg <= std_logic_vector(unsigned(result_reg) + 1);
         end if;
      end if;
  end process;  
:

BTW:
>  signal result_next: std_logic_vector(3 downto 0);
>  signal result_reg: std_logic_vector(3 downto 0);
Warum verwendest du sogar für so einen blödsinnig einfachen Zähler die 
getrennte Takt-Zustands-Schreibweise?

Sieh dir meinen Code an, simuliere und verstehe ihn.

Autor: Matthias Hanske (prahlehans)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Damit beschreibst du einen asynchron setz- und ladbaren Zähler:

Na laut meiner Aufgabenstellung soll es ein synchroner Zähler mit 
asynchronem Reset sein...Deswegen vorhin mein Einwand. Irgendwie war 
auch in der Vorgabe so ein Beispiel von nem stinknormalen Zähler. Da 
haben die auch Takt-Zustandssteuerung gemacht und den reset haben die 
auch so gemacht wie ich ihn hatte.


> Hast du dir mal das Syntheseergebnis im RTL-Viewer angesehen?
Ich hab nur mit ModelSim simuliert.


>Du bist offenbar lernresistent  :-/
Nun ja...Es ist halt so, dass ich seit vllt 2 Wochen erst mit VHDL in 
Kontakt geraten bin und daher komplexere Sachen nich auf Anhieb 
verstehe. Bisher hatten wir auch nur so einfache Sachen wie einen Muxer, 
arithmetischen Shifter...Das war noch simpel. Für dich is das hier vllt 
auch ein Klacks, nur ich hatte vorher noch nie mit sowas zu tun.

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

Bewertung
0 lesenswert
nicht lesenswert
Matthias Hanske schrieb:
> Na laut meiner Aufgabenstellung soll es ein synchroner Zähler mit
> asynchronem Reset sein...Deswegen vorhin mein Einwand. Irgendwie war
> auch in der Vorgabe so ein Beispiel von nem stinknormalen Zähler. Da
> haben die auch Takt-Zustandssteuerung gemacht und den reset haben die
> auch so gemacht wie ich ihn hatte.
Na gut, dann mach den Reset asynchron (wobei das bestenfalls 
"suboptimal" zu nennen ist), aber halte wenigstens das Setzen synchron.
architecture logik of counter is
  signal result_reg: std_logic_vector(3 downto 0) := "0000"; 
begin
  count: process(clk,reset) begin 
      if reset = '1' then 
         result_reg <= "0000"; 
      elsif (clk'event and clk = '1') then 
         if load = '1' then 
            result_reg <= start; 
         else
            result_reg <= std_logic_vector(unsigned(result_reg) + 1);
         end if;
      end if;
  end process;  
Aber das mit der Takt-Zustands-Beschreibung bei einem Zähler ist 
ungewöhnlich bis unübersichtlich...
BTW:
Ich würde für das Zählersignal einen integer range 0 to 15 verwenden und 
das Eingangssignal start sowie das Ausgangssignal output 
entsprechend umwandeln.

>> Hast du dir mal das Syntheseergebnis im RTL-Viewer angesehen?
> Ich hab nur mit ModelSim simuliert.
Du kannst ohne weiteres dein Design (nach Erweiterung der Sensitivliste 
um das fehlende load) simulieren. Aber in der Hardware wird dann an 
die asynchronen Set- und Reset-Eingänge der FF Kombinatorik eingebaut. 
Und Kombinatorik im asynchronen Resetpfad (genauso wie im Setpfad) ist 
unberechenbar...
Denn der load kann ja asynchron kommen und gehen wie er will. Was, 
wenn dann 2 deiner Zähler-FF noch ein aktives load Signal sehen, die 
anderen beiden nicht mehr? Siehe dazu: 
http://www.lothar-miller.de/s9y/archives/64-State-...

Autor: Matthias Hanske (prahlehans)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Na gut, dann mach den Reset asynchron (wobei das bestenfalls
> "suboptimal" zu nennen ist), aber halte wenigstens das Setzen synchron.
Aye Sir :)
> BTW:
> Ich würde für das Zählersignal einen integer range 0 to 15 verwenden und
> das Eingangssignal start sowie das Ausgangssignal /output/
> entsprechend umwandeln.
Das dürfen wir nicht machen, da wir das in den vorangegangenen Laboren 
auch nicht hatten. Wir sollen nur das verwenden, was auch bisher auf den 
Übungen vorkam und auf dem jetzigen vorkommt. Wer weiß, vielleicht haben 
wir im nächsten Labor mehr Spielraum. Aber meine Wave dazu sieht jetzt 
erstmal ordentlich aus.

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.