Hallo,
für eine Aufgabe sollen wir einen Inverter realisieren, der bei einer
steigenden Flanke am Eingang mit einer Verzögerung von 7 ns schaltet und
bei einer fallenden mit einer Verzögerung von 5 ns. Wir dürfen nur
rising_edge verwenden (also nicht falling_edge). Zusätzlich soll ein 12
Bit-Zähler implementiert sein. Den Zähler hab ich einfach in einem
zweiten Prozess gepackt, nur bei den unterschiedlichen Flanken bin ich
mir unsicher, ob das so stimmen kann:
Gibt es für das Werte zuweisen einen geschickteren Weg als einfach die
vielen 1en/0en zu tippen? Das wird doch sicher mit range gehen ?
Danke im Voraus.
Liebe Grüße
Jonas B. schrieb:> für eine Aufgabe sollen wir einen Inverter realisieren, der bei einer> steigenden Flanke am Eingang mit einer Verzögerung von 7 ns schaltet und> bei einer fallenden mit einer Verzögerung von 5 ns.
Soll das synthetisiert werden? Dann wird es schwierig. Oder ist es nur
für die Simu gedacht? Dann geht das mit den verzögerten Anweisungen.
Jonas B. schrieb:> Wir dürfen nur> rising_edge verwenden (also nicht falling_edge).
Toll. Eine Aufgabe des Stils: wenn ich dir die naheliegende und
angemessene Lösung verbiete, auf welche Wurstelei kommst du dann?
Meine Lösung wäre wahrscheinlich:
if inp'event then
if inp='0' then ....
elsif inp='1' then ...
end if;
end if;
(event war ja nicht explizit verboten, oder?)
Jonas B. schrieb:> Gibt es für das Werte zuweisen einen geschickteren Weg als einfach die> vielen 1en/0en zu tippen?
Da gibt es viele Wege. Da es gerade 12 Bit sind würde ich die Konstante
in Hex angeben: x"FFF" bzw. x"000"
Auch mit (others => '1') oder (others => '0') dürfte was gehen.
Jonas B. schrieb:> ob das so stimmen kann:
Was sagt deine Simulation?
> if not rising_edge(inp)
Das dürfte fast ständig "true" sein. Denn "keine" steigende Flanke gibts
quasi dauernd. Sogar nie, wenn man davon ausgeht, dass eine Flanke die
Zeit 0 hat. Wenn schon, dann würde ich für eine fallende Flanke das
Signal invertieren und dann auf die steigende Flanke abfragen:
1
ifrising_edge(notinp)
Aber die Verwendung der passenden Attribute ist sicher der bessere
Weg:
https://www.csee.umbc.edu/portal/help/VHDL/attribute.html> Gibt es für das Werte zuweisen einen geschickteren Weg als einfach die> vielen 1en/0en zu tippen?
Nimm einen integer und du kannst simple leserliche Dezimalzahlen
verwenden.
> Gibt es für das Werte zuweisen einen geschickteren Weg als einfach die> vielen 1en/0en zu tippen?
Dein Zähler könnte den Überlauf auch ganz von allein. Du musst ihn nicht
manuell zurücksetzen. Und warum nimmst du nicht wenigstens einen
unsigned Vektor als Zähler?
> für eine Aufgabe sollen wir einen Inverter realisieren, der bei einer> steigenden Flanke am Eingang mit einer Verzögerung von 7 ns schaltet und> bei einer fallenden mit einer Verzögerung von 5 ns.
Es ist im Prinzip eine schlechte Idee, symbolische Verzögerungen in
einem Code zu verwenden, der hinterher synthetisiert werden soll. Tu das
am Besten nach dieser erzwungenen Übung nie wieder!
Siehe den Beitrag "Re: Einfaches Schieberegister in VHDL?"
Ach ja, noch eine Ergänzung: da das mit den verzögerten Zuweisungen im
Inverterprozess ja ohnehin nur in der Simu klappt, kann man
wahrscheinlich auch ganz auf die Abfrage des events verzichten. In der
Sensitivity-Liste steht nur inp, der Prozess wird also immer genau dann
durchsimuliert, wenn bei inp ein event auftrat (also eine Signaländerung
stattfand).
Hi,
ja der Code ist für die Simulation, also nicht für eine Synthese
gedacht.
Danke für die vielen Tipps!
Stimmt, finde die Aufgabe auch etwas dämlich ? Also explizit steht drin
"Sie können hierfür die Funktion rising_edge() benutzen.". Dieses
"können" klingt für mich fast wie eine Anweisung nur mit rising_edge()
auszukommen.
Lothar M. schrieb:> Was sagt deine Simulation?
Bei der hat sich nichts invertiert/das Signal blieb konstant. Allerdings
hat edaplayground gestern ein wenig gestreikt.
Lothar M. schrieb:> enn schon, dann würde ich für eine fallende Flanke das> Signal invertieren und dann auf die steigende Flanke abfragen:if> rising_edge(not inp)
Oh das ist aber eine geniale Idee! Ja ich denke das liegt dann genau im
Sinne der Aufgabe, danke.
Wenn ich das aber implementiere (wie oben) kriege ich diese Meldung:
"COMP96 ERROR COMP96_0152: "Formal "s" of class signal must be
associated with a signal." "design.vhd" 17 20"
Jonas B. schrieb:> Wenn ich das aber implementiere (wie oben) kriege ich diese Meldung:> "COMP96 ERROR COMP96_0152: "Formal "s" of class signal must be> associated with a signal." "design.vhd" 17 20"
Na ja, der Code oben hat noch diverse Fehler (package numeric_std nicht
eingebunden, falsche Zuweisungsoperatoren, vaule statt value, fehlendes
end process...)
Aber dass du genau diese Fehlermeldung bekommst hätte ich bei dem Code
nicht erwartet. Bist du sicher, dass du diese entity übersetzt hast? Wie
sieht der tatsächliche Code denn inzwischen aus?
Tja: ich sehe nicht, wie die Fehlermeldung zu dieser entity passt. Ist
diese Entity tatsächlich unter dem Namen design.vhd gespeichert? (denn
der gemeldete Fehler liegt in design.vhd).
Zur eigentlichen Aufgabe: wie oben vermutet funktioniert es für die Simu
ganz ohne Flankenabfrage (aufgrund der sensitivity-Liste) - siehe
Anhänge...
Jonas B. schrieb:> if rising_edge(not inp) then -- falling edge
rising_edge() kann mit der Funktion "not()" als Argument nichts
anfangen. Du brauchst ein "Hilfssignal":
1
:
2
:
3
signalnotinp:std_logic;
4
begin
5
6
notinp<=notinp;
7
8
inveter:process(inp,notinp)
9
begin
10
ifrising_edge(notinp)then-- falling edge
11
outp<=notinpafter5ns;
12
endif;
13
ifrising_edge(inp)then
14
outp<=notinpafter7ns;
15
endif;
16
endprocess;
17
:
18
:
Achim S. schrieb:> Zur eigentlichen Aufgabe: wie oben vermutet funktioniert es für die Simu> ganz ohne Flankenabfrage
Genau wie der Zähler nur in der Simulation tut... ;-)
Im realen Leben ist die Sensitivliste des Zählers falsch. Oder es fehlt
im Prozess eine Abfrage auf die Flanke. Deshalb zählt der auch mit jeder
Taktflanke. Solche Flipflops gibts im realen Leben nicht...
Dazu das hier:
http://www.lothar-miller.de/s9y/categories/36-Kombinatorische-Schleife
Lothar M. schrieb:> Genau wie der Zähler nur in der Simulation tut... ;-)
Genau das war ja die Aufgabenstellung:
Jonas B. schrieb:> ja der Code ist für die Simulation, also nicht für eine Synthese> gedacht.
Hallo,
danke für die Hilfe. Nachdem ich das wie angegeben korrigiert hab passt
alles.
Seltsamerweise komme ich mit genau diesem Code auf eine seltsame
waveform (der Ausgang negiert einfach gar nicht). Wenn der Code im
Programm aber funktioniert, liegt das vielleicht an der Webseite (das
war die Webseite, die von der Vorlesung empfohlen wurde):
https://www.edaplayground.com/x/5eKJLothar M. schrieb:> Genau wie der Zähler nur in der Simulation tut... ;-)> Im realen Leben ist die Sensitivliste des Zählers falsch. Oder es fehlt> im Prozess eine Abfrage auf die Flanke. Deshalb zählt der auch mit jeder> Taktflanke. Solche Flipflops gibts im realen Leben nicht...> Dazu das hier:> http://www.lothar-miller.de/s9y/categories/36-Kombinatorische-Schleife
Danke, ich schaus mir mal an.
Mit welchem Programm nehmt ihr denn eure Waveforms auf? Das scheint mir
zuverlässiger als diese Seite zu sein.
Jonas B. schrieb:> Mit welchem Programm nehmt ihr denn eure Waveforms auf? Das scheint mir> zuverlässiger als diese Seite zu sein.
In meinem Fall: Xilinx ISE plus Multisim. Der Download und die
Installation dauern zwar etwas, aber dafür kann man damit auch ernsthaft
arbeiten.
In deiner Testbench fehlt imho die Komponentendeklaration. Füge die mal
ein, vielleicht läuft es dann besser.
Ach ja: bei der Instantiierung von myinverter ist auch noch ein "entity"
zu viel.
Und: bei verzögerten Anweisungen ist der Standard-Mode "inertial" (oder
so ähnlich). Der Ausgangs schaltet dann nur, wenn der Eingang länger als
die Verzögerungszeit stabil ist. Du muss umschalten auf transport oder
dein simuliertes Eingangssignal länger als 7 ns stabil halten.
Jonas B. schrieb:> Seltsamerweise komme ich mit genau diesem Code auf eine seltsame> waveform (der Ausgang negiert einfach gar nicht).
Wenn du irgendwelche Signalflsnken um 5 oder 7ns verzögern willst, dann
ist es sehr ungünstig, das Eingangssignal jede ns zu ändern.
Nimm mal den selben Takt wie Achim und ich...
Jonas B. schrieb:> Also explizit steht drin "Sie können hierfür die Funktion> rising_edge() benutzen.". Dieses "können" klingt für mich> fast wie eine Anweisung nur mit rising_edge() auszukommen.
Ich lese das eher als eine Hilfestellung für die Klassendeppen, die
keinen Ansatz haben. Sowas schreibt ein Lehrer meist hin, wenn er
mehrfach leere Zettel bekommen hat. :D
Wäre es für die Synthese gewesen, dann wäre eine solche Anweisung ein
Zaunpfahlwink gewesen, rising_edge mit einem Taktsignal zu benutzen, um
das Timing zu garantieren. Aber hier ist ja alles asynchron.
S. R. schrieb:> Jonas B. schrieb:>> Also explizit steht drin "Sie können hierfür die Funktion>> rising_edge() benutzen.". Dieses "können" klingt für mich>> fast wie eine Anweisung nur mit rising_edge() auszukommen.> Ich lese das eher als eine Hilfestellung für die Klassendeppen, die> keinen Ansatz haben.
Man könnte das auch mal so lesen: "Sie können nachschauen, was die
Funktion rising_edge() macht und darin eine Idee für die Lösung der
Aufgabe finden."
Und dann wäre man mit
https://www.csee.umbc.edu/portal/help/VHDL/packages/std_logic_1164.vhd
schon mal gut bedient.
BTW: wenn man sich dort den Quelltext mal genauer anschaut, dann ist
klar, warum das 's' in der zuvor geposteten Fehlermeldung auftaucht: