mikrocontroller.net

Forum: FPGA, VHDL & Co. CPLD als Top Octave Generator nutzen?


Autor: Kon Lion (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

gleich vorweg geschickt die Ankündigung, dass ich nicht allzuviel Ahnung 
im Bereich CPLD- Programmierung habe. Vielleicht kann mir ja bei meinem 
Vorhaben dennoch jemand helfen oder mir die Idee des Vorgehen 
vermitteln:

Ich würde gerne den TOG S50240 mit dem CPLD MAXII EPMT100 simmulieren. 
Eine Inputclock von 2MHz wird in 13 Ausgangssignale mit 50% duty cycle 
geteilt (/451, /426, /402, /379, /358, /478, /239, /253, /268, /284, 
/301, /319, /339).

Soll ich einfach versuchen 13 Divide-by-N counter zu programmieren oder 
gibt es eine effizientere Art? Ich würde Quartus als Programm nutzen, 
dann als Verilog schreiben oder Blockdiagramme nutzen, was ist für den 
Anfang der einfachere Weg?

Dann danke ich schon mal, lg

Autor: Audiomann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ein Thema gab es hier vor Jahren bereits. Finde es aber nicht. Da 
wurden genau diese Frequenzen behandelt. Irgendeiner hatte sogar noch 
einen besseren Vorschlag für die Teiler. Musst mal suchen.

Zur Frage:

Ja, das geht natürlich. Das sind 12 Zähler. Ob das musikalisch Sinn 
macht, ist eine andere Frage, weil die entstehenden Frequenzen nicht 
perfekt sind.

Passend zu Deinem Thema wäre vielleicht das hier:
Beitrag "Musik aus dem CPLD ;-)"

Was ich gerade sehe: Warum sind es 13 Teilerfrequenzen?

Autor: ./. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> So ein Thema gab es hier vor Jahren bereits.

Ja, da hatte jemand ein kaputte Orgel.

Mit einem kleinen Cyclone II geht es natuerlich ohne Probleme.
Sogar mit noch wesentlich perfekteren Teilerverhaelnissen.
In VHDL geht das recht uebersichtlich zu beschreiben.

Bei einem CPLD koennten es von den verfuegbaren Flip-Flops
zu wenige geben. Da wuerde ich vorher nochmal durchzaehlen
und mit dem DB vergleichen.

Autor: Jürgen S. (engineer) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde auch einen FPGA vorziehen, es sei denn, es braucht ein 
bestimmtes Gehäuse. Die Originalbausteine sind ja teilweise erschreckend 
teuer. Es gibt bekanntlich kleine Platinen mit DIL-Füsschen und 
aufgelötetem Chip, die als universelles replacement fungieren.

>Soll ich einfach versuchen 13 Divide-by-N counter zu programmieren oder
>gibt es eine effizientere Art?

Ja, Ich würde hier z.B. keine DDS verwenden, wenn da nicht Dithering und 
Werteinterpolation verwendet wird, bzw. reine Sinuswellen erzeugt werden 
sollen, weil sich das sonst nicht gut filtern lässt. Das erzeugt 
unharmonische Spektrem, speziell beim Phasing etc.

Besser ist es tatsächlich, eine stärker verstimmte Frequenz hinzunehmen 
und dafür ein sauberes Primärsignal zu haben.

Als Anregung:
http://www.96khz.org/htm/pldmodularorgan.htm

Die Stimmen kann man frequenzmäßig im PLD sogar besser hinbekommen, als 
das über TOS mit 2MHz und den o.g. Teilern möglich ist. Beispiele im 
Bild. Unter 10ppm Abweichung bei der gewählten Taktfrequenz (24 fache 
S/PDIF @ 192kHz).

Autor: Nils P. (torus)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Nur mal so in den Raum geworfen:

Die LPC17XX Microcontroller von NXP haben vier Timer mit jeweils vier 
Countern und Toggle Outputs. Das macht 16 Divider Ausgänge, die komplett 
in Hardware laufen.

Clock Input kann entweder intern oder über externe Clocks laufen.

D.h. so einen Top Octave Divider könnte man komplett in der Periphery 
des Microcontrollers implementieren. Die CPU muss nur die Pins 
konfigurieren, die Teiler und den Timer Mode setzen und kann dann in den 
Deep Sleep.

Aber klar, in einem etwas größeren CPLD ist das auch schnell gemacht.

Autor: Andreas F. (chefdesigner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nils P. schrieb:
> Die LPC17XX Microcontroller von NXP haben vier Timer mit jeweils vier
> Countern und Toggle Outputs. Das macht 16 Divider Ausgänge, die komplett
> in Hardware laufen.

... und die bieten darüber hinaus noch die Option, die Timer 
umzuschalten, um die Frequenz ganz genau zu bekommen. In jedem 
Gitarrenstimmgerät wird das so gemacht.

Autor: Markus W. (elektrowagi78) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kon Lion schrieb:
> Eine Inputclock von 2MHz wird in 13 Ausgangssignale mit 50% duty cycle
> geteilt (/451, /426, /402, /379, /358, /478, /239, /253, /268, /284,
> /301, /319, /339).

Hallo, ist Dir oder sonst jemandem zufällig bekannt, woher diese Zahlen 
kommen und warum sie mit ausgerechnet diesem Takt betrieben werden 
müssen?

Autor: foobar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Takt ist 2.00024MHz. Das durch die Teiler und nochmals durch ne 
2er-Potenz ergibt ne gleichstufige Stimmung. Z.B. 2000240Hz/284/16 = 
440Hz = a. Die Teiler selbst sind im Abstand von 2^(1/12), also 
239*2^(i/12) für i=0..12.

Autor: Jürgen S. (engineer) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Hallo, ist Dir oder sonst jemandem zufällig bekannt, woher diese Zahlen
> kommen und warum sie mit ausgerechnet diesem Takt betrieben werden
> müssen?
Ich würde sagen, das sind einfach die tiefst möglichen Zahlen, die ein 
einigermaßen akzeptables Ergebnis liefern. Diese bringen unter 2 Cent 
Abweichung in der Tonlage und eine Standardabweichung von <1%. Das 
nächst bessere Zahlenset wäre ein minimaler Faktor 301 danach Faktor 
353. Das wird tendenziell immer besser, es gibt aber Bessere und 
Schlechtere.

Um die Werte an sich zu beurteilen, hatte ich mal eine DB programmiert, 
die die Werte alle durchspielt und nach Güte sortiert. Die Güte ist 
dabei der Lageoffset gegenüber dem absoluten Ton und zudem die 
Standardabweichung, also die Homogentität der Töne. Diese bestimmt - 
unabhängig von der Lage - die Qualität der Akkorde. Man könnte z.B. auch 
die absolute Lage ignorieren und eine möglichst hohe Homogenität 
anstreben. Anders herum könnte man nach einer optimalen Taktfrequenz 
suchen.

Wenn man sich die Werte für die 239 ansieht, sind die eigentlich recht 
gut, bis auf den Ton Nummer 7, das wäre allerdings das Fis in C-Dur und 
das wird kaum benötigt. Etwas anderes ist es, wenn man in einer anderen 
Tonart spielt.

Die 2MHz werden auch hier im Betrag genannt:
Beitrag "Re: FPGA als digitaler Oszillator?"
Dort sind es auch die 2,00024

Wie das real in den Orgeln jeweils gemacht wird, weiß ich nicht. Ich 
habe für mein PLD-Orgel damals das Bestmögliche aus dem jeweils 
gegebenen FPGA-Takt herauszuholen versucht. Welchen Takt man dabei 
verwendet, ist natürlich willkürlich.

: Bearbeitet durch User
Beitrag #5514287 wurde vom Autor gelöscht.
Autor: Jürgen S. (engineer) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mir das nochmal angesehen und musste feststellen, dass ich für 
eine C-Dur-Stimmung auf 1,682 MHz herauskomme. Das hatte ich auch bei 
der Tabelle zugrundegelegt, kann ich mich erinnern.

Bei den angegebenen 2,00024 MHz errechne ich einen Lageoffset für die 
gleichstufige Stimmung zu 0,5%. Besser wäre meines Erachtens eine 
Frequenz von 1,999360 MHz. Das würde das C exakt treffen, liegt halt von 
den Fehlern nicht mehr so balanciert.

Was man auch sieht: Der TOS-Chip produziert bei der Normfrequenz zweimal 
das Dis, wozu auch immer. Ich bevorzugte daher 1,6MHz von oben. Die 
lassen sich über 3 Ecken auch aus einer PLL gewinnen und zu 126,1 MHz 
umbauen. Die sind genau das 75fache des Taktes und zugleich ein 
Vielfaches von 48kHz. Damit kann man so einen Chip emulieren.

Autor: Jürgen S. (engineer) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist noch was Nettes:

Basisteiler 150, normiert auf 7040Hz für C, Takt = 1,056MHz.

Das Besondere ist, dass sich die gerundeten Teiler von der 
gleichförmigen Stimmung hin zur reinen Stimmung bewegen. Die Teiler für 
F und G passen exakt für C-Dur und für das E nimmt man einen Wert 
geringer und liegt fast dran.

Das Schöne ist auch, dass hier direkt auch ein 96kHz Takt heraus kommt: 
1056/11 = 48000*2.

Für 873 klappt es sehr gut mit dem digitalen S/PDIF-Takt für 48kHz.

Autor: Kon Lion (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist nun etwas Zeit vergangen - andere Dinge hatten Priorität - aber 
ich habe versucht der Diskussion zu folgen. Vielen Dank für den Input!

Ich verstehe die grundlegenden Konzepte der Tonerzeugung und 
Frequenzteilung via Flip-Flops, wie anfangs erwähnt habe ich allerdings 
noch nicht so viel Ahnung von der Programmierung und Anwendung. Das soll 
sozusagen ein erstes Projekt sein, um in die Welt von CPLD/FPGA 
einzutauchen. Irgendwie komme ich aber nicht voran.

Runtergebrochen wären meine Fragen eigentlich: Ich habe ein Max II 
(EPM240T100C5N) Experemiertboard (mit 50MHz Clock Onboard, soweit ich 
verstehe) rumliegen, wie schaffe ich es daraus ein TOG-Chip Ersatz zu 
machen?

(Wie sähe ein einfacher Code aus? Lagetoleranz der Töne kann natürlich 
optimiert werden. Soll ich gleich die Onboard Clock nutzen oder die 
vorhandene 2MHz als Input? Und ließen sich in dem Zuge auch die weiten 
Divid-by-2-Counter ersetzen? (~80 I/O-Pins vorhanden))

Was ich als Beispiel-Code gefunden habe, ließe sich das 
anwenden/vereinfachen?
`timescale 1ns / 1ps

module clk2freq(
    input clk2mhz,
    output [4:0] notes
    );
 parameter ctarget = 239;
 reg [10:0] ctr;
 reg [4:0] out;
 initial ctr = 0;
 initial out = 0;
 assign notes[4:0] = out[4:0];

 always @(posedge clk2mhz) begin
   ctr = ctr + 1;
   if (ctr == ctarget) begin
    ctr = 0;
    out = out + 1;
   end
 end
endmodule


module main_clk_div(
    input clk,
    output mhz2
    );
 
 reg  [3:0] div_clk;
 initial div_clk = 0;
 assign mhz2 = div_clk[2];
 
 always @(posedge clk) begin
  div_clk = div_clk + 1;
 end
endmodule

module organ(
 input clk16,
 output [4:0] c_notes,

 output [4:0] cs_notes,

 output [4:0] d_notes,

 output [4:0] ds_notes,

 output [4:0] e_notes,

 output [4:0] f_notes,

 output [4:0] fs_notes,

 output [4:0] g_notes,

 output [4:0] gs_notes,

 output [4:0] a_notes,

 output [4:0] as_notes,

 output [4:0] b_notes
 );

   
 // create a 2mhz clock generator
 wire  clock2mhz;
 main_clk_div main_clock_gen(clk16, clock2mhz);


 clk2freq #(239) c_generator (clock2mhz, c_notes);

 clk2freq #(253) b_generator (clock2mhz, b_notes);

 clk2freq #(268) as_generator (clock2mhz, as_notes);

 clk2freq #(284) a_generator (clock2mhz, a_notes);

 clk2freq #(301) gs_generator (clock2mhz, gs_notes);

 clk2freq #(319) g_generator (clock2mhz, g_notes);

 clk2freq #(338) fs_generator (clock2mhz, fs_notes);

 clk2freq #(358) f_generator (clock2mhz, f_notes);

 clk2freq #(379) e_generator (clock2mhz, e_notes);

 clk2freq #(402) ds_generator (clock2mhz, ds_notes);

 clk2freq #(426) d_generator (clock2mhz, d_notes);

 clk2freq #(451) cs_generator (clock2mhz, cs_notes);

     
endmodule

Autor: Markus W. (elektrowagi78) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einmal scheint mir da was zu fehlen, nämlich die Erzeugung der Teiler 
und dann möchte ich die Frage stellen, wo Du wirklich sicher bist, dass 
Du Verilog verwenden möchtest?

Autor: Kon Lion (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ma W. schrieb:
> Einmal scheint mir da was zu fehlen, nämlich die Erzeugung der Teiler
> und dann möchte ich die Frage stellen, wo Du wirklich sicher bist, dass
> Du Verilog verwenden möchtest?

Hab mich zumindest bisher eher mit Verilog beschäftigt, VHDL ist 
gebräuchlicher? ICh entscheide mich halt am Anfang eine Sprache zu 
lernen, dachte das macht kein Unterschied?

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kon Lion schrieb:
> Was ich als Beispiel-Code gefunden habe, ließe sich das
> anwenden/vereinfachen?

Das ist doch schon ziemlich einfach.
modul organ ist das Top-Modul, das alles zusammenfasst.

modul clk2freq erzeugt die einzelnen Teiler für die 12 Noten (mit dem 
Teilfaktor als Parameter für jede Instanz, siehe organ Modul).
Das erzeugt dir gleich 5 Oktaven als Ausgang an 5 Pins für jede Note, 
nicht nur die Top-Oktave.

modul main_clk_div generiert die 2 MHz Grundfrequenz, anscheinend ist 
hier ein 16 MHz Eingang an einem Pin vorgesehen, aus dem die 2 MHz 
erzeugt werden. Dieser externe Clock Eingang, ermöglicht die ganze Orgel 
zu stimmen und z.B. mit Vibrato Modulation zu versehen. Zum Testen 
kannst du auch ein 2 MHz clock aus dem 50 MHz Oszillator deines Boards 
erzeugen.

Alles was du noch brauchst ist ein Pinmapping File, das den Clock 
Eingang und die Noten Ausgänge den gewünschten Pins zuordnet. Für einen 
ersten Syntheseversuch ist das aber nicht mal nötig, es werden dann 
einfach zufällige Pins verwendet.


Wenn man die freie Wahl hat zwischen Verilog und VHDL würde ich mich 
jederzeit für Verilog entscheiden. Hat fast nur Vorteile. Aber in diesem 
Teil der Welt wurden halt die meisten zu VHDL gezwungen, und können sich 
gar nicht vorstellen, dass es auch etwas einfacher geht. (Soll nicht der 
Aufruf zu einer neuen Runde language-war sein, sondern nur den TO in 
seiner Entscheidung bestätigen).

Autor: ./. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;

entity TOP is
  Port (
    clk    : in    STD_LOGIC;  -- 50 MHz
    t0    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t1    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t2    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t3    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t4    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t5    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t6    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t7    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t8    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t9    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t10    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t11    : buffer  STD_LOGIC_VECTOR (7 downto 0)
  );
end TOP;

architecture Behavioral of TOP is
signal c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11  :  integer;

begin

process (clk)
begin
  if rising_edge(clk) then
    c0 <= c0 + 1;
    c1 <= c1 + 1;
    c2 <= c2 + 1;
    c3 <= c3 + 1;
    c4 <= c4 + 1;
    c5 <= c5 + 1;
    c6 <= c6 + 1;
    c7 <= c7 + 1;
    c8 <= c8 + 1;
    c9 <= c9 + 1;
    c10 <= c10 + 1;
    c11 <= c11 + 1;
    if c0 = 5972  then  c0 <= 0; t0 <= t0 + 1;    end if;
    if c1 = 5637  then  c1 <= 0; t1 <= t1 + 1;    end if;
    if c2 = 5321  then  c2 <= 0; t2 <= t2 + 1;    end if;
    if c3 = 5022  then  c3 <= 0; t3 <= t3 + 1;    end if;
    if c4 = 4740  then  c4 <= 0; t4 <= t4 + 1;    end if;
    if c5 = 4474  then  c5 <= 0; t5 <= t5 + 1;    end if;
    if c6 = 4223  then  c6 <= 0; t6 <= t6 + 1;    end if;
    if c7 = 3986  then  c7 <= 0; t7 <= t7 + 1;    end if;
    if c8 = 3762  then  c8 <= 0; t8 <= t8 + 1;    end if;
    if c9 = 3551  then  c9 <= 0; t9 <= t9 + 1;    end if;
    if c10 = 3352  then  c10 <= 0; t10 <= t10 + 1;  end if;
    if c11 = 3163  then  c11 <= 0; t11 <= t11 + 1;  end if;
  end if;
end process;

end Behavioral;


*******************************************************
 Number of ports :                      97
 Number of nets :                     3783
 Number of instances :                1730
 Number of references to this view :     0

Total accumulated area : 

 Number of BUFG :                        1
 Number of CLB Flip Flops :            480
 Number of CY4 :                       264
 Number of FG Function Generators :    600
 Number of H Function Generators :      24
 Number of OBUF :                       96
 Number of Packed CLBs :               300
 Number of accumulated instances :    1730
***********************************************
Device Utilization for S40xlBG256
***********************************************
Resource                Used    Avail   Utilization
-----------------------------------------------
IOs                     97      205      47.32%
FG Function Generators  600     1568     38.27%
H Function Generators   24      784       3.06%
CLB Flip Flops          480     1568     30.61%


Ist aber nicht gerade ein CPLD...

Autor: Christoph db1uq K. (christoph_kessler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beitrag "Re: analoge Orgel reparieren"
da hatten wir das Thema vor fünf Jahren mal

Autor: ./. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> da hatten wir das Thema vor fünf Jahren mal

Ja, da war das aber noch ohne die Oktavteiler dahinter :-).

Autor: Andi (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Hier eine vereinfachte und verbesserte Verilog Version. Verbessert wurde 
der "off by one" Teiler Fehler, und es wird nur noch ein 2 MHz Eingang 
von einem Pin verwendet.

Auf einem MachXO2 Breakoutboard ergibt sich folgender 
Ressourcenverbrauch:
Design Summary:
   Number of registers:    166 out of  7209 (2%)
   Number of SLICEs:       114 out of  3432 (3%)
   Number of LUT4s:        228 out of  6864 (3%)
   Number of PIO sites used: 61 + 4(JTAG) out of 115 (57%)

module organ (
 input clock2M,                  // 2 MHz Input Pin
 output [4:0] c_notes,           // 5 Oktav-Ausgänge für jede Note
 output [4:0] cs_notes,
 output [4:0] d_notes,
 output [4:0] ds_notes,
 output [4:0] e_notes,
 output [4:0] f_notes,
 output [4:0] fs_notes,
 output [4:0] g_notes,
 output [4:0] gs_notes,
 output [4:0] a_notes,
 output [4:0] as_notes,
 output [4:0] b_notes
 );
   
 clk2freq #(239) c_generator  (clock2M, c_notes);    // 12 Teiler Instanzen mit je 5 Oktaven
 clk2freq #(253) b_generator  (clock2M, b_notes);
 clk2freq #(268) as_generator (clock2M, as_notes);
 clk2freq #(284) a_generator  (clock2M, a_notes);
 clk2freq #(301) gs_generator (clock2M, gs_notes);
 clk2freq #(319) g_generator  (clock2M, g_notes);
 clk2freq #(338) fs_generator (clock2M, fs_notes);
 clk2freq #(358) f_generator  (clock2M, f_notes);
 clk2freq #(379) e_generator  (clock2M, e_notes);
 clk2freq #(402) ds_generator (clock2M, ds_notes);
 clk2freq #(426) d_generator  (clock2M, d_notes);
 clk2freq #(451) cs_generator (clock2M, cs_notes);

endmodule


module clk2freq (                  // Teiler Modul (wird 12 mal verwendet)
    input clk2mhz,
    output [4:0] notes
 );
 parameter ctarget = 239;          // Teilerwert (wird durch Parameter beim Instanzieren überschrieben)

 reg [8:0] ctr = 0;                // 9 bit counter reicht für Teiler bis 451
 reg [4:0] out = 0;                // Zähler für 5 Oktaven
 assign notes[4:0] = out[4:0];     // Zähler mit Ausgängen verbinden 

 always @(posedge clk2mhz) begin
   ctr = ctr + 1;
   if (ctr == ctarget-1) begin     //Reset counter bei Erreichen des Teilerwertes-1
    ctr = 0;
    out = out + 1;                 //Zähler für 5 Oktaven, +1 bei jedem Reset des Teilers 
   end
 end
endmodule

Autor: Organist (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was passiert denn dann mit den so erzeugten Rechtecksignalen? Die 
müssten doch noch weiter geteilt werden, um auch die restlichen 
Frequenzen für die anderen Tasten zu erhalten. Sollte man dies nicht 
gleich mitrealisieren?

Autor: ./. (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
> Sollte man dies nicht gleich mitrealisieren?

Ist doch. Die harmlos aussehenden:
t0 <= t0 + 1;
t1 <= t1 + 1;
...

erzeugen in Verbindung mit den Portdefinitionen:
    t0    : buffer  STD_LOGIC_VECTOR (7 downto 0);
    t1    : buffer  STD_LOGIC_VECTOR (7 downto 0);
...

auch noch 8 Oktaven nach unten.
Nur 4, wie im Verilog-Beispiel sind natuerlich viel zu wenig.
Fuer die Fusslagen 16" bis 1" braucht man schon 5 Oktaven,
dazu kommen noch die u.U. 5 Oktaven des Manuals.

Aber: Praktisch wuerde man das so im Orgelbau kaum machen.
Da wuerde man eher simple Binaerzaehler (z.B. 4520, 4040) benutzen.
Die kann man naemlich nahe bei den Schaltkontakten des Manuals
unterbringen und muss nicht 8 x 12 Leitungen durch die Gegend
ziehen...

Die "alten" CMOS-ICs haben auch den Vorteil hohe Pegel fuer
die subtraktiven Filterschaltungen bereitzustellen und
die geringe Flankensteilheit ihrer Ausgangssignale erzeugt
weniger Stoerungen.

Autor: Kon Lion (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andi schrieb:
> Hier eine vereinfachte und verbesserte Verilog Version. Verbessert wurde
> der "off by one" Teiler Fehler, und es wird nur noch ein 2 MHz Eingang
> von einem Pin verwendet.

Klasse, vielen Dank! Sieht jetzt auch strukturierter aus und die 
Kommentare dazu haben mir fürs Verständnis einiges gebracht.

Auch der VHDL Code sieht verständlich und einfach aus, nur wie gesagt 
mit Verilog habe ich mich bisher etwas intensiver beschäftigt.

Die 5 Oktaven sollten für den Anfang auch passen, was genau der Tastatur 
der String-Maschine entspräche.

Autor: Jürgen S. (engineer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
./. schrieb:
> Die kann man naemlich nahe bei den Schaltkontakten des Manuals
> unterbringen und muss nicht 8 x 12 Leitungen durch die Gegend
> ziehen...

So! würde ich das gar nicht machen. Die Tonsignale sollte man - gerade 
wegen der Rechtecke - tunlichst nicht durch die Gegend schicken. Besser 
ist es, die Tastatur parallel abzufragen, zu multiplexen und das Signal 
zur Erzeugerplatine zu leiten und dort in Schieberegister zu legen, um 
sie wieder aufzufächern.

Diese werden dann mit UND-Gattern verknüpft und den einzelnen 
Orgel-Registerstufen zugeleitet, die dann die Klangformung aus den 
Rechtecken machen. Das ist wesentlich weniger störanfällig.

Das Allerbeste ist nach wie vor, man produziert die Töne auch gleich 
virtuell im PLD auf der Basis eines Sägezahns:
http://www.96khz.org/oldpages/simplesoundgenerator.htm

Autor: ./. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Tonsignale sollte man - gerade
> wegen der Rechtecke - tunlichst nicht durch die Gegend schicken.

Ja, aus so einem CPLD/FPGA kommen Signale aequivalent der AC-Serie
heraus. Deswegen ja der Hinweis diese Signale so nicht in einer
klassisch aufgebauten (Register-)Orgel zu benutzen.

Den Aufwand die Tastatursignale in einem CPLD/FPGA fuer eine
subtraktive Klangsynthese zu "gaten" wird glaub ich eh
niemand betreiben. Aber ich mag mich ja taeuschen.

Instrumente dieser Art waren z.B. das Roland RS-09 Organ/Strings.
Da waren dann 2 Kaefer fuer die Tonaufbereitung zustaendig.

Heute kann man da nun wirklich bessere Dinge anstellen.

Wie man sieht, gibt es aber die "klassischen" Orgelbauer noch.
Die wollen die vielleicht unzuverlaessig gewordenen Generatorsaetze
durch etwas zeitgemaesses ersetzen.
Und fuer die war dieser Hinweis, auch auf die CMOS-Teiler, gedacht.

Autor: Duke Scarring (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
./. schrieb:
> USE IEEE.STD_LOGIC_UNSIGNED.ALL;
> USE IEEE.NUMERIC_STD.ALL;
Autsch.
Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

./. schrieb:
> t0    : buffer  STD_LOGIC_VECTOR (7 downto 0);
          ^^^^^^
Und nochmal Autsch.

Hier eine VHDL-Version, die beide Probleme umgeht.
Und passend dazu eine Testbench.

In einen CPLD passt es trotzdem nicht ;-)

Duke

Autor: ./. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, ohne die "alten" Libs mochte das "betagte" Tool nicht.
Auch das "Buffer" war so in die Quelle gekommen.

Im uebrigen, solang unten etwas raus kommt ist es mir
herzlich egal...

Autor: Jürgen S. (engineer) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
./. schrieb:
> Wie man sieht, gibt es aber die "klassischen" Orgelbauer noch.
> Die wollen die vielleicht unzuverlaessig gewordenen Generatorsaetze
> durch etwas zeitgemaesses ersetzen.

Den von mir beschriebenen Ansatz fände ich aber sehr zeitgemäß und 
soweit ich weiß wird das in digitalen Orgeln auch so gemacht. Der 
Hintergrund ist einfach, dass die Signale durch ihre Nachbartasten 
zuviele Störung mitschleppen und eine direkte analoge Verarbeitung nicht 
machbar ist.
Wenigstens sollte man noch Schmitt-trigger einsetzen. Wenn man es 
hingegen total analog machen will, kann man auch die Register erst mit 
den Rechtecken beschießen, dann mischen sie sie den Tasten zuführen. 
Dann hat man mit den Tasten einen Analogmischer.

Es macht dann nichts aus, wenn eine gedrückte Taste sich nicht nur in 
ihrem Pfad sondern auch noch in den Nachbarn bemerkbar macht. So ist das 
bei meiner 1980er Ingrid-Orgel gemacht. Die ist made in italy, was den 
Ansatz möglicherweise erklärt.

Ein Bastler, der sein Böhm-Orgel mit Conrad-Teilen aufgezogen hat, hat 
mir aber mal erklärt, dass das Murks ist und sich das so gebaut, wie ich 
es oben beschrieb. Die Messungen, die wir gemacht hatten, ergaben, dass 
das Böhmsystem im Original pegelmässig in die Knie ging, wenn man 
mehrere Ausgänge desselben Teilers belastete. Schon deshalb sollte man 
das entkoppeln finde ich und dann ist das gaten direkt miterledigt.

Das saubere gaten erzeugt zudem auch präzise Phasen, was für den 
Zusammenklang wichtig ist, wenn die Frequenzen sehr genau stimmen. Dann 
kann man nämlich den einzelnen Teilwellen einen passenden Vorlauf 
spendieren, dass es zu keiner Interferenz kommt.

Beispiel im Bild: 2 digitale Wellen (rot und grün) und ihre gefilterten 
Pendants mit der Summe aus beiden (gelb), im unteren Bereich mit einer 
90 Grad Verschiebung der hohen Freuquenz.

Bei dem Thema Phase mit man z.B. mit Blick auf Phasing und Vibrato 
ohnehin noch genauer nachdanken, wie man die einzelnen Pfade behandeln 
will und da reicht eine einfach Ausgabe des Binärteiles über die Ports 
nicht.

Autor: Koo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andi schrieb:
>
 module organ (
>  input clock2M,                  // 2 MHz Input Pin
>  output [4:0] c_notes,           // 5 Oktav-Ausgänge für jede Note
>  output [4:0] cs_notes,
>  output [4:0] d_notes,
>  output [4:0] ds_notes,
>  output [4:0] e_notes,
>  output [4:0] f_notes,
>  output [4:0] fs_notes,
>  output [4:0] g_notes,
>  output [4:0] gs_notes,
>  output [4:0] a_notes,
>  output [4:0] as_notes,
>  output [4:0] b_notes
>  );
> 
>  clk2freq #(239) c_generator  (clock2M, c_notes);    // 12 Teiler 
> Instanzen mit je 5 Oktaven
>  clk2freq #(253) b_generator  (clock2M, b_notes);
>  clk2freq #(268) as_generator (clock2M, as_notes);
>  clk2freq #(284) a_generator  (clock2M, a_notes);
>  clk2freq #(301) gs_generator (clock2M, gs_notes);
>  clk2freq #(319) g_generator  (clock2M, g_notes);
>  clk2freq #(338) fs_generator (clock2M, fs_notes);
>  clk2freq #(358) f_generator  (clock2M, f_notes);
>  clk2freq #(379) e_generator  (clock2M, e_notes);
>  clk2freq #(402) ds_generator (clock2M, ds_notes);
>  clk2freq #(426) d_generator  (clock2M, d_notes);
>  clk2freq #(451) cs_generator (clock2M, cs_notes);
> 
> endmodule
> 
> module clk2freq (                  // Teiler Modul (wird 12 mal 
> verwendet)
>     input clk2mhz,
>     output [4:0] notes
>  );
>  parameter ctarget = 239;          // Teilerwert (wird durch Parameter 
> beim Instanzieren überschrieben)
> 
>  reg [8:0] ctr = 0;                // 9 bit counter reicht für Teiler 
> bis 451
>  reg [4:0] out = 0;                // Zähler für 5 Oktaven
>  assign notes[4:0] = out[4:0];     // Zähler mit Ausgängen verbinden
> 
>  always @(posedge clk2mhz) begin
>    ctr = ctr + 1;
>    if (ctr == ctarget-1) begin     //Reset counter bei Erreichen des 
> Teilerwertes-1
>     ctr = 0;
>     out = out + 1;                 //Zähler für 5 Oktaven, +1 bei jedem 
> Reset des Teilers
>    end
>  end
> endmodule 

Hoffe es stört nicht das mal wieder auszugraben... versuche den Code 
gerade zu simulieren, in Quartus Prime Lite. Compilern kein Problem, 
aber sich so wavetables ausgeben zu lassen scheint mir etwas komplexer. 
Muss ich in eine Testbench nur das Top-Level-Modul einbinden? Und dann 
in ModelSim starten?

Mein erster kläglicher Versuch:
module TOG_test;          

reg clock2M;             
wire [59:0] notes;

TOG DUT(.clock2M(clock2M),             
    .c_notes(notes),           
    .cs_notes(notes),
    .d_notes(notes),
    .ds_notes(notes),
    .e_notes(notes),
    .f_notes(notes),
    .fs_notes(notes),
    .g_notes(notes),
    .gs_notes(notes),
    .a_notes(notes),
    .as_notes(notes),
    .b_notes(notes)
    );

initial begin 
clock2M=0;
forever #500 clock2M=~clock2M;
end

endmodule

Autor: Weltbester FPGA-Pongo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du brauchst eine Testbench, darin enthalten eine Stimuli die die 
Eingänge deiner Schaltung bedient und die Schaltung selbst. Gfs noch 
einen Analyszer, der die Ausgänge abfängt und mit Vorgaben vergleicht.

Autor: Kon W. (koo)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Weltbester FPGA-Pongo schrieb im Beitrag #5739037:
> Du brauchst eine Testbench, darin enthalten eine Stimuli die die
> Eingänge deiner Schaltung bedient und die Schaltung selbst. Gfs noch
> einen Analyszer, der die Ausgänge abfängt und mit Vorgaben vergleicht.

Ich habe den Code jetzt einfach ohne Testbench in ModelSim geladen und 
einen clock input "erzwungen". Das scheint auch zu funktionieren, alle 
60 gewünschte Frequenzen werden erzeugt.


Bevor ich jetzt einen passendes CPLD board bestelle (eins mit EPM570: 
scheint günstig und alle 306 logic elements zu fassen), wollte ich mir 
noch mal Gedanken um die grundsätzliche Verschaltung des TOG Moduls 
machen. Ich habe mir ein Schema überlegt, um den Weg zu den Filterbänken 
zu verkürzen (nicht über Tastenkontakte leiten) und evtl. Midi in/out zu 
erlauben.

Was meint ihr, könnte das funktionieren? Oder wo sind Fehler / 
Schwierigkeiten?
z.B wie nutze ich am besten die 61 demux bits zum gaten der 
Ausgangssignale..

: Bearbeitet durch User
Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest dir erstmal die Verschaltung des TOP+Teiler, einer
mechanischen Tastatur fuer mehrere Fusslagen und der Filterbaenke
ansehen.

So wie du das da gezeichnet hast, wird das nichts.
Bei 6 Fusslagen: 16", 8", 5 1/3", 4", 2" und 1 3/5" z.B. sind
per Taste im Manual 6 Umschalter. Im Ruhezustand liegt am
Tastenausgang GND. Und wenn gedrueckt der Ton der aus den
Generatoren kommt.

Fuer 61 Tasten und z.B. 6 Fusslagen braeuchtest du 61 x 6 Schalter...

Da reicht dein CPLD hinten und vorne nicht.

Im uebrigen: Aus der ganzen Konstruktion kommt dann 60iger Jahre
Rechteckton mit ein wenig Filter dahinter.
Sowas will doch keiner mehr hoeren.

Autor: Kon W. (koo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... schrieb:
> Du solltest dir erstmal die Verschaltung des TOP+Teiler, einer
> mechanischen Tastatur fuer mehrere Fusslagen und der Filterbaenke
> ansehen.
>
> So wie du das da gezeichnet hast, wird das nichts.
> Bei 6 Fusslagen: 16", 8", 5 1/3", 4", 2" und 1 3/5" z.B. sind
> per Taste im Manual 6 Umschalter. Im Ruhezustand liegt am
> Tastenausgang GND. Und wenn gedrueckt der Ton der aus den
> Generatoren kommt.

Verstehe nicht ganz was Fußlagen sind, es geht um eine String-Maschine 
aus den 70ern, richtig. 61 Tasten, mehr nicht. Dachte halt eine Taste 
ein Bit zum steuern der 61 CPLD-Ausgänge (an /aus). Die Verarbeitung der 
Signale danach bleibt wie sie ist, mit filter, chourus, mixen ect.

Im Orginal wird die 2MHz clock eben in mehreren ICs in 61 Frequenzen 
zerlegt dann jede einzelne durch die Tastenkontakte geleitet und dann 
erst in die Filter, also viel Kabel.

Ob oder wie man die CLPD Ausgänge kontrollieren kann ist halt die frage, 
ich bin da leider sehr unerfahren. Das ganze Projekt soll mir eher zum 
lernen der Technik dienen als groß was zu revolutionieren..

: Bearbeitet durch User
Autor: ... (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Die klassischen Stringsensemble haben die Ausgaenge der Teiler
gewichtet verknuepft, um als Rohmaterial etwas aehnliches wie
einen Saegezahn zu produzieren.

Also etwa: 1/16

Aber auch die hatten mehrere Fusslagen. Z.B. 8" und 4".

Die dort verwendeten Schaltkreise konnter aber auch analoge
Signale verarbeiten.

Dort wurde auch die VCA-Funktion Attack und Release analog
realisiert.

Die 8X, 4X, 2X und X waeren da dann die entsprechenden
Fusslagen der Generatorbank.

Autor: ... (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
In einem FPGA wuerde ich das heute eher wie im Bild machen.

Das ist natuerlich geringfuegig aufwendiger.

Aber dafuer ist alle digital berechnbar und braucht keine
analoge Verarbeitung.

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.

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