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
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...
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...
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.
@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
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; |
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.
> 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.
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
Hmm, da kamen ja gleich zwei Beiträge dazu. Irgendwie will Xilinx ISE den Code nicht in RTL übersetzen. komisch. Gruß
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.