Hallo! ich bin neu hier und habe natürlich ein Problem.
Eigentlich will ich nur eine ganze Zahl die ich als std_logic_vector
bekomme auf vier 7-Segment Anzeigen anzeigen, aber das geht nicht so wie
ich will. Alles drum herum steht schon, sprich ich kann problemlos
Ziffern anzeigen wie ich will wenn ich diese Entity weglasse und fest
die Werte für die Ziffern rausgebe.
Aufgebaut ist es mit einem Top Modul, das die Eingabe macht, also von
den Switches das Bitmuster nimmt. Dann gibt es eine Entity Ziffer die
gibt es vier mal (wegen der vier 7-Segment Anzeigen) und die bekommt
einen 4-Bit std-logic_vector (also 0 ... 9) und liefert dem Top-Modul
einen 7-Bit std_logic_vector zurück, der dann an die einzelnen Segmente
geht.
Und dann gibt es die Entity Zahl. Diese bekommt die Eingabe und soll
dann vier 4-Bit std_logic_vector zurückliefern die an die vier Ziffern
gehen.
Und genau das macht Probleme.
Am liebsten hätte ich die Zahl zerlegt wie hier
Beitrag "integer in ziffern zerlegen" oder wie:
einer = A mod 10
A = A - einer
A = A / 10
zehner = A mod 10
A = A - zehner
A = A / 10
hunderter = A mod 10
A = A - hunderter
A = A / 10
tausender = A mod 10
Allerdings geht / nicht. Also hab ich das anders gemacht, mit einer
Tabelle. Ist zwar nicht schön, sollte aber gehen.
Mein Problem ist jetzt, dass der ISE Project Manager da so ziemlich
alles wegoptimiert(?) und nix funktionierened übrig bleibt. Daher habe
ich hier auch mal alle drei Codes eingebunden.
1. Die Top Entity. Ja ich gebe bisher einen festen wert an Zahl, aber
das dürfte nicht stören. Und das funktioniert auch, wenn ich in Zahl
einfach feste Werte wie "0001" für einer, zehner, hundert und tausend
zurückgebe zurückgebe.
Und hier noch die Warnings die ich bekomme:
WARNING:Xst:646 - Signal <z> is assigned but never used. This
unconnected signal will be trimmed during the optimization process.
WARNING:Xst:646 - Signal <h> is assigned but never used. This
unconnected signal will be trimmed during the optimization process.
WARNING:Xst:1290 - Hierarchical block <za1> is unconnected in block
<counter>.
It will be removed from the design.
WARNING:Xst:1290 - Hierarchical block <z1> is unconnected in block
<counter>.
It will be removed from the design.
WARNING:Xst:1290 - Hierarchical block <z2> is unconnected in block
<counter>.
It will be removed from the design.
WARNING:Xst:1290 - Hierarchical block <z3> is unconnected in block
<counter>.
It will be removed from the design.
WARNING:Xst:1290 - Hierarchical block <z4> is unconnected in block
<counter>.
It will be removed from the design.
WARNING:Xst:1710 - FF/Latch <seg_1> (without init value) has a constant
value of 0 in block <counter>. This FF/Latch will be trimmed during the
optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <seg_2>
(without init value) has a constant value of 0 in block <counter>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <seg_3>
(without init value) has a constant value of 1 in block <counter>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <seg_4>
(without init value) has a constant value of 1 in block <counter>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <seg_5>
(without init value) has a constant value of 1 in block <counter>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <seg_6>
(without init value) has a constant value of 1 in block <counter>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1710 - FF/Latch <seg_1> (without init value) has a constant
value of 0 in block <counter>. This FF/Latch will be trimmed during the
optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <seg_2>
(without init value) has a constant value of 0 in block <counter>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1710 - FF/Latch <seg_3> (without init value) has a constant
value of 1 in block <counter>. This FF/Latch will be trimmed during the
optimization process.
Da wird einfach Zeug weggeworfen oder so, das eigentlich notwendig ist,
wie "Signal <z> is assigned but never used." aber das wird doch in Zahl
sehr wohl genutzt? Die einer gehen allerdings, also nur zehner, hundert
und tausend nicht.
Vielen Dank!
-gb-
Das sollte nämlich gar nicht gehen... :-o
> Die einer gehen allerdings, also nur zehner, hundert und tausend nicht.
Das ist klar: nur bei den Einern muß nicht geteilt werden...
Du willst eine Umwandlung von Integer nach BCD. Also sowas:
http://www.lothar-miller.de/s9y/categories/44-BCD-Umwandlung
(die unteren Einträge)
Gustl Buheitel schrieb:> use ieee.std_logic_unsigned.all;> use ieee.numeric_std.all;> use ieee.std_logic_arith.all;
AUA!
Bitte nur eine numerische Bibliothek verwenden. Meine Header sehen so
aus:
1
libraryieee;
2
useieee.std_logic_1164.all;
3
useieee.numeric_std.all;
Die numeric_std ist in sich konsitent und wirklicher IEEE-Standard.
Für weitere Informationen bitte die Forumsuche bemühen.
Duke
Gustl Buheitel schrieb:> Jetzt habe ich das so gelöst:
if (count >= 0 and count < 10) then
a <= x;
b <= x;
end if;
Warum weist du das gleich 9 mal zu? Reicht 1 mal nicht aus?
Wozu brauchst du denn die 1000er, wenn dein Eingangsvektor gerade mal 8
Bit breit ist?
Wie bekommst du von aussen mit, dass deine Konvertierung fertig ist?
Duke Scarring schrieb:> Bitte nur eine numerische Bibliothek verwenden.
Denn wenn beide Bibliotheken, also sowohl
> use ieee.std_logic_unsigned.all;> use ieee.std_logic_arith.all;
wie auch
> use ieee.numeric_std.all;
verwendet werden, dann sind einige Typdefinitionen, Casts und
Konvertierungen doppelt vorhanden. Das kann seltsame Effekte und
Fehlermeldungen geben... :-o
> Für weitere Informationen bitte die Forumsuche bemühen.
Siehe z.B. den Beitrag "Redundanz in den IEEE Libs / Welche kann ich weg lassen?"
Ich habe jetzt mal deine Lösung und meinen Schieberegister-Ansatz
verglichen.
http://www.lothar-miller.de/s9y/archives/34-Vektor-nach-BCD.html
Deine Lösung schafft (mit den nötigen 13 Bits für sinnvolle 1000er) auf
einem Spartan 3 knapp 106 MHz und braucht dabei
Number of Slices 61
Number of Slice Flip Flops 53
Number of 4 input LUTs 106
Die Schieberegistervariante läuft mit 209 MHz und verbraucht wesentlich
weniger Logik:
Number of Slices 33
Number of Slice Flip Flops 55
Number of 4 input LUTs 43
Es werden zwar 2 FFs mehr gebraucht, die sind aber hauptsächlich dem
Ausgangspuffer zuzuschreiben. Lasse ich den weg, dann bleiben noch
Number of Slices 23
Number of Slice Flip Flops 39
Number of 4 input LUTs 43
Und die Taktfrequenz geht bis auf 251 MHz hoch...
Aller guten Dinge sind drei...
Die beiden vorher gelöschten Beiträge waren von mir... ;-)
Nachtrag:
wenn dann der Overflow noch weggelassen wird, ergeben sich
Number of Slices 21
Number of Slice Flip Flops 35
Number of 4 input LUTs 40
bei 241 MHz
Die VHDL-Datei dazu ist im Anhang.
Ähm warum?
Ich bin absoluter FPGA Neuling und habe jetzt in Zwei Tagen eine
Digitaluhr geschrieben die funktioniert und die man einstellen kann.
Klar wenn ich mich besser auskenne, dann würde ich das schon machen wenn
ich Zeit hätte.
Aber Danke für die Tips!
Und ich habe noch eine andere Frage bezüglich FPGA. Hier habe ich einen
Spartan3E auf einem digilent BASYS. Der hat ja internen SRAM. Wenn ich
jetzt ein fettes Array aufmache (4096 mal 24bit) (und das mache ich)
dann kann der das nicht bauen weil mein FPGA zu klein ist. Allerdings
steht da im ISE von Xilinx:
Total Number of 4 input LUTs Used: 11,108, Available: 1,920.
und drunter:
Number used as 16x1 Rams: 6,643
Jetzt ist meine Frage:
Nutzt der automatisch den internen RAM oder muss ich den extra
ansprechen? (gut der wäre auch zu klein aber ist nur ne Frage.)
Vielen Dank!
-gb-
Gustl Buheitel schrieb:> Ähm warum?
Was warum? Warum was?
> Ich bin absoluter FPGA Neuling und habe jetzt in Zwei Tagen eine> Digitaluhr geschrieben die funktioniert und die man einstellen kann.
Das ist nicht schlecht. Wenn auch etwas pragmatisch gelöst... ;-)
Gustl Buheitel schrieb:> Total Number of 4 input LUTs Used: 11,108, Available: 1,920.> und drunter:> Number used as 16x1 Rams: 6,643
Das heißt Distributed RAM. Hier wird jeweils 1 LUT als 16x1 Bit Speicher
konfiguriert.
> Jetzt ist meine Frage:> Nutzt der automatisch den internen RAM oder muss ich den extra> ansprechen? (gut der wäre auch zu klein aber ist nur ne Frage.)
Wenn du die BRAMs (Block RAMs) willst, dann mußt du so schreiben, dass
der Synthesizer BRAMs draus machen kann.
Wenn du einfach nur so ein asynchrones RAM beschreibst, dann wird daraus
Distributed RAM, das in den LUTs abgebildet wird.
Ein BRAM braucht einen Takt, ein Distributed RAM ist wie ein "normales
SRAM".
Sieh dir mal die beiden Implementierungen eines DDFS an: die, bei der
die Leseadresse getaktet ist, wird als BRAM abgebildet. Die ungetaktete
als Distributed RAM.
Mehr zum Thema im absolut lesenswerten XST User Guide...
Ok vielen Dank! Leider wird es auch mit BlockRAM zu viel für den FPGA.
Dann lieber gleich einen mit externem SD Ram.
Aber jetzt habe ich auch gleich ein neues Problem:
Ich habe zwei Eingänge, eines das nur triggert und eines das 12 Bit
breit ist und eine Zahl ist. Das Problem ist, dass zuerst der Trigger
von 1 auf 0 geht und dann so 1 Mikrosekunde später liegt das Bitmuster
an das ich einlesen will.
Ich hätte da gerne sowas gehabt wie if falling_edge(trigger) then wait
für 100 ns; und dann Bitmuster wegschreiben.
Gut wait geht ja leider nicht, also wäre es auch ok wenn ich derweil
meine 100Mhz Clock bis 100 zählen lasse. Aber das geht irgendwie auch
nicht.
Weil ich habe da einen Zähler den ich pro Takt um 1 erhöhe, dann will
ich den bei falling_edge trigger auf 0 setzen - und das wären schon
wieder mehrere Eingänge.
Irgendwas wird mir schon einfallen^^
Vielen Dank!
-gb-
Hallo!
Ich komme leider doch nicht auf eine Lösung ...
Es ist folgendes, ich bekomme ein Signal rein (das wird von 1 auf 0
gesetzt) und signalisiert, dass ein neues Bitmuster anliegt. Allerdings
liebt das Bitmuster erst ca. eine Mikrosekunde nach dem wechsel von 1
auf 0 am ersten Signal an. Das erste Signal wird super erkannt durch
falling_edge, aber wie schaffe ich es, dass er das zweite erst nach 100
Takten (bei 100Mhz) liest?
Ich bräuchte einen Zähler der auf die 100 Mhz Clock hört und mit der
immer hochzählt und der durch das falling_edge des ersten Signals auf 0
gesetzt werden kann, damit ich dann von neuem immer bis 100 zählen
lassen kann.
sowas
1
process(clock)
2
begin
3
ifrising_edge(clock)then
4
ifcount<1000then
5
count<=count+1;
6
endif;
7
ifcount<1000andfalling_edge(n)then
8
count<=0;
9
endif;
10
ifcount=100andn='0'then
11
spektrum(neu)<=spektrum(neu)+1;
12
endif;
13
ifcount=1000then
14
count<=0;
15
endif;
16
endif;
17
endprocess:
geht leider nicht. Aber wie schafft man es, dass man quasi auf zwei
Signale hört? also die Clock und noch eines?
Vielen Dank!
-gb-
Gustl Buheitel schrieb:> Aber wie schafft man es, dass man quasi auf zwei> Signale hört? also die Clock und noch eines?
Das geht nicht. Denn "man" will ja nicht hören, sondern das Design wird
auf FFs und Logik abgebildet.
> Ich bräuchte einen Zähler der auf die 100 Mhz Clock hört und mit der> immer hochzählt und der durch das falling_edge des ersten Signals auf 0> gesetzt werden kann, damit ich dann von neuem immer bis 100 zählen> lassen kann.
Es gibt kein FF mit einem steigenden und gleichzeitig einem fallenden
Takt als Eingang.
Kurz nochmal ein Verweis auf meine Postulate im
Beitrag "Re: vhdl-richtlinien f. synthese?"> Ich bräuchte einen Zähler der auf die 100 Mhz Clock hört
Das ist klar, denn du sollst keinen zweiten Takt im Design haben ;-)
> und der durch das falling_edge des ersten Signals auf 0> gesetzt werden kann, damit ich dann von neuem immer bis 100 zählen> lassen kann.
Du synchronisierst also das "erste" Signal ein und lässt eine
Flankenerkennung drauf los.
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung
Und wie gesagt: Nur 1 Takt in einem Anfängerdesign.
Danke! Also die Flankenerkennung habe ich verstanden, aber wie
synchronisiert man da? Ich hatte mir ja auch schon gedacht:
Man hat ja die Clock. Und dann diese andere Signal. Also macht man sowas
wie:
1
ifrising_edge(clock)then
2
ifcounter=0then
3
counter<=1;
4
signalalt<=signalneu;
5
endif;
6
ifcounter=1then
7
counter<=0;
8
ifsignalneu<signalaltthen
9
falingedge<='1';
10
endif;
11
endif;
nur ging das auch irgendwie nicht. Oder müsste da was gehen? Und wenn
ich dann eine Verzögerung brauche kann ich ja
1
iffallingedge='1'then
2
speicher<=counter;
3
fallingedge<='0';
4
endif;
machen und dann weiterzählen lassen und eine Schranke setzen wie
1
ifcounter-speicher=100then
2
spektrum(neu)<=spektrum(neu)+1;
3
endif;
sprich wenn er 100 weitergezählt hat dann guckt er erst das Bitmuster
an.
Ist das ein machbarer Ansatz oder bin ich da total auf dem Holzweg?
-gb-
Gustl Buheitel schrieb:>>> if counter - speicher = 100 then
Mach solche unnötigen Operationen nicht. Dies Synthese macht da wirklich
einen Subtrahierer rein. Und damit wird dein Design langsamer...
> Also die Flankenerkennung habe ich verstanden,
Gut... :-)
> aber wie synchronisiert man da?
Also hast du es leider doch nicht verstanden... :-(
> Man hat ja die Clock. Und dann diese andere Signal.
Na, wenn das alles ist...
1
libraryieee;
2
useieee.std_logic_1164.all;
3
4
entityedge_detect_and_delayis
5
port(async_sig:instd_logic;
6
clk:instd_logic;
7
valid:outstd_logic);
8
end;
9
10
architectureRTLofedge_detect_and_delayis
11
signalcount:integerrange0to100:=0;
12
signalfall:std_logic:='0';
13
begin
14
process
15
variablesr:std_logic_vector(3downto0):="0000";
16
begin
17
waituntilrising_edge(clk);
18
-- Flanken erkennen
19
fall<=notsr(2)andsr(3);
20
-- Eingang in Schieberegister einlesen
21
sr:=sr(2downto0)&async_sig;
22
endprocess;
23
24
processbegin
25
waituntilrising_edge(clk);
26
if(count<100)then-- Zähler bis 100
27
count<=count+1;
28
endif;
29
if(fall='1')then
30
count<=0;
31
endif;
32
endprocess;
33
34
valid<='1'whencount=99else'0';-- beim Schritt 99 für 1 Takt eine '1' ausgeben
Wow vielen Dank!
Bisher habe ich verstanden, dass man durch das Schieberegister sehr
schön sehen kann ob das steigend oder fallend ist.
Das wait until rising_edge(clk); verstehe ich nicht. Bzw. vermutlich
verstehe ich es falsch. Für mich sieht das genauso aus wie ein if
rising_edge(clk) - weil man wartet ja immer nur einen Takt?! Ok es ist
eleganter wie wenn man alles in eine if-Abfrage packt.
Das ist echt cool, weil das dann den Eingang bei jedem Takt betrachtet
und somit sehr schnell ist.
Also nochmal vielen Dank!
-gb-, der sich das Schieberegister gut merken wird.
Gustl Buheitel schrieb:> Das wait until rising_edge(clk); verstehe ich nicht.
Ein Prozess braucht entweder eine Sensitivliste oder eine
wait-Anweisung. Es gibt also 2 Arten, einen (synthetisierbaren) Prozess
zu beschreiben:
1.) Lehrbuchgemäß mit