mikrocontroller.net

Forum: FPGA, VHDL & Co. a2i - Konvertierung ASCII zu Integer


Autor: Dennis M. (vhdl_dennis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

ich würde in VHDL gerne die Funktion a2i() als Schaltung nachbilden. 
Diese soll möglichst wenig Takte benötigen und kann dafür auch mehr 
Logik verbrauchen.

Ausgangssituation:
z.B. 14 Byte (112 Bit) Eingangs-Vektor in dem 14 einzelne Ziffern 
gespeichert sind.

Ziel:
- Eine 64-Bit Integerzahl, die dem Ascii-String entspricht.
- Signed oder Unsigned, spielt erstmal keine Rolle.

- So viel, wie möglich parallel erledigen (Takteinsparung)

- Ziel-Plattform ist ein Xilinx Virtex

Schritte/Idee:

- Die einzelnen Ziffern "erkennen" und mit der Zehnerpotenz je 
Stellengewichtung multiplizieren

- Addition aller Multiplikationen

- Ergebnis : fertige int_64

Frage:

- Hat vielleicht jemand schon mal ein solches Projekt angefasst und mag 
mir den VHDL-Code zeigen/schicken?

- Aber konzeptionelle Vorschläge würden mir auch schon helfen.

Gruß Dennis

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis M. schrieb:
> - Eine 64-Bit Integerzahl, die dem Ascii-String entspricht.
Wo steht der "String"?
Ist das ein std_logic_vector-Array?

> - So viel, wie möglich parallel erledigen (Takteinsparung)
Du kannst das ganze komplett parallel machen. Ob das dann allerdings 
schneller (Laufzeit) ist als eine getaktete Lösung ist fraglich...

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre eine Möglichkeit:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity atoi is
    Port ( ascii      : in  STD_LOGIC_VECTOR (111 downto 0);
           value      : out  STD_LOGIC_VECTOR (63 downto 0));
end atoi;

architecture Behavioral of atoi is
begin
   process (ascii) 
   variable val  : unsigned (63 downto 0);
   variable mult : unsigned (63 downto 0); 
   begin
      val  := to_unsigned(0,64);
      mult := to_unsigned(1,64);
      for i in 0 to 13 loop
         val  := val + mult*(unsigned(ascii(i*8+7 downto i*8))-48);
         mult := mult * 10;
      end loop;
      value <= std_logic_vector(val);
   end process;
end Behavioral;
Die Synthese rennt durch, simulieren mußt du noch selber...

Autor: Matthias G. (mgottke)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soll das eine Art Prüfsumme sein? Oder was wird damit bezweckt?
Aus der entstandenen Zahl lässt sich nämlich nicht mehr die ASCII-Folge 
rekonstruieren.

Autor: Dennis M. (vhdl_dennis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Lothar,

Hi,

danke für den Vorschlag, werde ich mich morgen direkt mal dransetzen und 
ausprobieren. Bin mal gespannt, was der Simulator dazu sagt. Bin auch 
mal auf den kritischen Pfad und max. Frequenz neugierig. :)

@Matthias

Es ist ledeglich das Ergebnis als Integerzahl interessant.

Gruß Dennis

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis M. schrieb:
> was der Simulator dazu sagt.
Der braucht noch ein paar exaktere Zuweisungen:
   process (ascii) 
   variable val  : unsigned (63 downto 0);
   variable mult : unsigned (127 downto 0); 
   variable tmp  : unsigned (71 downto 0); 
   begin
      val  := to_unsigned(0,64);
      mult := to_unsigned(1,128);
      for i in 0 to 13 loop
         tmp  := mult(val'range)*(unsigned(ascii(i*8+7 downto i*8))-48);
         val  := val + tmp(val'range);
         mult := mult(val'range) * 10;
      end loop;
      value <= std_logic_vector(val);
   end process;

Oberflächlich getestet mit dieser simplen Testbench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
 
ENTITY tb_atoi IS
END tb_atoi;
 
ARCHITECTURE behavior OF tb_atoi IS 
   COMPONENT atoi
   PORT( ascii : IN  std_logic_vector(111 downto 0);
         value : OUT  std_logic_vector(63 downto 0));
   END COMPONENT;
   signal ascii : std_logic_vector(111 downto 0) := (others => '0');
   signal value : std_logic_vector(63 downto 0);
BEGIN
   uut: atoi PORT MAP (ascii => ascii, value => value);

   process begin      
      for i in 0 to 9 loop
         for t in 0 to 13 loop
            ascii(t*8+7 downto t*8) <= std_logic_vector(to_unsigned(i+48,8));
         end loop;
         wait for 10 ns;   
      end loop;
   end process;
END;

Autor: Harald Flügel (hfl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe Lothars Quellcode mal in Quartus eingetippt und in ein Stratix3 
FPGA fitten lassen. Das Ergebnis ist gar nicht mal soo schlecht: 679 
ALUTs, 23 Multiplyer und maximal 35 ns Durchlaufzeit (incl. Pin delay) 
ohne jegliche Constraints. Trotzdem würde ich zu einem etwas etwas 
hardwarenäheren Ansatz mit Pipelineregistern und explizit inszanzierten 
Addierern und Multiplzierern raten. Eine kombinatorische Logik mit 
hunderten hintereinandergeschalteten Logikelementen, da klingeln bei mir 
die Alarmglocken. Und das müssen so viele sein, sonst kämen bei dem FPGA 
keine 35 ns zusammen.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> und maximal 35 ns Durchlaufzeit
Beim Spartan 3 kommen knapp 34 ns (auch Pin to Pin) heraus... ;-)

> Trotzdem würde ich zu einem etwas etwas hardwarenäheren Ansatz mit
> Pipelineregistern ... raten.
Ich auch, aber das:
> mit explizit inszanzierten Addierern und Multiplzierern
wäre mir zuviel Arbeit. Das kann der Synthesizer schon...

Ich würde das Ganze evtl. auch eher auf mehrere Schritte aufteilen, um 
die Anzahl der Multiplizierer zu reduzieren.

Autor: Dennis M. (vhdl_dennis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Lothar,

hab das direkt mal ausprobiert. Im Simulator klappt´s ganz gut. Aber 
leider lässt es sich nicht in Hardware übersetzen.

In der Zeile
"mult := mult(val'range) * 10;"
verlängert sich "mult" mit jedem Schleifendurchkauf um 32 Bit (10 => 
integer).Denn a(a'range) * b(b'range) = c ( (a+b)'range ) :).

Ich werde nochmal weiter rumtüfeln. Danke für den Vorschlag!

Werde mir mal die DSP´s in dem Xilinx genauer anschauen. Oder mal 
schauen, ob der intern seperate Festaddierer beseitzt.

Im Internet ist zur Umsetzung von atoi() in VHDL ja echt nichts zu 
finden. Scheint wohl sonst keiner zu benötigen gg.

Gruß Dennis

Autor: Dennis M. (vhdl_dennis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm, da kamen ja gleich zwei Beiträge dazu.

Irgendwie will Xilinx ISE den Code nicht in RTL übersetzen. komisch.

Gruß

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis M. schrieb:
> Aber leider lässt es sich nicht in Hardware übersetzen.
Bei mir kommt:
:
WARNING:Xst:643 - "atoi.vhd" line 34: The result of a 480x8-bit multiplication is partially used. 
Only the 64 least significant bits are used. If you are doing this on purpose, you may safely ignore this warning. 
Otherwise, make sure you are not losing information, leading to unexpected circuit behavior.
:
Process "Generate Post-Place & Route Static Timing" completed successfully
Da heißt es wohl ausprobieren, ob hier dann "unexpected bevaiour" 
auftritt.

> Scheint wohl sonst keiner zu benötigen gg.
Sicher nicht in der Breite... :-o

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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