Forum: FPGA, VHDL & Co. Block Ram Mode


von Dirk (Gast)


Lesenswert?

Hallo,

ich wuerde gerne fuer mein Blockram den Mode aendern von default
"write first" in "read first". Ich benutze keine Templates fuer den
Blockram, weil es kein Template fuer diese Ramgroesse gibt.
Normalerweise stellt man den Mode ueber Generic Map ein, aber bei
meinem Modul bekomme ich dann Synthesize Fehler. Hat jemand ein Tipp?

Kann mir jemand helfen oder komme ich in diesen Fall nicht um den
Coregen herum?

Gruß,
Dirk
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
---- Uncomment the following library declaration if instantiating
7
---- any Xilinx primitives in this code.
8
--library UNISIM;
9
--use UNISIM.VComponents.all;
10
11
entity Block_ram is
12
   generic (
13
      RESET_ACTIVE   : std_logic := '1'
14
   );
15
   port (
16
      clk            : in  std_logic;
17
      en             : in  std_logic;
18
      ADRESSE        : in  std_logic_vector(13 downto 0);
19
      DB_I           : in  std_logic_vector(7 downto 0);
20
      DB_O           : out std_logic_vector(7 downto 0);
21
      we             : in  std_logic
22
   );
23
24
end entity Block_ram;
25
26
architecture RTL of Block_ram is
27
   constant BIT_DEPTH      : positive  := 16384;
28
   constant BIT_WIDTH      : positive  := 8;
29
   
30
   type ram_t is array(BIT_DEPTH-1 downto 0)
31
      of std_logic_vector(BIT_WIDTH-1 downto 0);
32
33
   -- infer RAM
34
   signal blockram   : ram_t; 
35
36
begin 
37
38
   process (clk)
39
   begin
40
  
41
      if rising_edge(clk) then  
42
       if(en = '1') then  
43
         if (we = '1') then
44
           blockram(conv_integer(ADRESSE)) <= DB_I;
45
           DB_O <= DB_I;
46
         else
47
           DB_O <= blockram(conv_integer(ADRESSE));
48
         end if;
49
       end if;
50
     end if;
51
52
   end process;
53
54
end RTL;

von Thomas B. (paraglider)


Lesenswert?

Hallo Dirk,

Statt

if (we = '1') then
   blockram(conv_integer(ADRESSE)) <= DB_I;
   DB_O <= DB_I;
else
   DB_O <= blockram(conv_integer(ADRESSE));
end if;

musst du schreiben:

if (we = '1') then
   blockram(conv_integer(ADRESSE)) <= DB_I;
end if;
DB_O <= blockram(conv_integer(ADRESSE));

Gruß,
Thomas

von Dirk (Gast)


Lesenswert?

Hallo,

mein Problem welches ich eiegentlich habe liegt wohl anderer Natur.


Ich hab das Problem das meine Daten richtig ins BRAM gespeichert
werden, aber wenn ich die Daten lese bekomme ich alle Daten um einen
Takt verschoben.

Mir wurde gestern erzaehlt das dieses an der inneren Pipelinestruktur
liegt und das ich ein Delay am Ram Output (1. Takt)brauche.

Ich verstehe das ueberhaupt nicht :(

Ich lege die Adresse an das BRAM und erwarte eigentlich in diesem Takt
auch die Daten. Ich dachte im ersten Moment das die Daten auch um einen
Takt falsch im BRAM liegen, aber Sie liegen richtig im RAM ,wenn ich mir
den Testbench anschaue.

Muss ich wirklich nach dieser Reihenfolge die Daten auslesen?

1. Takt Adresse anlegen
2. Takt Delay
3. Daten vom Ram an eine weitere Stufe geben?

Falls dem so ist wie realsiere ich soetwas und vorallendigen wieso ist
das so?

Gruß,
Dirk

von Dirk (Gast)


Lesenswert?

PS.: Ich hab sogar extra nochmal das Design mit den Xilinx Templates
geprüft, weil ich vermutet hatte das es ein Distrubted RAM ist welches
ISE aus meinen Code synthesized.

von Dirk (Gast)


Lesenswert?

Hi,

für eine bessere Hilfe befindet sich der Code im Anhang.
Ich würde mich drüber freuen, wenn sich jemand die Mühe machen würde
einmal über den Code zuschauen.

Oder kann jemand anderes mir seinen Erfahrungsbericht bei der Nutzung
des internen Blockram mitteilen?

Dirk

von Dirk (Gast)


Angehängte Dateien:

Lesenswert?

sry zu schnell.

von Thomas B. (paraglider)


Lesenswert?

Hallo Dirk,

dein Problem ist in der Tat ein anderes. Lies mal in der xapp463 nach.
Es ist eigentlich ganz einfach:

Du legst eine Adresse (und ggf. Daten) an das BRAM an. Am Ausgang tut
sich jetzt erstmal nichts, unabhängig vom Modus!

Beim nächsten Takt geht der Datenausgang auf den Wert entsprechend der
Adresse, die VOR dem Takt an das BRAM angelegt wurde. Beim Schreiben
ist dieser Wert vom Modus abhängig: Bei Write First ist es bereits der
neue Wert, bei Read First ist es noch der alte Wert der Speicherstelle.
Bei No Change ändert sich der Ausgang zunächst nicht!

Dieses Verhalten nennt man "synchrones Lesen/Schreiben" oder
"registered". Mag sein, dass es dir in deinem Fall nicht entgegen
kommt, ein echtes Hindernis sollte es aber nicht sein. Das "verteilte
RAM" verhält sich übrigens so, wie du es vielleicht vermutest: Der
Ausgang folgt direkt der Adresse - der Takt gilt nur für das Schreiben.
Also "asynchron Lesen/synchron Schreiben".

Gruß,
Thomas

von Dirk (Gast)


Lesenswert?

Hi,

ich bedanke mich fuer die Information jetzt werde ich wohl weiter
kommen.

GRuß,
Dirk

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.