Forum: FPGA, VHDL & Co. std_logic_vector zu ASCII wandeln


von New I. (newie)


Lesenswert?

Hallo zusammen,

habe folgende Frage:

Wie kann ich einen std_logic_vector nach ASCII wandeln.

z.B: Ich messe binär "10101010" und möchte am LCD dez 170 sehen.

Habe was über character'vol(conv_integer.... ) gefunden, aber komme grad 
nicht weiter. In den Conversion Functions steht auch nix drin.


Vorab besten Dank!


Gruss
Stanko

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

> Ich messe binär "10101010" und möchte am LCD dez 170 sehen.
Dann hilft dir ein character nicht unbedingt weiter, denn du kannst 
einen (VHDL-) character nicht auf FPGA-Portpins ausgeben. Vorher mußt du 
ihn wieder auf einen Vektor zurückwandeln. Damit das Ganze nicht in eine 
Konvertierungsorgie ausartet, solltest du es ein wenig binärer 
betrachten.

Du mußt erst mal die einzelnen Dezimalstellen ermitteln. Das hatten wir 
schon ein paar mal, zuletzt im 
Beitrag "Durch 10 teilen"

Wenn du dann die drei Dezimalstellen in BCD-Darstellung hast, dann 
stellt du dir die Frage: wie komme ich von binär 00000000 (=0) nach 
00110000 (=ASCII-Null)? Hier eine Tabelle zum Thema:

dez   binär      ASCII-binär
0     00000000   00110000
1     00000001   00110001
2     00000010   00110010
3     00000011   00110011
4     00000100   00110100
:

Du kannst das Muster leicht erkennen: einfach vor die 4-Bit-BCD-Zahl 
noch "0011" hängen. Fertig.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity bin2char is
6
    Port ( inp : in  STD_LOGIC_VECTOR (7 downto 0);
7
           einer : out  STD_LOGIC_VECTOR (7 downto 0);
8
           zehner : out  STD_LOGIC_VECTOR (7 downto 0);
9
           hunderter : out  STD_LOGIC_VECTOR (7 downto 0));
10
end bin2char;
11
12
architecture Behavioral of bin2char is
13
   subtype SLV12 is std_logic_vector (11 downto 0);
14
   type Rom128x8 is array (0 to 255) of SLV12;
15
   constant BCDRom : Rom128x8 := (
16
    x"000", x"001", x"002", x"003", x"004", x"005", x"006", x"007", x"008", x"009",  
17
    x"010", x"011", x"012", x"013", x"014", x"015", x"016", x"017", x"018", x"019",  
18
    x"020", x"021", x"022", x"023", x"024", x"025", x"026", x"027", x"028", x"029",  
19
    x"030", x"031", x"032", x"033", x"034", x"035", x"036", x"037", x"038", x"039",  
20
    x"040", x"041", x"042", x"043", x"044", x"045", x"046", x"047", x"048", x"049",  
21
    x"050", x"051", x"052", x"053", x"054", x"055", x"056", x"057", x"058", x"059",  
22
    x"060", x"061", x"062", x"063", x"064", x"065", x"066", x"067", x"068", x"069",  
23
    x"070", x"071", x"072", x"073", x"074", x"075", x"076", x"077", x"078", x"079",  
24
    x"080", x"081", x"082", x"083", x"084", x"085", x"086", x"087", x"088", x"089",  
25
    x"090", x"091", x"092", x"093", x"094", x"095", x"096", x"097", x"098", x"099",  
26
    x"100", x"101", x"102", x"103", x"104", x"105", x"106", x"107", x"108", x"109",  
27
    x"110", x"111", x"112", x"113", x"114", x"115", x"116", x"117", x"118", x"119",  
28
    x"120", x"121", x"122", x"123", x"124", x"125", x"126", x"127", x"128", x"129",  
29
    x"130", x"131", x"132", x"133", x"134", x"135", x"136", x"137", x"138", x"139",  
30
    x"140", x"141", x"142", x"143", x"144", x"145", x"146", x"147", x"148", x"149",  
31
    x"150", x"151", x"152", x"153", x"154", x"155", x"156", x"157", x"158", x"159",  
32
    x"160", x"161", x"162", x"163", x"164", x"165", x"166", x"167", x"168", x"169",  
33
    x"170", x"171", x"172", x"173", x"174", x"175", x"176", x"177", x"178", x"179",  
34
    x"180", x"181", x"182", x"183", x"184", x"185", x"186", x"187", x"188", x"189",  
35
    x"190", x"191", x"192", x"193", x"194", x"195", x"196", x"197", x"198", x"199",  
36
    x"200", x"201", x"202", x"203", x"204", x"205", x"206", x"207", x"208", x"209",  
37
    x"210", x"211", x"212", x"213", x"214", x"215", x"216", x"217", x"218", x"219",  
38
    x"220", x"221", x"222", x"223", x"224", x"225", x"226", x"227", x"228", x"229",  
39
    x"230", x"231", x"232", x"233", x"234", x"235", x"236", x"237", x"238", x"239",  
40
    x"240", x"241", x"242", x"243", x"244", x"245", x"246", x"247", x"248", x"249",  
41
    x"250", x"251", x"252", x"253", x"254", x"255" );
42
   signal digits : std_logic_vector (11 downto 0);
43
44
begin
45
   digits <= BCDRom(to_integer(unsigned(inp))); 
46
   
47
   -- Formal
48
   einer     <= std_logic_vector(("0000"&unsigned(digits (3 downto 0))) + to_unsigned(character'pos('0'),8));
49
   zehner    <= std_logic_vector(("0000"&unsigned(digits (7 downto 4))) + to_unsigned(character'pos('0'),8));
50
   hunderter <= std_logic_vector(("0000"&unsigned(digits(11 downto 8))) + to_unsigned(character'pos('0'),8));
51
52
   -- kürzere Schreibweise mit Hilfe von Nachdenken ermittelt ;-)
53
   einer     <= "0011"&digits (3 downto 0);
54
   zehner    <= "0011"&digits (7 downto 4);
55
   hunderter <= "0011"&digits(11 downto 8);
56
end Behavioral;
Die formale Beschreibung mit der expliziten Addition bringt gehörigen 
Mehraufwand in Form dreier Addiere mit ins Spiel (Screenshot). Die 
entfallen natürlich bei der direkten Concatenation von "0011".

von New I. (newie)


Lesenswert?

Hallo Lothar,

vielen Dank für die Antwort!
Hab die Sache grad simuliert und es funktioniert.

Die Einbindung ins FPGA ist nur noch Fleißarbeit.

Ich sage nur Eins: "Yes, You can!"


Gruss
Stanko

von Beobachter (Gast)


Lesenswert?

OffTopic:

Mensch Lothar, ich bin ja immer wieder fasziniert, mit wie viel Elan du 
hier den Leuten die Aufgaben machst... Respekt!

Mit deinem Wissen müsstet du ja eine Menge Geld als VHDL-Entwickler 
verdienen. Darf ich fragen, ob du das auch beruflich machst oder ist das 
nur ein Hobby?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Mit deinem Wissen müsstet du ja eine Menge Geld ... verdienen.
Ja, wie war das?
Ich verdiene mehr als ich bekomme ;-)

> Darf ich fragen, ob du das beruflich machst oder ist das nur ein Hobby?
Sowohl als auch.

von Michael (Gast)


Lesenswert?

Wenn ich den hier geposteten code verwende geht bei mir die Hunderter 
Stelle immer nur bis 2. Kann mir irgendwer erklären wieso?


Danke

mfg

michael

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Michael schrieb:
> Wenn ich den hier geposteten code verwende geht bei mir die Hunderter
> Stelle immer nur bis 2. Kann mir irgendwer erklären wieso?
Weil die Tabelle nur Einträge bis 255 hat, oder?

Konterfrage: WAS willst du machen?

von Michael (Gast)


Lesenswert?

Eine integer bzw. std_logic_vector Zahl auf einem LCD Display ausgeben.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Michael schrieb:
> Eine integer bzw. std_logic_vector Zahl auf einem LCD Display ausgeben.
Welchen Bereich?
0..99, oder -9999..9999 oder ?...?

von Michael (Gast)


Lesenswert?

Im Bereich von +/-32 Bit

von Uwe (Gast)


Lesenswert?

Bei Hexadezimal Anzeige ist das klein und einfach... bei Dezimal wär die 
Lookup-Tabelle aber 8Gbyte groß.
Da ist rechnen besser ... also ne kleine Statemachine ist wohl das beste 
dafür

von Michael (Gast)


Lesenswert?

Und wie Würde der Ansatz dafür aussehen, bin momentan etwas verwirrt.

von Uwe (Gast)


Lesenswert?

Reche doch mal selber auf nem Blatt Papier ...
Beitrag "HEX2BCD Code - Frage zum Ablauf"
Dann ne eigen Statemachine mit countern, Registern und Subtrahierern 
oder nen Picoblaze.
Man muß halt gucken wie oft die einer(Milliarden) reingehen (Dividieren 
bzw. zählen wie oft 1.000.000.000 subtrahiert werden können ohne das das 
Ergebnis negativ wird, dann Zählstand notieren im Register und man hat 
die einer Miliarden) dann die Hunderter Millionen usw. das Ergebins 
sollte also nie größer als 9 sein. also brauchst du im worst case ca 100 
durchläufe ...
Ach ne du wilst ja auch negative Zahlen haben, na dann ...
und jetzt bist du dran ...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Michael schrieb:
> Im Bereich von +/-32 Bit
Das passt nicht in einen "üblichen" Integer...

Uwe schrieb:
> Man muß halt gucken
... was schon dazu geschrieben wurde:
https://www.mikrocontroller.net/search?query=bcd+umwandeln&forums[]=9&sort_by_date=1

> also brauchst du im worst case ca 100 durchläufe ...
Es geht schneller: Beitrag "Schnelle Conversion bin2dec"

von Uwe (Gast)


Lesenswert?

>also brauchst du im worst case ca 100 durchläufe ...
>>Es geht schneller: Beitrag "Schnelle Conversion bin2dec"
Jupp aber ich meinte auf dem Papier bzw. so wie ebend geschrieben.
Zudem soller erst mal das Grundlegende Prinzip verstehen und kein 
optimiertes Design vorgelegt bekommen. Selber nachdenken schadet nicht 
...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Uwe schrieb:
> Jupp aber ich meinte auf dem Papier bzw. so wie ebend geschrieben.
> Zudem soller erst mal das Grundlegende Prinzip verstehen
Ja, da könnte man selber draufkommen. Oder zumindest versuchen, zu 
verstehen, warum der obige Code nur bis 255 funktioniert, oder zumindest 
den Post und die Links darin (wie z.B. denjenigen im 
Beitrag "Re: std_logic_vector zu ASCII wandeln") zu lesen und 
nachzuvollziehen, um was es da geht...

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
Noch kein Account? Hier anmelden.