Hallo Leute Ich benötige std_logic_vector Array in VHDL. Der Code sieht folgendermassen aus: LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.numeric_std.all; USE ieee.std_logic_unsigned.all; ENTITY blabla IS PORT ( ... ); END ENTITY blabla ; ARCHITECTURE rtl OF blabla IS -- My Signals TYPE RAM_TYPE IS ARRAY(255 downto 0) OF std_logic_vector(7 downto 0); -- line 49 SIGNAL Pixel_Buffer1 : RAM_TYPE := (others => X"00"); SIGNAL Pixel_Buffer2 : RAM_TYPE := (others => X"00"); .... BEGIN .... END ARCHITECTURE rtl; Ich vervende HDL Designer für die TestBench. Wenn ich aber den Code prüfen lasse erhalte ich folgende Fehlermeldung: Line 49: ERROR, Non-Standard IEEE type "INTEGER", used for index of array type "RAM_TYPE" Ich kann aber QuestaSim starten, die Signale Pixel_Buffer 1+2 fehlen jedoch. Fehlt da irgend noch eine ieee Lib? Danke und Gruss Antonio
entweder nur diese libraries USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all; oder diese hier USE ieee.numeric_std.all; aber nicht beide gleichzeitig
Antonio C. schrieb: > Fehlt da irgend noch eine ieee Lib? Ja, pack ruhig noch ein paar drauf. Viel hilft viel... :-/ Wie schon user schrieb: > aber nicht beide gleichzeitig Siehe den Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete" Aber das ist nicht dein Problem... Antonio C. schrieb: > Line 49: ERROR, Non-Standard IEEE type "INTEGER", used for index of > array type "RAM_TYPE" Mit ISIM geht das ohne Fehler (na gut, bei 256 hagelts den Index natürlich raus):
1 | LIBRARY ieee; |
2 | USE ieee.std_logic_1164.all; |
3 | USE ieee.std_logic_arith.all; |
4 | USE ieee.numeric_std.all; |
5 | USE ieee.std_logic_unsigned.all; |
6 | |
7 | entity versuchmachtkluch is |
8 | port ( y : out std_logic_vector(15 downto 0); |
9 | clk : in std_logic); |
10 | end versuchmachtkluch; |
11 | |
12 | architecture Behavioral of versuchmachtkluch is |
13 | |
14 | TYPE RAM_TYPE IS ARRAY(255 downto 0) OF std_logic_vector(7 downto 0); |
15 | SIGNAL Pixel_Buffer1 : RAM_TYPE := (x"11",X"22",x"33",others => X"00"); |
16 | SIGNAL Pixel_Buffer2 : RAM_TYPE := (x"aa",x"bb",x"cc",others => X"00"); |
17 | |
18 | begin
|
19 | |
20 | process
|
21 | variable y1: integer := 0; |
22 | begin
|
23 | wait until rising_edge(clk); |
24 | y <= Pixel_Buffer1(y1) & Pixel_Buffer2(y1); |
25 | y1:=y1+1; |
26 | end process; |
27 | |
28 | end Behavioral; |
BTW: RAM_TYPE IS ARRAY(255 downto 0) OF std_logic_vector Warum definierst du dein RAM kopfüber? Meine RAMs beginnen alle mit der Adresse 0 und steigen dann an...
Vielen Dank für die Antworten @Lothar: inkl. lustigen Kommentare... ;) Ich probier es mal aus...
Hallo Lothar Obiges Beispiel hat gut geklappt... Nun hätte ich die nächste Frage: Mit folgendem Code erstelle ich Stimulis... LIBRARY ieee; USE ieee.std_logic_1164.all; --USE ieee.numeric_std.all; ENTITY my_rgb2yuv_ip_tester IS PORT ( ... coe_iRED : OUT std_logic_vector(11 downto 0); ... ); END my_rgb2yuv_ip_tester; LIBRARY my_rgb2yuv_ip_lib; ARCHITECTURE rtl OF my_rgb2yuv_ip_tester IS -- Architecture declarations BEGIN coe_iRED(0) <= transport '0', '1' after 1896 ns, '0' after 2007 ns, '1' after 2192 ns, '0' after 2414 ns, '1' after 4527 ns, '0' after 4971 ns, '1' after 8486 ns, '0' after 8671 ns, '1' after 9337 ns, '0' after 10299 ns, '1' after 10743 ns, '0' after 11187 ns, '1' after 11668 ns, '0' after 12001 ns, '1' after 12889 ns, '0' after 13074 ns; coe_iRED(1) <= transport '0', '1' after 1970 ns, '0' after 2414 ns, '1' after 3117 ns, '0' after 3672 ns, '1' after 4375 ns, '0' after 5152 ns, '1' after 5670 ns, '0' after 5855 ns, '1' after 6817 ns, '0' after 8963 ns, '1' after 10221 ns, '0' after 11146 ns, '1' after 12293 ns, '0' after 13181 ns, '1' after 14846 ns, '0' after 15290 ns; ... ... ... END rtl; in QuestaSim sehe ich aber nur lauter Nullen bei coe_iRed. Kann mir jamand sagen was ich falsch mache??? Besten Dnak im Voraus. Gruss Antonio
ok war ne blöde Frage, wie wärs mit Simulations-Zeit verlängern in QuestaSim... ;)
Allerdings ist das natürlich KEINE Testbench. Denn eine Testbench (zumindest den Top-Level) erkennt man daran, dass die Entity keinen Port hat...
Jo das war der tester mit den Stimulis. Meine Testbench besteht aus - DUV.vhd - DUV_tb.vhd (Entitiy ohne ports) - DUV_tester.vhd (Stimulis) Erstellt in HDL Designer und simuliert mit QuestaSim... ;o) Greez
Ich habe obiges Array folgendermassen deklariert: TYPE RAM_TYPE IS ARRAY(0 to 921599) OF std_logic_vector(7 downto 0); Die 921599 gemäss 640x480x3 berrechnet. --> PixelBuffer für 1 frame. Gibt es eigentlich eine Grenze die nicht überschritten werden darf, ausser die memory des FPGA's? Ich verwende ein Cyclone IV Cyclone IV EP4CE115 FPGA 114,480 logic elements (LEs) 432 M9K memory blocks 3,888 Embedded memory (Kbits) 266 Embedded 18 x 18 multipliers 4 General-purpose PLLs 528 User I/Os Ein M9K Block ist glaub um 4k gross wenn ich mich nicht täusche... Danke und Gruss Antonio
>> Line 49: ERROR, Non-Standard IEEE type "INTEGER", used for index of >> array type "RAM_TYPE" >Mit ISIM geht das ohne Fehler (na gut, bei 256 hagelts den Index >natürlich raus): @Lothar: was geschieht genau, wenn der Index 256 ist? Wie kann ich der Index erweitern, damit ich ein Array für ein vollständigen Frame besitze (640x3x480)? greez Antonio
Antonio C. schrieb: >>Mit ISIM geht das ohne Fehler (na gut, bei 256 hagelts den Index >>natürlich raus): > @Lothar: was geschieht genau, wenn der Index 256 ist? Weil das "nur" für die Simulation war, kommt da einfach ein Fehler... In der Hardware würde ein 8-Bit-Zähler erzeugt, der einfach wieder bei 0 anfängt... Antonio C. schrieb: > Wie kann ich der Index erweitern, damit ich ein Array für ein > vollständigen Frame besitze (640x3x480)? Ich würde das x3 in einem RGB-Vektor packen, und den einfach 24Bit breit machen. Und dann bliebe noch ein 2-dimensionales Array übrig: http://www.lothar-miller.de/s9y/categories/32-Arrays
Hallo Lothar habe es so versucht (eigentlich nur letzten Prozess rilevant):
1 | LIBRARY ieee; |
2 | USE ieee.std_logic_1164.all; |
3 | USE ieee.numeric_std.all; |
4 | |
5 | |
6 | ENTITY my_rgb2yuv_ip IS |
7 | Generic ( CONSTANT Col : integer := 10; |
8 | CONSTANT Raw : integer := 10 |
9 | );
|
10 | PORT
|
11 | (
|
12 | -- Avalon Conduit to VHDL_Detector Clock Interface
|
13 | coe_iCLK_CCD : in std_logic; |
14 | coe_iRST_N_CCD : in std_logic; |
15 | -- Avalon Conduit to VHDL_Detector IN-Ports
|
16 | coe_iLVAL_CCD : in std_logic; |
17 | coe_iFVAL_CCD : in std_logic; |
18 | coe_iRED : in std_logic_vector(11 downto 0); |
19 | coe_iBLUE : in std_logic_vector(11 downto 0); |
20 | coe_iGREEN : in std_logic_vector(11 downto 0); |
21 | -- Avalon Clock Interface
|
22 | csi_clk : in std_logic; |
23 | csi_rst_n : in std_logic; |
24 | -- Avalon-MM Interface / Slave Port
|
25 | avs_write : in std_logic; |
26 | avs_writedata : in std_logic_vector(31 downto 0); |
27 | avs_read : in std_logic; |
28 | avs_readdata : out std_logic_vector(31 downto 0) |
29 | );
|
30 | END ENTITY my_rgb2yuv_ip; |
31 | |
32 | |
33 | |
34 | |
35 | ARCHITECTURE rtl OF my_rgb2yuv_ip IS |
36 | |
37 | -- My Signals
|
38 | |
39 | TYPE PixelVector IS ARRAY(0 to Col) OF std_logic_vector(23 downto 0); |
40 | TYPE LineVector IS ARRAY(0 to Raw) OF PixelVector; |
41 | SIGNAL FrameBuffer : LineVector; |
42 | |
43 | SIGNAL ColAddr : integer range 0 to Col := 0; |
44 | SIGNAL RawAddr : integer range 0 to Raw := 0; |
45 | |
46 | SIGNAL sig_LVAL : std_logic := '0'; |
47 | SIGNAL sig_FVAL : std_logic := '0'; |
48 | SIGNAL sig_DVAL : std_logic := '0'; |
49 | SIGNAL sig_RED : std_logic_vector(7 downto 0) := (others => '0'); |
50 | SIGNAL sig_GREEN : std_logic_vector(7 downto 0) := (others => '0'); |
51 | SIGNAL sig_BLUE : std_logic_vector(7 downto 0) := (others => '0'); |
52 | SIGNAL sig_RGB : std_logic_vector(23 downto 0) := (others => '0'); |
53 | SIGNAL sig_NULL : std_logic_vector(1 downto 0) := (others => '0'); |
54 | SIGNAL sig_DataPixelValue : std_logic_vector(31 downto 0) := (others => '0'); |
55 | |
56 | --End of my Signals
|
57 | |
58 | |
59 | |
60 | BEGIN
|
61 | |
62 | write_proc: process(csi_clk, csi_rst_n) |
63 | begin
|
64 | if csi_rst_n = '0' then |
65 | --<= (others => '0');
|
66 | elsif rising_edge(csi_clk) then |
67 | if avs_write = '1' then |
68 | --<= avs_writedata;
|
69 | end if; |
70 | end if; |
71 | |
72 | end process write_proc; |
73 | |
74 | |
75 | |
76 | read_proc: process(csi_clk, csi_rst_n) |
77 | begin
|
78 | if csi_rst_n = '0' then |
79 | sig_DataPixelValue <= (others => '0'); |
80 | elsif rising_edge(csi_clk) then |
81 | if avs_read = '1' then |
82 | --sig_DataPixelValue <= sig_FVAL & sig_LVAL & sig_BLUE & sig_NULL & sig_GREEN & sig_NULL & sig_RED & sig_NULL;
|
83 | end if; |
84 | end if; |
85 | end process read_proc; |
86 | |
87 | --avs_readdata <= sig_DataPixelValue;
|
88 | |
89 | |
90 | |
91 | fillFrameBuffer: process (coe_iCLK_CCD) |
92 | variable var_DVAL : std_logic; |
93 | begin
|
94 | if rising_edge (coe_iCLK_CCD) then |
95 | var_DVAL := coe_iLVAL_CCD and coe_iFVAL_CCD; |
96 | if var_DVAL = '1' then -- DataValid? |
97 | FrameBuffer(RawAddr)(ColAddr) <= coe_iBLUE(11 downto 4) & coe_iGREEN(11 downto 4) & coe_iRED(11 downto 4); |
98 | --FrameBuffer(RawAddr)(ColAddr) <= x"125687"; -- for debug
|
99 | if(ColAddr < Col) then |
100 | ColAddr <= ColAddr+1; |
101 | else
|
102 | ColAddr <= 0; |
103 | if(RawAddr < Raw) then |
104 | RawAddr <= RawAddr+1; |
105 | else
|
106 | RawAddr <= 0; |
107 | end if; |
108 | end if; |
109 | avs_readdata <= sig_NULL & sig_NULL & sig_NULL & sig_NULL & FrameBuffer(RawAddr)(ColAddr); |
110 | end if; |
111 | end if; |
112 | end process fillFrameBuffer; |
113 | |
114 | END ARCHITECTURE rtl; |
in der Sim funktioniert es gut nur mit Quartus bei der Synthese motzt er, er hätte nicht genügend M9K Memory Blöcke (432 x 4069Bit M9K). Wenn ich im letzten Prozess folgendes auskommentiere:
1 | avs_readdata <= sig_NULL & sig_NULL & sig_NULL & sig_NULL & FrameBuffer(RawAddr)(ColAddr); |
dann kommt keine Fehlermeldung. Ich habe 2 complilation reports als Bild hinzugefügt. Auch habe ich
1 | avs_readdata <= sig_NULL & sig_NULL & sig_NULL & sig_NULL & FrameBuffer(RawAddr)(ColAddr); |
ausserhalb des Prozesses gesetzt, kommt dieselbe Fehlermeldung. Mache ich da was falsch? Danke und Gruss Antonio
Schau Dir mal Deinen zweiten Report an. Vor allem die Zeile mit den memory bits. Du brauchst zu viele davon. Wenn Du Deine avs_readdata-Zeile auskommentierst, optimiert Dir der Synthesizer alles weg. Das ist bei VHDL u.U. so; kleine Änderung --> große Wirkung Duke
Duke Scarring schrieb: > Vor allem die Zeile mit den memory bits. Du brauchst zu viele davon. Richtig, das passt irgendwie nicht zum Code, denn 24 Bits *11 *11 sind weniger als 3000 Bits...
habe ich mit eben auch gedacht, es sind ja nur 2904 Bits... sollte ja genug haben... was könnte das denn heissen? Ich versuche nur den Code mit dem FrameBuffer in einem neun Projekt zu kompilieren.
andere, evtl. blöde Frage: Wieso werden in QuestaSim die Variablen nicht angezeigt?
habe es im neuen Projekt compiliert. Ist ja eigentlich klar, dass es nicht geht --> 24 x 640 x 480 = 7'372'800. Da sind einige memorys zu wenig. Wieso aber es mit 24 x 10 x 10 nicht ging ist komisch. Nichts desto trotz, ich werde den externen SRAM benutzen...
Antonio C. schrieb: > Wieso werden in QuestaSim die Variablen nicht angezeigt? Halb so schlimm: das kann ISIM auch noch nicht...
Antonio C. schrieb: > Wieso aber es mit 24 x 10 x 10 nicht ging ist komisch. Hm, liegt vielleicht daran, dass der BlockRAM ja eine Granularität hat. Bei Xilinx ist der 9 Bit mal 1024 (auf neueren Spartans usw.) bzw. 18 Bit x 1024, da verschenkt man natürlich bei 10 Bit Worbreite eine Menge Speicher. Wird wohl bei den anderen auch nicht viel anders sein.
Antonio C. schrieb: > Wieso aber es mit 24 x 10 x 10 nicht ging ist komisch. Es ist wie schon gesagt 24 x 11 x 11 ... :-o Ich vermute, der Synthesizer hat die Beschreibung falsch interpretiert und das RAM falsch angeschlossen... Irgendwo gibts für Altera auch Guidelines, wie etwas beschreiben werden muß (z.B. RAM), dass der Synthesizer das richtig erkennt.
nun in der Zwischenzeit habe ich den Fehler gefunden. In den Generics, in einer oberen Datei-Hierarchie stand immer noch 679x479 drin. Alles gelöscht und neu compiliert, da funktionierte es endlich. Aber jetzt zum nächsten Problem: Der Code im Anhang zeigt mir eine Fehlermeldung bei der Synthese: Error (276003): Cannot convert all sets of registers into RAM megafunctions when creating nodes. The resulting number of registers remaining in design exceeds the number of registers in the device or the number specified by the assignment max_number_of_registers_from_uninferred_rams. This can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis Ich vermute, weil ich 2 Prozesse, einen zum lesen und der andere zum schreiben verwende. Zusätzlich lese ich asynchron und das generiert Logikzellen. Ich habe mir die Beschreibung über FIFO's auf Deiner (Lothar Miller) Homepage gelesen. Wie kann uch da den Inhalt des Frambuffers einem schnelleren Prozess zum lesen übergeben? Danke und Gruss Antonio
1 | TYPE PixelVector IS ARRAY(0 to Col) OF std_logic_vector(23 downto 0); |
2 | TYPE LineVector IS ARRAY(0 to Raw) OF PixelVector; |
Das sind netto satte 1,8MBit. Wieviel hat dein FPGA? > Wie kann uch da den Inhalt des Frambuffers einem > schnelleren Prozess zum lesen übergeben? Du kannst den ganzen Framebuffer, der ja im RAM liegt, nur mit einem Multiplexer (Adresse, Daten) übergeben. > Ich vermute, weil ich 2 Prozesse, einen zum lesen und der andere zum > schreiben verwende. Zusätzlich lese ich asynchron und das generiert > Logikzellen. Für Xilinx gibt es den XST User Guide, in dem steht, wie man Code schreiben muss, damit der Synthesizer ein RAM erkennt. Für Altera gibt es auch sowas, ich meine dort auf Seite 11-23 was gefunden zu haben: http://www.altera.com/literature/hb/qts/qts_qii51007.pdf
> Das sind netto satte 1,8MBit. Wieviel hat dein FPGA? Ich habe ca. 3.4MBit, --> bevor ich den 2. Prozess zum lesen erstellte, zeigte er mir nach erfolgreichem compilieren ca. 60% Memory Nutzung. >> Wie kann ich da den Inhalt des Frambuffers einem >> schnelleren Prozess zum lesen übergeben? > Du kannst den ganzen Framebuffer, der ja im RAM liegt, nur mit einem > Multiplexer (Adresse, Daten) übergeben. Kannst Du mir darüber ein Code-Scnipsel als Beispiel geben? >> Ich vermute, weil ich 2 Prozesse, einen zum lesen und der andere zum >> schreiben verwende. Zusätzlich lese ich asynchron und das generiert >> Logikzellen. > Für Xilinx gibt es den XST User Guide, in dem steht, wie man Code > schreiben muss, damit der Synthesizer ein RAM erkennt. Für Altera gibt > es auch sowas, ich meine dort auf Seite 11-23 was gefunden zu haben: > http://www.altera.com/literature/hb/qts/qts_qii51007.pdf Sieht interessant aus, ist eigentlich gerade das was ich benötige. Schau mir es mal genauer an...
Antonio C. schrieb: >>> Wie kann ich da den Inhalt des Frambuffers einem >>> schnelleren Prozess zum lesen übergeben? >> Du kannst den ganzen Framebuffer, der ja im RAM liegt, nur mit einem >> Multiplexer (Adresse, Daten) übergeben. > Kannst Du mir darüber ein Code-Scnipsel als Beispiel geben? Bringt nichts, weil du ja gar keine 2 Puffer in dein RAM reinbekommst...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.