Forum: FPGA, VHDL & Co. Befehl in zwei Takten Ausführen


von Yaro (Gast)


Lesenswert?

Hallo Leute,

ich möchte in einem synchronen Prozess einen Befehl in einem und einen 
in zwei Takten ausführen Lassen, z.B. hier:
1
    ALU : process(CLK, reset)
2
    begin
3
        if reset = '1' then
4
            F <= (others => '0');
5
        elsif rising_edge(CLK) then
6
            case Cmd is
7
                when "0000" => F <= A + B;
8
                when "0001" => F <= A * B; --Zwei Takte lang Zeit lassen
9
                when others => F <= (others => '-');
10
            end case;
11
        end if;
12
    end process;

Da würde ich der Multiplikation gerne zwei Takte Zeit gaben (ohne 
Pipeline). Mit welcher Methode kann ich das machen?

Ich habe schon überlegt, in einer FSM den Takt für diesen Prozess zu 
erzeugen, aber das wäre dann ja clock gateing und würde zu Taktversatz 
führen.
Auf Gatterebene würde ich am liebsten das enable Signal der FlipFlops 
für einen Takt lang ausschalten. Dass die Xilinx toolchain aber versteht 
was ich da mache und den kürzesten Pfad entsprechend berechnet wage ich 
zu bezweifeln.

Was ist der Standard Weg für solche Vorhaben?

Gruß, Yaro

von Gustl B. (-gb-)


Lesenswert?

Also sowas wie
1
if Cmd = "0001" then
2
   if BIT = '0' then
3
      F <= A * B;
4
      BIT <= '1';
5
   else
6
      BIT <= '0';
7
end if;

Kann halt passieren, dass gerade keine Multiplikationsanfrage 
entgegengenommen wird weil die alte noch läuft. Du aknnst auch das 
Ergebnis erst nach 2 Takten abfragen, dazu muss man natürlich in jedem 
Takt einen anderen Ergebnisspeicher haben, also
1
if Cmd = "0001" then
2
   if BIT = '0' then
3
      F <= A * B;
4
      BIT <= '1';
5
   else
6
      BIT <= '0';
7
      G <= A * B;
8
end if;

Dann kannst du abwechseln F und G abfragen.

von user (Gast)


Lesenswert?

Du kannst das F signal einmal extra registerieren und dann das 
synthesetool das optimieren lassen

von daniel__m (Gast)


Lesenswert?

hi,

Yaro schrieb:
> (ohne
> Pipeline)

warum?

Der hier sicherlich empfohlene Weg ist kein Multicycle, sondern 
tatsächlich eine Pipelinestufe. Diese hat vor F zu erfolgen, gemäß:

Yaro schrieb:
1
ALU : process(CLK, reset)
2
    begin
3
        if reset = '1' then
4
            F <= (others => '0');
5
            P <= (others => '-');
6
        elsif rising_edge(CLK) then
7
            P <= A * B;
8
9
            case Cmd is
10
                when "0000" => F <= A + B;
11
                when "0001" => F <= P;
12
                when others => F <= (others => '-');
13
            end case;
14
        end if;
15
    end process;

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


Lesenswert?

Yaro schrieb:
> Da würde ich der Multiplikation gerne zwei Takte Zeit gaben (ohne
> Pipeline).
Wozu? Der Multiplizierer ist doch auf jeden Fall schnell genug. Und wenn 
du hinterher noch eine Registerebene schaltest, dann kostet dich der 
eine Takt Latency gar nichts, weil einfach die Register verwendet 
werden, die eh' schon im Multiplizierer drin sind...

von daniel__m (Gast)


Lesenswert?

hi,

Lothar Miller schrieb:
> Und wenn
> du hinterher noch eine Registerebene schaltest

Das Register sollte/muss vor dem Muxer sein, damit er je nach Bit-Breite 
in ein DSP gezogen werden kann.

von Yaro (Gast)


Lesenswert?

Ersteinmal vielen Dank für die schnellen Antworten.

Ohne Pipeline habe ich geschrieben, weil ich sowieso einen Takt lang 
warten muss und eine Pipeline nicht verwenden könnte. Wenns umsonst ist, 
habe ich natürlich nichts dagegen.

Ich bin neu bei FPGAs, deswegen erlaubt mir bitte einige Fragen:
Zunächst die Voraussetzung: Ich programmiere für einen Spartan3E


Wenn ich es richtig verstehe steht hier:

Mentor synthesis features a pipeline multiplier that involves putting 
levels of registers in
the logic to introduce parallelism and, as a result, use CLB resources 
instead of the
dedicated multipliers. A certain construct in the input RTL source code 
description is
required to allow the pipelined multiplier feature to take effect. See 
the Synthesis and
Simulation Design Guide for more information.
The following VHDL example will infer the MULT18X18SIO with the PREG 
output
register:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_arith.all;
4
use ieee.std_logic_unsigned.all;
5
entity mult18x18sio is
6
    port(a    : in  std_logic_vector(7 downto 0);
7
         b    : in  std_logic_vector(7 downto 0);
8
         clk  : in  std_logic;
9
         prod : out std_logic_vector(15 downto 0));
10
end mult18x18sio;
11
architecture arch_mult18x18sio of mult18x18sio is
12
begin
13
    process(clk) is
14
    begin
15
        if clk ’ event and clk = ’ 1 ’ then prod <= a * b;
16
    end if;
17
end process;
18
end arch_mult18x18sio;
19
{/code}
20
21
The following is a Synchronous Multiplier VHDL example coded for Mentor:
22
[code]
23
library ieee;
24
use ieee.std_logic_1164.all;
25
use ieee.std_logic_arith.all;
26
use ieee.std_logic_unsigned.all;
27
entity mult18x18sio is
28
    port(clk  : in  std_logic;
29
         a    : in  std_logic_vector(7 downto 0);
30
         b    : in  std_logic_vector(7 downto 0);
31
         prod : out std_logic_vector(15 downto 0));
32
end mult18x18sio;
33
architecture arch_mult18x18sio of mult18x18sio is
34
    signal reg_prod : std_logic_vector(15 downto 0);
35
begin
36
    process(clk)
37
    begin
38
        if (rising_edge(clk)) then
39
            reg_prod <= a * b;
40
            prod     <= reg_prod;
41
        end if;
42
    end process;
43
end arch_mult18x18sio;
(Quelle: 
http://www.xilinx.com/support/documentation/user_guides/ug331.pdf)

Dass der zweite Multiplizierer (mit der Pipelinestufe) nicht einen 
hartverdrahteten Multiplizierer, sondern einen selbstgebauten nutzt. Ist 
das richtig?



Wenn ich folgendes baue:
1
Gustl Buheitel schrieb im Beitrag #3489444:
2
> if Cmd = "0001" then
3
>    if BIT = '0' then
4
>       F <= A * B;
5
>       BIT <= '1';
6
>    else
7
>       BIT <= '0';
8
> end if;
Packe ich ja einfach nur eine Registerstufe hinter Die Multiplikation. 
Wird der Compiler erkennen, dass er sie auch in den Multiplizierer 
ziehen kann?


Wenn ich folgendes baue:
1
daniel__m schrieb im Beitrag #3489512:
2
> ALU : process(CLK, reset)
3
>     begin
4
>         if reset = '1' then
5
>             F <= (others => '0');
6
>             P <= (others => '-');
7
>         elsif rising_edge(CLK) then
8
>             P <= A * B;
9
> 
10
>             case Cmd is
11
>                 when "0000" => F <= A + B;
12
>                 when "0001" => F <= P;
13
>                 when others => F <= (others => '-');
14
>             end case;
15
>         end if;
16
>     end process;
Ist das ja equivalent zum zweiten Beispiel. Nehmen wir mal an, da wird 
kein hartverdrateter Multiplizierer genommen (vielleicht auch, weil 
keiner mehr übrig ist). Versteht der Compiler, dass er die Pipeline 
Stufe irgendwo in die Mitte des Multiplizierers packen soll, oder packt 
er sie am Ende hin, was für die Ausführungszeit ja garkeinen Gewinn 
bringen würde.


Ich habe bisher nur von hartverdrahteten Multiplizierern gelesen. Gibts 
auch Hartverdrahtete Addierer, oder lohnt sich das nicht?

Wieviel "Intelligenz" kann man vom VHDL Compiler erwarten? Lohnt es 
sich, ihm Strukturen vorzukauen?


Mit besten Grüßen,
Yaro

von Christoph Z. (christophz)


Lesenswert?

Yaro schrieb:
> Dass die Xilinx toolchain aber versteht
> was ich da mache und den kürzesten Pfad entsprechend berechnet wage ich
> zu bezweifeln.

Ja, der Synthesizer und das Place&Route finden das nicht automatisch 
heraus.
Den betreffenden Pfad muss du mit einer Multicycle Constraint versehen.

Bei Synplify sieht das etwa so aus:
1
define_multicycle_path  -from {{i:<Name des Quellsignals>}}  -to {{i:<Name des Ergebnissignals>}}  2

Lattice Par will das so:
1
MULTICYCLE FROM CELL "<Name des Quellsignals>" TO CELL "<Name des Ergebnissignals>" 2.000000 X ;

Die Mentor und Xilinx Tools müssen das auch können, die Dokumentation 
gibt sicher Beispiele dazu.

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.