a2i - Konvertierung ASCII zu Integer

OP #1807432
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
Moderator (Firma: Titel) Persönliche Seite #1807441
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...
Moderator (Firma: Titel) Persönliche Seite #1807597
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...
OP #1807917
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
Moderator (Firma: Titel) Persönliche Seite #1808012
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;
#1808205
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.
Moderator (Firma: Titel) Persönliche Seite #1808217
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.
OP #1808238
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
Moderator (Firma: Titel) Persönliche Seite #1808288
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren