Forum: FPGA, VHDL & Co. Signalwertzuweisung zu spät


von Johannes H. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo liebe Forenbesucher,

ich hätte da ein Problem wo ich leider nicht weiter komme. Wie im 
Betreff schon angegeben, habe ich ein Signal, dem ich alle 100Hz, ein 
Wert zuweisen will, jedoch ist es leider so, dass die Zuweisung um 100Hz 
hinterherhinkt. Es ist auch so, dass alle 100Hz das Zeilensignal der 
Wert ändert. Ich habe auch ein Bild von der Simulation angehängt.
1
architecture rtl of col_row_buttons is 
2
  
3
    constant C_CNTR : natural := 1000000; -- um 100Hz zu generieren
4
    
5
    signal s_presc_cntr    : natural;
6
    signal s_column     : natural range 0 to 3;
7
    signal s_presc_en     : std_logic;
8
    signal s_column_buttons  : std_logic_vector (COL_ROW_BUTTONS - 1 downto 0);
9
    signal s_pressed_button  : std_logic_vector (KEYPAD_BUTTONS - 1 downto 0);
10
begin 
11
    
12
  -- generieren des 100 Hz signals
13
    
14
  p_presc : process (clk_i, reset_i) 
15
  begin 
16
    if reset_i = '1' then 
17
      s_presc_cntr <= 0;
18
      s_presc_en <= '0';
19
    elsif clk_i = '1' and clk_i'event then 
20
      if s_presc_cntr >= C_CNTR then 
21
        s_presc_en <= '1';
22
        s_presc_cntr <= 0;
23
      else
24
        s_presc_en <= '0';
25
        s_presc_cntr <= s_presc_cntr + 1;
26
      end if; 
27
    end if; 
28
  end process p_presc;
29
      
30
  -- Zeilenwert alle 100Hz ändern
31
  
32
  p_column : process (clk_i, reset_i)
33
  begin 
34
    if reset_i = '1' then 
35
      s_column_buttons <= x"F"; 
36
      s_column <= 0;
37
    elsif clk_i = '1' and clk_i'event then 
38
      if s_presc_en = '1' then 
39
        if s_column = 0 then 
40
          s_column_buttons <= "1110";
41
          s_column <= s_column + 1; 
42
        elsif s_column = 1 then 
43
          s_column_buttons <= "1101";
44
          s_column <= s_column + 1; 
45
        elsif s_column = 2 then 
46
          s_column_buttons <= "1011"; 
47
          s_column <= s_column + 1; 
48
        elsif s_column = 3 then 
49
          s_column_buttons <= "0111";
50
          s_column <= 0; 
51
        end if;         
52
      end if; 
53
    end if; 
54
  end process p_column;
55
        
56
  col_buttons_o <= s_column_buttons;
57
58
  -- anhand Zeilensignal gedrückte Taste ermitteln
59
  
60
  p_press_buttons : process (clk_i, reset_i)
61
  begin 
62
    if reset_i = '1' then 
63
      s_pressed_button <= (others => '1');
64
    elsif clk_i = '1' and clk_i'event then 
65
        if s_presc_en = '1' then             -- alle 100Hz
66
          case s_column_buttons (3 downto 0) is 
67
            when "1110" => 
68
              if row_buttons_i(0) = '0' then 
69
                s_pressed_button <= s_pressed_button or  X"0002";   
70
              elsif row_buttons_i (1) = '0' then 
71
                s_pressed_button <= s_pressed_button or X"0010";  
72
              elsif row_buttons_i (2) = '0' then 
73
                s_pressed_button <= s_pressed_button or X"0080";  
74
              elsif row_buttons_i (3) = '0' then 
75
                s_pressed_button <= s_pressed_button or X"0001";   
76
              elsif row_buttons_i <= "1111" then 
77
                s_pressed_button <= (others => '0');
78
              end if; 
79
            when "1101" =>
80
              if row_buttons_i(0) = '0' then 
81
                s_pressed_button <= s_pressed_button or  X"0004";   
82
              elsif row_buttons_i (1) = '0' then 
83
                s_pressed_button <= s_pressed_button or X"0020";  
84
              elsif row_buttons_i (2) = '0' then 
85
                s_pressed_button <= s_pressed_button or X"0100";  
86
              elsif row_buttons_i (3) = '0' then 
87
                s_pressed_button <= s_pressed_button or X"8000";   
88
              elsif row_buttons_i <= "1111" then 
89
                s_pressed_button <= (others => '0');
90
              end if;
91
            when "1011" => 
92
              if row_buttons_i(0) = '0' then 
93
                s_pressed_button <= s_pressed_button or X"0008";   
94
              elsif row_buttons_i (1) = '0' then 
95
                s_pressed_button <=  s_pressed_button or X"0040";  
96
              elsif row_buttons_i (2) = '0' then 
97
                s_pressed_button <=  s_pressed_button or X"0200";  
98
              elsif row_buttons_i (3) = '0' then 
99
                s_pressed_button <=  s_pressed_button or X"4000";   
100
              elsif row_buttons_i <= "1111" then 
101
                s_pressed_button <= (others => '0');
102
              end if;
103
            when "0111" => 
104
              if row_buttons_i(0) = '0' then 
105
                s_pressed_button <= s_pressed_button or X"0400";   
106
              elsif row_buttons_i (1) = '0' then 
107
                s_pressed_button <= s_pressed_button or X"0800";  
108
              elsif row_buttons_i (2) = '0' then 
109
                s_pressed_button <= s_pressed_button or X"1000";  
110
              elsif row_buttons_i (3) = '0' then 
111
                s_pressed_button <= s_pressed_button or X"2000";   
112
              elsif row_buttons_i <= "1111" then 
113
                s_pressed_button <= (others => '0');
114
              end if;
115
            when others =>
116
              s_pressed_button <= (others => '0');
117
          end case;
118
        end if;
119
    end if; 
120
  end process; 
121
  pressed_button_o <= s_pressed_button;
122
end architecture rtl;

Wie man in der Simulation sehen kann, ist pressed button_o bei 
10000000ns (10ms) noch immer auf null obwohl er laut den row_button_i 
und col_button_o auf X"0002" sein sollte. Bei 20ms ist er dann auf 
X"0002" wobei hier das Signal schon X"0006" sein sollte (es ist erst bei 
30 ms). Es hinkt eben um 10ms hinterher.

Ich hoffe ihr könnt mir da weiterhelfen.

Lg Johannes

von Theor (Gast)


Lesenswert?

Naja. Leider reagieren reale Vorrichtungen nicht instantan, d.h. in 
Null-Zeit und in zusätzlich in einem Maß, dass von anderen Vorrichtungen 
als Veränderung erkannt wird.

D.h. im konkreten Fall, dass zwischen dem Ereignis der steigenden Flanke 
und der Änderung irgendeines, abhängigen Ausgangssignales Zeit vergeht. 
Dass muss man berücksichtigen.
Was einem da im Wege stehen kann, ist die unhinterfragte Annahme, alles 
müsse "sofort" geschehen. Das ist nicht der Fall.
Die Frage ist nur, ob und welche Verzögerungen akzeptabel sind.

von Johannes H. (Gast)


Lesenswert?

Vielen Dank für die schnelle Antwort :)

Ok also ist es nicht möglich, weil ich denke, dass mein VHDL-Code falsch 
ist.

Lg

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


Lesenswert?

Johannes H. schrieb:
> Vielen Dank für die schnelle Antwort :)
Die war zwar völlig korrekt, aber leider am Thema vorbei. Das Problem 
hier ist "vor" und "hinter" dem Flipflop...   ;-)

Johannes H. schrieb:
> Es hinkt eben um 10ms hinterher.
Glückwunsch, du hast Latency entdeckt.

Dein Problem liegt darin, dass du gleichzeitig nach je 10ms den 
nächsten Zustand der Marix setzt und (Achtung jetzt kommt es:) den 
bisherigen alten auswertest.

Ein Tipp: lass mal zum Ausprobieren diese 10ms Abfrage bei der 
Auswertung weg...

Johannes H. schrieb:
> ich denke, dass mein VHDL-Code falsch ist.
Der tut doch. Nur erwartest du das Falsche. Wie gesagt: jede 
Signalzuweisung in einem getakteten Prozess ergibt ein Flipflop. Und das 
übernimmt mit dem Takt die Information, die hör dem Takt am Eingang 
anlag. Einfach mal einen Abend drüber nachgrübeln.

: Bearbeitet durch Moderator
von Johannes H. (Gast)


Lesenswert?

Aha ok also das Problem ist dass ich s_column_button ein Wert zuweise 
aber im selben Zug abfrage?

Lothar M. schrieb:
> Ein Tipp: lass mal zum Ausprobieren diese 10ms Abfrage bei der
> Auswertung weg...

wenn ich die abfrage weglassen würde, müsste er dann (wenn ich es 
richtig verstanden habe) zumindest ein Taktzyklus hinterherhinken oder?

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


Lesenswert?

Johannes H. schrieb:
> Aha ok also das Problem ist dass ich s_column_button ein Wert zuweise
> aber im selben Zug abfrage?
Richtig: du speicherst da mit der selben Taktflanke die Auswertung des 
alten Werts und setzt gleichzeitig den neuen Wert der dann zu einem 
neuen Auswertungsergebnis führt...

> zumindest ein Taktzyklus hinterherhinken oder?
Ja.
Sonst müsste das Ergebnis kombinatorisch weitergegeben werden, dann 
kommt das mit der Latency eben irgendwo später.

Aber bei einer Tastenabfrage kann das eigentlich kein Problem sein...

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