2016-07-26 15 views
1

Ich möchte die Geschwindigkeit meines VHDL Design sehen. Soweit ich weiß, ist dies in der Quartus II Software mit Fmax angegeben. Nach dem Zusammenstellen meines Designs zeigt es einen Fmax von 653,59 MHz. Ich schrieb eine Testbench und führte einige Tests durch, um sicherzustellen, dass das Design wie erwartet funktioniert. Das Problem, das ich mit dem Design habe, ist, dass bei der steigenden Flanke der Uhr die Eingaben richtig eingestellt sind, aber die Ausgabe nur nach einem weiteren Zyklus erfolgt.Versuchen, Fmax in VHDL zu finden, aber zusätzlichen Zyklus der Verzögerung

Meine Frage ist: Wie kann ich die Geschwindigkeit meines Entwurfs überprüfen (längste Verzögerung zwischen den Eingangsports und dem Ausgangsport) und auch die Ausgabe der Addition zur gleichen Zeit erhalten, zu der die Eingänge geladen werden/zur gleichen Zeit Zyklus?

Meine Testbench Ergebnisse sind wie folgt:

ein: 0001 und b: 0101 gibt XXXX
a: 1001 und b: 0001 gibt 0110 (das erwartete Ergebnis aus dem vorherigen Berechnung)
a: 1001 und b: 1001 gibt 1010 (das erwartete Ergebnis aus der vorherige Berechnung)
etc

Code:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity adder is 
    port( 
     clk : in STD_LOGIC; 
     a : in unsigned(3 downto 0); 
     b : in unsigned(3 downto 0); 
     sum : out unsigned(3 downto 0) 
    ); 
end adder; 

architecture rtl of adder is 

signal a_r, b_r, sum_r : unsigned(3 downto 0); 

begin 
    sum_r <= a_r + b_r; 
    process(clk) 
    begin 
     if (rising_edge(clk)) then 
      a_r <= a; 
      b_r <= b; 
      sum <= sum_r; 
     end if; 
    end process; 
end rtl; 

Prüfstand:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
entity testbench is 
end entity; 

architecture behavioral of testbench is 
    component adder is 
     port( 
      clk : in STD_LOGIC; 
      a : in unsigned(3 downto 0); 
      b : in unsigned(3 downto 0); 
      sum : out unsigned(3 downto 0) 
     ); 
    end component; 
    signal a, b, sum : unsigned(3 downto 0); 
    signal clk : STD_LOGIC; 
begin 
    uut: adder 
     port map(
      clk => clk, 
      a => a, 
      b => b, 
      sum => sum 
     ); 
    stim_process : process 
    begin 
     wait for 1 ns; 
     clk <= '0'; 
     wait for 1 ns; 
     clk <= '1'; 
     a <= "0001"; 
     b <= "0101"; 
     wait for 1 ns; 
     clk <= '0'; 
     wait for 1 ns; 
     clk <= '1'; 
     a <= "1001"; 
     b <= "0001"; 
     wait for 1 ns; 
     clk <= '0'; 
     wait for 1 ns; 
     clk <= '1'; 
     a <= "1001"; 
     b <= "1001"; 
    end process; 
end behavioral; 
+0

Mögliche Duplikate von: http://electronics.stackexchange.com/questions/247566/finding-fmax-in-fpga-design-without-adding-extracycle – Paebbels

+0

Es ist trivial einfach, entweder Eingangs- oder Ausgangsregister zu eliminieren, ODER beides - spart entweder 1 oder 2 Zyklen - aber es wird auf Kosten von einem viel niedrigeren Fmax (längere Zykluszeit). Das ist unvermeidlich. –

+0

Beim Löschen der Register wird kein Fmax angezeigt. – gilianzz

Antwort

1

gibt es eine Ausgabe SUM_R als Ausgabe bei der Verwendung?

Sie brauchen die Ein- und Ausgangsregister nicht, wenn Sie diese ALU als reine kombinatorische Logik betrachten. Die Fmax, sobald Sie sie gelöscht haben, wird verschwinden, wird dann abhängig sein und was es verbunden ist und woran es angeschlossen ist und nur wenn eingehende aus Registern und ausgehende ist zu Registern. Wenn es nur Logik ist, die von Eingang zu Ausgang und von Eingangspin zu Ausgangspin geht, ist es äußerst schwierig zu sagen, was die Ausbreitungsverzögerung ist und Anbietersoftware wie Altera und andere moderne Anbieter haben keine Werkzeuge, die für diese Art von geeignet sind Analyse.

Deshalb hören Sie Leute, die über Schwierigkeiten in der asynchronen Entwurfslogik sprechen.

Ich denke, solch eine feine Analyse ist schwierig mit Sicherheit und Genauigkeit durchzuführen. Da für Sie die Laufzeitverzögerung in Picosekunden wäre. Sogar in der Literatur ist es schwierig, quantitative Antworten auf die Ausbreitungsverzögerung zu finden.

Warum ist es schwierig? Denken Sie daran, dass die Ausbreitungsverzögerung durch die gesamte Pfadkapazität bestimmt wird, es gibt eine Möglichkeit, die Ausbreitungsverzögerung für Transistoren zu schätzen, aber ich kenne die tiefen Details darüber, wie die LUTs intern aufgebaut sind, so kann ich Ihnen keine gute Schätzung geben. Es hängt also stark von der Familie, dem Herstellungsprozess, dem FPGA-Aufbau und davon ab, ob die Last an IO angeschlossen ist.

Sie können jedoch Ihre eigenen Schätzungen machen, indem auf den logischen Planer gehen, Blick auf den Weg und übernehmen etwa 20-100ps Ausbreitungsverzögerung pro LUT, die es bewegt sich durch

unter dem Bild sehen.

enter image description here

Was Sie zu entwerfen versuchen, eine ALU. Per Definition sollte eine ALU in der Theorie einfach eine kombinatorische Logik sein.

Daher sollte streng genommen Ihr Addiercode nur dies sein.

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity adder is 
    port( 
     a : in unsigned(3 downto 0); 
     b : in unsigned(3 downto 0); 
     sum : out unsigned(3 downto 0) 
    ); 
end adder; 

architecture rtl of adder is 
begin 
    sum <= a + b; 
end rtl; 

Wo keine Uhr erforderlich ist, da diese Funktion wirklich ein kombinatorischer Prozess ist.

Allerdings, wenn Sie Ihre ALU in eine Bühne gehen zu wollen, wie, wie ich beschrieben habe, was Sie sollten tun, ist eigentlich diese

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity adder is 
    port( 
     clk : in STD_LOGIC; 
     a : in unsigned(3 downto 0); 
     b : in unsigned(3 downto 0); 
     sum : out unsigned(3 downto 0) 
    ); 
end adder; 

architecture rtl of adder is 

signal a_r, b_r, sum_r : unsigned(3 downto 0); 
signal internal_sum : unsigned(3 downto 0); 

begin 
    sum <= sum_r; 
    internal_sum <= a_r + b_r; 

    process(clk) 
    begin 
     if (rising_edge(clk)) then 
      a_r <= a; 
      b_r <= b; 
      sum_r <= internal_sum; 
     end if; 
    end process; 
end rtl; 

Sie haben über nicht erwähnt durchführen, damit ich nicht, dass diskutieren Hier.

Schließlich, wenn Sie Altera verwenden, haben sie einen sehr schönen RTL-Viewer, den Sie sehen können, um Ihr synthetisches Design zu sehen. Unter Extras-> Netlist Viewer-> RTL Viewer.

+0

Also IO-Register hier sind ein Muss, weil ich die Fmax sehen will. Mein Problem ist jedoch der zusätzliche Taktzyklus. Soll ich diesen Zyklus haben? Teste ich mein Design falsch? – gilianzz

+1

Herkömmliche Entwurfsmethodik ist durch synchrone Konstruktion, was bedeutet, dass die Implementierung von allem mit Stufen und Pipelines geplant wird. Ein zusätzlicher Taktzyklus ist zu erwarten. Es ist die Natur der digitalen Logik. Warum willst du Fmax sehen? Es wird sich erheblich ändern, sobald Sie beginnen, mehr Logik in Ihr Design zu bringen. Selbst in der Industrie ist es üblich, in 50-100 MHz Taktfrequenz zu arbeiten. Es ist schon schnell genug, um viele Dinge zu tun. Bitte stellen Sie weitere Fragen, wenn Sie haben. Und upvote und gib mir ein Häkchen, wenn du denkst, ich habe deine Frage beantwortet! – CJC

+1

Sie könnten also fragen, warum gibt es einen zusätzlichen Taktzyklus? weil Sie Ihre Daten an der steigenden Flanke jeder Uhr einlesen. Somit bleibt der Ausgang derselbe wie bis zur nächsten ansteigenden Flanke, daher die zusätzliche Taktverzögerung. Und die Register sind wichtig, weil Sie Metastabilität verhindern müssen. Was ist Metastabilität? Es ist eine Verletzung der Setup- und Haltezeit. Wie kommt das vor? Es tritt auf, wenn Ihr System ein ansteigendes Flanke-Ereignis durchläuft, aber die beobachteten Signale sich ändern, wenn es sich zu nahe an einem steigenden Ereignis befindet (Setup-Zeit) und zu früh nach dem ansteigenden Flanke-Ereignis (Haltezeit) – CJC