Division von 2 Vektoren

#1564620
Lesenswert?

Hallo zusammen!
Ich brauche 2 Vektoren miteinander zu dividieren. Dazu habe ich ein 
kleines Programm geschrieben, das zwei std_logic_vectoren mit der Längen 
10 miteinander dividiert. Leider funktioniert das nicht:( Ich denke, 
dass es an die unterschiedlichen Dauer der Instruktionen liegt. So die 
Werte, die durch Verschiebung entstehen können möglicherweise erts in 
der nächsten Clock fertig sein, so dass die for-schleife mit falschen 
Werten arbeitet. Vielleicht kann man  irgendwie eine Verzögerung 
überlegen, befor man in die for- Schleife kommt. Und darf ich überhaupt 
in diesem Fall die for- Schleife benutzen??? Bin für jede Hilfe dankbar! 
Hier ist mein Programm und Testbench.


library STD;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity VectorDivision is
Port(Clock   : in std_logic;
     VectorA : in std_logic_vector(9 downto 0);
     VectorB : in std_logic_vector(9 downto 0);
    Ergebnis:out std_logic_vector(9 downto 0);
    Rest    :out std_logic_vector(9 downto 0));
end VectorDivision;

architecture Behavioral of VectorDivision is

signal Nullen: std_logic_vector(8 downto 0):=(others=>'0');
signal tempA:  std_logic_vector(18 downto 0);
signal tempB:  std_logic_vector(27 downto 0);
signal tempC:  std_logic_vector(18 downto 0);
signal y:      std_logic_vector(9 downto 0);
begin

Process (Clock)
begin
if rising_edge(Clock) then
 tempA <=Nullen & VectorA;--Erweiterung mit Nullen, damit beim Vergleich
 tempB <=Nullen & VectorB & Nullen;   -- die Laengen uebereinstimmen

 for i in 9 downto 0 loop
   tempC <= tempB(27-i downto 9-i);
   if tempA >= tempC then   -- Vector A mit Vector B*2**i vergleichen
      y(i)<= '1';           --A groesser als B*2**i wird i-Bit gesetzt
      tempA <= tempA-tempC; --und B*2**i wird von A abgezogen
   else
       y(i) <=  '0';
    end if;
 end loop;

   Rest <= tempA(9 downto 0);
   Ergebnis <= y;
 end if;
end process;
end Behavioral;



library STD;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY TB_VecortDivision IS
END TB_VecortDivision;

ARCHITECTURE behavior OF TB_VecortDivision IS

    COMPONENT VectorDivision
    PORT(
         Clock : IN  std_logic;
         VectorA : IN  std_logic_vector(9 downto 0);
         VectorB : IN  std_logic_vector(9 downto 0);
         Ergebnis : OUT  std_logic_vector(9 downto 0);
         Rest : OUT  std_logic_vector(9 downto 0)
        );
    END COMPONENT;

signal Clock : std_logic := '0';
signal VectorA : std_logic_vector(9 downto 0) := "1111101000"; --1000 
dec
signal VectorB : std_logic_vector(9 downto 0) := "0000010100"; --  20 
dec
signal Ergebnis: std_logic_vector(9 downto 0);
signal Rest    : std_logic_vector(9 downto 0);
constant ClockPeriod: time:= 6.666 ns;

BEGIN

   uut: VectorDivision PORT MAP (
          Clock => Clock,
          VectorA => VectorA,
          VectorB => VectorB,
          Ergebnis => Ergebnis,
          Rest => Rest
        );

   ClockProcess :process
   begin
    Clock <= '1';
    wait for ClockPeriod;
    Clock <= '0';
    wait for ClockPeriod;
   end process;

END;
Admin Persönliche Seite #1564919
Lesenswert?

Signale erhalten ihren neuen Wert erst dann, wenn der Prozess zum 
nächsten Mal ausgeführt wird. Wenn du Variablen anstatt von Signalen 
verwenden würdest, dann könnte dein Programm zumindest im Simulator 
funktionieren. Für die Synthese ist der Ansatz aber komplett falsch; 
wiederholte Ausführung mit Schleifen gibt es da nicht, das muss man von 
Hand mit einem Zustandsautomaten machen. Am besten schaust du dir noch 
mal ein paar einfachere VHDL-Beispiele an, und liest nach wie die 
einzelnen Konstrukte (Variablen, Signale, Schleifen) funktionieren. Da 
fehlen noch ein paar Grundlagen bevor du dich an einen Dividierer wagen 
kannst.
Moderator (Firma: Titel) Persönliche Seite #1565103
Lesenswert?

> Ich denke, dass es an die unterschiedlichen Dauer der Instruktionen liegt.
Diese Denkweise ist grundlegend falsch.  :-o
Deine VHDL-Beschreibung wird parallel in Hardware umgesetzt, und mit 
jedem Takt einmal komplett ausgeführt. Wenn da ein langsamer 
Kombinatorikpfad drin ist, dann sagt dir das das Synthesetool.

Vergiss für den Anfang das Schlüsselwort loop. Eine Schleife in VHDL 
beschreibt nicht etwas, das nacheinander x-mal ausgeführt wird, 
sondern etwas, das x-mal gleichzeitig auf das FPGA abgebildet wird.

Und vor allem: wenn du irgendwas simulieren kannst, dann heißt das noch 
lange nicht, dass du es auch auf Hardware synthetisiert bekommst...


BTW:
Beitrag "Re: Funktionsplan in VHDL übersetzen"
#1565986
Lesenswert?

Erstmal danke für eure Anweisungen! Ich habe jetzt versucht das ganze 
als einen Zustandsautomat zu machen. Das Ergebnis  im Vergleich zum 
richtigen wird um ein bit nach nach hinten verschoben. Und das wird 
erstmal wenn z zweimal komplett durchgelaufen wird. Hat jemand eine Idee 
woran es liegen kann?

entity VectorDivision is
Port(Clock   : in std_logic;
     VectorA : in std_logic_vector(9 downto 0);
     VectorB : in std_logic_vector(9 downto 0);
     Ergebnis:out std_logic_vector(9 downto 0);
     Rest    :out std_logic_vector(9 downto 0));
end VectorDivision;

architecture Behavioral of VectorDivision is

signal Nullen: std_logic_vector(8 downto 0):=(others=>'0');
signal tempA:  std_logic_vector(18 downto 0);
signal tempB:  std_logic_vector(18 downto 0);
signal tempC:  std_logic_vector(27 downto 0);
signal y:      std_logic_vector(9 downto 0);
signal z,zplus :integer:=9;

begin

Process (Clock)
 begin
   if rising_edge(Clock) then
      z <= zplus;
      if z=9 then
         tempA <= Nullen & VectorA;
         tempC <= Nullen & VectorB & Nullen;
      end if;

      tempB <= tempC(27-z downto 9-z);

      if tempA >= tempB then
         y(z)  <= '1';
         tempA <= tempA - tempB;
      else
          y(z)<='0';
      end if;

    end if;
   end process;

 Process(z)
  begin
    case z is
     when 0=>  zplus <= 9; Rest <= tempA(9 downto 0);Ergebnis<=y;
     when others => zplus <= z-1;
   end case;
 end process;

end Behavioral;
Moderator (Firma: Titel) Persönliche Seite #1566493
Lesenswert?

Du bemerkst das in der Simulation, richtig?

Übliche Ursache für eigenartiges Verhalten in der simulation: die 
Sensitivliste eines kombinatorischen Prozesses ist unvollständig.
1
Process(z)
Hier gehört das temA und y auch mit rein, denn beim Zustand 9 hängt das 
Ergebnis auch von diesen beiden Werten ab:
1
Process(z, tempa, y) 
2
begin
3
 case z is
4
  when 0      =>  zplus <= 9;
5
  when 9      =>  zplus <= z-1; Rest <=tempA(9 downto 0); Ergebnis<=y;
6
  when others =>  zplus <= z-1;
7
 end case;
8
end process;
#1567291
Lesenswert?

Ja genau, das stelle ich durch die Simulation fest! Die Erweiterung der 
Sensitivliste hat leider nichts gebracht. Zusätzlich bei der Division 
mit Rest (z.B. 1000 durch 3) ergibt sich  das falsche Ergebnis, das sich 
ständig je 10. Takt zwischen 166dec(0010100110 ist eigentlich 333dec um 
ein bit nach rechts verschoben) und 512dec(1000000000)  wechselt.

Wenn ich mein Code von Hand  durchgehe dann soll alles stimmen, aber in 
der Realität.... Ich habe kein Plan:(

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren