Teiler durch 1,953125

Gast #2106026
Lesenswert?

Hallo,
ich habe einen uralt Frequenzzähler mit Nixieröhren. Dem möchte ich 
gerne einen Vorteiler durch 1000 verpassen. Der Vorteiler würde aus zwei 
Teilen bestehen.
Erstens wird durch 512 geteilt.
Dann durch 1,953125.
Das macht zusammen 1000.

Ich habe da einen Schaltplan mit TTL-IC's, möchte das aber lieber in 
einem CPLD XC9572 machen.
Wie kann ich das in VHDL programmieren?
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #2106045
Lesenswert?

Georg Bunter schrieb:
> Wie kann ich das in VHDL programmieren?
Ein "Dreizeiler":
1
:
2
use ieee.numeric_std.all;
3
:
4
  port ( clkin : in std_logic;
5
         clkout : out std_logic );
6
:
7
signal co: std_logic := '0';
8
signal count : integer range 0 to 499 := 0;
9
:
10
:
11
process begin
12
   wait until rising_edge(clkin);
13
   if count<499 then 
14
      count <= count+1;
15
   else 
16
      count <= 0;
17
      co    <= not co;
18
   end if;
19
end process;
20

21
clkout <= co;
22
:
Gast #2106073
Lesenswert?

Helmut Lenzen schrieb:
> Du must dir einen Teiler durch 1000 aufbauen. Durch 1,953125 teilen geht
> nicht.

Doch, müsste schon irgendwie gehen:
Da ist ein Zähler der bis 125 zählt.
Da gibt es einen Ausgang wo die Eingangsimpulse durchkommen oder nicht.
Inerhalb dieses Zählerzyklus von 125 Impulsen müssten 64 Impuls 
durchkommen und 61 nicht.
Das ist dann 125/64 = 1,953125

Wahrscheinlich macht diese oben gepostete Schaltung genau das, ich 
kapier's nur irgendwie gerade nicht...

Ich könnte die jetzt natürlich einfach nachbauen, ohne die zu verstehen.
Ich möchte das aber lieber in VHDL machen, das ich mal was lerne  ;-)
#2106080
Lesenswert?

Also es geht um einen "binary rate multiplier", so heißt der 
Impuls-Verschluck-Zähler üblicherweise. Such mal nach dem Datenblatt zum 
Standard-TTL-IC 7497, der macht n/64 Stufen.

Insgesamt soll die Schaltung ergeben: f_aus=f_in/(512*1000/512), die 
1000/512 sind dabei die genannten 1,953125.

1000/512 kann man noch kürzen, = 125/64 (oder 5^3/2^6). Der 
Impuls-Verschlucker muß also 64 von 125 Impulsen durchlassen, den Rest 
ausblenden.

Der 74HC390 enthält zwei Fünfer-Teiler und zwei Zweier-Teiler, mit zwei 
Stück geht das schon irgendwie, ich hätte nur Bedenken, dass kurze 
Glitches entstehen, wenn man die Verknüpfungen über weitere Gatter 
macht.
#2106097
Lesenswert?

Sebastian Hepp schrieb:
> Die Schaltung mit 74HC soll 13GHz und mehr schaffen? Sind die Bausteine
> wirklich so schnell? Und denke an HF-gerechtes Layout. ;)

Georg (TO) schreibt doch:
>Mein Vorteiler der durch 512 teilt, kann das auch bei GHz-Frequenzen.
>Das CPLD hat 15ns...

ALSO NOCHMAL 13Ghz / 512 = 25.39 Mhz
ist doch ganz einfach, mann muss halt nur ALLES lesen, wenn mann
dazu keine Lust hat soll mann auch keine vermutungen oder aehnliches
in die Welt setzen, gell?
#2106498
Lesenswert?

Wie wärs denn damit: Du schreibst dir Modelle der verwendeten 
TTL-Bausteine, verbindest diese nach Schaltplan, schreibst dir eine 
Testbench dazu und schaust Dir das mal in der Simulation an. Dann 
versteht man vielleicht, was die Schaltung tut, und kann das entweder 
direkt verwenden oder ein neues Modell schreiben, das das Gleiche tut.

Grüße,
Harald
#2106632
Lesenswert?

Nachtrag: Habe das Vorgeschlagene mal eben in Verilog runtergetippt und 
simuliert. Siehda, meine Testbench meldet nach 1000 Clocks:

# rising edges of input clock: 1000
# rising edges of output clock: 512
# ratio: 1.953125

Der geteilte Takt sieht aber echt nach Zahnlücke aus! Da fehlen manchmal 
ganze 3 Takte. Und ob das Ganze in Realität funktioniert, müsste man 
noch prüfen.

Grüße,
Harald
Angehängte Dateien:
#2106812
Lesenswert?

Und noch ein Nachtrag: Mit synchronem Design hat das alles natürlich 
nichts zu tun! In der Schaltung gibt es viele einzelne Clocks und dafür 
sind FPGA eigentlich nicht gemacht. Wenn dir längere Zahnlücken nichts 
ausmachen, dann bietet sich an, einen 125-er Zähler von 0 bis incl. 124 
zu machen, und das "64er"-Bit invertiert als Freigabe für das 
Durchreichen des Clocks zu nehmen. Dann kommen 64 von 125 Takten durch, 
was einen Teiler von 1,953125 ergibt.

Grüße,
Harald
Moderator (Firma: Titel) Persönliche Seite #2106906
Lesenswert?

Harald Flügel schrieb:
> Wenn dir längere Zahnlücken nichts
> ausmachen, dann bietet sich an, einen 125-er Zähler von 0 bis incl. 124
> zu machen, und das "64er"-Bit invertiert als Freigabe für das
> Durchreichen des Clocks zu nehmen. Dann kommen 64 von 125 Takten durch,
> was einen Teiler von 1,953125 ergibt.
Das mit den "Pulspaketen" lässt sich locker mal so "nebenher" 
beschreiben:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4

5
entity Divider is
6
    Port ( cin : in  STD_LOGIC;
7
           cout : out  STD_LOGIC);
8
end Divider;
9

10
architecture Behavioral of Divider is
11
signal cnt : integer range 0 to 124 := 0;
12
signal enable : std_logic;
13
begin
14

15
   process begin
16
      wait until falling_edge(cin);
17
      if cnt<124 then cnt <= cnt+1;
18
      else            cnt <= 0;
19
      end if;
20
      if cnt<64 then  enable <= '1';
21
      else            enable <= '0';
22
      end if;
23
   end process;
24
 
25
   cout <= cin when enable='1' else '0';
26

27
end Behavioral;
Und braucht gerade mal
1
Device Used   XC9536XL-5-PC44  
2
Macrocells    Pterms         Registers     Pins         Function Block Inputs 
3
9/36  (25%)   16/180  (9%)   8/36  (23%)   2/34  (6%)   15/108  (14%)

Diese Testbench
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.ALL;
3
USE ieee.numeric_std.ALL;
4

5
USE ieee.math_real.ALL;
6
 
7
use std.textio.all;
8
use ieee.std_logic_textio.all;
9
 
10
ENTITY tb_divider IS
11
END tb_divider;
12
 
13
ARCHITECTURE behavior OF tb_divider IS 
14
 
15
    -- Component Declaration for the Unit Under Test (UUT)
16
 
17
    COMPONENT Divider
18
    PORT(
19
         cin : IN  std_logic;
20
         cout : OUT  std_logic
21
        );
22
    END COMPONENT;
23
    
24

25
   --Inputs
26
   signal cin : std_logic := '0';
27

28
   --Outputs
29
   signal cout : std_logic;
30
   
31
   signal count_cout : real := 0.0;
32
   signal count_cin  : real  := 0.0;
33
 
34
BEGIN
35
 
36
  -- Instantiate the Unit Under Test (UUT)
37
   uut: Divider PORT MAP (
38
          cin => cin,
39
          cout => cout
40
        );
41

42
   cin <= not cin after 10ns;
43
   
44
   count_cout <= count_cout+1.0 when rising_edge(cout);
45
   count_cin  <= count_cin+1.0  when rising_edge(cin);
46
   
47
   process 
48
   variable l : line;
49
   variable r : real;
50
   begin
51
      wait for 1 ms;
52
      write(l, string'("teilerverhaeltnis: "));
53
      r := count_cin/count_cout;
54
      write(l, real'image(r));
55
      writeline(output, l);
56
   end process;
57
END;
zeigt dann an, dass das Ganze prinzipiell geklappt hat:
1
teilerverhaeltnis: 1.953125e+00
Angehängte Dateien:
Moderator (Firma: Titel) Persönliche Seite #2107225
Lesenswert?

Aber auch die elegantere Lösung macht sich nicht ohne:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4

5
entity Divider is
6
    Port ( cin : in  STD_LOGIC;
7
           cout : out  STD_LOGIC);
8
end Divider;
9

10
architecture Behavioral of Divider is
11
signal cnt : unsigned (6 downto 0) := (others=>'0');
12
signal enable : std_logic := '0';
13
begin
14

15
   process begin
16
      wait until falling_edge(cin);
17
      if cnt<124 then cnt <= cnt+1;
18
      else            cnt <= (others=>'0');
19
      end if;
20
      enable <= cnt(0) after 7 ns;
21
      if cnt=0 or cnt=60 then enable <= '1' after 7 ns;
22
      end if;
23
   end process;
24
 
25
   cout <= cin after 7 ns when enable='1' else '0' after 7 ns;
26

27
end Behavioral;
Ich habe hier mal für die Simulation noch ein paar Zeiten eingeführt, um 
zu sehen, wie sich das Ganze in etwa verhält.

Lediglich 2 PT für den zweiten Vergleicher werden zusätzlich benötigt:
1
Device Used   XC9536XL-5-PC44  
2
Macrocells    Pterms         Registers     Pins         Function Block Inputs 
3
9/36  (25%)   18/180  (10%)  8/36  (23%)   2/34  (6%)   15/108  (14%)
Angehängte Dateien:
Gast #2107615
Lesenswert?

Lothar Miller schrieb:
> Aber auch die elegantere Lösung macht sich nicht ohne:

Ah ja, du gibst bei cnt=0 und bei cnt=60 jeweils noch einen Impuls dazu.
Dann gibt es auf 125 Eingangsimpuls 62 + 2 = 64 Impulse.
Hübsch.

Ich habe mal den Schaltplan, den ich ganz oben gepostete habe 
entdröselt:
Da ist ein Zähler (1/2 74HC390), der zählt von 0...4
Das Nor-Gatter lässt nur bei Zählerstand 0, 1, 2, 3 die Eingangsimpuls 
durch.
Bei Zählerstand 4 kommen die Eingangsimpulse nicht durch.
Es werden also 4 von 5 Impulsen durchgelassen.
Also ist es ein Teiler durch 1,25
Werden drei solche Teiler hintereinandergeschaltet haben wir einen 
Teilerfaktor von 1,953125  QED

Was bedeutet
1
after 7 ns;
?
Gast #2108022
Lesenswert?

Belasse doch das Teilerverhältnis bei 512, oder gehe noch auf 1:1024, 
und passe im gleichen Verhältnis die Torzeit des Zählers an (verlängern 
auf das 1,024-fache) - dann stimmt die Anzeige (bis auf den Faktor 1000) 
wieder. Oder mache das umschaltbar, damit der Zähler ohne Vorteiler auch 
noch verwendbar bleibt.
Gast #2108041
Lesenswert?

Außerdem könnte man einen m:n-Teiler wie folgt dahinschreiben:
1
  -- 64/125
2
  if Div >= 125-64 then
3
    Div    <= Div - to_unsigned (125-64, 8);
4
    ClkOut <= '1';
5
  else
6
    Div    <= Div + to_unsigned (    64, 8);
7
    ClkOut <= '0';
8
  end if;
#2108069
Lesenswert?

Alle Vorschläge die bisher gebracht wurden sind doch für die Katz.
Offenbar liest keiner was der Fragesteller wirklich machen will.
Eine sinnvolle Lösung sieht so aus:

13GHz/8 Teiler

Dann /125

/5 /5 /5

Alle 4 ICs gibts hier: http://www.hittite.com/

Das wird natürlich nicht gerade billig.


Viel preiswerter wäre es die Zeitbasis von 1s Torzeit auf eine passende 
Zeit anzupassen damit ein Vorteiler durch 1024 passt.
Moderator (Firma: Titel) Persönliche Seite #2108129
Lesenswert?

Helmut S. schrieb:
> Offenbar liest keiner was der Fragesteller wirklich machen will.
Er will eine sehr hohe Taktfrequenz mit seinem langsamen Frequenzzähler 
messen. Und er kann blitzschnell durch 512 teilen. Und um nicht rechnen 
zu müssen oder um den Faktor 1.024 daneben zu liegen, will er die letzte 
Teilerstufe durch einen gebrochenen Teiler bewerkstelligen...

df1as schrieb:
> Außerdem könnte man einen m:n-Teiler wie folgt dahinschreiben:
Ich möchte aber behaupten, dass ein Teilerverhältnis kleiner 2 so nicht 
geht. Denn diese Geschichte kann ja nur durch den Ursprungstakt 
weitergeschaltet werden, und daher bestenfalls mit jedem Takt 1 mal 
umschalten...
Moderator (Firma: Titel) Persönliche Seite #2108483
Lesenswert?

>> Außerdem könnte man einen m:n-Teiler wie folgt dahinschreiben:
> Ich möchte aber behaupten, dass ein Teilerverhältnis kleiner 2 so nicht
> geht. Denn diese Geschichte kann ja nur durch den Ursprungstakt
> weitergeschaltet werden, und daher bestenfalls mit jedem Takt 1 mal
> umschalten...
So ist es.

Aber wenn man wie gehabt aus dem Zähler nur das Clock-Enable gewinnt, 
dann geht es:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4

5
entity Divider is
6
    Port ( cin : in  STD_LOGIC;
7
           cout : out  STD_LOGIC);
8
end Divider;
9

10
architecture Behavioral of Divider is
11
signal cnt : unsigned (7 downto 0) := (others=>'0');
12
signal enable : std_logic := '1';
13
begin
14

15
   process begin
16
      wait until falling_edge(cin);
17
      if cnt > 125-64 then
18
         cnt  <= cnt - to_unsigned (125-64, 8);
19
         enable <= '1';
20
      else
21
         cnt  <= cnt + to_unsigned (    64, 8);
22
         enable <= '0';
23
      end if;
24
   end process;
25

26
   cout <= cin after 7 ns when enable='1' else '0' after 7 ns;
27
 
28
end Behavioral;
Mir gefällt hier besonders, dass keine solche "Dreierpakete" mehr 
auftauchen. Und vor allem: die ist wunderbar skalierbar. Allerdings hat 
diese elegante Lösung einen etwas höheren Ressourcenverbrauch:
1
Device Used   XC9536XL-5-PC44  
2
Macrocells    Pterms         Registers     Pins         Function Block Inputs 
3
10/36  (28%)  36/180  (20%)  9/36  (25%)   2/34  (6%)   17/108  (16%)
Angehängte Dateien:
Gast #2108521
Lesenswert?

Lothar Miller schrieb:
> Helmut S. schrieb:
>> Offenbar liest keiner was der Fragesteller wirklich machen will.
> Er will eine sehr hohe Taktfrequenz mit seinem langsamen Frequenzzähler
> messen. Und er kann blitzschnell durch 512 teilen. Und um nicht rechnen
> zu müssen oder um den Faktor 1.024 daneben zu liegen, will er die letzte
> Teilerstufe durch einen gebrochenen Teiler bewerkstelligen...

Könnte man nicht die Gate-Zeit des Zählers so ändern (ohne die 
Nixieröhren dabei rauszuoperieren), daß 1024 als Teilerfaktor passen?

MfG Klaus

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren