Hallo, Leute
irgendwie habe ich gerade eine "Blokade" ;-)
Es gibt ja einen Graycode Zähler, wo sich nur 1 Bit ändert. Ist zwar
schön und gut, aber nun bräuchte ich einen, wo sich 2 Bits ändern :-o
Und zwar immer
z.B. "0000" -> "0011" -> "0101" -> "0110" und so weiter.
Hat jemand vielleicht eine Idee?
kest
Leider nicht. Ich brauche einen Zähler ;-) Und beliebige Bitbreiten :-/
Aber trotzdem danke
Das ist ja noch komplizierter, als ich es mir gedacht habe :-o Im
großen und ganzem geht es um DC-Ballancierte Vectoren, also wo die
Anzahl der Einsen und Nullen gleich ist. Aber okay, werde mich da noch
schlau machen.
Kest
:-o Ist ja cool. Das heißt, man zählt einfach, und hinten hängt man ein
Parity Bit ran? Muss das noch genauer anschauen, aber ich denke mal,
das ist schon mal eine mögliche Lösung.
Vielen Dank!
Kest
Genau, einfach normal hochzählen, aber das erste Bit freilassen bzw auf
0 setzten. Das wird dann 1, wenn eine ungerade Anzahl "einsen" im
Binärwert stehen !! NICHT eine ungerade Zahl !!!
Gruß, Thomas
Tja, Thomas
das ist doch viel schwerer, als ich es mir gedacht habe :-o Ich meine,
das, was Du vorgeschlagen hast, ist schon richtig, aber leider dann
doch nicht für mich brauchbar :-(
Ich erzähle mal kurz, was ich brauche:
ich bräuchte eine Bildungsvorschrift, um ALLE Möglichkeiten in einem 10
Bit Vector durchzuzählen, wo die gleiche Anzahl von einsen und nullen
ist.
beginnend vielleicht mit
"0000101111"
"0000110111"
"0000111011"
"0000111101"
"0000111110"
"0001011110"
"0001101110"
oder wie auch immer, bin jetzt ducheinander gekommen ;-)
Jetzt habe ich alle Möglichkeiten im ROM abgespeichert, ist aber
irgendwie nicht das Wahre. (bei 10 Bit sind es 252 Möglichkeiten)
Würde mich riesig freuen, wenn jemand da eine Idee hat
Kest
Falls ja, hier mein Auszug aus meiner Large Integer Library für Delphi:
procedure NToGreenCode(var A: IInteger; const B: IInteger);
var
R: IInteger;
begin
NShl(R, B, 1);
NXor(A, B, R);
end;
oder in kurz
GreenCode := (Input * 2) xor Input.
thats all, easy ;)
Gruß Hagen
Ich würde es über eine Truth-table machen:
Ein Repeat-Macro von 0..1023 (10 Bit) laufen lassen und immer, wenn der
Wert genau 5 Einsen enthält, den Wert in der Truth-table ablegen und den
Index hochzählen.
Der Index am Ende ist dann auch der Rücksetzwert des Binärzählers für
die Truth-Table.
Peter
Na ja, also doch die einsen zählen. :-/ Irgendwie muss es doch einfacher
gehen
@Hagen: nein, Greencode ist es wohl leider nicht
Wen es noch interessiert, hier sind die ersten ein Paar Werte:
1F,2F,37,3B,3D.3E,4F,57,5B,5D,5E,67,6B,6D,6E,73,75,76,79,7A,7C,8F,97,9D,
9E,A7,AB,AD,AE,B3,B5,B6,B9,BA,BC
und so weiter.
Eine ziemlich seltsamme Codierung, woher hast du diese, und kannst du
mal alle Werte von 0 bis 255 der Reihenfolge nach posten (so wie oben)
Gruß Hagen
"Na ja, also doch die einsen zählen. :-/ Irgendwie muss es doch
einfacher gehen"
Wenn ja, dann findet der Compiler es heraus.
Für den ist es ein Klacks, alle 1024 Werte zu testen und nur die
gültigen zu implementieren.
Und dann schau Dir einfach mal die Logikgleichungen für die Truth-Table
an.
Der Code ist sowas ähnliches wie Manchester, d.h. er ist
gleichstromfrei, kann also über eine Funkstrecke übertragen werden.
Peter
Blöder Code, meiner Meinung nach vollständig "unpraktikabel" und
unoptimiert.
Man erzeugt eine Liste aller binären Zahlen zwischen 0 bis 1024 die
immer 5 Bits gesetzt haben. Diese Liste durchnummeriert ergibt dann die
Werte für die Zahlen 0 bis 252.
Gruß Hagen
Dein Zähler könnte als simpliziert so funktionieren.
Erhöhe einen binären 10 Bit Vektor solange um +1 bis wieder 5 Bits im
Vektor auf 1 stehen. Dies wäre die "Addition" +1 auf diesen
speziellen Zähler.
Gruß Hagen
Also doch keine "richtige" Bildungsvorschrift? Das ist ja schade :-/
Dass das unpraktikabel ist und blöd, mag man noch streiten ;-) Es geht
um ein Sony-LED-Modul. Und Sony hält sich da sehr bedekt - eigentlich
reagieren sie nicht drauf :-/ Na ja, dann eben Brute-force :-o :-)
Kest
>>Wie hast du das gemacht? Ich sehe da schon Gesetzmäsigkeiten, aber>>wie genau, kapiere ich es nicht!
Keine Ahnung, eines meiner anderen Hobbies ist die Zahlentheorie und
Kryptographie. Eventuell habe ich das ein "Auge" für solche Muster
entwickelt.
Hat aber auch nicht lange gedauert das rauszufinden.
Deshalb sage ich ja "blöder Code". Denn dahinter dürfte sich
keienrlei realer Mathematik verbergen (gefühlsmäßig geschätzt), sondern
simpelste, hm Programierer-Denkerei.
Ich schätze mal das du um Lookup Tables nicht drumherum kommen wirst.
Es gäbe zwar einen Algorithmus zu Konvertierung in beide Richtungen,
aber im Grunde kann ich nicht nachvollziehen warum man diesen Code so
und nicht anders konstruiert hat.
Wir gesagt willst +1 in diesem Code addieren dann heist dies: addiere
so lange +1 bis der Code 5 gesetzte Bits enthält.
Willst du +1 subtrahieren in diesem Code dann musst du solange 1 vom
Vektor abziehen bis wiederum 5 Bits gesetzt sind.
Eine Regel um diesen Schritt, bzw. Schrittweite auszurechen fällt mir
so spantan aber nicht ein. Müsste man mal analysieren.
Gruß hagen
Trotzdem vielen Dank, Hagen!
Wenn ich da weiter komme, poste ich meine Ergebnisse hier rein.
Dass mit "solange +1 addieren" möchte ich nicht, zu doof in VHDL. Da
sind bestimmt 2-3 Gatter (Xor oder so) und dann hat man's - vermute
ich mal. Auf jeden Fall muss ich da weiter forschen.
mfg
kest
Hallo Kest
Welche Bedingungen muss der Code erfüllen?
1. Gleiche Anzahl von LO und HI
2. 10 Bit lang
3. ???
Der Code hat folgende Eigenschaften:
Der Code ist nicht linear, da kein Nullelement vorhanden ist und weil
zum Beispiel die beiden erlaubten Codewörter
00 0001 1111 XOR 00 0010 1111 = 00 0011 0000 kein erlaubtes
Codewort ergeben.
Ein verschieben eines erlaubten Codewortes ergibt wider ein erlaubtes
Codewort.
Da bleibt dir wohl nichts anderes üblich als es mit Zuweisungslisten zu
machen.
Holger
@Kest:
>> Interessant ist, wie die "0" immer von links nach rechts wandert.
Das ist eine Folge der grundsätzlich gesehen binären Zählweise. Solche
"Muster" wirst du auch bei Codes erhalten die 3,7 oder sonstwieviele
Bits gesetzt haben müssen. Denn die dahinterliegende Zählweise ist ja
immer noch binär, nur das man halt alle Zahlen mit ungleich X Bits als
ungültig erklärt.Deshalb sagte ich ja "blöder" Code, weil
"unintelligent".
@Holger:
>> Der Code ist nicht linear, da kein Nullelement vorhanden ist und>> weil zum Beispiel die beiden erlaubten Codewörter>> ?00 0001 1111? XOR ?00 0010 1111? = ?00 0011 0000? kein erlaubtes>> Codewort ergeben.
Das ist analytisch betrachtet erstmal irrelevant. Funktional ist es
absolut unklar und höchst wahrscheinlich und auch unwichtig eine solche
Operation überhaupt durchführbar zu machen.
Auch die Linearität ist eine einsitige Sicht auf diesen Code. Denn er
ist ja in gewissem Sinne linear. Wir erkennen Muster, wie "immer 5
Bits von 10 müssen gesetzt sein", wie "die Null wandert vom MSB zum
LSB".
ich stimme dir zu, wenn man sagt das es sicherlich cleverer Codierungen
gibt die die gleichen funktionalen Eigenschaften erreichen, aber mit
einfacheren Bildungsregeln oder eben wie du meinst "linear".
Schau'ma mal.
Gruß Hagen
@Kerst:
beschreibe doch mal genauer wie du diesen Code anwenden musst.
Sprich wird tatsächlich nur +1,-1 ein solcher Counter-Code gezählt oder
musst du beliebige Werte in/von diesen Code konvertieren ?
Zudem kann ich noch nicht nachvollziehen welche Relevanz ein solcher
Code in einem LCD hätte.
Gruß Hagen
@Hagen:
Es werden alle Werte nach einander augegeben - also der Reihenfolge
nach. Und deshalb eben immer +1. Jetzt habe ich alles mit einer Tabelle
Realisiert, ist aber unschön ;-)
Es geht nicht um LCD sondern LED - Modul. Das ganze ist von Sony und
ist 16x16 Pixel groß (R,G,B). das ganze kann man eben "irgendwie"
ansteuern. Mit Hilfe von Logic Analyzer sieht man, dass alle Werte
DC-Ballanced sind (10 Bit), weil wegen großen Strömen und so (wenn da
zig solche Module zusammen hängen ist schon was los. So viel zum
Hintergrund.
Es wird vieles eben so kodiert. Okay, man hätte auch 8 Bit für 252
Adressen (oder werten) nehmen, aber die Japaner nehmen da eben 10 Bit
ballanced. :-o
Mehr dürft ihr mich jetzt nicht fragen, kenne eben das Protokoll nicht
:-( (Und kein Datenblatt sowieso)
Kest
nee, MCU ist zu langam. Ich muss seriell 10 MBit schicken.
Im FPGA weis ich wenigstens wie lange ein Frame ist und solche Sachen -
timing ist da sehr wichtig. Klappt aber alles mehr recht als schlech
:-(
Das mit dem Zähler war ja quasi eine Teilaufgabe ;-) Ich fand es sehr
interessant, und wollte wissen, welche Ideen da andere haben :-)
Kest
Ich würde 3 Funktionen schreiben die auf deinen 10 Bit Vektoren
arbeiten.
1.) BitCount10() siehe hier im Forum unter "Weils so schön var Bits im
Vektor zählen". Damit kannst du mit relativ wenigen LE's, zb 56 LEs
bei einem 32Bit Vektor eine Bits zählen, kombinatorisch.
2.) IncVector() der deinen Vektor um +1 imkrementiert. Dabei eine
kombinatorische Loop die per BitCount10() solang +1 addiert bis 5 Bits
auf 1 gesetzt sind.
3.) DecVector() um -1 zu addieren.
Eine reine Lookuptabelle hat bei mir 188 LE's ergeben.
Gruß Hagen
@Hagen:
Durch diese analytische Vorgehensweise kann man feststellen, dass es
für diesen Code kein Generatormatrix geben kann.
| Information | Codewort
0 | 0000 0000 | 00 0001 1111
1 | 0000 0001 | 00 0010 1111
2 | 0000 0010 | 00 0011 0111
3 | 0000 0011 | 00 0011 1011
1 XOR 2 ist ungleich 3
Selbst eine Umsortierung der Codewörter würde in diesem Fall nicht
helfen.
@Kest
Für dein Projekt benötigst du bestimmt noch einen Prozessor.
Als Lösung würde ich vorschlagen:
1.FPGA mit SRAM oder SDRAM
Im FPGA einen Prozessor und ein SERIALIZER integrieren.
(Den NIOS II [32 bit RISC] von Altera kann man mit 50MHz und mehr
takten. [Vorraussetzung: FPGA mit entsprechender Geschwindigkeit])
2. µC oder µP mit externen SERIALIZER
Was für eine Schnittstelle weisen deine LED Module auf. (Differenz oder
single-ended)
Holger
@Holger:
>>Durch diese analytische Vorgehensweise kann man feststellen,>>dass es für diesen Code kein Generatormatrix geben kann.
Da stimme ich dir absolut zu, sagte ja -> blöder Code ;)
Es müsste aber bei der Synthese ein besseres Verfahren geben als eine
Lookup Tabelle, meine ich !??
Die Lookup Tabelle auf einen Cyclone kostet ca. 188 LE's.
Die BitCount() Funktion mit 10 Bit Vektoren sollte nicht mehr als 20-30
LE's kosten, fehlt noch die kombinatorische Addition/Subtration Loop
mit +1.
Gruß Hagen
Wusste ich doch das ich sowas schon mal programmiert hatte !
Also in meiner Large Integer Library für Delphi habe ich schon mal
einer Permutations Funktion in Assembler gecodet. Brauchte diese um
große LimLimLee Primzahlen zu erzeugen.
function NNextPermutation(C: Cardinal): Cardinal;
// get next successive bit combination such that Result > C and
// BitCount(Result) = BitCount(C)
asm
MOV EDX,EAX
NEG EDX
AND EDX,EAX
ADD EAX,EDX
MOV ECX,EAX
NEG ECX
AND ECX,EAX
SUB ECX,EDX
@@1: SHR ECX,1
JNC @@1
OR EAX,ECX
end;
Man nimmt nun eine 32 Bit Variable und setzt sie zu Anfang auf
0000011111b -> 31d. Dann eine Schleife von 0 bis 251
L := 31;
for I := 0 to 251 do
begin
WriteLn( ToBinary(L, 10) );
L := NNextPermutation(L);
end;
und schwups kommt exakt unsere Tabelle raus.
So, den Assembler müsste man ja nach VHDL portieren können, so schwer
dürfte das nicht sein.
Gruß Hagen
Boa, Hagen, sage ich doch: Du bist mein Held :-)
WErde mal morgen austesten.
@high_speed:
Mit NIOS II habe ich es auch mal gemacht. Leider ohne Serializierer.
Und deshalb gab ich es ja auch auf, weil ich dann zu langsam war. Noch
Serializierer zu implementieren war mir ehrlich gesagt zu doof. Da habe
ich gleich alles in VHDL auf so einem Cyclone Board implementiert
(jetzt nichts gegen NIOS II, aber manchmal möchte man eben straight
forward was machen und nicht zig Abstraktionsebenen).
Die LED-Module haben zwei differentielle Eingänge (also eins für 8x16
Pixel). Da drin ist dann noch viel Elektronik, und das gefällt mir eben
nicht). Um einen Pixel auszugeben, muss man wohl nicht nur den ganzen
Protokoll kennen, sondern auch interne Adressen und viel mehr) Erst
dachte ich, dass da nur LED-Treiber sind und eben Encoder
(Differentiell auf Parallell oder so). Aber na ja, da musste doch glatt
so ein Prozessor von Toshiba sein :-/
Das Ziel ist einfach mit einem FPGA (oder vielleicht sogar CPLD) mal
einen Pixel bestimmter Farbe zu setzen. Denkst du! Bevor da überhaupt
was zu sehen gibt, müssen bestimmte (ich weis aber nicht welche)
Register beschrieben werden, dann müssen noch Adressen kodiert werden
(DC - Ballanced), dann Daten... und, und, und... Und nun zum
eigentlichen Problem, wo ich absolut kein Plan habe (noch nicht): Man
kann wohl mehr als 760 Zeilen darstellen (mehrere Module über
einander), aber man hat nur 252 Zeilenadressen :-o Die Module sind
untereinander in der Dasy-Chain verbunden und der Teufel weis, wie
alles funktioniert... Aber, ehrlich, würdet ihr da aufgeben und das
Teil entsorgen? ;-) Nee... mich hat jetzt Sportsgeist gepackt, und ich
lasse erst los, wenn entweder das Modul Schrott ist, oder ich
wenigstens ein Quadrat in Cyan zeichnen kann ;-) :-o
Das war's eigentlich schon zum Zähler :-)
@Hagen:
ich kann mich errinnern, dass ich selber in TurboPascal ein Programm
geschrieben habe, welche alle Permutationen durchgeht. Dann habe ich
einem Typen zugehört, der darüber eine Studien (oder war das
Diplomarbeit?) geschrieben hat. Er hat da irgendwas vollkommen Neues
und "Geniales" vorgeschlagen. Hab' das auch gleich implementiert,
und es war tatsächlich "besser". Wie nun besser, kann ich leider
nicht mehr verifizieren, war so vor 15 Jahren, und ich war genau so alt
;-)
Aber, was Du gemacht ist schon schön :-) Da freut man sich echt, wenn
man sieht, dass jemand sowas macht, aus der Liebe zu den Zahlen.
mfg
Kest
Danke. Ich habe aber immer noch das Gefühl das mein obiger VHDL noch zu
umständlich ist. Das dumme ist aber, wie immer keine Dokumentation zum
Source gemacht: WIE und WARUM ich das damals gedanklich so konstruiert
habe. D.h. der Source funktioniert aber ich muß sozusagen wieder von
vorne die Funktionsweise des Algos. neu durchdenken, Mist.
Denn, inkrementieren geht ja schon, aber wie den Algo. so umbauen das
er dekrementiert.
Gruß Hagen
Hi Peter,
was für eine Sytax ist das ?
int val = 31;
for (idx = 0; i<252; i++) {
printf(idx, val);
int d = -val & val;
val += d;
int c = -val & val;
c -= d;
while (c > 0) && (c & 1 == 0) do c >>= 1;
val |= c >> 1;
}
var
val,idx,d,c: Cardinal;
begin
val := 31;
for idx = 0 to 251 do
begin
writeln(idx:5, val:5);
d := -val and val;
Inc(val, d);
c := -val and val - d;
while (c > 0) and not Odd(c) do c := c shr 1;
val := val or c shr 1;
end;
end;
in deiner Syntax schaffe ich dies leider nicht ;)
Gruß Hagen
@Hagen,
"was für eine Sytax ist das ?"
Das ist die Macrosprache des Keil A51 Assemblers für alle 8051
Derivate.
Dieses Macro erzeugt nur die Tabelle (zur Assemble-Zeit).
Hier noch mal das Macro mit einer 2-fachen Schleife und der
dazugehörenden Konvertierungsfunktion:
1
;input: A = index 0..251
2
;ouput: A = bit 7..0
3
; R0 = bit 9..8
4
;
5
bin_51:
6
add a, acc ;* 2
7
mov dptr, #fuenf_einsen
8
jnc _b511
9
inc dph ;upper 128 words
10
_b511:
11
mov r0, a
12
movc a, @a+dptr ;high byte (first)
13
xch a, r0
14
inc a
15
movc a, @a+dptr ;low byte
16
ret
17
;
18
$sa noli
19
fuenf_einsen:
20
idx set 0
21
val set 0
22
rept 1024
23
eins set 0
24
tmp set val
25
rept 9
26
eins set eins + (tmp and 1)
27
tmp set tmp shr 1
28
endm
29
if( eins = 5 )
30
$rs
31
dw val
32
$sa noli
33
idx set idx + 1
34
endif
35
val set val + 1
36
endm
37
$rs
38
end
Die $sa noli und $rs Anweisungen schalten nur das Listing aus bzw. an.
Ohne sie ist das Listfile sonst 31782 Zeilen lang und 2,2MB groß, da
die Wiederholmacros (rept nn) expandiert werden.
Das Symbol idx ist eigentlich überflüssig.
Ich habs nur zur Kontrolle eingefügt, um zu sehen, daß auch wirklich
252 (0FCh) Werte erzeugt werden.
Die Tabelle wird also zur Assemble-Zeit generiert und die Funktion
bin_51 wird dann zur Laufzeit aufgerufen.
Ich hab jetzt nicht exakt überprüft, ob man damit 10MBit z.B. auf einem
Silabs 8051 mit max 100MIPS schafft, sollte aber gehen.
Peter
P.S.:
Nur als Exkurs, daß manchmal auch ein µC einen FPGA ersetzen kann.
So einiges deiner Erklärungen konnte ich schon vorher irgendwie
nachvollziehen, zb. $noli,$ sind bedingte "compilierungen".
Das was abeer immer noch nicht nachvollziehe sind Abfragen wie IF THEN
ELSE. Wird aber offtopic und falls ich irgendwann einmal mit K51 zu
tuen habe gibts ja die Doku um zum richtigen Zeitpunkt das richtige
Wissen zu lernen ;)
Gruß Hagen