Forum: FPGA, VHDL & Co. std_logic_vector Array in vhdl


von Antonio C. (antonio-c)


Lesenswert?

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

von user (Gast)


Lesenswert?

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

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


Lesenswert?

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...

von Antonio C. (antonio-c)


Lesenswert?

Vielen Dank für die Antworten
@Lothar: inkl. lustigen Kommentare... ;)

Ich probier es mal aus...

von Antonio C. (antonio-c)


Lesenswert?

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

von Antonio C. (antonio-c)


Lesenswert?

ok war ne blöde Frage, wie wärs mit Simulations-Zeit verlängern in 
QuestaSim...  ;)

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


Lesenswert?

Allerdings ist das natürlich KEINE Testbench.
Denn eine Testbench (zumindest den Top-Level) erkennt man daran, dass 
die Entity keinen Port hat...

von Antonio C. (antonio-c)


Lesenswert?

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

von Antonio C. (antonio-c)


Lesenswert?

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

von Antonio C. (antonio-c)


Lesenswert?

>> 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

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


Lesenswert?

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

von Antonio C. (antonio-c)


Angehängte Dateien:

Lesenswert?

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

von Duke Scarring (Gast)


Lesenswert?

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

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


Lesenswert?

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...

von Antonio C. (antonio-c)


Lesenswert?

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.

von Antonio C. (antonio-c)


Lesenswert?

andere, evtl. blöde Frage:

Wieso werden in QuestaSim die Variablen nicht angezeigt?

von Antonio C. (antonio-c)


Lesenswert?

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...

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


Lesenswert?

Antonio C. schrieb:
> Wieso werden in QuestaSim die Variablen nicht angezeigt?
Halb so schlimm: das kann ISIM auch noch nicht...

von Christian R. (supachris)


Lesenswert?

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.

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


Lesenswert?

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.

von Antonio C. (antonio-c)


Angehängte Dateien:

Lesenswert?

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

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


Lesenswert?

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

von Antonio C. (antonio-c)


Lesenswert?

> 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...

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


Lesenswert?

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
Noch kein Account? Hier anmelden.