Forum: FPGA, VHDL & Co. Serieller Multiplizierer - Funktion - Problem


von Holger (Gast)


Lesenswert?

Hallo,

ich hatte schon einmal eine Frage zu diesem Problem, hatte mich aber 
sehr unglücklich ausgedrückt und den Code ungeschickt vereinfacht, so 
dass das eigentliche Problem nicht klar heraus gestellt wurde.

Es geht um folgende Funktion, die in einem seriellen Multiplizierer 
verwendet wird.
1
FUNCTION calc(
2
  factor1  : STD_LOGIC_VECTOR; --(11 downto 0)
3
  factor2  : STD_LOGIC_VECTOR; --(11 downto 0)
4
  index    : NATURAL;
5
  schritte : NATURAL;
6
  result   : STD_LOGIC_VECTOR  --(23 downto 0)
7
) RETURN STD_LOGIC_VECTOR IS
8
 
9
VARIABLE v_factor1       : STD_LOGIC_VECTOR(result'RANGE); --(23 downto 0)
10
VARIABLE v_summe    : STD_LOGIC_VECTOR(result'RANGE);--(23 downto 0)
11
VARIABLE v_temp     : STD_LOGIC_VECTOR(v_summe'RANGE);--(23 downto 0)
12
               
13
BEGIN
14
  v_summe := result;
15
  v_temp := (OTHERS => '0');
16
  FOR i IN 0 TO schritte - 1 LOOP
17
    IF (i <= schritte - 1)) THEN
18
      IF (factor2(index + i) = '1') THEN
19
        v_temp(factor1'HIGH+index+i downto index+i) := factor1;
20
      ELSE
21
        v_temp := (others => '0');
22
      END IF;
23
      v_summe := v_summe + v_temp;
24
    ELSE
25
      EXIT;
26
    END IF;
27
  END LOOP;
28
    RETURN v_summe;
29
END;
Diese rufe ich auf, um die Bits von Faktor 2 zu untersuchen um dann 
entsprechend zu dem Ergebnis der Multiplikation aufzuaddieren.
Diese Additionen sollen in einem Takt durchführbar sein. Wieviele Bits 
in einem Takt untersucht werden, legt "schritte" fest, womit dann die 
LOOP erstellt und durchlaufen wird.

Nun meckert mir Quartus an, dass die RANGE in dieser Zeile
1
v_temp(factor1'HIGH+index+i downto index+i) := factor1;
nicht konstant ist und damit ist die Sache nicht synthetisierbar.
Modelsim hingegen simuliert es anstandslos.

Nun fehlt mir die zündende Idee, wie ich das umschreiben kann, um 
dennoch die Shiftoperationen beizubehalten.

Könnte mir jemand einen Gedankenanstoß geben?

Vielen Dank!

von Falk B. (falk)


Lesenswert?

@  Holger (Gast)

>Nun meckert mir Quartus an, dass die RANGE in dieser Zeile

>v_temp(factor1'HIGH+index+i downto index+i) := factor1;

>nicht konstant ist und damit ist die Sache nicht synthetisierbar.
>Modelsim hingegen simuliert es anstandslos.

Logisch. Simulieren kann man fast alles, synthetisieren aber deutlich 
weniger.

>Nun fehlt mir die zündende Idee, wie ich das umschreiben kann, um
>dennoch die Shiftoperationen beizubehalten.

Man könnte ggf. das höchstwertige Bit per Dekoder finden und dadurch 
Durchläufe sparen.

Beitrag ""Höchstes" Bit finden"

Ob das am Ende aber sonderlich sinnvoll ist bei einem seriellen 
Multiplizierer bleibt fraglich.

MFG
Falk

von Kritischer Hans (Gast)


Lesenswert?

Warum wird denn hier überhaupt seriell multipliziert? Ist doch viel 
grösser, als einen parallele MUL-Architektur

von Holger (Gast)


Lesenswert?

Kritischer Hans schrieb:
> Warum wird denn hier überhaupt seriell multipliziert? Ist doch viel
> grösser, als einen parallele MUL-Architektur
Eine Multiplikation mit einem Addierer ist größer als eine mit mehr als 
einem Addierer? Oder verstehe ich die Frage falsch?

Man könnte die Frage auch auf folgendes Problem herunterbrechen:
Wie verschiebe ich z.B. in einem 16bit Vektor einen 8bit Vektor mit 
jedem Takt immer eine Stelle weiter nach links?

Dazu habe ich einen Counter, der die Bit-stelle nach oben zählt.
Nur wie bekomme ich das LSB an diese Stelle, ohne die Variable in der 
RANGE mit angeben zu müssen?

Vielen Dank!

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


Lesenswert?

Holger schrieb:
> Eine Multiplikation mit einem Addierer ist größer als eine mit mehr als
> einem Addierer? Oder verstehe ich die Frage falsch?
Multiplizeirer sind doch schon als Hardwarekomponente auf dem FPGA...

Holger schrieb:
> Man könnte die Frage auch auf folgendes Problem herunterbrechen:
> Wie verschiebe ich z.B. in einem 16bit Vektor einen 8bit Vektor mit
> jedem Takt immer eine Stelle weiter nach links?
Nein, du willst das ganze ja ohne Takt machen, denn in deiner 
For-Schleife ist keinerlei Takt beteiligt!

> Wie verschiebe ich z.B. in einem 16bit Vektor einen 8bit Vektor mit
> jedem Takt immer eine Stelle weiter nach links?
Du initialisierst das 16Bit Register mit irgendeinem Wert (z.B. auch mit 
den 8 Bit auf 7..0) und schiebst dann das 8 Bit Register Bit für Bit da 
durch...

von Holger (Gast)


Lesenswert?

Lothar Miller schrieb:
> Nein, du willst das ganze ja ohne Takt machen
Die Syntax bleibt doch aber die gleiche?!

> Du initialisierst das 16Bit Register mit irgendeinem Wert (z.B. auch mit
> den 8 Bit auf 7..0) und schiebst dann das 8 Bit Register Bit für Bit da
> durch...
Ubd wie genau mache ich das geschickt?
1
variable temp : std_logic_vector(15 downto 0);
2
variable faktor : std_logic_vector( 7 downto 0);
3
4
temp(faktor'HIGH+index downto index) <= faktor;
5
index <= index + 1;
6
-- zwischendurch temp immer wieder nullen,
7
-- damit die LSB nicht erhalten bleiben
So geht es ja leider im Quartus nicht, weil die RANGE nicht konstant 
ist.
Irgendwie habe ich gerade einen Knoten im Kopf...  :(

Vielen Dank!

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


Lesenswert?

Holger schrieb:
> Lothar Miller schrieb:
>> Nein, du willst das ganze ja ohne Takt machen
> Die Syntax bleibt doch aber die gleiche?!
Ein Schieberegister sind hintereinander gekopllete Flipflops, und das 
sieht so aus:
1
   if rising_edge(clk) then
2
      register16bit <= register16bit(14 downto 0) & '0';
3
   end if;

Hat das Ähnlichkeit mit deinem Multiplexer?

>> Du initialisierst das 16Bit Register mit irgendeinem Wert (z.B. auch mit
>> den 8 Bit auf 7..0) und schiebst dann das 8 Bit Register Bit für Bit da
>> durch...
> Ubd wie genau mache ich das geschickt?
1
   if rising_edge(clk) then
2
      if (load='1') then
3
          register16bit <= x"00" & register8bit;
4
      else
5
          register16bit <= register16bit(14 downto 0) & '0';
6
      end if; 
7
   end if;

> Irgendwie habe ich gerade einen Knoten im Kopf...  :(
Ja, offenbar...
Vergiss mal die Sache mit der Funktion und vergiss auch mal die 
Variablen. Ich wette, deine Aufgabe lässt sich mit einem (getakteten) 
Pozess und Signalen lösen...

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.