Dividierer und Multiplizierer in einem Rechenwerk

Gast #3420107
Lesenswert?

Hallo Leute,
Ich bin wie viele andere auch ein Neuling mit VHDL und soll für einen 
Laborversuch ein 3-Bit Rechenwerk aufbauen, dass einen Addierer, einen 
Subtrahierer, einen Multiplizierer und einen Dividierer beinhaltet und 
über einen Multiplexer entsprechend der Steuersignale durchschaltet.

Dabei werden 2 3-Bit Werte eingelesen und als Zweierkomplement 
"verwendet" (Wertebereich also -4 bis 3). Am Ausgang soll das Ergebnis 
als 4-Bit Zahl ausgegeben und ebenfalls als Zweierkomplement dargestellt 
werden (Wertebereich: -8 bis 7).

Bei der Multiplikation soll eine Berreichsüberschreitung im positiven 
durch "1111" und im negativen durch "0000" dargestellt werden. Der 
Dividierer soll keine Dezimalstellen anzeigen (Division mit Rest, ohne 
den Rest anzuzeigen) aber eine eventuelle 0 am zweiten Ausgang abfangen.

Addierer, Subtrahierer und MUX funktionieren soweit, aber der 
Multiplizierer und der Dividierer machen Probleme.

Dividierer
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5
entity Labor_Aufgabe_4_Div is
6
  port(
7
    a,b : in std_logic_vector (2 downto 0);
8
    y : out std_logic_vector(3 downto 0)
9
    );
10
end entity Labor_Aufgabe_4_Div;
11

12
architecture behav of Labor_Aufgabe_4_Div is
13
  signal aint,bint : unsigned(3 downto 0);
14
  signal sum : unsigned(3 downto 0);
15
  
16
  begin
17
  
18
  aint <= unsigned (a(2)&a);
19
  bint <= unsigned (b(2)&b);
20
  
21
  Div : process(sum) is 
22
    begin
23
  if b /= "000" then
24
  sum <= aint / bint;
25
  y <= std_logic_vector(sum);
26
  else
27
  y <= "1111";
28
  end if;
29
  end process;
30
    
31
end architecture;

ich kriege bei der Simulation teils Dont cares raus, was ich mir noch 
nicht so richtig erklären kann. Auch die "normalen" Ergebnisse stimmen 
nicht ganz.
Wo liegt mein Denkfehler?

Der Multiplizierer funktioniert prinzipiell auch allerdings krieg ich es 
nicht auf die Reihe die Berauchsüberschreitung aufzustellen. Ich hab 
schon verschiedenste IF-Else-Verzweigungen zusammengeschrieben, aber 
bisher kam nur Mist dabei heraus.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4

5
entity Labor_Aufgabe_3_Mult is
6
  port(
7
    a,b : in std_logic_vector (2 downto 0);
8
    y : out std_logic_vector(3 downto 0)
9
    );
10
end entity Labor_Aufgabe_3_Mult;
11

12
architecture behav of Labor_Aufgabe_3_Mult is
13
  signal aint,bint : unsigned(2 downto 0);
14
  signal sum : unsigned(5 downto 0);
15
  
16
  begin
17
  
18
  aint <= unsigned (a);
19
  bint <= unsigned (b);
20
  sum <= aint * bint;
21
  
22
  y <= std_logic_vector(sum(3 downto 0));
23

24
end architecture;

So sieht das ganze bis jetzt aus (ohne Bereichsgrenzen). Außerdem können 
nur 4 Bit am ausgang dargestellt werden, was einige Ergebnisse 
verfälscht.

Ich würde mich über Denkanstöße mehr freuen als über Komplettlösungen, 
da ich die Berschreibung auch gerne verstehen möchte und daher möglichst 
viel selbst machen will. Deswegen sind Algorithmen wie der Dividierer 
von lkmiller für mich eher unpassend.

Vielen Dank im Voraus
Grüße Thomas

Randinformation:
Software: Lattice Diamond 2.2
PLD: Lattice MachX02
Moderator (Firma: Titel) Persönliche Seite #3420653
Lesenswert?

Thomas schrieb:
> signal aint,bint : unsigned(2 downto 0);
> signal sum : unsigned(5 downto 0);
Thomas schrieb:
> Da war ich einwenig faul und hab die Variablennamen nicht geändert,
> sollte aber an der Funktion nichts ändern, da Variablennamen (fast) frei
> wählbar sind.
Dir ist schon klar, dass Variablen und Signale in VHDL etwas 
grundlegend unterschiedliches sind?

> Deswegen sind Algorithmen wie der Dividierer von lkmiller für mich eher
> unpassend.
Für die wenigen Bits würde ich auch niemals einen aufwendigen Divider 
aufsetzen, sondern einfach die paar Werte vorher ausrechnen und in einem 
ROM ablgen...

Thomas schrieb:
> ich kriege bei der Simulation teils Dont cares raus, was ich mir noch
> nicht so richtig erklären kann.
Ich habe noch nie ein "-" also ein /Don't Care/ bei einer Simulation 
herausbekommen. Oder meinst du "X" also eine Kollision, oder "U" also 
ein Undefined?

> Auch die "normalen" Ergebnisse stimmen nicht ganz.
Was stimmt denn nicht?

> Wo liegt mein Denkfehler?
Da, wo du meinst, dass irgendwer mit Raten weiter kommt...
Gast #3420696
Lesenswert?

Zur Division: sum ist zu Beginn undefined, und kann nur im Div-Prozess 
gesetzt werden. Der Div-Prozess wird in der Simulation aber nie 
durchlaufen, weil die Sensitivity-List des Prozesses völlig falsch ist.
Gast #3420757
Lesenswert?

Bei deinen Operatorgrössen (je 3Bits) und der Anzahl Operationen
(3:Add,Mul,Div) lässt sich dein Rechenwerk komplett in ein
internes RAM einpacken: 2x 3Bits + 2 Bits als Addresse und
dann 4 Bits als Datenausgang, d.h. 256x4 == 1024 Bits total.
Xilinx' aktuelle FPGAs haben interne RAMs mit 16KBits, bei
Altera fängt's ab 4KBits an.
Moderator (Firma: Titel) Persönliche Seite #3420888
Lesenswert?

Sigi schrieb:
> Xilinx' aktuelle FPGAs haben interne RAMs mit 16KBits, bei
> Altera fängt's ab 4KBits an.
Knapp vorbei...
Thomas schrieb:
> Randinformation: Software: Lattice Diamond 2.2
> PLD: Lattice MachX02
Aber auch im MachXO gibt es RAMs. Und ein Addierer/Subtrhierer muss da 
ja nicht rein. Ich würde nur den Divider und evtl. die Multiplikation da 
rein packen (obwohl die auch in den LUTs gut aufgehoben ist)...
Gast #3421614
Lesenswert?

Halle

Achim S. schrieb:
> weil die Sensitivity-List des Prozesses völlig falsch ist.

Danke!
Man hat uns nicht erklärt, was in die Klammer rein muss und ich hab in 
meinem studentischen Leichtsinn einfach etwas aus einem anderen Projekt 
übernommen. Hab mich in die VHDL-Artikel auf Microcontroller.net 
eingelesen und dann die rechtigen Signale eingesetzt. Jetzt läuft auch 
alles.

Lothar Miller schrieb:
> Dir ist schon klar, dass Variablen und Signale in VHDL etwas
> grundlegend unterschiedliches sind?

Hab in C gedacht. Sorry.

Lothar Miller schrieb:
> Ich habe noch nie ein "-" also ein /Don't Care/ bei einer Simulation
> herausbekommen. Oder meinst du "X" also eine Kollision, oder "U" also
> ein Undefined?

Ich dachte die Xe wären Don't Cares weil ich es so aus der 
Digitaltechnik kannte. Hab mich wohl geirrt. Danke für die Aufklärung.

Lothar Miller schrieb:
> Was stimmt denn nicht?

Manche Zahlenwerte waren schlichtweg falsch, Undefined oder standen auf 
X.

berndl schrieb:
> oehm, du schreibst was von Zweierkomplement und verwendest 'unsigned'?
> Damit funktioniert das propagieren des Vorzeichenbits aber nur in
> manchen (positiven) Faellen...

spielt das wirklich eine Rolle? ich dachte dem PLD kann es doch egal 
sein, er muss die Werte nur auf der Bitebene verrechnen und das 
funktioniert sowohl mit signed als auch mit unsigned (mit der simulation 
getestet).
Schlussendlich kommt an den LEDs auf dem Board ein binärer Wert raus den 
ich dann interpretieren muss.

Danke für die Hilfe,
Grüße Thomas

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