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


von Dennis M. (vhdl_dennis)


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

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


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...

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


Lesenswert?

Das wäre eine Möglichkeit:
1
library IEEE;
2
use IEEE.std_logic_1164.all;
3
use IEEE.numeric_std.all;
4
5
entity atoi is
6
    Port ( ascii      : in  STD_LOGIC_VECTOR (111 downto 0);
7
           value      : out  STD_LOGIC_VECTOR (63 downto 0));
8
end atoi;
9
10
architecture Behavioral of atoi is
11
begin
12
   process (ascii) 
13
   variable val  : unsigned (63 downto 0);
14
   variable mult : unsigned (63 downto 0); 
15
   begin
16
      val  := to_unsigned(0,64);
17
      mult := to_unsigned(1,64);
18
      for i in 0 to 13 loop
19
         val  := val + mult*(unsigned(ascii(i*8+7 downto i*8))-48);
20
         mult := mult * 10;
21
      end loop;
22
      value <= std_logic_vector(val);
23
   end process;
24
end Behavioral;
Die Synthese rennt durch, simulieren mußt du noch selber...

von Matthias G. (mgottke)


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.

von Dennis M. (vhdl_dennis)


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

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


Lesenswert?

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

Oberflächlich getestet mit dieser simplen Testbench:
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.ALL;
3
USE ieee.numeric_std.ALL;
4
 
5
ENTITY tb_atoi IS
6
END tb_atoi;
7
 
8
ARCHITECTURE behavior OF tb_atoi IS 
9
   COMPONENT atoi
10
   PORT( ascii : IN  std_logic_vector(111 downto 0);
11
         value : OUT  std_logic_vector(63 downto 0));
12
   END COMPONENT;
13
   signal ascii : std_logic_vector(111 downto 0) := (others => '0');
14
   signal value : std_logic_vector(63 downto 0);
15
BEGIN
16
   uut: atoi PORT MAP (ascii => ascii, value => value);
17
18
   process begin      
19
      for i in 0 to 9 loop
20
         for t in 0 to 13 loop
21
            ascii(t*8+7 downto t*8) <= std_logic_vector(to_unsigned(i+48,8));
22
         end loop;
23
         wait for 10 ns;   
24
      end loop;
25
   end process;
26
END;

von Harald F. (hfl)


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.

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


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.

von Dennis M. (vhdl_dennis)


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

von Dennis M. (vhdl_dennis)


Lesenswert?

Hmm, da kamen ja gleich zwei Beiträge dazu.

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

Gruß

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


Lesenswert?

Dennis M. schrieb:
> Aber leider lässt es sich nicht in Hardware übersetzen.
Bei mir kommt:
1
:
2
WARNING:Xst:643 - "atoi.vhd" line 34: The result of a 480x8-bit multiplication is partially used. 
3
Only the 64 least significant bits are used. If you are doing this on purpose, you may safely ignore this warning. 
4
Otherwise, make sure you are not losing information, leading to unexpected circuit behavior.
5
:
6
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

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.