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
Hallo kest Hilft dir das weiter?
1 | library ieee; |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.std_logic_unsigned.all; |
4 | |
5 | entity Test_Con_Sp is |
6 | port( CLK : in std_logic; |
7 | RES : in std_logic; |
8 | Q : out std_logic_vector (3 downto 0) |
9 | );
|
10 | end Test_Con_Sp; |
11 | |
12 | architecture verhalten of Test_Con_Sp is |
13 | signal QINT : std_logic_vector (3 downto 0); |
14 | begin
|
15 | |
16 | process(CLK, RES) |
17 | begin
|
18 | if RES = '1' then |
19 | QINT <= (others => '0'); |
20 | elsif CLK'event and CLK = '1' then |
21 | |
22 | case QINT is |
23 | when "0000" => QINT <= "0011" ; |
24 | when "0011" => QINT <= "0101" ; |
25 | when "0101" => QINT <= "0110" ; |
26 | -- when "...." => QINT <= "...." ;
|
27 | when others => QINT <= "0000"; --when others => null; |
28 | end case; |
29 | |
30 | end if; |
31 | end process; |
32 | |
33 | Q <= QINT; |
34 | |
35 | end verhalten; |
MfG Holger
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
:-o Green Code? Höre ich jetzt zum ersten Mal, und google spuckt auch nicht gerade viel aus Kannst Du bitte mehr erzählen? mfg Kest
Ok, suchst du sowas -> 00, 000000000 01, 000000011 02, 000000110 03, 000000101 04, 000001100 05, 000001111 06, 000001010 07, 000001001 08, 000011000 09, 000011011 0A, 000011110 .... A4, 111101100 A5, 111101111 A6, 111101010 A7, 111101001 A8, 111111000 A9, 111111011 AA, 111111110 AB, 111111101 AC, 111110100 AD, 111110111 AE, 111110010 AF, 111110001 B0, 111010000 ... F0, 100010000 F1, 100010011 F2, 100010110 F3, 100010101 F4, 100011100 F5, 100011111 F6, 100011010 F7, 100011001 F8, 100001000 F9, 100001011 FA, 100001110 FB, 100001101 FC, 100000100 FD, 100000111 FE, 100000010 FF, 100000001 Links HEX Wert -> Rechts Green Code. Beachte aber auch das der Green Code logicherweise zu seiner Codierung 9 Bits benötigt !! Gruß Hagen
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
Ok, habe die Liste selber erzeugt: 00: 01F, 00000 11111 01: 02F, 00001 01111 02: 037, 00001 10111 03: 03B, 00001 11011 04: 03D, 00001 11101 05: 03E, 00001 11110 06: 04F, 00010 01111 07: 057, 00010 10111 08: 05B, 00010 11011 09: 05D, 00010 11101 0A: 05E, 00010 11110 0B: 067, 00011 00111 0C: 06B, 00011 01011 0D: 06D, 00011 01101 0E: 06E, 00011 01110 0F: 073, 00011 10011 10: 075, 00011 10101 11: 076, 00011 10110 12: 079, 00011 11001 13: 07A, 00011 11010 14: 07C, 00011 11100 15: 08F, 00100 01111 16: 097, 00100 10111 17: 09B, 00100 11011 18: 09D, 00100 11101 19: 09E, 00100 11110 1A: 0A7, 00101 00111 1B: 0AB, 00101 01011 1C: 0AD, 00101 01101 1D: 0AE, 00101 01110 1E: 0B3, 00101 10011 1F: 0B5, 00101 10101 20: 0B6, 00101 10110 21: 0B9, 00101 11001 22: 0BA, 00101 11010 23: 0BC, 00101 11100 24: 0C7, 00110 00111 25: 0CB, 00110 01011 26: 0CD, 00110 01101 27: 0CE, 00110 01110 28: 0D3, 00110 10011 29: 0D5, 00110 10101 2A: 0D6, 00110 10110 2B: 0D9, 00110 11001 2C: 0DA, 00110 11010 2D: 0DC, 00110 11100 2E: 0E3, 00111 00011 2F: 0E5, 00111 00101 30: 0E6, 00111 00110 31: 0E9, 00111 01001 32: 0EA, 00111 01010 33: 0EC, 00111 01100 34: 0F1, 00111 10001 35: 0F2, 00111 10010 36: 0F4, 00111 10100 37: 0F8, 00111 11000 38: 10F, 01000 01111 39: 117, 01000 10111 3A: 11B, 01000 11011 3B: 11D, 01000 11101 3C: 11E, 01000 11110 3D: 127, 01001 00111 3E: 12B, 01001 01011 3F: 12D, 01001 01101 40: 12E, 01001 01110 41: 133, 01001 10011 42: 135, 01001 10101 43: 136, 01001 10110 44: 139, 01001 11001 45: 13A, 01001 11010 46: 13C, 01001 11100 47: 147, 01010 00111 48: 14B, 01010 01011 49: 14D, 01010 01101 4A: 14E, 01010 01110 4B: 153, 01010 10011 4C: 155, 01010 10101 4D: 156, 01010 10110 4E: 159, 01010 11001 4F: 15A, 01010 11010 50: 15C, 01010 11100 51: 163, 01011 00011 52: 165, 01011 00101 53: 166, 01011 00110 54: 169, 01011 01001 55: 16A, 01011 01010 56: 16C, 01011 01100 57: 171, 01011 10001 58: 172, 01011 10010 59: 174, 01011 10100 5A: 178, 01011 11000 5B: 187, 01100 00111 5C: 18B, 01100 01011 5D: 18D, 01100 01101 5E: 18E, 01100 01110 5F: 193, 01100 10011 60: 195, 01100 10101 61: 196, 01100 10110 62: 199, 01100 11001 63: 19A, 01100 11010 64: 19C, 01100 11100 65: 1A3, 01101 00011 66: 1A5, 01101 00101 67: 1A6, 01101 00110 68: 1A9, 01101 01001 69: 1AA, 01101 01010 6A: 1AC, 01101 01100 6B: 1B1, 01101 10001 6C: 1B2, 01101 10010 6D: 1B4, 01101 10100 6E: 1B8, 01101 11000 6F: 1C3, 01110 00011 70: 1C5, 01110 00101 71: 1C6, 01110 00110 72: 1C9, 01110 01001 73: 1CA, 01110 01010 74: 1CC, 01110 01100 75: 1D1, 01110 10001 76: 1D2, 01110 10010 77: 1D4, 01110 10100 78: 1D8, 01110 11000 79: 1E1, 01111 00001 7A: 1E2, 01111 00010 7B: 1E4, 01111 00100 7C: 1E8, 01111 01000 7D: 1F0, 01111 10000 7E: 20F, 10000 01111 7F: 217, 10000 10111 80: 21B, 10000 11011 81: 21D, 10000 11101 82: 21E, 10000 11110 83: 227, 10001 00111 84: 22B, 10001 01011 85: 22D, 10001 01101 86: 22E, 10001 01110 87: 233, 10001 10011 88: 235, 10001 10101 89: 236, 10001 10110 8A: 239, 10001 11001 8B: 23A, 10001 11010 8C: 23C, 10001 11100 8D: 247, 10010 00111 8E: 24B, 10010 01011 8F: 24D, 10010 01101 90: 24E, 10010 01110 91: 253, 10010 10011 92: 255, 10010 10101 93: 256, 10010 10110 94: 259, 10010 11001 95: 25A, 10010 11010 96: 25C, 10010 11100 97: 263, 10011 00011 98: 265, 10011 00101 99: 266, 10011 00110 9A: 269, 10011 01001 9B: 26A, 10011 01010 9C: 26C, 10011 01100 9D: 271, 10011 10001 9E: 272, 10011 10010 9F: 274, 10011 10100 A0: 278, 10011 11000 A1: 287, 10100 00111 A2: 28B, 10100 01011 A3: 28D, 10100 01101 A4: 28E, 10100 01110 A5: 293, 10100 10011 A6: 295, 10100 10101 A7: 296, 10100 10110 A8: 299, 10100 11001 A9: 29A, 10100 11010 AA: 29C, 10100 11100 AB: 2A3, 10101 00011 AC: 2A5, 10101 00101 AD: 2A6, 10101 00110 AE: 2A9, 10101 01001 AF: 2AA, 10101 01010 B0: 2AC, 10101 01100 B1: 2B1, 10101 10001 B2: 2B2, 10101 10010 B3: 2B4, 10101 10100 B4: 2B8, 10101 11000 B5: 2C3, 10110 00011 B6: 2C5, 10110 00101 B7: 2C6, 10110 00110 B8: 2C9, 10110 01001 B9: 2CA, 10110 01010 BA: 2CC, 10110 01100 BB: 2D1, 10110 10001 BC: 2D2, 10110 10010 BD: 2D4, 10110 10100 BE: 2D8, 10110 11000 BF: 2E1, 10111 00001 C0: 2E2, 10111 00010 C1: 2E4, 10111 00100 C2: 2E8, 10111 01000 C3: 2F0, 10111 10000 C4: 307, 11000 00111 C5: 30B, 11000 01011 C6: 30D, 11000 01101 C7: 30E, 11000 01110 C8: 313, 11000 10011 C9: 315, 11000 10101 CA: 316, 11000 10110 CB: 319, 11000 11001 CC: 31A, 11000 11010 CD: 31C, 11000 11100 CE: 323, 11001 00011 CF: 325, 11001 00101 D0: 326, 11001 00110 D1: 329, 11001 01001 D2: 32A, 11001 01010 D3: 32C, 11001 01100 D4: 331, 11001 10001 D5: 332, 11001 10010 D6: 334, 11001 10100 D7: 338, 11001 11000 D8: 343, 11010 00011 D9: 345, 11010 00101 DA: 346, 11010 00110 DB: 349, 11010 01001 DC: 34A, 11010 01010 DD: 34C, 11010 01100 DE: 351, 11010 10001 DF: 352, 11010 10010 E0: 354, 11010 10100 E1: 358, 11010 11000 E2: 361, 11011 00001 E3: 362, 11011 00010 E4: 364, 11011 00100 E5: 368, 11011 01000 E6: 370, 11011 10000 E7: 383, 11100 00011 E8: 385, 11100 00101 E9: 386, 11100 00110 EA: 389, 11100 01001 EB: 38A, 11100 01010 EC: 38C, 11100 01100 ED: 391, 11100 10001 EE: 392, 11100 10010 EF: 394, 11100 10100 F0: 398, 11100 11000 F1: 3A1, 11101 00001 F2: 3A2, 11101 00010 F3: 3A4, 11101 00100 F4: 3A8, 11101 01000 F5: 3B0, 11101 10000 F6: 3C1, 11110 00001 F7: 3C2, 11110 00010 F8: 3C4, 11110 00100 F9: 3C8, 11110 01000 FA: 3D0, 11110 10000 FB: 3E0, 11111 00000 Gruß Hagen
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
:-o Wie hast du das gemacht? Ich sehe da schon Gesetzmäsigkeiten, aber wie genau, kapiere ich es nicht! Mensch, Hagen, mein Held ;-) Kest
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
Es gibt eine "Regel" bzw. ein Muster. Erzeuge die Liste wie ich, und bilde den Differnezbetrag = Abstände zwischen den succesiven Werten. Dann ergibt sich: 00: 01F, 00000 11111, 31 01: 02F, 00001 01111, 16 02: 037, 00001 10111, 8 03: 03B, 00001 11011, 4 04: 03D, 00001 11101, 2 05: 03E, 00001 11110, 1 06: 04F, 00010 01111, 17 07: 057, 00010 10111, 8 08: 05B, 00010 11011, 4 09: 05D, 00010 11101, 2 0A: 05E, 00010 11110, 1 0B: 067, 00011 00111, 9 0C: 06B, 00011 01011, 4 0D: 06D, 00011 01101, 2 0E: 06E, 00011 01110, 1 0F: 073, 00011 10011, 5 10: 075, 00011 10101, 2 11: 076, 00011 10110, 1 12: 079, 00011 11001, 3 13: 07A, 00011 11010, 1 14: 07C, 00011 11100, 2 Letzer Wert ist der betragsmäßige Abstand von Code zu Code. Wie man sieht könnte man dies eventuell per Rechtshift ausrechnen. Gruß Hagen
Jep, das habe ich schon gemacht. Aber - keine Chance :-/ Interessant ist, wie die "0" immer von links nach rechts wandert. Aber na ja. 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
Hm, und warum ein FPGA/CPLD ? Versuche es doch erstmal in eine stinknormale MCU zu basteln, das dürfte einfacher sein. Gruß Hagen
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
Und hier mal ein Beispiel, wie so eine Tabelle mit einem Assemblermacro auf einem Mikrokontroller aussieht.
1 | $sa noli |
2 | idx set 0 |
3 | val set 0 |
4 | rept 1024 |
5 | if((val and 1) + ((val shr 1) and 1) + ((val shr 2) and 1) + |
6 | ((val shr 3) and 1) + ((val shr 4) and 1) + ((val shr 5) and 1) + ((val |
7 | shr 6) and 1) + ((val shr 7) and 1) + ((val shr 8) and 1) + (val shr 9) |
8 | = 5) |
9 | $rs |
10 | dw val |
11 | $sa noli |
12 | idx set idx + 1 |
13 | endif |
14 | val set val + 1 |
15 | endm |
16 | $rs |
17 | |
18 | end |
Als Anhang das Listfile. Peter
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.