Forum: FPGA, VHDL & Co. Automatisch Zeiten Anpassen mit VHDL


von Samer A. (Firma: Personal) (thedestroyer)


Lesenswert?

Hallo Leute :),

ich möchte ein 16x2 LCD steuern. Im Brochure steht, dass das LCD 
einzuschalten, muss man ein Paar Periode Warten.

http://www.xilinx.com/support/documentation/boards_and_kits/ug334.pdf

Auf Seite 54, sieht man, dass es 15 ms, 4.1 ms, ... gewarten muss.

Kann man das automatisch mit VHDL schreiben unabängig von Takt frequenz, 
um alles automatisch zu kriegen, wenn den Oscillator geändert ist? ich 
erwarte etwas wie das folgende:

1
architecture of temp is
2
CONSTANT taktFreq : INTEGER := 50000000; --for 50 MHz clock. This can only be changed when clock is changed, so that all time constraints are proportional to this value
3
SIGNAL state : INTEGER range 1 to 10; --state machine
4
SIGNAL wait_counter : INTEGER := 0;
5
begin
6
   process(clk)
7
   if(rising_edge(clk))
8
   begin
9
      case state is
10
         when 0 => 
11
            if(wait_counter = taktFreq*15*10**-3) --wait 15 ms
12
               state <= state + 1;
13
            else
14
               wait_counter <= wait_counter + 1;
15
            end if;
16
         when 1 =>
17
            ...
18
      end case;
19
   end if;
20
   end process;
21
begin
22
end architecture temp;

So habe ich es nicht geschafft, und habe immer probleme mit Synthesis 
bekommen. Es muss nicht sein wie ich es geschrieben habe, aber wie kann 
man das "Professionally" tun? :)

Vielen Dank

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


Lesenswert?

Samer Afach schrieb:
> Kann man das automatisch mit VHDL schreiben unabängig von Takt frequenz,
> um alles automatisch zu kriegen, wenn den Oscillator geändert ist?
Ja. Rechne einfach mit der Anzahl Takte pro Millisekunde:
1
  CONSTANT taktFreq : INTEGER := 50000000; 
2
  constant onems : integer := 1000/taktFreq;
3
4
  signal wait_counter : integer;
5
6
     if (wait_counter = taktFreq*15*onems) then
Oder direkt mit der Zeit:
1
  CONSTANT taktFreq : INTEGER := 50000000; 
2
  constant cycletime : time := 1 sec / taktFreq;
3
  
4
  signal wait_counter : integer;
5
6
     if (wait_counter = taktFreq*(15ms/cycletime)) then    -- bei Xilinx nötig:  -use_new_parser yes
Bei dieser Lösung muß mit Xilinx ISE der neue Parser verwendet werden:
http://www.lothar-miller.de/s9y/archives/79-use_new_parser-YES.html

von PittyJ (Gast)


Lesenswert?

Da man öfter warten muss, habe ich mit eine Komponente dafür 
geschrieben.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity WaitUnit is
    Port ( Signal Clock     : in  STD_LOGIC;
     Signal Start     : in  STD_LOGIC;
           Signal WaitingTime : in  integer;
           Signal EndOfWait   : out STD_LOGIC := '0'
        );

end WaitUnit;

architecture Behavioral of WaitUnit is
  signal Actual   : integer    := -1;
  signal StartOld: std_logic := '0';

begin

  ClockDown: process (Clock,Start,WaitingTime,StartOld) is begin

    if rising_edge(Clock) then

      if StartOld='0' and Start='1' then
        -- rising start edge
        EndOfWait <= '0';
        Actual    <= WaitingTime;
      else
        if Actual > 0 then
          Actual <= Actual -1;
          EndOfWait <= '0';
        elsif Actual = 0 then
          EndOfWait <= '1';
        else
          EndOfWait <= '0';
        end if;
      end if;

      -- always remember the current start for the next time
      StartOld <= Start;

    end if; -- rising edge
  end process ClockDown;


end Behavioral;



Diese wird dann in übergeordneten Komponenten eingebunden und aufgerufen 
mit:

...
  WaitUnitInstance : component WaitUnit
    port map
    (
      Clock_50MHz,
      WaitingStart,
      WaitingTime,
      WaitingEnd
    );

..
und
..
        constant c_Frequency: real := 50000000.0;

  WaitingStart     <= '1';
  WaitingTime      <= integer(c_Frequency*0.040);



Funktioniert mit Xilinx und Altera.

..

von Samer A. (Firma: Personal) (thedestroyer)


Lesenswert?

Vielen Dank für eure Antworten.

Ich werde das Component probieren. Vielen Dank dafür.

Aber:

Lothar Miller schrieb:
> Samer Afach schrieb:
>> Kann man das automatisch mit VHDL schreiben unabängig von Takt frequenz,
>> um alles automatisch zu kriegen, wenn den Oscillator geändert ist?
> Ja. Rechne einfach mit der Anzahl Takte pro Millisekunde:
>
1
>   CONSTANT taktFreq : INTEGER := 50000000;
2
>   constant onems : integer := 1000/taktFreq;
3
> 
4
>   signal wait_counter : integer;
5
> 
6
>      if (wait_counter = taktFreq*15*onems) then
7
>
> Oder direkt mit der Zeit:
>
1
>   CONSTANT taktFreq : INTEGER := 50000000;
2
>   constant cycletime : time := 1 sec / taktFreq;
3
> 
4
>   signal wait_counter : integer;
5
> 
6
>      if (wait_counter = taktFreq*(15ms/cycletime)) then    -- bei Xilinx
7
> nötig:  -use_new_parser yes
8
>
> Bei dieser Lösung muß mit Xilinx ISE der neue Parser verwendet werden:
> http://www.lothar-miller.de/s9y/archives/79-use_new_parser-YES.html

Aber hier ist 0 < onems < 1!!! wie kann das sein wenn onems ein Integer 
ist?

und in deinem zweiten Beispiel, hast du keine Leere Taste zwischen 15 
und ms geschrieben, ist es so OK?

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


Lesenswert?

Samer Afach schrieb:
> Aber hier ist 0 < onems < 1!!! wie kann das sein wenn onems ein Integer
> ist?
Hmmm... dumm gelaufen, das muß wohl etwas ein wenig anders skaliert 
werden. Probiers mal mit Real-Zahlen.   ;-)

von Samer A. (Firma: Personal) (thedestroyer)


Lesenswert?

Aber können Real-Zahlen Synthesisiert werden? gibts Einschränkungen 
darauf?

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.