Ich versuche, einen Bildschirmpuffer zu verwenden, um die Bits von Videodaten zu speichern, zu ändern und an die DVI-Übertragungsschnittstelle auszugeben.
Ich kann mich nicht entscheiden, welche Art von RAM ich als Bildschirmpuffer verwenden soll. Nach einiger Lektüre kam ich zu dem Schluss, dass abgeleiteter Dual-Port-RAM die beste Wahl wäre. Ich bin mir jedoch nicht sicher, wie ich die Lese- und Schreibports verwenden soll. Ich habe es bereits geschafft, einen RAM-Block abzuleiten und ihn mit einer Funktion zu instanziieren, die eine .mif-Datei generiert.
Meine aktuelle Entwicklung sieht wie folgt aus:
Also versuche ich, GLEICHZEITIG zu schreiben und zu lesen. Die Uhr ist für beide gleich.
Ich habe der Einfachheit halber keine Codes eingebettet und versucht, so klar wie möglich zu sein. Wenn nötig oder gewünscht, werde ich Codeschnipsel posten.
Meine Frage ist folgende: Gibt es eine bessere Herangehensweise an dieses Problem, da meine bisherigen Versuche nicht erfolgreich waren. Es scheint, dass ich nicht in den RAM schreiben kann und ich kann den Grund dafür nicht finden. Irgendetwas sagt mir, dass ich Probleme mit dem Timing habe. Wenn sich jemand damit identifizieren kann, helfen Sie mir bitte.
Danke!
Bearbeiten:
Ja, ich speichere 1 Bit pro Pixel für Speicherzwecke und entscheide über die Farbe im DVI-Übertragungsblock, der danach kommt. Die Entscheidung basiert auf den Koordinaten des hcounter und vcounter des DVI. Ich instanziiere das RAM mit '1' in jeder Zelle. Ich überprüfe dies, indem ich es lese und mit einer konstanten Farbe auf dem Bildschirm ausgebe:
if vcounter < 900 then
if hcounter < 1440 then
if pixel_in_sgnl = '0' then
dviRed <= "11111111";
dviGreen<= "00000000";
dviBlue <= "00000000";
else
dviRed <= "00000000";
dviBlue <= "11111111";
dviGreen <= "00000000";
end if;
Wenn ich jedoch versuche, den Inhalt des RAM zu ändern und ihn dann zu lesen und auf dem Bildschirm auszugeben, lese ich sie immer noch als 1, da sich die Farbe nicht ändert. Zum Beispiel möchte ich im folgenden Code "0000000000000000" an Position 10000 schreiben, und als Ergebnis sollte ich eine andersfarbige Linie auf einem konstanten Hintergrund beobachten. Ich hoffe, ich konnte klar genug sein.
FB: FrameBuffer port map ( data_a => "0000000000000000",
data_b => "ZZZZZZZZZZZZZZZZ",
addr_a => 10000, --address_write_sgnl,
addr_b => address_read_sgnl,
we_a => '1',
we_b => '0',
clk_106 => DVI_clock,
q_a => open,
q_b => pixel_data_sgnl);
Dies ist der abgeleitete RAM, den ich online gefunden und leicht modifiziert habe:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FrameBuffer is
port
(
data_a : in std_logic_vector(15 downto 0);
data_b : in std_logic_vector(15 downto 0);
addr_a : in natural range 0 to 80999;
addr_b : in natural range 0 to 80999;
we_a : in std_logic ;
we_b : in std_logic ;
clk_106 : in std_logic;
q_a : out std_logic_vector(15 downto 0);
q_b : out std_logic_vector(15 downto 0)
);
end FrameBuffer;
architecture rtl of FrameBuffer is
-- Build a 2-D array type for the RAM
subtype word_t is std_logic_vector(15 downto 0);
type memory_t is array(0 to 80999) of word_t;
FUNCTION initialize_ram
return memory_t is
variable result : memory_t;
BEGIN
FOR i IN 0 to 80999 LOOP
result(i) := "1111111111111111";
END LOOP;
RETURN result;
END initialize_ram;
-- Declare the RAM
shared variable ram : memory_t :=initialize_ram ;
begin
-- Port A
process(clk_106)
begin
if(rising_edge(clk_106)) then -- Port A
if(we_a = '1') then
ram(addr_a) := data_a;
-- Read-during-write on the same port returns NEW data
q_a <= data_a;
else
-- Read-during-write on the mixed port returns OLD data
q_a <= ram(addr_a);
end if;
end if;
end process;
-- Port B
process(clk_106)
begin
if(rising_edge(clk_106)) then -- Port B
if(we_b = '1') then
ram(addr_b) := data_b;
-- Read-during-write on the same port returns NEW data
q_b <= data_b;
else
-- Read-during-write on the mixed port returns OLD data
q_b <= ram(addr_b);
end if;
end if;
end process;
end rtl;
Edit2:
Ich glaube, ich habe es geschafft, das Problem des Schreibens in den RAM zu lösen, aber ich kann immer noch darüber diskutieren, um mein Design zu verbessern. Jetzt stecke ich fest, wenn ich meinen Pufferausgang an DVI füttere. Wie ich bereits erwähnt habe, halte ich 1 Bit pro Pixel im RAM, aber die RAM-Ausgangsbreite beträgt 16 Bit. Also muss ich diese 16 Bit speichern und sie bei jeder DVI-Taktflanke nacheinander an DVI senden. Ich mache es wie folgt:
process(clk106M, locked_sgnl)
begin
if locked_sgnl = '0' then
address_counter <= (others => '0');
counter <= "10000";
pixel_in_register <= (others => '0');
elsif rising_edge(clk106M) and (locked_sgnl = '1') then
if (address_counter < "10011110001101000") then
if counter >= 16 then
pixel_in_register <= pixel_in;
address_counter <= address_counter + '1';
counter <= "00000";
else
pixel_in_sgnl <= pixel_in_register(0);
pixel_in_register <= '0' & pixel_in_register(15 downto 1);
counter <= counter + '1';
end if;
else
address_counter <= (others => '0');
end if;
end if;
end process;
buffer_address_dvi <= address_counter;
Ich verwende ein Register und halte die Pufferausgabe im Inneren. Dann gebe ich bei jedem Taktzyklus für 16 Zyklen das LSB des Inhalts des Registers aus und verschiebe die Daten nach rechts. Was mir im Kopf bleibt, ist, ob ich die Leseadresse früher generieren muss oder nicht.
Wenn derzeit eine 0 im Puffer vorhanden ist, entspricht dieses Pixel Grün. Wenn 1, entspricht es Blau. Was ich tue, ist, dass ich den RAM voller '1's instanziiere. Dann schreibe ich '0' in einen Teil davon und versuche, eine dicke horizontale Linie auf dem Bildschirm zu beobachten. Glücklicherweise sehe ich diese horizontale Linie, aber sie ist nicht stationär. Es wischt den Bildschirm von oben nach unten oder von unten nach oben, ich kann es nicht unterscheiden. Was könnte die Ursache für dieses spezielle Problem sein?
Vor ein paar Tagen gefunden:
Ich habe die Framebuffer-Adresse nicht nur während des aktiven Teils des DVI erhöht, sondern auch während der Austastperioden. Dies führte zu einer Verschiebung auf dem Bildschirm. Vielen Dank für Ihre Antworten.
David Tweed
Toygun Başaklar
mng
Toygun Başaklar
mng