Forum: FPGA, VHDL & Co. Auf-Ab Zähler VHDL


von Mirko (Gast)


Lesenswert?

Hallo, ich habe ein kleines Problem mit meinem Programm. Ich soll einen 
Zähler entwerfen, der zwischen zwei 4-Bit Zahlen (Input) hoch und runter 
zählt. Die Zahlen werden anschließend in einer 7 Segment Anzeige 
ausgegeben, was auch ganz gut funktioniert. Ich habe nun das Problem, 
dass mein Zähler bis zum Minimum runter zählt und anschließend immer +1 
und dann wieder Minimum. Also zB. ist das Minimum 3 und der Zähler 
startet bei 6, dann bekomme ich diese Zahlenfolge: 6,5,4,3,4,3,4,... 
Kann mir jemand sagen warum dies so ist, bzw was ich ändern kann?
1
entity count4bit is
2
  port (
3
    MLEFT: in std_logic_vector(1 downto 0);    --Geschwindigkeit ClockLeft
4
    MRIGHT: in std_logic_vector(1 downto 0);  --Geschwindigkeit ClockRight
5
    A, B : in std_logic_vector (3 downto 0);
6
    y1: out std_logic_vector (1 to 8);
7
    D9, D11: out std_logic;
8
    C: out std_logic
9
  );
10
    
11
end entity count4bit;
12
13
architecture behavior of count4bit is
14
    signal ClkLeft, ClkRight, Clk100Hz, ClkOsc : std_logic;
15
    signal ModeLeft, ModeRight: std_logic_vector (1 downto 0);
16
    signal count4: std_logic_vector(3 downto 0) := "0000";
17
      signal dir1 : boolean;
18
  begin
19
      Clock: entity work.ClkGen(behavior)
20
      port map(
21
      ClkModeLeft => ModeLeft, 
22
      ClkModeRight => ModeRight, 
23
      PulseLeft => '0', 
24
      PulseRight => '0',
25
      ClkLeft => ClkLeft, 
26
      ClkRight => ClkRight,
27
      Clk100Hz => Clk100Hz,
28
      ClkOsc => ClkOsc);  
29
      
30
31
      minmax: entity work.minmax(behavior)
32
      port map(
33
      A => A,
34
      B => B,
35
      dir => dir1,
36
      count => count4);
37
      
38
      seg7: entity work.dec7s(behavior)
39
      port map(
40
      y => y1,
41
      count7 => count4 );
42
      
43
      C <= '1';    --Segmentauswahl
44
45
  ----------------------------------------
46
    
47
  main: process(clkleft,dir1) is
48
  begin
49
  
50
    if (rising_edge(clkleft)) then      --addieren bzw subtrahieren
51
      if (dir1 = false) then
52
        count4 <= std_logic_vector (unsigned (count4) + 1);
53
        D9  <= '0';      --Anzeige aufwaerts/ abwaerts zaehlen
54
        D11 <= '1';
55
      else
56
        count4 <= std_logic_vector (unsigned (count4) - 1);
57
        D9  <= '1';
58
        D11 <= '0';
59
      end if;
60
    end if;
61
    
62
  end process main;
63
64
  -----------------------------------------
65
66
  ClockMode: process (MLEFT, MRIGHT) is
67
  begin
68
    ModeLeft  <= MLEFT;
69
    ModeRight <= MRIGHT;
70
  end process ClockMode;
71
end architecture behavior;
72
73
-----------------------------------------
74
-----------------------------------------
75
76
entity minmax is
77
  port (
78
    count : in std_logic_vector (3 downto 0);
79
    dir : out boolean;
80
    A, B : in std_logic_vector (3 downto 0)
81
    );
82
  
83
  end entity minmax; 
84
 
85
 
86
architecture behavior of minmax is 
87
88
signal help : boolean;
89
90
begin
91
  
92
  dir4: process (count,A,B) is
93
    
94
  begin
95
    
96
    if count = A then
97
      help <= false;
98
    elsif count = B then
99
      help <= true;
100
    end if;
101
    
102
    dir <= help;
103
    
104
  end process dir4;
105
106
end architecture behavior;

: Bearbeitet durch Moderator
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Vorneweg:
1
Antwort schreiben
2
Wichtige Regeln - erst lesen, dann posten!
3
    :
4
    :
5
    Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
6
7
Formatierung (mehr Informationen...)
8
    :
9
    :
10
    [vhdl]VHDL-Code[/vhdl]

Mirko schrieb:
> Also zB. ist das Minimum 3 und der Zähler startet bei 6, dann bekomme
> ich diese Zahlenfolge: 6,5,4,3,4,3,4,...
Wie stellst du das fest? Mit einer Simulation?

Mirko schrieb:
1
     if count = A then
2
       help <= false;
3
     elsif count = B then
4
       help <= true;
5
     end if;
Das ist ein Latch, das von Kombinatorik angesteuert wird. Das geht 
unbedingt schief! Stichwort zur weiteren Recherche: "Glitch"

Du bist da heute schon der Zweite, der sowas asynchrones probiert: 
Beitrag "Re: Stoppuhr Normal/Addition/Split, Funktion abhängig von "Taktrate""

Der Merksatz dazu ist: Latches verwenden nur die, die es können und die, 
die es nicht können. Erstere bewusst und Zweitere aus Zufall...  ;-)

Mach da einen Takt mit rein und aus dem "help" ein Flipflop statt eines 
Latches.

: Bearbeitet durch Moderator
von Mirko (Gast)


Lesenswert?

Hi, vielen erstmal Dank fürs bearbeiten, das mit dem Dateianhang merk 
ich mir fürs nächste mal.

Lothar M. schrieb:
> Wie stellst du das fest? Mit einer Simulation?

Ich kann die Zahlenfolge an meinem Demoboard ablesen,bekomme den Code so 
wie er ist auch aufgespielt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Diesen Prozess hier kannst du genauso gut oder besser duch die 
entsprechenden Concurrent-Anweisungen ersetzen:
1
--  ClockMode: process (MLEFT, MRIGHT) is
2
--  begin
3
    ModeLeft  <= MLEFT;
4
    ModeRight <= MRIGHT;
5
--  end process ClockMode;

Zum Code selber:
Insgesamt sind die Signalnamen extrem ungünstig und völlig nichtssagend: 
was ist denn "A" und "B"? Und was ist "dir"? Sollten die drei nicht 
besser /durchgängig/(!!) z.B. minimum, maximum und dirUP heißen? Oder du 
definierst einen neuen Typ für "dir", sodass du z.B. so abfragen kannst:
if dir = UP then ...

Und auch die Kommentare sind nutzlos: nicht mal am Kommentar kann man 
ablesen, ob jetzt hoch oder runter gezähl werden soll. Man muss den 
entsprechenden Code lesen und verstehen, um zu erahnen, was da gewollt 
ist.

Du solltest die komplette Takterzeugung aus dem Zählermodul heraushalten 
und dort nur den 1 gültigen Takt einspeisen.

Und zum Takt: wird wer immer noch auf diese krude Art&Weise händisch mit 
Zählern und toggelnden Flipflops erzeugt? Auf eine Art also, von der ich 
schon im Beitrag "Lauflicht mit vorgegbenen Clkgen" schrieb, dass man 
das so nicht macht, weil es nicht zuverlässig funktioniert?
Zur Takterzeugung in FPGAs nimmt man deren Taktmanager und arbeitet mit 
Clock-Enables.

Generell: wenn man das verbastelte Design mal soweit verbiegt, dass man 
den eigentlichen Zähler und seine Umschaltung (was man ja eigentlich 
überprüfen will) simuliert, dann sieht man (im Screenshot die untern 5 
Signale), dass der "im Prinzip" schon funktioniert, nur nicht ganz 
rechtzeitig umschaltet (abwärts wird auf 2 gezählt trotz Untergrenze 3, 
und aufwärts bis 7 trotz Obergrenze 6). Der dort beobachtete Effekt 
nennt sich "Latency".

: Bearbeitet durch Moderator
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.