Liege ich da richtig, oder bin ich komplett auf dem Holzweg?
P.S.: Ich habe versucht danach zu googeln, finde unter "verilog bedingte
zuweisung" nur die Erklärung für den einfachen Fall: "Bedingung ?
Anweisung (wenn wahr) : Anweisung (wenn falsch)". Wenn ich diese
Struktur "weiterspinne" komme ich auf meine Lösung, möchte sie aber von
Verilog-Experten bestätigt wissen.
Danke im voraus
~Freduardo
Duke Scarring schrieb:> freduardo schrieb:>> set_mtr_lb <= (axi_config_cs == SETSLAVELOOPBACK) ? 0 : (axi_config_cs>> == SETMASTERLOOPBACK) ? 1 : set_mtr_lb;> Oh, übersichtlicher, wartbarer Code ;-)>> Ich würe es so versuchen:> [vhdl]> process( axi_config_cs, set_mtr_lb)> begin>> if axi_config_cs = SETSLAVELOOPBACK then> set_mtr_lb <= '0';> else> if axi_config_cs = SETMASTERLOOPBACK then> set_mtr_lb <= '1';> end if;> end if;>> end process;> [/vhld]>> Duke
Der Verilog-Code stammt aus einem automatisch erzeugten Beispiel-Projekt
für nen Ethernet-IP Core von Xilinx. Leider sind diese Projekte so gut,
wie immer in Verilog geschrieben, da tue ich mir als VHDL-ler z.T. recht
schwer mit der "komischen" Syntax.
Sorry, dass ich es nicht direkt dazugeschrieben habe: Die Zuweisung
befindet sich in einem getakteten Prozess. Beim Umsetzen nach VHDL habe
ich das Ganze als if elsif... beschrieben.
Danke für die schnelle Antwort.
Ja Xilinx scheint VHDL nicht zu mögen oder kennt sich mit den
Möglichkeiten nicht wirklich aus.
Ich hänge hier gerade mit diversen AXI-Interfaces ab. Da wären
VHDL-records ideal, um die Verdrahtung übersichtlich zu machen, aber
nein: jedes Signal wird einzeln behandelt...
freduardo schrieb:> Liege ich da richtig, oder bin ich komplett auf dem Holzweg?
Sieht richtig aus. Ich würde den zweiten Teilausdruck (nach dem ersten
else) noch in Klammern setzen, zwecks Übersichtlichkeit.
Btw, seit VHDL-2008 kann man 'when' auch in Prozessen benutzen, d.h. man
musst das nicht mehr in if/then/else übersetzen.
Siehe
http://www.synthworks.com/papers/VHDL_2008_end_of_verbosity_2013.pdf
Slide 9.
Welche Lösung übersichtlicher ist, sei dahin gestellt.
Danke schon mal für die Antworten auf die erste Frage.
Ich nutze den Thread für eine weitere Frage - hoffe es ist so in
Ordnung.
Heute bin ich über einen Verilog-"Prozess" gestolpert, den ich nicht
ganz verstehe.
1
always@(*)begin
2
wait_cnt_int=wait_cnt;
3
if(pkt_gen_load_config_reg)begin
4
wait_cnt_int=16'h450;
5
endelseif(wait_cnt[15])begin
6
wait_cnt_int=wait_cnt_int;
7
endelsebegin
8
wait_cnt_int=wait_cnt_int-1;
9
end
10
end
Wenn ich das in VHDL (2008) schreibe komme ich auf:
1
process(all)
2
begin
3
wait_cnt_int<=wait_cnt;
4
if(pkt_gen_load_config_reg='1')then
5
wait_cnt_int<=x"0450";
6
elsif(wait_cnt(15)='1')then
7
wait_cnt_int<=wait_cnt_int;
8
else
9
wait_cnt_int<=wait_cnt_int-1;
10
endif;
11
endprocess;
*wobei das elsif auch durch einen else if Zweig ersetzt werden kann,
ohne dass der logische Sinn sich ändern würde (richtig?)
Jetzt frage ich mich, welchen Sinn die Default-Zuweisung:
1
wait_cnt_int<=wait_cnt;
hat?
Dem Signal wait_cnt_int wird ja durch if-elsif-else in jedem Durchlauf
ein Wert zugewiesen. Die Default-Zuweisung wird nie "bis zum Ende des
Prozesses überleben".
Was übersehe ich?
Oder kann man diese always @(*)-Block nicht einfach so in einen
VHDL-Prozess übersetzen?
Auch dieser Verilog-Code stammt aus dem Xilinx Beispiel-Projekt für den
Ethernet-Core.
freduardo schrieb:> Heute bin ich über einen Verilog-"Prozess" gestolpert
Ist der tatsächlich komplett oder wird das wait_cnt_int im Originalcode
weiter unten nochmal verwendet?
> Jetzt frage ich mich, welchen Sinn die Default-Zuweisung:> wait_cnt_int <= wait_cnt;> hat?
Das ist ja deine (vermutlich falsche) Übertragung, im Verilog-Original
steht da:
wait_cnt_int <= wait_cnt;
Und vermutlich verhält sich wait_cnt_int in diesem Verilog-Fall wie eine
VHDL Variable und über nimmt den Wert "sofort" in dieser Zeile.
Fürderhin wird dann auf wait_cnt_int herumgerechnet und das Ergebnis
später wait_cnt zugewiesen.
freduardo schrieb:> wobei das elsif auch durch einen else if Zweig ersetzt werden kann,> ohne dass der logische Sinn sich ändern würde (richtig?)
Richtig.
> Jetzt frage ich mich, welchen Sinn die Default-Zuweisung: [...]> hat?
Keinen, aus den Gründen, die du schon genannt hast. Aber an diesem
Codeschnipsel ist noch mehr seltsam, z.B. will man
wait_cnt_int = wait_cnt_int - 1;
in keinem kombinatorischen Prozess sehen. Und
wait_cnt_int = wait_cnt_int;
will man überhaupt nicht sehen.
Ein typisches Beispiel für einen schlampig formulierten Codefetzen. Hast
du mal probiert, ob dieser Code simuliert und synthetisiert?
@Vancouver: Der Code lässt sich simulieren. Es ist das Beispiel-Projekt
zum Xilinx IP-Core AXI 1G/2.5G Ethernet Subsystem - lässt sich in Vivado
mit "Open IP Exmaple Design" erzeugen.
Danke Euch für die Hilfe.
Hallo nochmal,
je weiter ich mich durch das Beispiel-Projekt (immernoch das in Vivado
automatisch erzeugte Example-Project zum AXI-Ethernet IP-Core)
durchkämpfe, umso mehr Fragen tauchen auf...
(Falls es möglich ist, könnte ein Moderator den Thread evtl. umbenennen
in sowas wie: "Anfängerfragen zu Verilog".
Jetzt bin ich über ein case-Statement in Verilog gestolpert, das ich mir
gar nicht erklären kann.
In einem Module werden folgende localparam definiert:
1
localparamCMNDSETSPEED1000=8'h1,
2
CMNDSETSPEED100=8'h2,
3
CMNDSETSPEED10=8'h3,
4
CMNDTGLEADDRSWAP=8'h8,
5
CMNDTGLEADDRSWAPMTR=8'h8,
6
CMNDSETMASTERLOOPBACK=8'h5,
7
CMNDTOGGLEEXTPHYLB=8'hC,
8
CMNDSETSLAVELOOPBACK=8'h9,
9
CMNDAPPLYSOFTRESET=8'h6,
10
CMNDTGLEPATGENEN=8'hB,
11
CMNDTGLEPATCHKEN=8'hA,
12
CMNDREPROGRAMREG=8'h0,
13
CMNDRESETPATCHKERROR=8'h4,
14
CMNDWRITE2AXILREG=8'hD,
15
CMNDREADAXILREG=8'h7,
16
CMNDTGLETXACTIVITY=8'hE;
CMNDTGLEADDRSWAP und CMNDTGLEADDRSWAPMTR haben jeweils den Wert 8.
im gleichen Module wird die folgende Function definiert:
In dem case-Statement innerhalb der Funktion gibt es eine überlappende
Abfrage.
Soweit ich gelesen habe, dürfen solche überlappenden case-Statements in
Verilog mit casez verwendet werden.
Die function wird in dem Module aufgerufen und der Code lässt sich
simulieren.
Daher jetzt die Frage: Was übersehe ich hier schon wieder?
Die localparam TOGGLEADDRSWAPSLB und TOGGLEADDRSWAPMTR haben
unterschiedliche Werte. Daher ist mir völlig unklar, welcher Wert von
der Funktion zurückgegeben wird, wenn ein Aufruf mit dem cmnd_data = 8
geschieht.
freduardo schrieb:> Falls es möglich ist, könnte ein Moderator den Thread evtl. umbenennen> in sowas wie: "Anfängerfragen zu Verilog".
Den Betreff kann man mit jedem Beitrag ändern...
freduardo schrieb:> Daher ist mir völlig unklar, welcher Wert von> der Funktion zurückgegeben wird, wenn ein Aufruf mit dem cmnd_data = 8> geschieht.
Im Zweifelsfall kannst Du die Funktion separat simulieren.
Ich würde stark vermuten, das bei einem Input von 8 das Resultat
TOGGLEADDRSWAPSLB ausgegeben wird.
Möglicherweise ist aber auch die Definition von CMNDTGLEADDRSWAP oder
CMNDTGLEADDRSWAPMTR falsch und es ist nur noch niemandem aufgefallen...
Duke
Duke Scarring schrieb:> Ja Xilinx scheint VHDL nicht zu mögen oder kennt sich mit den> Möglichkeiten nicht wirklich aus.> Ich hänge hier gerade mit diversen AXI-Interfaces ab. Da wären> VHDL-records ideal, um die Verdrahtung übersichtlich zu machen, aber> nein: jedes Signal wird einzeln behandelt...
Das Problem ist nicht VHDL, sondern die Tatsache, dass Vivado derzeit
massive Probleme hat, records für Interfaces in Block Designs zu
verwenden. Dort ist std_logic_vector schon das höchste der Gefühle. Ich
fände es auch wesentlich schöner, wenn man sich Interfaces nicht
zwingend per IP-XACT und Gräbern an Attributen wie X_INTERFACE_INFO und
X_INTERFACE_PARAMETER zusammenbauen müsste, sondern wahlweise auch
einfach einen Record verwenden könnte.
Vancouver schrieb:> Btw, seit VHDL-2008 kann man 'when' auch in Prozessen benutzen, d.h. man> musst das nicht mehr in if/then/else übersetzen.
Xilinx mag VHDL-2008 nicht, zumindest nicht in Vivado. :-( Man darf es
nicht in IP-Blöcken verwenden, und die Umsetzung der Features ist
offenbar halbherziger als in ISE.