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
portmap(
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(7downto0):=x"5F";--5F ist die Adresse des Wertes den ich laden will (der Wert ist entweder eine 0 oder 1).
20
variablesel:std_logic(0downto0);
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.
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
> 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 ?
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.
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
portmap(
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(7downto0):=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
signalRegsel:std_logic(15downto0);
19
20
ifWriteAddr<=SEL_BIT(adr'range)thenRegsel<=ram1b(15downto0);--muss ich hier nicht die explizite stelle des Wertes sagen oder nicht
21
endif;-- 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.
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.
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.
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
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
signalSelReg:std_logic_vector(15downto0);--extra Register was den 31 register des 1 DPR generiert
2
aliassel:std_logic_vector(0downto0)isSelReg(15downto15);--umschaltbit, 15 bit des 31 Registers
3
aliasBlock:std_logic_vector(2downto0)isSelReg(2downto0);--3 bits für die DataAddressen für den 2 DPR
4
5
signalDataWriteAddr:std_logic_vector(6downto0);--Daten Adressen 4bits (Adressen des DPR1 + 3 untersten bits des SelReg)
6
7
--meine Dual Port Rams
8
9
DPRAM_1:DPRAM_1
10
portmap(
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
portmap(
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
'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"whenData1Addr=x"1F"andMappedWriteEnable='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'whenData1Addr(4)='0'andsel="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(2downto0)&WriteAddr(3downto0)whensel="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.