Hallo
ich quael mich schon laenger mit RAMs in Altera herum. Wobei es nicht um
deren Verwendung an sich geht, das klappt einwandfrei, es geht mehr
darum, die Modul-Bauweise ordentlich einzupflegen.
Im aktuellen Fall geht es um einen Video Filter, der eine Bildzeile
Delay erzeugt. Die Zeile muss dadurch natuerlich gebuffert werden, und
das mach ich mit einem RAM. Funktioniert auch fein, allerdings ist das
RAM mit dem MegaWizzard generiert und dadurch in allen Parametern
fixiert. Der Filter soll aber so aufgebaut werden, dass er auch auf
andere Video Domains gesetzt werden kann (groesserer oder kleinerer
Frame z.B.), wodurch die laenge und/oder Tiefe des RAMs natuerlich
verandert werden muss. Das VHDL Modul wird via Generics an die Video
domain angepasst, sprich Anzahl pixels per Zeile, Anzahl Zeilen per
Frame, Video bitbreite etc.
Wie ist es jetzt hinzubekommen, dass ich im Modul-Code das RAM
initialisiere und als Parameter dafuer die Generics benutze?
Die einzige Moeglichkeit, die ich bisher gefunden habe, ist das
"ramstyle" Attribut. Allerdings wird das RAM dann in Logic Cells
synthetisiert (was zugegeben etwas umstaendlich ist).
Wenn mich nicht alles taeuscht kriegt der Synthesizer Probleme damit,
dass ich das RAM auf zwei verschiedenen Adressen lese und gleichzeitig
schreibe.
Wenn ich normal ein MegaWizzard RAM einbinde (altsyncram als dualport)
ist das ganze hingegen kein Problem.
1 | -- Address with offset of 1, reads ahead of write pointer
|
2 | s_line_rdaddress <= to_unsigned (s_pixel_cnt + 1, G_BUFFER_ADRS_WIDTH);
|
3 | s_line_wraddress <= to_unsigned (s_pixel_cnt, G_BUFFER_ADRS_WIDTH);
|
4 |
|
5 |
|
6 | line_buffer: entity work.dpr_linebuffer(SYN)
|
7 | port map
|
8 | (
|
9 | clock => i_clk,
|
10 | data => std_logic_vector (s_line_data),
|
11 | rdaddress => std_logic_vector (s_line_rdaddress),
|
12 | wraddress => std_logic_vector (s_line_wraddress),
|
13 | wren => '1',
|
14 | unsigned (q) => s_line_q
|
15 | );
|
Hier noch eben mein Versuch mit dem RAMSTYLE Attribut:
1 | type t_line_buffer is array (0 to G_NMBR_HOR) of unsigned (G_VIDEO_WIDTH - 1 downto 0);
|
2 | signal s_line_buffer : t_line_buffer := (others => (others => '0'));
|
3 | attribute ramstyle : string;
|
4 | attribute ramstyle of s_line_buffer : signal is "M9K";
|
Die Zugriffe (lesen und schreiben) sind entsprechend dem ersten
Codeschnipsel (also write und read address)
Das ganze rennt auf einem cyclone 3, wir benutzen Quartus II 9.1
Ich hoffe die Problemstellung ist einigermassen zu verstehen. Ich hab
das ganze mit Xilinx auch schon mal hinbekommen vor ein paar Jahren,
aber bei Altera stehe ich gerade irgendwie ziemlich doof da, wobei es
wahrscheinlich einfach nur am richtigen Attribut scheitert.
Danke im Vorraus schonmal fuer Denkanstoesse