www.mikrocontroller.net

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


Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht 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.
library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_arith.all; 
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;


entity counter is
port (CLK1: in std_logic;
        an: out std_logic_vector (3 downto 0);
        seg: out std_logic_vector(6 downto 0));
end counter;

architecture behav of counter is

component zahl is
    port (input: std_logic_vector(12 downto 0);
        zehner, einer, hundert, tausend: out std_logic_vector(3 downto 0));
end component;
    
component ziffer is
    port (x: in std_logic_vector (3 downto 0);
      s: out std_logic_vector (6 downto 0));
end component;

signal x0,x1,x2,x3: std_logic_vector (3 downto 0);
signal pre_count: std_logic_vector(18 downto 0);
signal segm0,segm1,segm2,segm3: std_logic_vector(6 downto 0);

begin
za1: Zahl port map ("1111111111111" ,x0,x1,x2,x3);
z1: ziffer port map (x0, segm0);
z2: ziffer port map (x1, segm1);
z3: ziffer port map (x2, segm2);
z4: ziffer port map (x3, segm3);

    process(CLK1)
        begin
            if rising_edge(CLK1) then
                if pre_count < 400000 then
                    pre_count<=pre_count + 1;
                    if (pre_count > 0 and pre_count < 100000) then
                        seg <= segm0;
                        an <= "1101";
                    elsif (pre_count > 100000 and pre_count < 200000) then
                        seg <= segm1;
                        an <= "1110";
                    elsif (pre_count > 200000 and pre_count < 300000) then
                        seg <= segm2;
                        an <= "1011";
                    elsif (pre_count > 300000 and pre_count < 400000) then
                        seg <= segm3;
                        an <= "0111";
                    end if;
                else
                pre_count <= "0000000000000000000";
                end if;
            end if;
        end process;
end behav;
            

2. Ziffer. Funktioniert auch wie es soll.
library ieee; use ieee.std_logic_1164.all;

entity ziffer is
    port (x: in std_logic_vector (3 downto 0);
          s: out std_logic_vector (6 downto 0));
end ziffer;

architecture a of ziffer is
begin
    s(0) <= not x(1) and (( x(2) and not x(0)) or (x(0) and not x(2) and not x(3))) ;
    s(1) <= x(2) and  ((x(1) and not x(0) ) or ( not x(1) and x(0)))  ;
    s(2) <= x(1) and not x(2) and not x(0);
    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));
    s(4) <= x(0) or (x(2) and not x(1));
    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));
    s(6) <= (not x(1) and not x(2) and not x(3)) or (x(0) and x(1) and x(2));
end a;

3. Zahl. Funktioniert nicht, hat keine Syntax-Fehler, aber es wird fast 
alles wegoptimiert.
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;


entity Zahl is
port(input: std_logic_vector(12 downto 0);
        zehner, einer, hundert, tausend: out std_logic_vector(3 downto 0));
end Zahl;
architecture a of Zahl is

signal e: integer range 0 to 9;
signal z: integer range 0 to 99;
signal h: integer range 0 to 999;
signal t: integer range 0 to 9999;

begin
t <= to_integer(unsigned(input));
e <= t mod 10;
z <= t mod 100;
h <= t mod 1000;

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));
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));
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));
tausend(3) <= '1' when ((t >= 8000) and (t < 9000)) or ((t >= 9000) and (t < 10000));

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));
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));
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));
hundert(3) <= '1' when ((h >= 800) and (h < 900)) or ((h >= 900) and (h < 1000));

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));
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));
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));
zehner(3) <= '1' when ((z >= 80) and (z < 90)) or ((z >= 90) and (z < 100));

einer <= conv_std_logic_vector(e,4);
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-

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bekommst du irgendwelche Infos dazu:
e <= t mod 10;
z <= t mod 100;
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)

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank!

Jetzt habe ich das so gelöst:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;


entity Zahl is
port(clock: std_logic;
    input: std_logic_vector(7 downto 0);
    zehner, einer, hundert, tausend: out std_logic_vector(3 downto 0));
end Zahl;
architecture a of Zahl is

signal e: integer range 0 to 9;
signal z: integer range 0 to 9;
signal h: integer range 0 to 9;
signal t: integer range 0 to 9;
signal x: integer range 0 to 9999;
signal count: integer range 0 to 1000;
signal a: integer range 0 to 9999;
signal b: integer range 0 to 9999;
begin
x <= to_integer(unsigned(input));

process(clock)
    begin
      if rising_edge(clock) then
        if count < 1000 then
          count <= count + 1;
          if (count >= 0 and count < 10) then
            a <= x;
            b <= x;
          end if;
        end if;
        if (count >= 10 and count < 100) then
            if (a >= 1000) then
              a <= a - 1000;
              t <= t + 1;
            end if;
            if (a < 1000 and a >= 100) then
              a <= a - 100;
              h <= h + 1;
            end if;
            if (a < 100 and a >= 10) then
              a <= a - 10;
              z <= z + 1;
            end if;
            if (a < 10 and a >= 1) then
              a <= a - 1;
              e <= e + 1;
            end if;
        end if;
        if count >= 999 and b /= x then
          count <= 0;
          e <= 0;
          z <= 0;
          h <= 0;
          t <= 0;
        end if;
      end if;
    end process;
    
einer <= conv_std_logic_vector(e,4);
zehner <= conv_std_logic_vector(z,4);
hundert <= conv_std_logic_vector(h,4);
tausend <= conv_std_logic_vector(t,4);
end a;

Autor: Duke Scarring (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
library ieee;
use ieee.std_logic_1164.all;
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?"

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt mal deine Lösung und meinen Schieberegister-Ansatz 
verglichen.
http://www.lothar-miller.de/s9y/archives/34-Vektor...

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht 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-

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht 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-

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht 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
process(clock)
begin
if rising_edge(clock) then
if count < 1000 then
count <= count +1;
end if;
if count < 1000 and falling_edge(n) then
count <= 0;
end if;
if count = 100 and n = '0' then
spektrum(neu) <= spektrum(neu) +1;
end if;
if count = 1000 then
count <= 0;
end if;
end if;
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-

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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-Flan...

Und wie gesagt:  Nur 1 Takt in einem Anfängerdesign.

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht 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:
if rising_edge(clock) then
if counter = 0 then
counter <= 1;
signalalt <= signalneu;
end if;
if counter = 1 then
counter <= 0;
if signalneu < signalalt then
falingedge <= '1';
end if;
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
if fallingedge = '1' then
speicher <= counter;
fallingedge <= '0';
end if;
machen und dann weiterzählen lassen und eine Schranke setzen wie
if counter - speicher = 100 then
spektrum(neu) <= spektrum(neu) + 1;
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-

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...
library ieee;
use ieee.std_logic_1164.all;

entity edge_detect_and_delay is
  port (async_sig : in std_logic;
        clk       : in std_logic;
        valid     : out std_logic);
end;

architecture RTL of edge_detect_and_delay is
signal count : integer range 0 to 100 := 0;
signal fall  : std_logic := '0';
begin
  process
    variable sr : std_logic_vector (3 downto 0) := "0000";
  begin
    wait until rising_edge(clk);
    -- Flanken erkennen
    fall <= not sr(2) and sr(3);
    -- Eingang in Schieberegister einlesen
    sr := sr(2 downto 0) & async_sig;
  end process;

  process begin
    wait until rising_edge(clk);
    if (count<100) then   -- Zähler bis 100
       count <= count+1;
    end if;
    if (fall='1') then
        count <= 0;
    end if;
  end process;
   
  valid <= '1' when count=99 else '0'; -- beim Schritt 99 für 1 Takt eine '1' ausgeben

end architecture;

Autor: Gustl Buheitel (-gb-)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
process (clk) begin
  if rising_edge(clk) then
    :
  end if;
end process;

2.) Mit einem wait until
process (clk) begin
  wait until rising_edge(clk);
  :
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-i...

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

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.