eine kurze Frage zu Xilinx BlockRAM im Spartan 3E:
Wie wird ein BlockRAM mit Speicherbreite 4Bit umgesetzt? Werden trotzdem
8Bit verwendet, der Rest ist einfach nicht benutzt oder wird ein
"echtes" 4Bit RAM erstellt?
Wäre auch ein 1Bit RAM möglich?
Sowas stelle ich mir vor:
Dann klick doch mal auf Synthesize und gucke, was rauskommt:
1
Loading device for application Rf_Device from file '4vlx15.nph' in environment ...
2
INFO:Xst:2452 - Unit <RAM_4Bit> : The small RAM <Mram_RAM> will be implemented on LUTs in order to maximize performance and save block RAM resources. If you want to force its implementation on block, use option/constraint ram_style.
> wird ein "echtes" 4Bit RAM erstellt?
Ja.
Allerdings werden bei deinem BRAM je nach FPGA einige Bits nicht
verwendet. Du brauchst nur 4096 Bits, ein BRAM eines S3 hat 18kBit, d.h.
du verwendest nur 1/4 davon (die unbenutzen Adressen werden einfach auf
0 gelegt).
> Wäre auch ein 1Bit RAM möglich?
Ja. Steht in der XAPP463.
Danke euch beiden für die Antworten.
Ich werde mal die AppNote studieren.
(ich wusste, dass sicher eine zum Thema bestehen muss, habe sie aber
nicht gefunden)
Martin
Anschlussfrage:
Ist es auch möglich, ein RAM zu erstellen, welches auf der einen Seite
2^9x32Bit organisiert ist, auf der anderen Seite 2^14*1Bit ?
Meine bisherigen Abklärungen deuten auf ein "Nein" hin.
Der Workaround wäre dann wohl: auch auf der zweiten Seite mit einer
grösseren Datenbreite zugreifen und die Bits mit nachgeschalteter Logik
decodieren.
Martin
> Anschlussfrage:> Ist es auch möglich, ein RAM zu erstellen, welches auf der einen Seite> 2^9x32Bit organisiert ist, auf der anderen Seite 2^14*1Bit ?
Ja. Ich habe selbst schon mit einem RAM gearbeitet, welches auf der
einen Seite als 2k*16 Bits und auf der anderen Seite als 1k*32 Bits
organisiert war. Bis auf die konkreten Zahlen habe ich also "genau das"
schon gemacht.
Das geht aber glaub ich nur wenn die eine Seite eine ganzzahlige
Vielfache einer zweierpotenz ist und hängt ggf auch vom Chip ab, ich
würd einfach mal schauen was der Coregenerator sagt.
> 2^9x32Bit organisiert ist, auf der anderen Seite 2^14*1Bit ?> Meine bisherigen Abklärungen deuten auf ein "Nein" hin.
Ich meine die XAPP463 auch so interpretieren zu können :-/
> Der Workaround wäre dann wohl: auch auf der zweiten Seite mit einer> grösseren Datenbreite zugreifen
Das Problem ist nicht die Seite mit 1 Bit. Es geht um die Breitseite :-o
Es gibt kein RAMB16_S1_S32, mit dem ein direktes Ummappen möglich wäre.
Es gibt nur einen RAMB16_S1_S36, also 1 Bit auf der einen, 36 bit auf
der anderen Seite :-/
Wenn ich z.B. auf der 1-Bit Seite an Adresse 0 etwas schreibe, kommt das
an der breiten Seite an Adresse 0 Bit 0 heraus.
Wenn ich auf auf der 1-Bit Seite an Adresse 31 etwas schreibe, kommt das
an der breiten Seite auf Adresse 0 Bit 31 heraus.
Wenn ich jetzt aber auf auf der 1-Bit Seite an Adresse 32 etwas
schreibe, und bei einem 32-Bit Wort dann die Adresse 1 Bit 0 erwarten
würde, kommt das am BRAM an der breiten Seite auf Adresse 0 Bit 32
heraus.
D.h. das BRAM kann nicht einfach als 1-->32 Bit-Buskonverter verwendet
werden. Eine Möglichkeit wäre jetzt, beim Schreiben auf der 1-Bit-Seite
die Adresse so zu manipulieren, dass auf der 36-Bit-Seite die Bits
35..32 nicht beschrieben werden.
Geht doch:
RAMB16_S1_S36 ist genau das, was Du brauchst:
an den Bits 0..31 (DOA(31 downto 0) oder DOB(31 downto 0))
liegen genau die 32 'eingeschriebenen' Bits
Bits 32..35 (DOPA(3 downto 0) oder DOPB(3 downto 0) einfach
'open' lassen
Gast wrote:
> RAMB16_S1_S36 ist genau das, was Du brauchst:
Sieht gut aus.
Wie verwende ich dieses Konstrukt nun konkret in meinem VHDL Code?
Kann mir da jemand evtl. ein Beispiel zeigen?
Lothar Miller wrote:
> Das sieht gut aus:
Tut es, ja.
Ich binde also das Dual Port RAM also als "component" ein:
1
componentRAMB16_S1_S36
2
port(
3
DIA:instd_logic_vector(0downto0);
4
ADDRA:instd_logic_vector(13downto0);
5
ENA:instd_logic;
6
WEA:instd_logic;
7
SSRA:instd_logic;
8
CLKA:instd_logic;
9
DOA:outstd_logic_vector(0downto0);
10
11
DIB:instd_logic_vector(31downto0);
12
DIPB:instd_logic_vector(3downto0);
13
ADDRB:instd_logic_vector(8downto0);
14
ENB:instd_logic;
15
WEB:instd_logic;
16
SSRB:instd_logic;
17
CLKB:instd_logic;
18
DOB:outstd_logic_vector(31downto0);
19
DOPB:outstd_logic_vector(3downto0)
20
);
21
endcomponent;
und verwende das Teil in der üblichen Art als Instanz:
1
U_RAMB16_S1_S36:RAMB16_S1_S36
2
portmap(
3
DIA=>X,-- insert 1 bit data in bus (<0 downto 0>)
4
ADDRA=>Y,-- insert 14 bits address bus
5
ENA=>Z,-- insert enable signal
6
...
Soweit, so gut.
Welche RAM Konfigurationen möglich sind, entnehme ich der AppNote 463,
Seite 10, Tabelle 7 (Bild im Anhang)
Woher nehme ich nun aber die Port Beschreibung? Muss ich mir diese aus
einem Beispiel kopieren oder sind die Port Maps für die einzelnen
Konfigurationsvarianten irgendwo abrufbar?
Aus dem Datenblatt zusammenklauben erscheint mir etwas mühsam...
Danke für die bisherigen Antworten.
Martin Kohler wrote:
> Woher nehme ich nun aber die Port Beschreibung?
Die steht in den Komentaren hinter dem Beispiel. Da solltest du
natürlich nicht X,Y und Z abschliessen, sondern eher z.B.
1
portmap(
2
DIA=>datain,-- insert 1 bit data in bus (<0 downto 0>)
3
ADDRA=>addrin,-- insert 14 bits address bus
4
ENA=>'1',-- insert enable signal / immer enabled
5
WEA=>write,-- insert write enable signal
6
SSRA=>'0',-- insert set/reset signal
7
CLKA=>clkin,-- insert clock signal
8
DOA=>open,-- insert 1 bit data out bus (<0 downto 0>)
9
--
10
DIB=>(others=>'0'),-- insert 32 bits data in bus (<31 downto 0>)
11
DIPB=>(others=>'0'),-- insert 4 bits parity data in bus (or <35 downto 32>)
12
ADDRB=>addrout,-- insert 9 bits address bus
13
ENB=>'1',-- insert enable signal / immer enabled
14
WEB=>'0',-- insert write enable signal / nur lesen
15
SSRB=>'0',-- insert set/reset signal
16
CLKB=>clkout,-- insert clock signal
17
DOB=>dataout,-- insert 32 bits data out bus (<31 downto 0>)
18
DOPB=>open-- insert 4 bits parity data out bus (or <35 downto 32>)
19
);
Hier jetzt 1 Bit Eingangsbreite und 32 Bit Ausgangsbreite. Du könntest
natürlich auch auf beiden Seiten lesen bzw. schreiben.
Danke für die bisherigen Antworten!
Lothar Miller wrote:
> Die steht in den Komentaren hinter dem Beispiel. Da solltest du> natürlich nicht X,Y und Z abschliessen, sondern eher z.B.
Ist schon klar, danke trotzdem ;-)
Gast wrote:
> sorry - genauer> <Xilinx-Installation>\doc\usenglish\books\docs\<device>_hdl\<device>.pdf
bei mir:
C:\Programme\Xilinx_92i\doc\usenglish\books\docs\s3edl
--> also eher: ...\docs\<device>dl
Die Port Beschreibungen habe ich nun im ISE auch gefunden:
>ISE x.y >Edit >Language Templates >VHDL >Device Primitive Instantiation >FPGA >RAM/ROM >Block RAM >...Spartan-3E >Dual-Port (Mis-matched Port Widths) >16k/1k x
1/16 ...
Wenn ich nun den oben beschriebenen Typ wähle erhalte ich den folgenden
(hier abgekürzten) Code:
1
-- <-----Cut code below this line and paste into the architecture body---->
Die im Teil "generic map" eingetragenen Daten werden als Initialwert in
s DPRAM übernommen, ich könnte so z.B. den Programmcode für einen
PicoBlaze einfügen, richtig?
Sehe ich auch richtig, dass ich den "generig map" Teil weglassen kann
und dann alles mit '0' resp. (others => '0') initialisiert wird?
Gruss, Martin