Forum: FPGA, VHDL & Co. Optimierte Multiplikationsverfahren mit >= 32 Bit Inputs


von Nico B. (Firma: Hochschule Bonn-Rhein-Sieg) (jacetms)


Lesenswert?

Hallo Zusammen,

vorab möchte ich sagen, dass ich im Bereich VHDL ein Neuling bin, daher 
möchte ich auch meine Frage etwas detaillierter vorstellen.

Ich möchte gerne eine bestimmte Form der Montgomery Multiplikation in 
VHDL umsetzten. Dabei werden die Faktoren (a und b jeweils 32 Bit 
std_logic_vector) für die Multipliaton in 5 Teile zerlegt.
Dies geschieht durch Na = (a'length / 5) + (a'length mod 5). Nb ist 
identisch aufgebaut. D.h. bei einem 32 Bit Input erhalte ich 5 Outputs a 
8 Bit, was auch ohne Probleme funktioniert.

Im nächsten Schritt soll die Montgomery Multiplikation mit diesen 5 
Inputs durchgeführt werden. Da dieses Verfahren sehr groß ist, werde ich 
nur einen kleinen Teil präsentieren.

Die beiden Faktoren (a4,a3,a2,a1,a0),(b4,b3,b2,b1,b0) jeweils 8 Bit 
lang, werden beispielsweise folgendermaßen miteinander multipliziert:

(a0 + a1 + a2 + a3 + a4) * (b0 + b1 + b2 + b3 + b4) * (X^5 - X^4 + X^3)

Im hinteren Teil werden die Ergebnisse wieder um gewisse Stellen 
geshiftet.
Daher wird auch das Na,Nb benötigt, um zu wissen, um wie viele Stellen 
geshiftet werden muss.

Im Folgenden Beispiel werden die Faktoren a und identisch b 
folgendermaßen behandelt:
a4 = tempf1upper
a3 = tempf1middle1
a2 = tempf1middle2
a1 = tempf1middle3
a0 = tempf1lower

b4 = tempf2upper
b3 = tempf2middle1
b2 = tempf2middle2
b1 = tempf2middle3
b0 = tempf2lower

Ich habe das ganze jetzt mit unsigned realisiert. Bei der Simulation 
stelle ich jedoch fest, dass er mir bei den Variablen tempResult und 
shiftResult die Werte in die Mitte des Vektors schreibt. Woran liegt 
dies?

Gäbe es eine Möglichkeit, die Berechnung in std_logic_vectoren 
durchzuführen? Am liebsten wäre es, wenn ich weiterhin  mit integer, 
unsigned, signed arbeiten könnte, da so das shiften sehr einfach 
durchgeführt werden kann. Im weiteren Verlauf soll das ganze aber mit 
256 Bit werden funktionieren. Daher komme ich leider mit Integern und 
der gleichen nicht weiter.

Ich hoffe mir kann weiter geholfen werden und bedanke mich schon mal für 
die Antworten.

VG

JaceTMS

Beispiel-Quellcode (Soll erstmal nur Simulierbar sein):
1
library ieee;
2
use ieee.std_logic_1164.ALL;
3
use IEEE.numeric_std.all;
4
5
entity mont_mult_ma_nb is
6
  port(
7
      --Eingehnde Ports
8
      f1upper: in std_logic_vector (7 downto 0);
9
      f1middle1: in std_logic_vector (7 downto 0);
10
      f1middle2: in std_logic_vector (7 downto 0);
11
      f1middle3: in std_logic_vector (7 downto 0);
12
      f1lower: in std_logic_vector (7 downto 0);
13
      f2upper: in std_logic_vector (7 downto 0);
14
      f2middle1: in std_logic_vector (7 downto 0);
15
      f2middle2: in std_logic_vector (7 downto 0);
16
      f2middle3: in std_logic_vector (7 downto 0);
17
      f2lower: in std_logic_vector (7 downto 0);
18
      randomGen: in std_logic_vector (1 downto 0);
19
      N : in integer;
20
      clk : in std_logic;
21
      --Ausgehende Ports
22
      result : out std_logic_vector
23
    );
24
end mont_mult_ma_nb;
25
26
architecture Behavioral of mont_mult_ma_nb is
27
begin
28
  montgomery : process (f1upper, f1middle1, f1middle2, f1middle3, f1lower, f2upper, f2middle1, f2middle2, f2middle3, f2lower, randomGen, N, clk)
29
    
30
    --Temporäre Variablen für die Berechnung
31
    variable tempf1upper : unsigned (7 downto 0) := (others=>'0');
32
    variable tempf1middle1 : unsigned (7 downto 0) := (others=>'0');
33
    variable tempf1middle2 : unsigned (7 downto 0) := (others=>'0');
34
    variable tempf1middle3 : unsigned (7 downto 0) := (others=>'0');
35
    variable tempf1lower : unsigned (7 downto 0) := (others=>'0');
36
    variable tempf2upper : unsigned (7 downto 0) := (others=>'0');
37
    variable tempf2middle1 : unsigned (7 downto 0) := (others=>'0');
38
    variable tempf2middle2 : unsigned (7 downto 0) := (others=>'0');
39
    variable tempf2middle3 : unsigned (7 downto 0) := (others=>'0');
40
    variable tempf2lower : unsigned (7 downto 0) := (others=>'0');
41
    
42
    --Temporäre Variablen für die vorberechneten Ergebniswerten
43
    variable tempResult1 : unsigned (21 downto 0) := (others=>'0');
44
45
    
46
    --Temporäre Variablen für shift_left Funktion
47
    variable shiftResult1 : unsigned (63 downto 0) := (others=>'0');
48
49
      
50
  begin
51
  
52
    if (rising_edge(clk)) then
53
      if (randomGen = "11") then
54
        
55
        --Typenumwandlung von std_logic_vector -> signed
56
        tempf1upper := unsigned(f1upper(7 downto 0));
57
        tempf1middle1 := unsigned(f1middle1(7 downto 0));
58
        tempf1middle2 := unsigned(f1middle2(7 downto 0));
59
        tempf1middle3 := unsigned(f1middle3(7 downto 0));
60
        tempf1lower := unsigned(f1lower(7 downto 0));
61
        tempf2upper := unsigned(f2upper(7 downto 0));
62
        tempf2middle1 := unsigned(f2middle1(7 downto 0));
63
        tempf2middle2 := unsigned(f2middle2(7 downto 0));
64
        tempf2middle3 := unsigned(f2middle3(7 downto 0));
65
        tempf2lower := unsigned(f2lower(7 downto 0));
66
        
67
        --Berechnung der Multiplikationen
68
        tempResult1 := (tempf1upper + tempf1middle1 + tempf1middle2 + tempf1middle3 + tempf1lower) * (tempf2upper + tempf2middle1 + tempf2middle2 + tempf2middle3 + tempf2lower);
69
70
        
71
        --Berechnung der shift_left Funktionen
72
        shiftResult1 := shiftResult1 + shift_left(tempResult1, 5*N) - shift_left(tempResult1, 4*N) + shift_left(tempResult1, 3*N);
73
        
74
        
75
        --Ergebnis Addition
76
        result <= std_logic_vector(shiftResult1);
77
    
78
      end if;
79
    end if;  
80
  end process montgomery;
81
end Behavioral;

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


Lesenswert?

Kleiner Tipp, probiers mal aus:
1
[vhdl]
2
VHDL-Code
3
[/vhdl]

von tspotz (Gast)


Lesenswert?

Du willst doch eigentlich das ihr rechnen :

        --Berechnung der shift_left Funktionen
        shiftResult1 := shift_left(tempResult1, 5*N) - 
shift_left(tempResult1, 4*N) + shift_left(tempResult1, 3*N);

        Ergebnis := TempResult1 * ShiftResult1;

von Nico B. (Firma: Hochschule Bonn-Rhein-Sieg) (jacetms)


Lesenswert?

Hallo,

hab gemerkt, dass das so nicht weiter aufgeht, was ich vor habe.
Versuche das ganze jetzt auf einem anderen Weg und schaue, in wie weit 
ich dort komme.

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.