Forum: FPGA, VHDL & Co. 1-Bit ALU -- geht es besser?


von Läubi .. (laeubi) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ich lese gerade das Buch: "Structured Computer Organisation".
Im Abschnitt "The Digital Logic Level" ist eine 1-Bit ALU beschrieben, 
welche ich mal versucht habe in VHDL Nachzubilden (siehe Anhang).
Zur Zeit hat diese auf nem Spartan 3 folgende Werte:
4 Slices / 7 LUTs
Maximum combinational path delay: 12.030ns

Ich frage mich nur, ob man da noch das ganze geschickter beschreiben 
kann sodass die Synthese das FPGA besser ausnutzt, meine bisherigen 
Versuche das zu minimieren sind leider fehlgeschlagen, aber dass muß ja 
nichts heißen.

Da später die ALU kaskadiert wird um größere Bitbreiten zu berechnen 
erscheint mir das Delay schon etwas hoch.

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


Angehängte Dateien:

Lesenswert?

> Maximum combinational path delay: 12.030ns
Da streust du dir selber Sand in die Augen:
Wenn du mal einen Takt einführst, und die Eingangs- und Ausgangssignale 
taktest, dann siehst du, dass die meiste Zeit in den Eingangs- und 
Ausgangs-Pintreibern des FPGAs verplempert wird.

> Da später die ALU kaskadiert wird um größere Bitbreiten zu berechnen
> erscheint mir das Delay schon etwas hoch.
In deiner fertigen CPU wirst du mit diesen Signalen aber niemals an die 
Pins fahren, sondern diese synchron im FPGA weiterbearbeiten.

Mit dem Code im Anhang sieht das Ganze entspannter aus:
1
   Minimum period: 3.883ns (Maximum Frequency: 257.539MHz)
2
   Minimum input arrival time before clock: 1.572ns
3
   Maximum output required time after clock: 6.216ns
4
   Maximum combinational path delay: No path found
(mit Speedgrade -5)

Und auch an der Beschreibung selber würde ich etwas ändern.
Weg mit den Variablen und ein wenig Concurrent, damit man den MUX 
schöner sieht:
1
architecture Behavioral of OneBitAlu is
2
signal AV, BV: std_logic;
3
signal SUM : std_logic_vector(1 downto 0);
4
begin
5
    AV  <= '0'   when ENA='0' else
6
           not A when INVA='1' else
7
           A;
8
    BV  <= '0' when ENB='0' else
9
           B;
10
    MUXout: process (AV, BV, Cin, F)
11
    begin
12
        Cout <= '0';
13
        case F is
14
            -- AND
15
            when "00" => Y <= AV AND BV;
16
            -- OR
17
            when "01" => Y <= AV OR BV;
18
            -- NOT B
19
            when "10" => Y <= NOT BV;
20
            -- A + B
21
            when "11" => SUM := ("0"&AV) + ("0"&BV) +("0"&Cin);
22
                         Y    <=  SUM(0);
23
                         Cout <=  SUM(1);
24
            when others => Y <= '-';
25
        end case;
26
    end process;
27
end Behavioral;

Und zudem würde ich eher das NUMERIC_STD Package nehmen.

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


Lesenswert?

Okokok.
Und ich sach' noch: Nimm Concurrent-Zuweisungen und Signale  :-o
So passts:
1
    :
2
    BV  <= '0' when ENB='0' else
3
           B;
4
    SUM <= ("0"&AV) + ("0"&BV) + ("0"&Cin);
5
6
    MUXout: process (AV, BV, Cin, F)
7
    :
8
            -- A + B
9
            when "11" => Y    <=  SUM(0);
10
                         Cout <=  SUM(1);
11
    :

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

@Lothar Miller: Ich kann nur sagen, das hats gebracht! Da wäre ich nie 
drauf gekommen, das das die Ausgangstreiber sind, wieder was gelernt...
Bin jezt für meine 32bit Version aus 1-Bit ALUs von 75ns auf Period 13ns 
gekommen, das ist annehmbar, war schon etwas frustriert das dieser 
Ansatz so dermaßen fehlgeschlagen war.

Habe auch nochmal ne "native" Version mit std_logic_vector gemacht kom 
dort auf kom ich auf 9ns, da kann er wohl noch etwas mehr rausholen.

Hätte dazu aber gleich mal ne Frage:
Minimum period: 9.275ns (Maximum Frequency: 107.817MHz)
   Minimum input arrival time before clock: 1.941ns
   Maximum output required time after clock: 17.895ns
   Maximum combinational path delay: No path found

Was ist den jezt hier die "Laufzeit" meiner ALU/Logic?

Und zu dem Concurrent:
 Was für einen Vorteil habe ich dadurch? In meinem Fall hat das 
umstellen auf Concurrent nix gebracht was die Laufzeit betrifft, habe 
mich aber schon gefragt ob ein Process ohne CLK oder eine Concurrent 
Anweisung "besser" ist oder ob ich überhaupt die ganze ALU lieber als 
eine Zuweisung versuche zu schreiben...

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


Lesenswert?

> Und zu dem Concurrent:
> Was für einen Vorteil habe ich dadurch?
1. Es liest sich schöner  ;-)
2. Du sparst dir diese (blödsinnigen) Variablen.
3. Wenn du Kombinatorik concurrent schreibst,
   mußt du nicht auf irgendwelche Sensitivity-Listen achten.

> Was ist den jezt hier die "Laufzeit" meiner ALU/Logic?
9.275ns - tsu - tcko --> also etwa 8ns, das ist die Zeit, die die 
ALU-Kombinatorik braucht.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Alles klar, super dann kann es ja weitergehen :)
Habe jezt meine "große" ALU auch auf Concurrent umgeschrieben, eine 
Variable brauch ich aber trozdem für die Flags, wenn ich die auch 
COncurrent mache ist das komischerweise langsamer. (Die große ALU hat 
ein Negativ und ein Zero Flag).

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


Lesenswert?

> ist das komischerweise langsamer.
Sieh dir mal die statische Timinganalyse (Post Place/Route Static 
Timing) an, da steht detailliert, welcher Pfad der Flaschenhals im 
Design ist.

von Läubi .. (laeubi) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hab den Report mal angehängt, sehr erhellend ist der nicht, außer das er 
mir Sagt das das ZeroFlag irgenwie ärger macht.
1
------------+------------+------------------+--------+
2
            | clk (edge) |                  |  Clock |
3
Destination | to PAD     |Internal Clock(s) |  Phase |
4
------------+------------+------------------+--------+
5
xFLAG_N     |    9.788(R)|clk_BUFGP         |   0.000|
6
xFLAG_Z     |   23.030(R)|clk_BUFGP         |   0.000|
7
xY<0>       |    7.360(R)|clk_BUFGP         |   0.000|
8
....

Habe das Flag direkt an den Ausgang gelegt:
1
ALUInst:     n32bitALU PORT MAP(A,B,Y,INC,INVA,ENA,ENB,F, xFLAG_Z, FLAG_N);
Weil ich festgestellt habe das wenn ich das über ein Zwischensignal 
mache das ganze langsamer wird...

Erzeugen tue ich die Flags folgendermaßen:
1
-- Ausgangs Mux
2
MUXout: process (E_OR, E_AND, E_NOT, E_SUM, F)
3
variable ERG   : std_logic_vector(n-1 downto 0);
4
variable ZERO  : std_logic_vector(n-1 downto 0) := (others => '0');
5
begin
6
    case F is
7
        -- AND
8
        when "00" =>   ERG := E_AND; --CA AND CB;
9
        -- OR
10
        when "01" =>   ERG := E_OR; --CA OR CB;
11
        -- NOT B
12
        when "10" =>   ERG := E_NOT; --NOT CB;
13
        -- A + B + INC
14
        when "11" =>   ERG := E_SUM;
15
        when others => ERG := (others => '-');
16
    end case;
17
    -- Flags
18
    FLAG_N <= ERG(n-1);
19
    if ERG = ZERO then
20
        FLAG_Z <= '1';
21
    else
22
        FLAG_Z <= '0';
23
    end if;
24
    Y      <= ERG;
25
end process;

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


Lesenswert?

> INFO:Timing:2698 - No timing constraints found, doing default enumeration.
Wenn du der Toolchain keine Vorgaben machst, dann gibt die sich auch 
keine Mühe.

> ... das das ZeroFlag irgenwie ärger macht.
> ... clk to PAD  23.030(R)...
Das Ganze ist derzeit eher eine akademische Spielerei. In der realen CPU 
wird das Z-Flag sowieso nicht auf ein Pad geführt. Mach dir um die 
Laufzeit hier mal keine Gedanken.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Okay, alles klar, dann werd ich mich mal weiter vorarbeitenim CPU Model 
und dann sehen wie sich das mit dem Delay entwickelt.
Ich wollte nur von Anfang an bei den "Basics" schon versuchen möglichst 
effizient zu arbeiten, man muß ja nicht unütz da Zeit verschenken. :)

Bedanke mich auf jeden fall schonmal.

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.