Binär-zu-BCD-Konvertierung

Ich habe eine 8-Bit-Zahl, deren Werte von 0 bis 99 reichen. Ich muss das mithilfe digitaler Schaltungen in eine richtige 8-Bit-BCD-Darstellung der Zahl umwandeln.

Falls Sie es wissen müssen, der ursprüngliche Wert ist ein Temperaturwert, der von einem ADC gelesen wird, und ich brauche ihn in BCD, um ihn in zwei 7-Segment-Anzeigen anzuzeigen. Ich kann keinen Mikrocontroller verwenden.

Es macht keinen Sinn, dass Sie keinen Mikrocontroller verwenden können. Jede alternative Schaltung benötigt mehr Platz und ist komplexer. Gehen Sie zurück und finden Sie heraus, was das eigentliche Problem hinter der Mikrocontroller-Einschränkung ist, und kommen Sie dann zurück, wenn Sie das eigentliche Problem benennen können.
Ist die Einschränkung "Ich kann keinen Mikrocontroller verwenden" von oben ("Sednus, ich möchte, dass Sie diese Temperatur bauen -> 7-Segment-Ding, und übrigens - verwenden Sie keinen Mikrocontroller") oder aus Ihren eigenen Wünschen heraus, um das Programmieren zu vermeiden Mikrocontroller?
mögliches Duplikat von binär codierten Dezimal-ICs
Jede praktische Lösung erfordert irgendein programmierbares Gerät: sei es ein EPROM, ein CPLD oder ein Mikrocontroller. Sie könnten dies mit diskreten Logikgattern tun, aber das wäre nur praktisch, wenn dies eine Hausaufgabe ist. Wir benötigen weitere Informationen, bevor wir Ihnen eine akzeptable Antwort geben können.
Ich soll eine Klimaanlagensteuerung mit einem FPGA entwerfen. Ich habe den größten Teil des Designs fertig. Ich habe nur versucht, einen einfachen Weg zu finden, um diese Konvertierung durchzuführen.
Das macht noch keinen Sinn. Warum muss es ein FPGA sein? Sicherlich ist die Geschwindigkeit nicht erforderlich. Ein Mikrocontroller wäre wirtschaftlicher und einfacher zu implementieren und flexibler zu ändern. Nennen Sie uns die tatsächlichen Anforderungen, nicht die Ihrer Meinung nach mögliche Lösung.
Es ist Teil eines Klassenprojekts ...
"Es ist Teil eines Klassenprojekts" . Das hättest du am Anfang erwähnen sollen. Aber Sie haben immer noch nicht beantwortet, warum kein Mikrocontroller.
@Olin Lathrop - Wenn es sich um eine Aufgabe handelt, wird die Auswahl der Technologien oft künstlich eingeschränkt, um den Fokus dort zu platzieren, wo er für eine bestimmte Lektion vorgesehen ist. Darüber hinaus bietet diese spezielle Anforderung effizientere Lösungen innerhalb einer FPGA (ROM-Tabelle) als das Einfügen eines Soft-Prozessorkerns in das Design, wenn einer für andere Zwecke nicht benötigt wird.
@Chris: Ja, manchmal schränken Zuweisungen künstlich ein, aber es liegt am OP, uns dies mitzuteilen. Ich habe keinen weichen Kern in einem FPGA vorgeschlagen, sondern nur ein kleines Mikro verwendet. Hier gibt es nichts, was ein FPGA zu einer besseren Lösung macht als nur ein Mikro.
@Olin Lathrop - wie bereits erwähnt, gehört zu dem Projekt mehr als diese Konvertierung von Binär zu BCD. Vermutlich wird das FPGA ausgewählt, um pädagogische und/oder allgemeine funktionale Ziele zu erfüllen. Die Lösung dieses kleinen Teils des Problems, das so einfach mit einem Tisch zu lösen ist, dass kein Softcore erforderlich ist, rechtfertigt sicherlich nicht die Verkabelung eines externen Mikros und das Einbringen seiner Support-Tools, bis oder sofern es keinen Grund dafür gibt kann nicht intern durchgeführt werden oder ein pädagogischer Auftrag, das externe Mikro zu verwenden.

Antworten (4)

Einfachster Weg:

Verwenden Sie ein 256-Byte-EPROM / EEPROM.

Der Eingangswert wird auf den Adressbus gelegt.

Der Ausgang auf dem Datenbus ist das, was Sie für diese Adresse programmiert haben - programmieren Sie ihn also mit einer Zuordnung von Binär- zu BCD-Werten.

Dies ist die einfachste Lösung, insbesondere in Bezug auf die Anzahl der Komponenten: 1. Wenn der Grund, warum Mikrocontroller nicht verfügbar sind, darin besteht, dass OP sie nicht programmieren kann, wird dies nicht helfen.
Er sagt, er kann keinen benutzen – nicht, warum er keinen benutzen kann. Er kann durchaus in der Lage sein, einen zu benutzen, aber man hat ihm gesagt, er darf es nicht.
Das FPGA hat möglicherweise keinen internen RAM, entweder weil es überhaupt keinen hat oder weil sie alle bereits verwendet werden.
@Mike DeSimone - Die FPGA-Tools können kleine ROMs im FPGA-Fabric selbst implementieren, wenn keine Blockspeicher verfügbar sind.
Einige FPGA-Tools können dies tun, und bei einigen müssen Sie ihnen dies ausdrücklich mitteilen.
@Mike DeSimone - Modellieren Sie ein ROM mit Sprachprimitiven, und ich wäre überrascht, wenn es ein Tool gibt, das es nicht im Fabric implementieren kann. Einige Tools sind jedoch intelligent genug, um zu erkennen, dass Sie einen Speicher benötigen, und ersetzen einen Blockspeicher, wenn einer verfügbar ist und das modellierte Verhalten erfüllt. Sie selbst scheinen eine Antwort gepostet zu haben, die von dieser Fähigkeit der Tools abhängt, auf eine praktikable Implementierung zu schließen, sei es aufschlussreich oder blind.
Ich erinnere mich, dass ich vor ein paar Jahren Probleme damit mit Alteras Quartus II hatte. Das Modellieren eines ROM bedeutete, dass die Analysis & Synthesis-Phase ein ROM unter Verwendung eines Speicherblocks ableiten und dann zur Fitter-Zeit die Kompilierung anhalten würde, wenn Sie dadurch die Anzahl der verfügbaren Speicherblöcke überschreiten würden. Es konnte das ROM nicht zur Fitter-Zeit in Gates zurücksetzen. Also musste ich etwas tun (ein Kontrollkästchen oder so), um es anzuweisen, die Implementierung als Gates zu erzwingen.

Der einfache und schnelle Weg ohne Nachschlagetabelle ist die Verwendung des Double-Dabble-Algorithmus . Es funktioniert nur durch Verschieben um 1 und Addieren von 3 und iteriert "die Anzahl der Bits" mal, daher sehr effizient auf Mikrocontrollern und Architekturen ohne Multiplikation / Division und Barrel-Shifter-Hardware

Um zum Beispiel 97 10 = 110 0001 2 in BCD umzuwandeln

0000 0000   1100001   Initialization
0000 0001   1000010   Shift (1)
0000 0011   0000100   Shift (2)
0000 0110   0001000   Shift (3)
0000 1001   0001000   Add 3 to ONES, since it was 6
0001 0010   0010000   Shift (4)
0010 0100   0100000   Shift (5)
0100 1000   1000000   Shift (6)
0100 1011   1000000   Add 3 to ONES, since it was 8
1001 0111   0000000   Shift (7)
   9    7

Die Zahl wird mit 7 Bits geschrieben (dh das höchstwertige Bit ist Bit 6), sodass sie nach 7 Verschiebungen endet.

Dies ist die beste Lösung, wenn sie auf eine VHDL-Implementierung in einem FPGA beschränkt ist. Ich wünschte, ich könnte mehrmals hochstimmen, um Ihre Antwort besser sichtbar zu machen ...

Du sollst das mit einem FPGA machen? Schreiben Sie ein Programm in irgendeiner Sprache (C, C++, Python, Perl ... spielt keine Rolle, solange Sie damit vertraut sind), das die folgende Ausgabe erzeugt.

Zunächst die Präambel:

module BinaryToBCD
(
    input [6:0] setting,
    output [3:0] tens,
    output [3:0] ones
)

always @(setting)
begin
    case(setting)

Erstellen Sie dann für jede Zahl von 0 bis 99 diese Gruppe von Linien:

    7'd__: begin
        tens = 4'd_;
        ones = 4'd_;
    end

Tragen Sie dort die entsprechenden Werte ein _. Ein Python-Beispiel:

for k in range(100):
    print "    7'd%d: begin" % k
    print "        tens = 4'd%d;" % (k // 10)
    print "        ones = 4'd%d;" % (k % 10)
    print "    end"
    print

Abschließend die Postambel:

    default: begin
        tens = 4'hX;
        ones = 4'hX;
    end

    endcase
end

endmodule

Jetzt speichern Sie dies als Verilog .v-Datei und füttern es Ihrem FPGA-Compiler und lassen es die Drecksarbeit erledigen.

Viele, viele Dinge in FPGAs reduzieren sich darauf, „den Code so zu schreiben, wie das Problem ohne allzu viel Aufhebens gelöst wird, und den Compiler die Drecksarbeit erledigen zu lassen“. Code-Generator-Programme sind Ihre Freunde.

Muss das Gerät die Konvertierung in einem einzigen Schritt durchführen oder kann es sich um einen iterativen Prozess handeln?

Die billigste Methode in Bezug auf die Schaltung besteht wahrscheinlich darin, eine getaktete Schaltung zu haben, die sich, wenn sie mit einer Zahl N im BCD-Format geladen und einem Einzelbiteingang C zugeführt wird, beim nächsten Taktzyklus selbst mit 2 * N + C lädt. Füttern Sie eine solche Schaltung zuerst mit einer Binärzahl MSB, und nachdem alle Bits verschoben wurden, hält sie diese Zahl in BCD. Dieser Ansatz kann mit Binär- oder BCD-Zahlen beliebiger Größe verwendet werden, wobei zu beachten ist, dass der Übertrag einer Stufe den Übertrag der nächsten Stufe nicht sofort bis zum nächsten Taktzyklus beeinflussen kann.

Falls gewünscht, kann man das BCD-Register verwenden, um die ursprüngliche Zahl herauszuschieben. Für den allgemeinen Fall müssen Sie die Logik so anordnen, dass die Teile des Registers, die einen Teil der Zahl im Binärformat enthalten, die BCD-Logik deaktiviert haben, damit sie als direkter Shifter fungieren. Im speziellen Fall von zwei Ziffern könnte man die unteren drei Bits des Registers mit den drei MSBs der Zahl und die oberen 4 Bits mit den unteren vier Bits der Zahl vorladen und sich einfach nicht mit irgendeiner BCD-Logik für die obere Ziffer (da es sowieso 0-9 sein sollte). Wenn Sie mehr als zwei Ziffern verwenden, ist eine etwas ausgefallenere Logik erforderlich, aber es kann sich trotzdem lohnen, dieselben Register zum Halten der Binärzahl und des BCD-Ergebnisses zu verwenden.

Übrigens ist es möglich, den umgekehrten Ansatz zu verwenden, um eine BCD-Zahl in eine Binärzahl umzuwandeln. Jede Ziffer sollte gleich ihrem Wert sein, dividiert durch zwei (einfache Verschiebung nach rechts), plus entweder fünf oder null, abhängig vom Zustand des LSB der nächsthöheren Ziffer.