Forum: FPGA, VHDL & Co. Xilinx (Digilent Nexys4) mit Micron SRAM Ansteuerung


von Alex (Gast)


Lesenswert?

Hallo
ich bin ein FPGA Neuling und habe mir ein Nexys4 zum rumbasteln gekauft.

Jetzt habe ich das Problem, dass bei meinem Project der interne BRAM 
nicht mehr ausreicht. Da das Board, wie auch das Nexys3, einen 128Mb 
großen Cellram (Pseudo Stratic RAM) hat, wollte ich darauf ausweichen. 
Das größte Problem ist, dass ich aus den Manuals nicht schlau werde bzw. 
nicht verstehe, wie ich so einen SRAM ansteuere. Ich habe mich schon 
durch verschiedene Tutorials und Vorlesungen gelesen doch nicht das 
richtige gefunden.

Mein jetziger code sieht so aus
1
module ram # ( parameter ADDRBITS=10 ) (
2
  address,
3
  clock,
4
  data,
5
  wren,
6
  q);
7
8
  input  [ADDRBITS-1:0]  address;
9
  input    clock;
10
  input  [255:0]  data;
11
  input    wren;
12
  output  [255:0]  q;
13
14
  //synthesis attribute ram_style of store is block
15
  reg [255:0] store [(2 << (ADDRBITS-1))-1:0];
16
  reg[ADDRBITS-1:0] raddr_reg;
17
  
18
  always @ (posedge clock)
19
  begin
20
    raddr_reg <= address;
21
    if (wren)
22
      store[address] <= data;
23
  end
24
  
25
  assign q = store[raddr_reg];
26
      
27
endmodule

und damit klappt auch alles nur dass der Speicherplatz dann nicht 
ausreicht.
So spreche ich das Modul an:
1
ram ram1 (ram_addr, ram_clk, ram1_din, ram_wren, ram1_dout);

Jetzt zu dem, was ich für sram gefunden habe:
1
module sram_model(
2
  input [9:0] addr,
3
  inout [7:0] data,
4
  input oe_n,
5
  input we_n
6
  );
7
  
8
  
9
  reg [7:0] sram[0:1023];
10
  
11
  always @ (posedge we_n)
12
    sram[addr] = data;
13
    
14
  assign data = (oe_n == 0) ? sram[addr] : 8'bz;
15
  
16
endmodule

Wie kann ich das ansprechen?

Jetzt zu meinem Problem:
wenn ich das jetzt richtig verstehe kann ich ja nur ein 8Bit wort über 
data einlesen bzw. herausbekommen. Aber eine Zelle von dem Ram soll 
8Mbit haben. Vielleicht verstehe ich auch die Grundlagen eines solchen 
RAM noch nicht.

Die komplizierten Sachen wie asynchrone/synchrone/burst Ansteuerung habe 
ich mir noch nicht angeschaut.

von Gustl B. (-gb-)


Lesenswert?

Also Micron hat da ein hybsches Dokument zu.

www.micron.com/~/media/Documents/Products/Data%20Sheet/DRAM/Mobile%20DRA 
M/PSRAM/128mb_burst_cr1_5_p26z.pdf

Da ist für jeden Zugriff, also lesen, schreiben und die 
unterschiedlichen Arten ein Diagramm wie die Signale aussehen sollen, 
also so eine "Wellenform".

Das solltest du nachbilden, also mit den richtigen Timings die da auch 
dabei stehen. Async read/write ist noch das Einfachste aber nicht 
sonderlich schnell.

Ich habe das auf dem Nexys2 gemacht und kann dir bei Bedarf etwas Code 
geben.

von Alex (Gast)


Lesenswert?

Das Micron Datenblatt habe ich mir schon durchgelesen. Doch leider kann 
ich damit nicht so viel anfangen.

Wäre super, wenn du den Code mal posten könntest, damit ich grob eine 
Ahnung davon bekomme, wie so etwas funktioniert.

von Gustl B. (-gb-)


Lesenswert?

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use IEEE.numeric_std.all;
4
5
entity sram is
6
7
port (clock: in std_logic;
8
    oe, wr, ce: out std_logic;
9
    addr: out std_logic_vector(23 downto 1);
10
    data: inout std_logic_vector(15 downto 0));
11
end sram;
12
13
architecture Behavioral of sram is
14
15
16
signal b: std_logic;
17
signal address: std_logic_vector(23 downto 1):= "00000000000000000000000";
18
signal sro: std_logic_vector(15 downto 0); --sram out
19
signal sri: std_logic_vector(15 downto 0); --sram in
20
21
begin
22
23
data <= sro when b = '0' else "ZZZZZZZZZZZZZZZZ";
24
sri <= data when b = '1';
25
26
process begin
27
   wait until rising_edge(clock);
28
  
29
30
    if counter_lesen < 5 then
31
      counter_lesen <= counter_lesen + 1;
32
    elsif counter_lesen = counter_lesen and START_LESEN = '1' then
33
      counter_lesen <= 0;
34
    end if;
35
36
     
37
    if counter_lesen = 0 then -- lesezugriff
38
      ce <= '1';
39
      oe <= '1';
40
      wr <= '1';
41
      b <= '1';
42
    elsif (counter_lesen = 1 or counter_lesen = 2) then
43
      ce <= '0';
44
      oe <= '1';
45
      wr <= '1';
46
      b <= '1';
47
      addr <= address;
48
    elsif (counter_lesen = 3 or counter_lesen = 4 or counter_lesen = 5) then
49
      ce <= '0';
50
      oe <= '0';
51
      wr <= '1';
52
      b <= '1';
53
      addr <= address;
54
        buff(15 downto 0) <= sri;
55
    end if;
56
       
57
    if counter_schreiben < 3 then
58
      counter_schreiben <= counter_schreiben + 1;
59
    elsif counter_schreiben = counter_schreiben and START_SCHREIBEN = '1' then
60
      counter_schreiben <= 0;
61
    end if;
62
     
63
    if counter_schreiben = 0 then -- schreibzugriff
64
      ce <= '1';
65
      oe <= '0';
66
      wr <= '0';
67
      b <= '1';
68
    elsif counter_schreiben = 1 then
69
      ce <= '0';
70
      oe <= '0';
71
      wr <= '1';
72
      b <= '1';
73
      addr <= ad1;
74
    elsif counter_schreiben = 2 then
75
      ce <= '0';
76
      oe <= '0';
77
      wr <= '0';
78
      b <= '0';
79
      addr <= address;
80
      sro <= buff(15 downto 0);
81
    elsif counter_schreiben = 3 then
82
      ce <= '1';
83
      oe <= '0';
84
      wr <= '0';
85
      b <= '0';
86
      addr <= address;
87
      sro <= buff(15 downto 0);
88
    end if;
89
90
91
end process;
92
93
94
end Behavioral;

Also das habe ich jetzt schnell "modifiziert", also alles Zusätzliche 
rausgeworfen.
Was mit den gelesenen Daten geschieht und woher die zu schreibenden 
kommen und wie die Addresse generiert wird ist hier noch komplett 
unvollständig. Es zeigt nur den sequentiellen Ablauf eines Asynchronen 
Schreib- und Lesezugriffs. Der Takt war bei mir 50MHz.

von Alexander F. (alexf91)


Angehängte Dateien:

Lesenswert?

Ich arbeite derzeit an einem kleinen Projekt mit dem Nexys2-Board.

Der RAM dient hierbei als Zwischenspeicher für Berechnungen und VGA 
Ausgabe, deshalb die vielen Signale in der Portdefinition.

Ich schreibe jeweils 32 Words in den Speicher und lese auch genau so 
viele aus (Konfiguration im 32 Words Burst-Mode).
Die Daten kommen aus dem CalcFifo und werden in den LineFifo 
geschrieben.

Als Eingangstakt werden 80MHz verwendet. Der RAM wird mit um 180° 
verschobenen 80MHz getaktet, damit ich die Setup- und Hold-Zeiten 
erfülle.

Der Code ist noch ungetestet, die Simulation sieht fürs erste ganz gut 
aus. Ich arbeite derzeit noch an einer Testbench mit dem von Micron 
bereitgestellten Simulationsmodell.

: Bearbeitet durch User
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.