Forum: FPGA, VHDL & Co. Graukeil Bild im FPGA erzeugen


von Andreas B. (loopy83)


Lesenswert?

Hallo zusammen,

ich möchte gerne mit meinem FPGA ein Graukeilbild erzeugen, um die 
Kommunikation zu einem PowerPC zu testen.

Die Aufgabe besteht darin, ein Bild mit 2048x2048 Pixeln zu füllen. 
Dabei sollen die Werte von 0 bis 3FF (10 bit) Zeilenweise wandern. Der 
Graukeil wird also in 2048 Zeilen zwei mal dargestellt.

Ich möchte nun also 2048 mal die 0 in ein Fifo schreiben und dann via 
IRQ signalisieren, dass die erste Zeile im Fifo liegt und ausgelesen 
werden kann. Dann wird 2048 mal die 1 geschrieben usw usw bis 1024. Das 
der FiFo nie leer ist und/oder überläuft, dafür sorge ich.

Nun habe ich gelesen, dass es in VHDL keine echten for Schleifen gibt, 
da diese Ausdrücke parallel im FPGA implementiert werden und alle mit 
einem Takt abgearbeitet werden.

Wie kann ich es einfach und schnell realisieren, dass 2048 Werte in ein 
Fifo geschrieben werden, dann der Schreibwert um eins incrementiert wird 
und dann wieder 2048 Werte geschrieben werden?

Ich habe es schon händisch mit einem Counter versucht, aber da ist mir 
die Abbruchbedingung und die Verschachtelung sehr sehr schwer gefallen.

Kann mir jemand Hinweise dzau geben, wie man derartige Aufgaben 
geschickt lösen kann?

Vielen Dank!
Andi

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


Lesenswert?

Andreas B. schrieb:
> Ich möchte nun also 2048 mal die 0 in ein Fifo schreiben und dann via
> IRQ signalisieren, dass die erste Zeile im Fifo liegt und ausgelesen
> werden kann.
Du brauchst also einen Fifo, der mindestens zwei Zeilen aufnehmen kann, 
denn wenn du nach Füllen der ersten Zeile einen Interrupt setzt, dann 
müsstest du ja warten, bis der Zeilenfifo wieder befüllt werden kann.

Ich bin mir noch nicht so ganz sicher, ob du weißt, was du wirklich 
willst.

> Wie kann ich es einfach und schnell realisieren, dass 2048 Werte in ein
> Fifo geschrieben werden, dann der Schreibwert um eins incrementiert wird
> und dann wieder 2048 Werte geschrieben werden?
Mit einem Counter. Wirklich, das reicht aus  :-/

> Ich habe es schon händisch mit einem Counter versucht, aber da ist mir
> die Abbruchbedingung und die Verschachtelung sehr sehr schwer gefallen.
wenn du das richtig anfängst, wird da nichts verschachtelt.

Also: 2048 (Pix/Zeile) ist eine Zweierpotenz (=11Bit).
und 2048 Zeilen ist wieder eine Zweierpotenz(=11Bit).
Toll.
Also brauchst du nur einen Zähler mit 22 Bit und du bist fertig:
1
  signal counter : unsigned (21 downto 0) := (others=>'0');
2
3
  process (clk) begin
4
     if rising_edge(clk) then
5
        if enable='1' then          -- nur zählen, wenn erlaubt von fifo-verwaltung
6
           counter <= counter+'1';  -- das wars.
7
        end if;
8
     end if;
9
  end process;
10
11
  pixel_adresse  <= std_logic_vector(counter(11 downto 0));
12
  zeilen_adresse <= std_logic_vector(counter(21 downto 12));
13
  pixel_data     <= std_logic_vector(counter(20 downto 12)); 
14
  interrupt      <= '1' when counter(11 downto 0) = ((11 downto 0)=>'0') else '0';

von Andreas B. (loopy83)


Lesenswert?

Hallo und vielen Dank,

auf die Idee mit den 22bit wäre ich nie gekommen, aber irgendwie ist sie 
sehr logisch und einfach... ich bin scheinbar noch nicht lange genug im 
FPGA Geschäft, um auf diese Art von Lösung zu kommen.

Den IRQ löse ich mit einem prog_full vom Fifo aus. Dass der PPC schon 
anfangen kann mit auslesen, während noch die letzten Pixel der Zeile in 
den Fifo geschoben werden. So reicht mir ein 4096er Fifo und ich laufe 
nicht Gefahr, dass dieser überläuft, solange der PPC dafür sorgt, dass 
er immer brav ausließt, sobald der IRQ gesetzt wird.

Ich würde die ganze Geschichte noch gerne kontinuierlich gestalten, also 
immer wieder von vorne anfangen und somit ein Bild nach dem anderen 
auslesen. Dafür muss ich den Counter ja zurücksetzen und dafür eine 
Bedingung schaffen. Nur wie frage ich das unsigned Signal counter auf 
3FFFFF ab?
Ich könnte ihn auch als std_logic_vector erstellen, aber damit dann +'1' 
zu rechnen soll wohl unsauber sein.

Vielen Dank!
Andi

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


Lesenswert?

Andreas B. schrieb:
> Ich könnte ihn auch als std_logic_vector erstellen, aber damit dann +'1'
> zu rechnen soll wohl unsauber sein.
Richtig. Man rechnet nicht mit Vektoren.
Dafür gibt es die numeric_std und die Datentypen signed und unsigned.
Und passenderweise gibt es dazu gleich noch die passenden 
Typkonvertierungen:
http://www.lothar-miller.de/s9y/archives/14-Numeric_Std.html

> Nur wie frage ich das unsigned Signal counter auf 3FFFFF ab?
if counter = x"3FFFFF" then ...

> Dafür muss ich den Counter ja zurücksetzen
Der Counter setzt sich dank unsigned beim incementieren von x3fffff 
nach x400000 selbst zurück, indem er einfach auf 0 überläuft, weil er 
keinen Übertrag (das 23. Bit) mehr aufnehmen kann.

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.