Forum: FPGA, VHDL & Co. Dual Port Ram, VHDL


von Mass (Gast)


Lesenswert?

Hallo,

Ich hab da ein Problem, ich habe ein Dual Port Ram, dort sind bestimmte 
Werte abgelegt, ich möchte explizit einen Wert zu ener bestimmten 
Adresse laden und dies in einer variable oder signal speichern, und 
solange dieser Wert nicht verändert wird, soll er so bleiben.

so ungefähr sieht das aus:
1
--mein Dual Port Ram
2
3
DPRAM_1 : DPRAM_1_S
4
      port map (
5
        -- Port A 
6
        clka => Clk,
7
        wea(0) => '0',                                    
8
        addra => WriteAddr, 
9
        dina => DataIn,
10
        douta => DataOut,
11
        -- Port B 
12
        clkb => Clk,
13
        web(0) => WriteEnable,
14
        addrb => Addr,
15
        dinb => WriteData,
16
        doutb => ram1b 
17
      );
18
19
SEL_BIT: std_logic_vector(7 downto 0) := x"5F"; --5F ist die Adresse des Wertes den ich laden will (der Wert ist entweder eine 0 oder 1).
20
variable sel: std_logic (0 downto 0);
21
22
Addr <= SEL_BIT(adr'range)
23
sel <= ram1b; --ich hab so gedacht, dass wenn zu der bestimmten Adresse ich den Wert lade, 
24
                       --ich den Ausgang des rams an die Variable sel übergebe, aber er läd ja alle werte des Rams, wie komme ich dazu, dass nur der eine Wert zu Adresse 5F übergeben wird und dann auch immer gespeichert bleibt.
Ich möchte eine Abfrage machen:

if sel = "0" then
Anweisung;
else
alternativ Anweisung;
end if;


wenn ich nun in der Simulation anschaue, läd er den wert an der STelle 
5F richtig, wie kann ich nun zielgnau, den bestimmten Wert an der 
Adresse 5F in eine Variable abspeichern, so dass er immer dort bestehen 
bleibt, jeden Takt soll er überprüfen nach diesen ´Wert, sobald dieser 
Wert geändert wird, wird ne andere Anweisung durchgeführt und der neue 
Wert bleibt dann in der variable.

von Uwe (Gast)


Lesenswert?

Hää ? Nochmal was willst du machen ?

von Sebastian H. (sebihepp)


Lesenswert?

Na, in dem du jeden Takt die Adresse erneut ausliest und mit dem 
gespeicherten Wert vergleichst.

von Duke Scarring (Gast)


Lesenswert?

Dein Text liest sich für mich etwas wirr. Vergiss das erstmal mit den 
Variablen. Nimm Signale. Die Teile die einen Wert speicher heißen 
übrigens Register. Vielleicht kannst Du mit diesen Begriffen Deine Frage 
noch mal stellen?

Duke

von Uwe (Gast)


Lesenswert?

> ich möchte explizit einen Wert zu ener bestimmten
> Adresse laden und dies in einer variable oder signal speichern
und wofür jetzt das Dual Port RAM ?

> solange dieser Wert nicht verändert wird, soll er so bleiben.
Ja das nennt man allgemein speichern

wo ist dein Problem ?

von P. K. (pek)


Lesenswert?

Dein Hintergrund (welche Anforderungen führen auf solch eine Aufgabe, 
vielleicht muss Du Dir das Ziel nochmals vor Augen führen) ist mir zwar 
nicht ganz klar, würde es aber in etwa folgendermassen (frei nach 
"divide & conquer") angehen:

- Lass das RAM wie's ist, als Building Block. Egal ob FPGA oder 
ASIC/Chip, da existieren vorgefertigte RAM-Blocks, die Du nicht ändern 
oder mit Speziallogik anreichern willst, schon aus Timing-Gründen.

- Parallel dazu, sozusagen als Wrapper ums RAM herum baust Du ein kleine 
State-Machine mit besagtem Wert in einem Register, welche den Zugriff 
auf die erwähnte Speicherzelle abfängt und das Write-Enable falls nötig 
gated. Aus Timing-Sicht ist dazu zu sagen: Entweder Dein Design verträgt 
die (wenigen) zusätzlichen Logic-Levels die benötig sind, oder Du musst 
halt pipelinen.

von Mass (Gast)


Lesenswert?

Ja ich weiß es ist doch einbißchen wirr, nachdem ich selbst gelesen 
hatte was ich geschrieben habe, nochmal
von einem VME Bus werden Adressen in das Dual Port Ram geladen, in das 
Dual port Ram (.coe file) sind einige Werte abgelegt und diese Adressen 
werden den einzelnen Werten zugewiesen. Nun möchte ich eine Abfrage 
machen, wenn eine bestimmte Adresse z.B 5F kommt, soll der Wert zu der 
zugehörigen Adresse in ein Register abgelegt werden, dabei wird das 
WriteEnable auf 0 gesetzt. Danach ist dieser Wert ja in diesem Register 
abgespeichert und ich mach daraufhin noch eine Abfrage, nämlich, falls 
dieser Wert eine null ist soll folgende Anweisuung durchgeführt werden 
ansonsten folgende Anweisung.

wie speichere ich nun den Wert, der an der besagten Adresse anliegt in 
ein Register.

Port A ist die VME Seite und Port B ist die Ram Seite (Werte in der .coe 
file)
1
DPRAM_1 : DPRAM_1_S
2
      port map (
3
        -- Port A 
4
        clka => Clk,
5
        wea(0) => '0',                                    
6
        addra => WriteAddr, 
7
        dina => DataIn,
8
        douta => DataOut,
9
        -- Port B 
10
        clkb => Clk,
11
        web(0) => WriteEnable,
12
        addrb => Addr,
13
        dinb => WriteData,
14
        doutb => ram1b 
15
      );
16
17
SEL_BIT: std_logic_vector(7 downto 0) := x"5F"; --5F ist die Adresse des Wertes den ich in das Register Regsel speichern will (der Wert ist entweder eine 0 oder 1), die Werte in der .coe file sind aber 16 bit groß
18
signal Regsel: std_logic (15 downto 0);
19
20
 if WriteAddr <= SEL_BIT(adr'range) then Regsel <= ram1b(15 downto 0); --muss ich hier nicht die explizite stelle des Wertes sagen oder nicht
21
end if;-- ist dieser Ansatz richtig oder mach ich immer noch einen Denkfehler

Danke für euere Hilfe, ich komme langsam an die Grenzen meiner VHDL 
Kenntnisse.

von Uwe (Gast)


Lesenswert?

Du brauchst eine Statemachine mit Block RAM oder mußt dir selber aus 
Registern dein RAM bzw. CAM machen. Also ich hab zumindest den Eindruck 
das du ein CAM willst ( Contend Adressable Memory ). Guck mal ob es das 
ist was du willst und ob du das nicht schon als fertige Komponente hast. 
Ansonste selber machen.

von Mass (Gast)


Lesenswert?

kannst du mir ein Beispiel zeigen wie das CAM aufgebaut ist oder 
funktioniert.Danke.

von Mass (Gast)


Lesenswert?

Hallo, ich glaube sowas brauche ich.
Hab auf dieser Seite:

http://www.asic-world.com/examples/vhdl/cam.html

eine Cam gefunden, kann ich die für meine Zwecke gebrauchen. müsste doch 
statt den ganzen ports, die namen des Dual port rams ersetzen, den clk 
des rams und das enable, datain und addr usw. und die signale kann ich 
doch so lassen.

kannst mir einer anhand dieses Beispiels erklären wie das ganze 
funktioniert.Danke.

von Hans (Gast)


Lesenswert?

Der CAM-Code ist großer Bullshit. SynplifPro optimiert alles weg, 
außerdem
gibt es im kombinatorischen Prozess eine kombinatorische 
Feedback-Schleife. Kauf dir mal lieber ein vernünftiges VHDL-Buch 
(Hinweise gibt es ja zu genüge) und fang an, selber nachzudenken.

VG, Hans

von Hans (Gast)


Lesenswert?

Außerdem: Wo soll in der CAM-Beschreibung der Speicher sein? Ich sehe 
keinen!

von Matthias (Gast)


Lesenswert?

Vielleicht hat ja das was damit zu tun:

-- Coder       : Deepak Kumar Tala (Verilog)
-- Translator  : Alexander H Pham (VHDL)

Lost in translation?

von Mass (Gast)


Lesenswert?

Hallo, das eine problem hat sich geklärt, hatte sowas gar nicht nötig 
gehabt, hab aber ein weiteres Problem mit dem Dual port Ram.

Aus der VME Seite werden 5 bit Adressen auf das Port A des ersten Rams 
gegeben. Ich habe zurzeit 2 Dual Port Rams, die verschiedene Daten 
auslesen unter bestimmten Bedingungen, sollen auf den einen oder anderen 
DPR zugegriffen werden. für den zweiten Dual Port ram benötige ich 7 bit 
adressen um auf das Port A zu geben, da ich aber zu wenig adressen habe 
bastle ich mir einfach ein register einmal aus den ersten 4 bits der 5 
bit Adressen des ersten DPR, dafür muss ich für die Adressen 0-15 (Adr 
bits: 0-3) das WriteEnable deaktivieren, dann kann ich die Adressen in 
ein Register übernehmen. in dem DPR 1 habe ich 32 Register a16 bit daten 
drin. Das 31 reister ist bei mir unbenutzt, so will ich das 15 bit des 
31 Registers als Umschaltbit zwischen beiden DPRs benutzen und die 
letzten 3 bits für den Adressbereich für den 2 DPR.

hab so ungefähr implementiert:
1
signal SelReg: std_logic_vector(15 downto 0); --extra Register was den 31 register des 1 DPR generiert
2
alias sel: std_logic_vector(0 downto 0) is SelReg(15 downto 15); --umschaltbit, 15 bit des 31 Registers
3
alias Block: std_logic_vector(2 downto 0) is SelReg(2 downto 0); --3 bits für die DataAddressen für den 2 DPR
4
5
signal DataWriteAddr: std_logic_vector(6 downto 0); --Daten Adressen 4bits (Adressen des DPR1 + 3 untersten bits des SelReg)
6
7
--meine Dual Port Rams
8
9
DPRAM_1 : DPRAM_1
10
      port map (
11
        -- Port A 
12
        clka => Clk,
13
        wea(0) => VmeWriteEnabble,                                    
14
        addra => WriteAddr, 
15
        dina => DataIn,
16
        douta => DataOut,
17
        -- Port B 
18
        clkb => Clk,
19
        web(0) => Data1WriteEnable,
20
        addrb => Data1Addr,
21
        dinb => Data1WriteData,
22
        doutb => Dataram1
23
      );
24
25
DPRAM_1 : DPRAM_2
26
      port map (
27
        -- Port A 
28
        clka => Clk,
29
        wea(0) => VmeWriteEnabble,                                    
30
        addra => DataWriteAddr, 
31
        dina => DataIn,
32
        douta => DataOut,
33
        -- Port B 
34
        clkb => Clk,
35
        web(0) => Data2WriteEnable,
36
        addrb => Data2Addr,
37
        dinb => Data2WriteData,
38
        doutb => Dataram2 
39
      );
40
41
42
43
--VmeWriteEnable ist eine zwischenvariable für den WE des VME Busses
44
VmeWriteEnable <= '1' when Data1Addr /= x"1F" and MappedWriteEnable = '1' else 
45
         '0'; --das writeenable wird auf 1 eingeschaltet wenn die daten Adresse des DPR 1 ungleich 31ter Register ist, ansonsten soll WE deaktiviert werden, wenn das WE deaktiviert wird wird doch dann das DPR1 abgeschaltert
46
47
SelReg <= x"8000" when Data1Addr = x"1F" and MappedWriteEnable = '1'; ---SelReg ist das parallel Register zum 31 register des DPR1, soll mit der Vorgabe mit dem höchsten Bit gleich 1 zugewiesen werden, 
48
--wenn die Daten Adresse gleich 31 register ist (nur beim 31 register sollen die Prozesse ablaufen) und wenn das WE von der VME Seite 1 ist. 
49
  
50
VmeWriteEnabble <= '0' when Data1Addr(4) = '0' and sel = "1"; --nun will ich, dass das VmeWriteEnabble auf die Adressen 0-15 (Register) deaktiviert wird, wenn das 5 bit des Data1Addr 0 ist heisst es doch, 
51
--dass die ersten 16 Register angesprochen werden, die sollen dann abgeschaltet werden und diese 4 bits sollen dann DataAdress zugewiesen werden, und wenn das sel bit 1 ist, soll, mit dem sel bit will ich von DPR1 zu DPR2 wechseln können.
52
DataWriteAddr<= Sinus_Block(2 downto 0) & WriteAddr(3 downto 0) when sel = "1"; --dass ist nun das DataAddr, besteht aus den untersten 3 bits des extra Registers und 4 bits der Adressen des DPR1
Ich habs so ungefähr realisiert, aber ich glaube irgenwo mache ich einen 
Denkfehler funktioniert nicht ganz wie ich es will. Ich hoffe, dass man 
das verstehen kann was ich da gemacht habe und geschrieben habe. Vielen 
Dank.

von Duke Scarring (Gast)


Lesenswert?

Simulierst Du Dir das Ganze? Ich finde meine meisten Fehler durch die 
Simulation...

Duke

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.