moin, jaja, das Thema scheint alt zu sein, doch leider verstehe ich a. nicht wo da das Problem ist, und b. sind alle Beispiele die ich hier im Archiv gefunden habe nicht brauchbar, weil ich steigende und fallende Flanke abfragen will. Also erstmal mein Coce: entity kds_reg_ddin is generic (width: positive := 8); port(clk, reset: in std_logic; din : in std_logic_vector(width-1 downto 0); dout_h, dout_l: out std_logic_vector(width-1 downto 0)); end kds_reg_ddin; architecture simulation of kds_reg_ddin is signal zwischenspeicher: std_logic_vector(width-1 downto 0); signal last_value_rising: std_logic_vector(width-1 downto 0); signal last_value_falling: std_logic_vector(width-1 downto 0); begin process(clk, reset) begin if reset = '0' then dout_h <= (others=> '0'); dout_l <= (others=> '0'); zwischenspeicher <= (others => '0'); elsif clk'event and clk = '1' then -- rising edge dout_h <= last_value_rising; dout_l <= zwischenspeicher; last_value_falling <= din; elsif clk'event and clk = '0' then --falling edge zwischenspeicher <= last_value_falling; last_value_rising <= din; end if; end process; end simulation; Das soll ein DDR-Umsetzer sein, den ich fuer die Uni programmieren muss. Der muss nach Vorgabe sowohl steigende als auch fallende Flanke abfragen koennen. Nun gibt mir Xilinx ISE natuerlich eine bad synchonous description aus. In der Hilfe von Xilinx steht dann was von das 'event must be present in the topmost IF statement und no more embedded 'event satement within the process. Aha. Wieso? was? wie mache ich denn einen Process mit asynchronem reset, und abfrage auf steigende und fallende flanke mit nur einem 'event in der "topmost" If-abfrage? Irgedwer wird das doch schonmal gemacht haben? nur sind leider, wie schon erwaehnt, alle beispiele hier im Forum nur fuer steigende Flanken. Danke, TIM
versuch mal, das zweite clock'event in einen eigenen Process zu schreiben. vielleicht ist ihm das alles zu schnell
process(reset, clk) begin if reset = '0' then dout_h <= (others=> '0'); dout_l <= (others=> '0'); zwischenspeicher <= (others => '0'); elsif rising_edge(clk) then dout_h <= last_value_rising; dout_l <= zwischenspeicher; last_value_falling <= din; end if; end process; process(clk) begin if clk'event and clk = '0' then zwischenspeicher <= last_value_falling; last_value_rising <= din; end if; end process; dann kommt das raus: Analyzing Entity <kds_reg_ddin> (Architecture <simulation>). INFO:Xst:1304 - Contents of register <zwischenspeicher> in unit <kds_reg_ddin> never changes during circuit operation. The register is replaced by logic. Entity <kds_reg_ddin> analyzed. Unit <kds_reg_ddin> generated. ======================================================================== = * HDL Synthesis * ======================================================================== = Synthesizing Unit <kds_reg_ddin>. Related source file is "H:/Dokumente und Einstellungen/user/Eigene Dateien/Uni/KDS/Ueb10/synthese/kds_reg_ddin/kds_reg_ddin.vhd". Found 8-bit register for signal <dout_h>. Found 8-bit register for signal <dout_l>. Found 8-bit register for signal <last_value_falling>. Found 8-bit register for signal <last_value_rising>. Found 8-bit register for signal <zwischenspeicher>. Summary: inferred 40 D-type flip-flop(s). Unit <kds_reg_ddin> synthesized. ======================================================================== = HDL Synthesis Report Macro Statistics # Registers : 5 8-bit register : 5 ======================================================================== = ======================================================================== = * Advanced HDL Synthesis * ======================================================================== = ======================================================================== = Advanced HDL Synthesis Report Macro Statistics # Registers : 40 Flip-Flops : 40 ======================================================================== = ======================================================================== = * Low Level Synthesis * ======================================================================== = ERROR:Xst:528 - Multi-source in Unit <kds_reg_ddin> on signal <zwischenspeicher<7>> Sources are: Output signal of FD_1 instance <zwischenspeicher_7> Signal <zwischenspeicher<7>> in Unit <kds_reg_ddin> is assigned to GND ERROR:Xst:528 - Multi-source in Unit <kds_reg_ddin> on signal <zwischenspeicher<6>> Sources are: Output signal of FD_1 instance <zwischenspeicher_6> Signal <zwischenspeicher<6>> in Unit <kds_reg_ddin> is assigned to GND ERROR:Xst:528 - Multi-source in Unit <kds_reg_ddin> on signal <zwischenspeicher<5>> Sources are: Output signal of FD_1 instance <zwischenspeicher_5> Signal <zwischenspeicher<5>> in Unit <kds_reg_ddin> is assigned to GND ERROR:Xst:528 - Multi-source in Unit <kds_reg_ddin> on signal <zwischenspeicher<4>> Sources are: Output signal of FD_1 instance <zwischenspeicher_4> Signal <zwischenspeicher<4>> in Unit <kds_reg_ddin> is assigned to GND ERROR:Xst:528 - Multi-source in Unit <kds_reg_ddin> on signal <zwischenspeicher<3>> Sources are: Output signal of FD_1 instance <zwischenspeicher_3> Signal <zwischenspeicher<3>> in Unit <kds_reg_ddin> is assigned to GND ERROR:Xst:528 - Multi-source in Unit <kds_reg_ddin> on signal <zwischenspeicher<2>> Sources are: Output signal of FD_1 instance <zwischenspeicher_2> Signal <zwischenspeicher<2>> in Unit <kds_reg_ddin> is assigned to GND ERROR:Xst:528 - Multi-source in Unit <kds_reg_ddin> on signal <zwischenspeicher<1>> Sources are: Output signal of FD_1 instance <zwischenspeicher_1> Signal <zwischenspeicher<1>> in Unit <kds_reg_ddin> is assigned to GND ERROR:Xst:528 - Multi-source in Unit <kds_reg_ddin> on signal <zwischenspeicher<0>> Sources are: Output signal of FD_1 instance <zwischenspeicher_0> Signal <zwischenspeicher<0>> in Unit <kds_reg_ddin> is assigned to GND CPU : 2.42 / 2.77 s | Elapsed : 2.00 / 2.00 s --> Total memory usage is 89936 kilobytes Number of errors : 8 ( 0 filtered) Number of warnings : 0 ( 0 filtered) Number of infos : 1 ( 0 filtered) Process "Synthesize" failed ist zwar anders, aber nicht besser ;-)
versuch mal: process(clk) begin if reset = '0' then zwischenspeicher <= (others => '0'); elsif clk'event and clk = '0' then zwischenspeicher <= last_value_falling; last_value_rising <= din; end if; end process; und oben das zwischenspeicher raus. Gruss, Simon
if reset = '0' then -- blabla elsif clk'event then if clk = '0' then --fallende Flanke -- blabla end if; if clk = '1' then --steigende Flanke -- blabla end if; end if;
Hallo Es ist gerade eine etwas ungewöhnliche Uhrzeit und ich muß zugeben ich bin nicht so ganz nüchtern. Aber nun zum Thema. Was für einen FPGA bzw. CPLD benutzt du? Manche haben keine falling edge FFs und das kann Probleme machen. Ich habe hier irgendwo schon einen Thread zu dem Thema gesehen/beantwortet hmmm ... Na ja morgen bin ich wohl in einer besseren Position das zu beantworten. Cpt
So hier mal der link zu der Problemstellung: http://www.mikrocontroller.net/forum/read-9-263317.html#new Cpt
Vergiss Verhaltensbeschreibung wenn Du für DDR-Rams mit Zweiflanken-FF arbeiten willst. Dazu nimmt man ein DDR-FF. Schau also mal in den Libraryguide und dort z.B. nach FDDRCPE. Das ist ein FF mit zweiflanken, Clockenable und asynchronen Set und Reset. IN VHDL baut man das wie folgt ein: component FDDRCPE -- synthesis translate_off generic (INIT : bit := '1'); -- synthesis translate_on port (Q : out STD_ULOGIC; C0 : in STD_ULOGIC; C1 : in STD_ULOGIC; CE : in STD_ULOGIC; CLR : in STD_ULOGIC; D0 : in STD_ULOGIC; D1 : in STD_ULOGIC; PRE : in STD_ULOGIC); end component; -- Component Attribute specification for FDDRCPE -- should be placed after architecture declaration but -- before the begin keyword attribute INIT : string; attribute INIT of FDDRCPE_instance_name : label is "0"; -- values can be (0 or 1) -- Component Instantiation for FDDRCPE should be placed -- in architecture after the begin keyword FDDRCPE_INSTANCE_NAME : FDDRCPE -- synthesis translate_off generic map (INIT => bit_value) -- synthesis translate_on port map (Q => user_Q, C0 => user_C0, C1 => user_C1, CE => user_CE, CLR => user_CLR, D0 => user_D0, D1 => user_D1, PRE => user_PRE); Also nix mit rising_edge und falling_edge in ein oder zwei prozessen. Für das synthesetool gibt es (derzeit) keine synthesefähige Verhaltensbeschreibung. Es kann sehr wohl in VHDL beschriben werden, aber für die Xilinxsynthese muss es die direkte Einbindung der zweiflanken- FF sein.
ich hab grad nochmal im "Synthesis and simulaltion Design guide" der ISE 8.1 nachgelesen. Da steht im Kap. 4 unter "using double data rate IOB Register" The dual data rate register primitives (the synchronous set/reset with clock enable FDDRRSE, and asynchronous set/reset with clock enable FDDRCPE) must be instantiated in order to utilize the dual data rate registers in the outputs. Also Ausgangs-FF die an DDR RAM hängen gibts keine Verhaltensbeschreibung die die Synthese mit XST versteht, es muss das DDR-Register Primitiv eingebunden werden. Es ist wie so oft, nicht alles was VHDL korrekt beschribene werden kann, ist Hardware. Die Denkweise für code für die Synthese ist von Hardware zum VHDL nicht umgekehrt.
hmm, aber auf meinem Aufgabenblatt steht explizit: "Entwerfen Sie das DDR-Register in "Verhaltens VHDL". Ich wollen mich doch nciht veraeppeln
@ SSSSSSS SSSSSSSS: "unsupported Clock statement." hatte ich leider schon alles ausprobiert. es ist ja echt zum verzweifeln, zumal die uns null Hinweis zur Problemloesung gegeben haben
ich hab hier mal den link: http://user.cs.tu-berlin.de/~thilden/vhdl.pdf Als zielsystem soll es ein VirtexE sein, aber nur alibihalber, das programm wird nie da draufgeschrieben werden, ist ein reines Softwarelabor, ohne praktischen Einsatz
Hallo Tim Ich habe deinen Code gerade mal durch Quartus II 4.2 (Altera) gejagt. Anscheinend wird bei der Analysis & Synthesis etwas optimiert, was der Fitter nicht mehr im FPGA realisieren kann. Ergänz mal den Reset! Dann funktioniert es.
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | |
4 | entity kds_reg_ddin is |
5 | generic (width: positive := 8); |
6 | port(clk : in std_logic; |
7 | reset : in std_logic; |
8 | din : in std_logic_vector(width-1 downto 0); |
9 | dout_h : out std_logic_vector(width-1 downto 0); |
10 | dout_l : out std_logic_vector(width-1 downto 0)); |
11 | end kds_reg_ddin; |
12 | |
13 | |
14 | architecture simulation of kds_reg_ddin is |
15 | |
16 | signal zwischenspeicher : std_logic_vector(width-1 downto 0); |
17 | signal last_value_rising : std_logic_vector(width-1 downto 0); |
18 | signal last_value_falling : std_logic_vector(width-1 downto 0); |
19 | |
20 | begin
|
21 | |
22 | process(clk, reset) |
23 | begin
|
24 | if reset = '0' then |
25 | dout_h <= (others=> '0'); |
26 | dout_l <= (others=> '0'); |
27 | last_value_falling <= (others=> '0'); |
28 | last_value_rising <= (others=> '0'); |
29 | zwischenspeicher <= (others => '0'); |
30 | elsif clk'event and clk = '1' then -- rising edge |
31 | dout_h <= last_value_rising; |
32 | dout_l <= zwischenspeicher; |
33 | last_value_falling <= din; |
34 | elsif clk'event and clk = '0' then --falling edge |
35 | zwischenspeicher <= last_value_falling; |
36 | last_value_rising <= din; |
37 | end if; |
38 | end process; |
39 | |
40 | end simulation; |
MfG Holger Der auch dachte, dass man das in 2 Prozessen schreiben muss.
Folgende mögliche Lösung hab ich letztens in der Newsgroup gelesen: 2 FF mit xor-Verknüpfungen. Ich habe es aber slebst noch nicht getestet, ob es eine Synthese übersteht....
1 | entity test is |
2 | port (clk1, clk2, reset, data1, data2 : in std_logic ; |
3 | q_orig, q_replace : out std_logic ) ; |
4 | end entity test ; |
5 | |
6 | architecture test of test is |
7 | signal q1, q2 : std_logic ; |
8 | begin
|
9 | |
10 | process (reset, clk1) |
11 | begin
|
12 | if reset='1' then |
13 | q1 <= '0'; |
14 | elsif rising_edge(clk1) then |
15 | q1 <= data1 xor q2; |
16 | end if; |
17 | end process; |
18 | |
19 | process (reset, clk2) |
20 | begin
|
21 | if reset='1' then |
22 | q2 <= '0'; |
23 | elsif rising_edge(clk2) then |
24 | q2 <= data2 xor q1; |
25 | end if; |
26 | end process; |
27 | |
28 | q_replace <= q1 xor q2; -- decode output |
29 | |
30 | end architecture ; |
Hallo André Deine Version kann man nicht Synthetesieren. >> Error: VHDL Case Statement or If Statement error at ddr_fehler2.vhd(20): can't synthesize condition that contains an isolated 'EVENT predefined attribute << MfG Holger
Bei meinem Post muessen die clk jeweils natürlich 180 Grad verschoben sein, sonst funzt es nicht. Dafür benutzt man dann noch nur FF mit steigender Flanke. Weiss ni, ob das nun gut oder schlecht ist. synthetisieren ässt es sich auf jeden fall, gard probiert.
@ high_speed: wo genau soll ich da Reset ergaenzen? ich seh da so spontan keinen Unterschied zu meinem Coce. @ T.M.: Du musst entschuldigen, aber ich bin Elektrotechniker, und eigentlich nicht wirklich firm in diesem Digitalkram, besonders nicht in dieser Abstarktion von Code auf Logikbausteine. Kannst du evtl. mal fuer 'dumme' erklaeren was dieses Xor FF macht? hab jetzt ueberall gelesen, dass das Problem die FFs sind, die nur auf eine Flanke triggern koennen. Kann ich dann nicht einfach eine zweite clk einfuehren clk2 <= not clk, und dann einmal nach clk'event and clk='1' und beim zweitenmal nach clk2'event and clk='1' fragen?
1 | if reset = '0' then |
2 | dout_h <= (others=> '0'); |
3 | dout_l <= (others=> '0'); |
4 | last_value_falling <= (others=> '0'); -- neu |
5 | last_value_rising <= (others=> '0'); -- neu |
6 | zwischenspeicher <= (others => '0'); |
MfG Holger
Xor = exclusive oder ist immer 1 wenn die Verküpfungsglieder unterschiedlich sind. Das heisst in dem Beispiel, die FF schalten bei Flanke auf 1 wenn Eingangssignal und Ausgang des anderen FF unterschiedlich sind, sonst setzen sie es auf 0. Und der Gesamtausgang verknüpft die beiden FF-Ausgänge nochmal xor miteinander. Aber deine Idee mit einem invertiertem Clock geht ja auch, nur musst du dann ein internes Signal einführen, dass die 2 FF Ausgänge miteinander verknüpt, weil du sonst Multisource bekommst. Hab meins mal bissl überarbeitet:
1 | -- double-edge sensitive register : |
2 | library ieee ; |
3 | use ieee.std_logic_1164.all ; |
4 | |
5 | entity test is |
6 | port (clk,reset, data: in std_logic ; |
7 | q : out std_logic ) ; |
8 | end entity test ; |
9 | |
10 | architecture test of test is |
11 | signal q1, q2 : std_logic ; |
12 | signal clk2 : std_logic; |
13 | begin
|
14 | |
15 | clk2 <= not clk; |
16 | |
17 | -- replacement processes : |
18 | process (reset, clk) |
19 | begin
|
20 | if reset='1' then |
21 | q1 <= '0'; |
22 | elsif rising_edge(clk) then |
23 | q1 <= data xor q2; |
24 | end if; |
25 | end process; |
26 | |
27 | process (reset, clk2) |
28 | begin
|
29 | if reset='1' then |
30 | q2 <= '0'; |
31 | elsif rising_edge(clk2) then |
32 | q2 <= data xor q1; |
33 | end if; |
34 | end process; |
35 | |
36 | q <= q1 xor q2; -- decode output |
37 | |
38 | end architecture ; |
Aber die Zeile clk2 <= not clk; macht man lieber mit einer DCM oder was ähnichen, weil man sonst Verzögerung im 2. Takt bekommt, durch die Laufzeit durch den Inverter.
was ist denn nun DCM schon wieder? Und das 2 Flanken KK verstehe ich nun, aber wie baue ich das denn jetzt ein? Ihr muesst verstehen, dass ich sonst nur richtige Programmiersprachen C, Java, programmiere. Das ist hier alles eine Abstraktionsebene zu hoch, oder besser gesagt, zu hardwarenah, um abstrakt zu sein.
@high_speed: nee, das geht nicht, da kommt der selbst Fehler: bad asynchronous expression. Haette mich ehrlich auch gewundert, wenn das gebracht haette. Hab inzwischen eine Variante, die einfach einen invertierten clk benutzt, und ich somit nur auf steigende flanken abfragen muss. Laesst sich auch synthetisieren, allerdings mit Warnungen. Leider kommt in der anschliessenden Simualtion nicht mehr das raus, was rauskommen soll.
Hast du mal meinen letzten Vorschlag oben probiert? Sonst stell mal deine Variante rein... Mit einem DCM (digital clock manager) kann man aus 1 Takt verschiedene dazu phasenverschobene, also aauch einen invertierten Takt herstellen. Vorteil dabei ist, dass sie alle "synchron" zueinander laufen, bei der Lösung mit dem Inverter hat der invertierte Takt eine kleine Verzögerung, da man die Laufzeit des Inverters berücksichtigen muss.
Hallo Tim Dann versuche mal die Version mit 2 Prozessen:
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | |
4 | entity kds_reg_ddin is |
5 | generic (width: positive := 8); |
6 | port(clk : in std_logic; |
7 | reset : in std_logic; |
8 | din : in std_logic_vector(width-1 downto 0); |
9 | dout_h : out std_logic_vector(width-1 downto 0); |
10 | dout_l : out std_logic_vector(width-1 downto 0)); |
11 | end kds_reg_ddin; |
12 | |
13 | |
14 | architecture simulation of kds_reg_ddin is |
15 | |
16 | signal zwischenspeicher : std_logic_vector(width-1 downto 0); |
17 | signal last_value_rising : std_logic_vector(width-1 downto 0); |
18 | signal last_value_falling : std_logic_vector(width-1 downto 0); |
19 | |
20 | begin
|
21 | process(clk, reset) |
22 | begin
|
23 | if reset = '0' then |
24 | dout_h <= (others=> '0'); |
25 | dout_l <= (others=> '0'); |
26 | last_value_falling <= (others => '0'); --neu |
27 | elsif clk'event and clk = '1' then -- rising edge |
28 | dout_h <= last_value_rising; |
29 | dout_l <= zwischenspeicher; |
30 | last_value_falling <= din; |
31 | end if; |
32 | end process; |
33 | |
34 | |
35 | process(clk, reset) |
36 | begin
|
37 | if reset = '0' then |
38 | zwischenspeicher <= (others => '0'); |
39 | last_value_rising <= (others => '0'); --neu |
40 | elsif clk'event and clk = '0' then --falling edge |
41 | zwischenspeicher <= last_value_falling; |
42 | last_value_rising <= din; |
43 | end if; |
44 | end process; |
45 | |
46 | end simulation; |
Ohne die Ergänzung beim Reset gab es die gleiche Fehlermeldung. Ansonsten die Register aufzeichnen und mal schauen was wegfallen kann. MfG Holger
Hallo Tim Ich habe es mir noch mal aufgezeichnet. Meine Vermutung, dass sich "Zwischenspeicher" rauskürzt bestätigt sich. Anmerkung zum Aufgabenzettel: Man merkt, dass der, der es geschrieben hat, keine Ahnung von Hardware hat. Werte werden niemals bei einer Datenflanke eingelesen. Das führt zu metastabilen Zuständen der Flip-Flops. Die Clock muss soweit verzögert werden, so dass eindeutige Logikzustände anliegen, die dann in die Register (D-Flip-Flops) eingelesen werden können. MfG Holger
@Holger: Ja sorry, war halt nur eine Idee von mir. Hab mit der praktischen Anwendung von VHDL noch nicht so große Erfahrung.
Hier die Simulation. (Ohne Zwischenspeicher) MfG Holger
hehe, das mit den Daten zur Flanke hab ich mir auch schon gedacht. Aber die Heinis, die die Aufgaben stellen, machen eignelich nichts anderes als Logic zu Programmieren und aufm FPGA zu schmeissen. Synthetisieren laesst sich dein Vorschlag mit den zwei prozessen, kann die Simulation nur leider im MOment nicht kompilieren, weil mir eine UNISIM Lib fehlt, die ich mir erst besorgen muss. Inzwischen habe ich auch verstanden, wie mir der Vorschalg von T.M. bei meinem Problem helfen kann. werde den mal umsetzen, waehrend ich auf die Lib von meinem Kumpel warte.
Die Lehrveranstaltung habe ich vor einem Jahr absolviert. Ohne mich jetzt noch einmal in die Aufgabe zu vertiefen kann ich sagen, dass das nicht soo schwer ist. Du hast doch die Beschreibung des D-Flipflops vorgegeben. Das muss nur entsprechend instantiiert werden. An der Verhaltensbeschreibung brauchst du nichts zu ändern. An die fehlenden Libs kommst du übrigens auch umsonst ran. Zieh die das aktuelle Webpack von www.xilinx.com und installiere es. Vorausgesetzt du verwendest Modelsim und arbeitest unter Linux, kannst du die Libs selbst kompilieren mit dem Befehl: compxlib -s mti_se -f all -l all -dir <modelsimpath>/xilinx_libs Unter Windows sollte das so ähnlich auch funktionieren. Gruß, Jan
<An die fehlenden Libs kommst du übrigens auch umsonst ran. Zieh die das <aktuelle Webpack von www.xilinx.com und installiere es. Vorausgesetzt du <verwendest Modelsim und arbeitest unter Linux, kannst du die Libs selbst <kompilieren mit dem Befehl: <compxlib -s mti_se -f all -l all -dir <modelsimpath>/xilinx_libs Modelsim unter Linux? Kostenlose starterversion?? Gibst det wirklich? Wo?
<hmm, aber auf meinem Aufgabenblatt steht explizit: "Entwerfen Sie das <DDR-Register in "Verhaltens VHDL". Ich wollen mich doch nciht <veraeppeln Naja als FPGA Input gehts auch in verhaltens-vhdl (steht auch an der genannten Stelle). Beim Output, also daten zum DDR, wäre ich überrascht, wenns die synthese überlebt.
@FPGAküchle: Von einem kostenlosen Modelsim war nie die Rede. UNISIM und Konsorten sind von Xilinx und das Webpack ist in der Tat umsonst.
soo, ich hab die Aufgabe geloest, ganz ohne dual-edge FF. Danke an alle fuer ihre anregungen, auch wenn ich wohl hoffentlich nicht allzu bald hier wieder auftauchen werde, denn der grosse Spass beim VHDLn ist mir noch nicht ganz augenscheinig. TIM
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.