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