www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Zähler + Schieberegister = Problem


Autor: Vasso (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo, hallo

nachdem ich ein neues Rechner kaufen müsste, und das ganze etwas 
funktionierte, stehe ich hier wieder vor einem anderen Problem, und ich 
komme leider nicht mehr weiter.

Was ich eigentlich vorhabe, sollte eigentlich schnell, einfach gemacht 
werden. So habe ich es mir rorgestellt, aber da habe ich mich wohl 
geiirt.

Ich habe folgendes gemacht:

- 4Bit-Zähler
  CLK : Clock  (Eingang)
  ENA : Enable (Eingang)
  CLR : Clear  (Eingang)
  q[3..0] : 4Bit (Ausgang)
  Gate_Out : Interrupt für Latch (Ausgang)
  Int_Out : Interrupt für Mikrocontroller (Ausgang)

  Gate_Out und Int_Out sind erstmal HIGH.
  Erreicht der Zähler die 9 werden beide Ausgänge Gate_out und Int_Out 
LOW
  gesetzt. Der Zähler wird dann auf 0 zurückgesetzt, und Gate_Out ist
  sofort wieder HIGH. Int_Out bleibt solange LOW bis der Zähler die 4
  erreicht.
  Also der Zähler zählt wie folgend:
  0,1,2,3,4,5,6,7,8,(9-Reset->0),1,2,3,4,5,6,7,8,(9-Reset->0),1,2,3,4,...

  Das so wie oben beschrieben funktioniert sehr gut.

- 9Bit Schieberregister mit Latch.
  CLK : Clock (Eingang)
  DAT : Daten, seriel IN (Eingang)
  ENA : Enable (Eingang)
  CLR : Clear (Eingang)
  Gate : Wenn HIGH werden die 9Bits vom Schieberegister ins Latch 
(Ausgang)
         geschoben. Wenn LOW dann ändert sich beim Takten das
         Schieberegister, der Ausgang bleibt unverändert.

  Das funktioniert auch sehr gut.


Und jetzt wenn ich beide zusammen habe, dann gibt es ein kleines 
Problem.
Der Zähler zählt wie folgend:
0,1,2,3,4,5,6,7,(8-Reset->0),1,2,3,4,5,6,7,8,(8-Reset->0),1,2,3,4,...
Da aber Gate_Out und Int_Out doch das machen, was sie machen sollen
(also HIGH->LOW->HIGH), dann muss es doch heißen, dass die 9 erreicht 
wurde. Ich sehe aber die 9 doch gar nicht. und bis dahin habe ich genau 
8x Takt gemacht. Woher kommt das 9. Takt?
oder was ist das für ein Phänomen?


Ist das irgendwie bekannt?
Im Anhang sind alle Projektdateien.



Danke
Vasso


Autor: Vasso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe das ganze jetzt auch so versucht,
verhält sich ähnlich wie davor.

library ieee;
use ieee.std_logic_1164.all;
use IEEE.numeric_std.all;

entity CntrShift is
  generic (n : natural := 9);
  port (   dat : in std_ulogic;
    clk : in std_ulogic;
    enable : in std_ulogic;
    q : out std_ulogic_vector(n-1 downto 0);
    clear : in std_ulogic;
    Cnt : out STD_LOGIC_VECTOR(3 downto 0);
    Int : out std_ulogic);
end entity CntrShift;


architecture rtl of CntrShift is

signal counter : unsigned(3 downto 0);
signal reg : std_ulogic_vector(n-1 downto 0);
signal IntSignal : STD_LOGIC;

begin
  process (clk,clear,enable,counter,reg,IntSignal) is
  begin
    if (clear = '1') then
      reg <= (others => '0');
      counter <= (others => '0');
      IntSignal <= '1';
    elsif rising_edge(clk) then
      if (enable = '1') then
        counter <= counter + 1;
        reg <= reg(n-2 downto 0) & dat;
      end if; -- enable
    end if; -- rising_edge

    if (counter >= "1001") then
      q <= reg;
      IntSignal <= '0';
      counter <= (others => '0');
          elsif (counter = "0100") then
      IntSignal <= '1';
    end if;

    Int <= IntSignal;
    Cnt <= std_logic_vector(counter);
       end process;

end architecture rtl;


Ich man kann meinen Fehler sehen!!


Gruß
Vasso

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich man kann meinen Fehler sehen!!

Wirklich ?

Liegt es daran das es ein SIGNAL und keine VARIABLE ist?

Autor: Roger Steiner (edge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nimm die Zaehlerabfrage samt reset in den rising_edge(clk) block. Dein 
jetztiges Konstrukt macht das asynchron und triggert auch fleisig auf 
zustandwechsel des Zaehlers, nicht immer gewuenscht.

Autor: Vasso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Dirk:
es sollte: >>ich hoffe, man kann meinen Fehler sehen.<<
Was muss eine Variable sein?

@Steiner:
der Reset muss asynchron sein. Aber die Zählerabfrage werde ich in den 
rising_edge Block nehmen. Das werde ich jetzt so testen.

Danke
Vasso

Autor: Vasso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe die Zählerabfrage in den rising_edge Block getan.
jetzt zählt er wie folgt:
0,1,2,3,4,5,6,7,9 und bei 10 geht er wieder auf 0
oder auch
0,1,2,3,4,5,6,7,9 und bei 10 geht er wieder auf 1


Gruß
Vasso

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ganz versteh ich zwar nicht, was du machen sillst, aber probier es 
mal so. Alles in einen synchronen Prozess, ausser die Zuweisungen an die 
Ausgänge, die sind nebenläufig.
begin

  process (clk,clear) is
  begin
    if (clear = '1') then
      reg <= (others => '0');
      counter <= (others => '0');
      IntSignal <= '1';
    elsif rising_edge(clk) then
      if (enable = '1') then
        if (counter = "0100") then
          IntSignal <= '1';
        elsif (counter = "1001") then
          q <= reg;
          IntSignal <= '0';
          counter <= (others => '0');
        else
          counter <= counter + 1;
          reg <= reg(n-2 downto 0) & dat;
        end if;
      end if; -- enable
    end if; -- rising_edge
  end process;

  Int <= IntSignal;
  Cnt <= std_logic_vector(counter);

end architecture rtl;

Autor: Vasso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Steiner:
ich habe jetzt auch den Reset in den rising_edge Block getan.
Der verhält sich wie davor.

@T.M.:
wenn der Zähler die 4 erreicht hat, tut er dann nichts mehr!
da habe ich folgendes direkt in die "if (enable = '1') then" 
hineingeschrieben.
          counter <= counter + 1;
          reg <= reg(n-2 downto 0) & dat;
und der Zählt wie davor.
0,1,2,3,4,5,6,7,9 und bei 10 geht er wieder auf 0.

ich brauche eigentlich sowas wie der 74HCT595 und einem 4Bit Zähler, der 
beim 9. Takt die 9Bits vom Schieberegister ins Latch (Ausgang) schiebt.

Der 74HCT595 hat aber nur 8Bit.

Wenn ich den Counter bei 8 (also nicht bei 9) abfrage, und dort den 
counter resete, dann funktioniert alles. Aber ich brauche 9Bits.


Gruß
Vasso

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da is mir nen Fhler unterlaufen, so müsste der Prozess aussehen:
  process (clk,clear) is
  begin
    if (clear = '1') then
      reg <= (others => '0');
      counter <= (others => '0');
      IntSignal <= '1';
    elsif rising_edge(clk) then
      if (enable = '1') then
        reg <= reg(n-2 downto 0) & dat;
        if (counter = "0100") then
          IntSignal <= '1';
          counter <= counter + 1;
        elsif (counter = "1001") then
          q <= reg;
          IntSignal <= '0';
          counter <= (others => '0');
        else
          counter <= counter + 1;
        end if;
      end if; -- enable
    end if; -- rising_edge
  end process;

  

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also. Das Schieberegister soll die ganze Zeit laufen, egal, was der 
Zähler macht. Wenn der Zähler 9 erreicht hat, sollen die Werte im 
Schieberegister an einen Ausgang gelegt werden? Also so eine Art 
seriell-parallel Wandler?

T.M.

Autor: T.M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"...ich brauche eigentlich sowas wie der 74HCT595 und einem 4Bit Zähler, 
der beim 9. Takt die 9Bits vom Schieberegister ins Latch (Ausgang) 
schiebt..."

Sowas hier?
signal counter : natural range 0 to 8;
signal reg     : std_ulogic_vector(n-1 downto 0);

begin;

counter_reg : process (clk, clear) is
begin
  if clear = '1' then
    counter <= 0;
    reg <= (others => '0');
  elsif rising_edge(clk) then
    if (enable = '1') then
      reg <= reg(n-2 downto 0) & dat;
      if counter = 8 then
        counter <= 0;
        q       <= reg;
      else
        counter <= counter + 1;
      end if; -- enable
  end if; -- rising_edge
end process counter_reg;

Autor: Vasso (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe jetzt alle mögliche Varianten getestet. Ich bekomme immer den 
gleichen/ähnlichen Fehler. Der zähler zählt immer noch wie folgend:
0,1,2,3,4,5,6,7 dann 9 und bei 10 geht er wieder auf 0 oder auf 1 
zurück.
oder auch ähnliches Verhalten. Das passiert aber nur wenn ich real 
teste.

Wenn ich aber mit der Software simuliere, dann macht und zeigt er alles 
richtig!

Kann es sein, dass der EPM3032 oder der EPM3064 das so nicht können?

Was ich kömisch finde, ist:
Der Zähler allein funktioniert, und Schieberegister allein funktioniert 
auch. Aber wenn beides zusammen dann macht er das oben beschriebene 
Problem.


Gruß
Vasso

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.