Forum: FPGA, VHDL & Co. Ganze Zahl in Ziffern zerlegen


von Gustl B. (-gb-)


Lesenswert?

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.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use IEEE.std_logic_arith.all; 
4
use IEEE.std_logic_unsigned.all;
5
use IEEE.numeric_std.all;
6
7
8
entity counter is
9
port (CLK1: in std_logic;
10
        an: out std_logic_vector (3 downto 0);
11
        seg: out std_logic_vector(6 downto 0));
12
end counter;
13
14
architecture behav of counter is
15
16
component zahl is
17
    port (input: std_logic_vector(12 downto 0);
18
        zehner, einer, hundert, tausend: out std_logic_vector(3 downto 0));
19
end component;
20
    
21
component ziffer is
22
    port (x: in std_logic_vector (3 downto 0);
23
      s: out std_logic_vector (6 downto 0));
24
end component;
25
26
signal x0,x1,x2,x3: std_logic_vector (3 downto 0);
27
signal pre_count: std_logic_vector(18 downto 0);
28
signal segm0,segm1,segm2,segm3: std_logic_vector(6 downto 0);
29
30
begin
31
za1: Zahl port map ("1111111111111" ,x0,x1,x2,x3);
32
z1: ziffer port map (x0, segm0);
33
z2: ziffer port map (x1, segm1);
34
z3: ziffer port map (x2, segm2);
35
z4: ziffer port map (x3, segm3);
36
37
    process(CLK1)
38
        begin
39
            if rising_edge(CLK1) then
40
                if pre_count < 400000 then
41
                    pre_count<=pre_count + 1;
42
                    if (pre_count > 0 and pre_count < 100000) then
43
                        seg <= segm0;
44
                        an <= "1101";
45
                    elsif (pre_count > 100000 and pre_count < 200000) then
46
                        seg <= segm1;
47
                        an <= "1110";
48
                    elsif (pre_count > 200000 and pre_count < 300000) then
49
                        seg <= segm2;
50
                        an <= "1011";
51
                    elsif (pre_count > 300000 and pre_count < 400000) then
52
                        seg <= segm3;
53
                        an <= "0111";
54
                    end if;
55
                else
56
                pre_count <= "0000000000000000000";
57
                end if;
58
            end if;
59
        end process;
60
end behav;

2. Ziffer. Funktioniert auch wie es soll.
1
library ieee; use ieee.std_logic_1164.all;
2
3
entity ziffer is
4
    port (x: in std_logic_vector (3 downto 0);
5
          s: out std_logic_vector (6 downto 0));
6
end ziffer;
7
8
architecture a of ziffer is
9
begin
10
    s(0) <= not x(1) and (( x(2) and not x(0)) or (x(0) and not x(2) and not x(3))) ;
11
    s(1) <= x(2) and  ((x(1) and not x(0) ) or ( not x(1) and x(0)))  ;
12
    s(2) <= x(1) and not x(2) and not x(0);
13
    s(3) <= (x(2) and (( not x(1) and not x(0)) or (x(1) and x(0)) )) or (not x(2) and not x(1) and x(0) and not x(3));
14
    s(4) <= x(0) or (x(2) and not x(1));
15
    s(5) <= (x(1) and x(0)) or (x(0) and not x(2) and not x(3)) or( x(1) and not x(2));
16
    s(6) <= (not x(1) and not x(2) and not x(3)) or (x(0) and x(1) and x(2));
17
end a;

3. Zahl. Funktioniert nicht, hat keine Syntax-Fehler, aber es wird fast 
alles wegoptimiert.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
use ieee.numeric_std.all;
5
use ieee.std_logic_arith.all;
6
7
8
entity Zahl is
9
port(input: std_logic_vector(12 downto 0);
10
        zehner, einer, hundert, tausend: out std_logic_vector(3 downto 0));
11
end Zahl;
12
architecture a of Zahl is
13
14
signal e: integer range 0 to 9;
15
signal z: integer range 0 to 99;
16
signal h: integer range 0 to 999;
17
signal t: integer range 0 to 9999;
18
19
begin
20
t <= to_integer(unsigned(input));
21
e <= t mod 10;
22
z <= t mod 100;
23
h <= t mod 1000;
24
25
tausend(0) <= '1' when ((t >= 1000) and (t < 2000)) or ((t >= 3000) and (t < 4000)) or ((t >= 5000) and (t < 6000)) or ((t >= 7000) and (t < 8000)) or ((t >= 9000) and (t < 10000));
26
tausend(1) <= '1' when ((t >= 2000) and (t < 3000)) or ((t >= 3000) and (t < 4000)) or ((t >= 6000) and (t < 7000)) or ((t >= 7000) and (t < 8000));
27
tausend(2) <= '1' when ((t >= 4000) and (t < 5000)) or ((t >= 5000) and (t < 6000)) or ((t >= 6000) and (t < 7000)) or ((t >= 7000) and (t < 8000));
28
tausend(3) <= '1' when ((t >= 8000) and (t < 9000)) or ((t >= 9000) and (t < 10000));
29
30
hundert(0) <= '1' when ((h >= 100) and (h < 200)) or ((h >= 300) and (h < 400)) or ((h >= 500) and (h < 600)) or ((h >= 700) and (h < 800)) or ((h >= 900) and (h < 1000));
31
hundert(1) <= '1' when ((h >= 200) and (h < 300)) or ((h >= 300) and (h < 400)) or ((h >= 600) and (h < 700)) or ((h >= 700) and (h < 800));
32
hundert(2) <= '1' when ((h >= 400) and (h < 500)) or ((h >= 500) and (h < 600)) or ((h >= 600) and (h < 700)) or ((h >= 700) and (h < 800));
33
hundert(3) <= '1' when ((h >= 800) and (h < 900)) or ((h >= 900) and (h < 1000));
34
35
zehner(0) <= '1' when ((z >= 10) and (z < 20)) or ((z >= 30) and (z < 40)) or ((z >= 50) and (z < 60)) or ((z >= 70) and (z < 80)) or ((z >= 90) and (z < 100));
36
zehner(1) <= '1' when ((z >= 20) and (z < 30)) or ((z >= 30) and (z < 40)) or ((z >= 60) and (z < 70)) or ((z >= 70) and (z < 80));
37
zehner(2) <= '1' when ((z >= 40) and (z < 50)) or ((z >= 50) and (z < 60)) or ((z >= 60) and (z < 70)) or ((z >= 70) and (z < 80));
38
zehner(3) <= '1' when ((z >= 80) and (z < 90)) or ((z >= 90) and (z < 100));
39
40
einer <= conv_std_logic_vector(e,4);
41
end a;

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-

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Bekommst du irgendwelche Infos dazu:
1
e <= t mod 10;
2
z <= t mod 100;
3
h <= t mod 1000;
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)

von Gustl B. (-gb-)


Lesenswert?

Vielen Dank!

Jetzt habe ich das so gelöst:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4
use ieee.numeric_std.all;
5
use ieee.std_logic_arith.all;
6
7
8
entity Zahl is
9
port(clock: std_logic;
10
    input: std_logic_vector(7 downto 0);
11
    zehner, einer, hundert, tausend: out std_logic_vector(3 downto 0));
12
end Zahl;
13
architecture a of Zahl is
14
15
signal e: integer range 0 to 9;
16
signal z: integer range 0 to 9;
17
signal h: integer range 0 to 9;
18
signal t: integer range 0 to 9;
19
signal x: integer range 0 to 9999;
20
signal count: integer range 0 to 1000;
21
signal a: integer range 0 to 9999;
22
signal b: integer range 0 to 9999;
23
begin
24
x <= to_integer(unsigned(input));
25
26
process(clock)
27
    begin
28
      if rising_edge(clock) then
29
        if count < 1000 then
30
          count <= count + 1;
31
          if (count >= 0 and count < 10) then
32
            a <= x;
33
            b <= x;
34
          end if;
35
        end if;
36
        if (count >= 10 and count < 100) then
37
            if (a >= 1000) then
38
              a <= a - 1000;
39
              t <= t + 1;
40
            end if;
41
            if (a < 1000 and a >= 100) then
42
              a <= a - 100;
43
              h <= h + 1;
44
            end if;
45
            if (a < 100 and a >= 10) then
46
              a <= a - 10;
47
              z <= z + 1;
48
            end if;
49
            if (a < 10 and a >= 1) then
50
              a <= a - 1;
51
              e <= e + 1;
52
            end if;
53
        end if;
54
        if count >= 999 and b /= x then
55
          count <= 0;
56
          e <= 0;
57
          z <= 0;
58
          h <= 0;
59
          t <= 0;
60
        end if;
61
      end if;
62
    end process;
63
    
64
einer <= conv_std_logic_vector(e,4);
65
zehner <= conv_std_logic_vector(z,4);
66
hundert <= conv_std_logic_vector(h,4);
67
tausend <= conv_std_logic_vector(t,4);
68
end a;

von Duke Scarring (Gast)


Lesenswert?

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
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;

Die numeric_std ist in sich konsitent und wirklicher IEEE-Standard.
Für weitere Informationen bitte die Forumsuche bemühen.

Duke

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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?"

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

Ä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-

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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...

von Gustl B. (-gb-)


Lesenswert?

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-

von Gustl B. (-gb-)


Lesenswert?

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
if rising_edge(clock) then
4
if count < 1000 then
5
count <= count +1;
6
end if;
7
if count < 1000 and falling_edge(n) then
8
count <= 0;
9
end if;
10
if count = 100 and n = '0' then
11
spektrum(neu) <= spektrum(neu) +1;
12
end if;
13
if count = 1000 then
14
count <= 0;
15
end if;
16
end if;
17
end process:

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-

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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
if rising_edge(clock) then
2
if counter = 0 then
3
counter <= 1;
4
signalalt <= signalneu;
5
end if;
6
if counter = 1 then
7
counter <= 0;
8
if signalneu < signalalt then
9
falingedge <= '1';
10
end if;
11
end if;

nur ging das auch irgendwie nicht. Oder müsste da was gehen? Und wenn 
ich dann eine Verzögerung brauche kann ich ja
1
if fallingedge = '1' then
2
speicher <= counter;
3
fallingedge <= '0';
4
end if;
machen und dann weiterzählen lassen und eine Schranke setzen wie
1
if counter - speicher = 100 then
2
spektrum(neu) <= spektrum(neu) + 1;
3
end if;
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-

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity edge_detect_and_delay is
5
  port (async_sig : in std_logic;
6
        clk       : in std_logic;
7
        valid     : out std_logic);
8
end;
9
10
architecture RTL of edge_detect_and_delay is
11
signal count : integer range 0 to 100 := 0;
12
signal fall  : std_logic := '0';
13
begin
14
  process
15
    variable sr : std_logic_vector (3 downto 0) := "0000";
16
  begin
17
    wait until rising_edge(clk);
18
    -- Flanken erkennen
19
    fall <= not sr(2) and sr(3);
20
    -- Eingang in Schieberegister einlesen
21
    sr := sr(2 downto 0) & async_sig;
22
  end process;
23
24
  process begin
25
    wait until rising_edge(clk);
26
    if (count<100) then   -- Zähler bis 100
27
       count <= count+1;
28
    end if;
29
    if (fall='1') then
30
        count <= 0;
31
    end if;
32
  end process;
33
   
34
  valid <= '1' when count=99 else '0'; -- beim Schritt 99 für 1 Takt eine '1' ausgeben
35
36
end architecture;

von Gustl B. (-gb-)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
1
process (clk) begin
2
  if rising_edge(clk) then
3
    :
4
  end if;
5
end process;

2.) Mit einem wait until
1
process (clk) begin
2
  wait until rising_edge(clk);
3
  :
4
end process;

Diese beiden Schreibweisen ergeben genau das selbe Ergebnis. Allerdings 
kann es im 2. Fall keine unvollständige Sensitivliste geben (weil ja gar 
keine da ist). siehe:
http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html

Aber die Synthesetools können noch mehr:
http://www.lothar-miller.de/s9y/archives/47-wait-im-Prozess.html

> -gb-, der sich das Schieberegister gut merken wird.
Das ist eine gute Idee... ;-)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Sch...lags kaputt... :-/
Nachtrag:
>>> 2.) Mit einem wait until
ist natürlich keine Sensitivliste nötig bzw. erlaubt:
1
  process begin
2
    wait until rising_edge(clk);
3
     :
4
  end process;

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
Noch kein Account? Hier anmelden.