Forum: FPGA, VHDL & Co. ALU VHDL ohne Process


von Baxbear F. (baxbear)


Lesenswert?

Hi,

wir sollen mit VHDL eine ALU schreiben, dürfen in VHDL nur verwenden was 
schon thematisiert wurde. Heißt, da ich letztes mal schon alles neu 
machen musste weil ich Prozesse verwendet habe müsste es jetzt irgendwie 
ohne gelöst werden.

Folgende Aufgabenstellung:
Alu 2 7-Bit Eingänge (a, b)
ein 3-Bit Steuersignal (s)
ein 7-Bit Ausgang (c)
folgende Funktionen sollen möglich sein:

a>b (dann niederwertigstes auf 1 oder 0 von c)
a==b
a+1
a+b
UND
ODER
<<3
a%b

so angefangen habe ich wie folgt:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity alu is
6
  port (
7
    a : in std_logic_vector(0 to 6);
8
    b : in std_logic_vector(0 to 6);
9
    s : in std_logic_vector(0 to 2);
10
    c : out std_logic_vector(0 to 6)
11
  );
12
end entity alu;
13
14
architecture alu of alu is
15
begin
16
  with s select
17
    c(6) <= '1' when unsigned(a) > unsigned(b) else '0' when "000",
18
    c(6) <= '1' when unsigned(a) = unsigned(b) else '0' when "001",
19
    c <= std_logic_vector(signed(a) + 1) when "010";
20
end architecture;

Allerdings glaube ich selber nicht an dieses seltsame Konstrukt welches 
ich dort versuche zu erstellen. Könnte mir bitte jemand sagen, wie es 
richtig geht?

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


Lesenswert?

Benjamin F. schrieb:
> ein 7-Bit Ausgang (c)
Normalerweise hat eine ALU aber mehr Ausgänge. Den Überlauf, den du dort 
so umständlich abhandelst, der gehört in ein Overflow-Flag. Und 
zusätzlich gibt es noch andere Flags (Carry, Negative, ...).

> Allerdings glaube ich selber nicht an dieses seltsame Konstrukt
Das hier gibt ein Latch für c(5..0):
  c(6) <= '1' when unsigned(a) > unsigned(b) else '0' when "000",
Denn die müssen ja ihre "alten" Werte speichern.

> std_logic_vector(0 to 6);
Die Bitreihenfolge ist äusserst unüblich. Das ist, wie wenn du die 
Wertigkeit einer Dezimalzahl so definierst:
Einer Zehner Hunderter Tausender
Und damit
4102
das heutige Jahr ist...

Mit diesem Befehl hier wackelst du nämlich am "hintersten, rechtesten" 
Bit:
  c(6) <= '1' when unsigned(a) > unsigned(b) else '0' when "000",

Aber insgesamt ist der Ansatz und der Weg schon richtig. Die Sache mit 
signed und unsigned und den entsprechenden Carry- und Überlaufflags 
musst du dir allerdings noch ansehen...

von Baxbear F. (baxbear)


Lesenswert?

Lothar Miller schrieb:
> Benjamin F. schrieb:
>> ein 7-Bit Ausgang (c)
> Normalerweise hat eine ALU aber mehr Ausgänge. Den Überlauf, den du dort
> so umständlich abhandelst, der gehört in ein Overflow-Flag. Und
> zusätzlich gibt es noch andere Flags (Carry, Negative, ...).

Ja, mag sein, allerdings soll meine ALU genau einen 7-Bit-Ausgang haben.

>> Allerdings glaube ich selber nicht an dieses seltsame Konstrukt
> Das hier gibt ein Latch für c(5..0):
>   c(6) <= '1' when unsigned(a) > unsigned(b) else '0' when "000",
> Denn die müssen ja ihre "alten" Werte speichern.

Ich verstehe leider trotzdem nicht wie ich es richtig machen müsste 
gerade diese Zeile hätte ich gerne korrigiert bekommen, da ich dann 
zumindest weiß wie ich vorgehen muss.

>> std_logic_vector(0 to 6);
> Die Bitreihenfolge ist äusserst unüblich. Das ist, wie wenn du die
> Wertigkeit einer Dezimalzahl so definierst:
> Einer Zehner Hunderter Tausender
> Und damit
> 4102
> das heutige Jahr ist...
>
> Mit diesem Befehl hier wackelst du nämlich am "hintersten, rechtesten"
> Bit:
>   c(6) <= '1' when unsigned(a) > unsigned(b) else '0' when "000",

möchte ich auch, da ich nach Aufgabenstellung das Ergebnis von boolschen 
Abfragen in das niederwertigste Bit schreiben möchte.

> Aber insgesamt ist der Ansatz und der Weg schon richtig. Die Sache mit
> signed und unsigned und den entsprechenden Carry- und Überlaufflags
> musst du dir allerdings noch ansehen...

Die einzelnen Flags soll ich nicht setzen, wir sollen immer nur genau 
die Aufgabenstellung umsetzen.

Wäre nett wenn du/sie mir zeigen könntest/könnten wie es an der 
entsprechenden Stelle mit den verschachtelten Bedingungen richtig geht.

MfG
baxbear

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


Lesenswert?

Baxbear F. schrieb:
>>> std_logic_vector(0 to 6);
>> Die Bitreihenfolge ist äusserst unüblich.
>> Mit diesem Befehl hier wackelst du nämlich am "hintersten, rechtesten"
>> Bit:
>>   c(6) <= '1' when unsigned(a) > unsigned(b) else '0' when "000",
> möchte ich auch, da ich nach Aufgabenstellung das Ergebnis von boolschen
> Abfragen in das niederwertigste Bit schreiben möchte.
Dann dreh die Bitreihenfolge um (wie sonst der Rest der Welt eben auch) 
und schreib das Ergebnis in das Bit 0, denn das wäre für mich das 
niederwertigste Bit...

Ich drehe also mal die Bitreihenfolge in die richtige Richtung:
>>> Allerdings glaube ich selber nicht an dieses seltsame Konstrukt
>> Das hier gibt ein Latch für c(5..0):
>>   c(6) <= '1' when unsigned(a) > unsigned(b) else '0' when "000",
>> Denn die müssen ja ihre "alten" Werte speichern.
> Ich verstehe leider trotzdem nicht wie ich es richtig machen müsste
> gerade diese Zeile hätte ich gerne korrigiert bekommen, da ich dann
> zumindest weiß wie ich vorgehen muss.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity alu is
6
  port (
7
    a : in  std_logic_vector(6 downto 0);
8
    b : in  std_logic_vector(6 downto 0);
9
    s : in  std_logic_vector(2 downto 0);
10
    c : out std_logic_vector(6 downto 0)
11
  );
12
end entity alu;
13
14
architecture alu of alu is
15
signal au,bu,cu : unsigned (6 downto 0);
16
begin
17
  au <= unsigned(a);
18
  bu <= unsigned(b);
19
  c  <= std_logic_vector(cu);
20
  
21
  with s select
22
    cu <= "0000001" when au > bu else "0000000" when "000",
23
    cu <= "0000001" when au = bu else "0000000" when "001",
24
    cu <= au + 1                                when "010",
25
    ...;
26
27
end architecture;
Das Kapitel signed vs. unsigned ist bei deiner Alu komplett 
uninteressant, weil kein Überlauf und kein Unterlauf behandelt wird. 
Dazu wären die erwähnten Flags nötig...

> a%b
Modulo? Hoppala!
Das ist sehr anspruchsvoll und wird kombinatorisch so einfach nicht 
gehen...

von Baxbear F. (baxbear)


Lesenswert?

Ok, danke erstmal soweit, allerdings funktioniert dein Vorschlag auch 
nicht.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity alu2 is
6
  port (
7
    a : in  std_logic_vector(6 to 0);
8
    b : in  std_logic_vector(6 to 0);
9
    s : in  std_logic_vector(2 to 0);
10
    c : out std_logic_vector(6 to 0)
11
  );
12
end entity alu2;
13
14
architecture alu2 of alu2 is
15
signal au, bu, cu : unsigned (6 downto 0);
16
begin
17
  au <= unsigned(a);
18
  bu <= unsigned(b);
19
20
  with s select
21
    cu <= "0000001" when au > bu else "0000000" when "000",
22
    cu <= "0000001" when au = bu else "0000000" when "001",
23
    cu <= au + 1                                when "010";
24
25
  c  <= std_logic_vector(cu);
26
27
end architecture;

Folgende Fehlermeldungen erhalte ich:
-- Compiling architecture alu2 of alu2
** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(22): Signal "au" is type 
ieee.NUMERIC_STD.UNSIGNED; expecting type 
ieee.std_logic_1164.STD_LOGIC_VECTOR.
** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(22): Choice in selected signal assignment must 
be locally static.
** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(22): near ">": expecting ';' or ','
** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(17): (vcom-1272) Length of expected is 7; length 
of actual is 0.

** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(18): (vcom-1272) Length of expected is 7; length 
of actual is 0.

** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(19): (vcom-1272) Length of expected is 0; length 
of actual is 7.

** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(26): VHDL Compiler exiting

von Duke Scarring (Gast)


Lesenswert?

Baxbear F. schrieb:
> (6 to 0)
Das geht?

von baxbear (Gast)


Lesenswert?

huch, keine Ahnung warum ich das jetzt gemacht habe.

k hier nochmal:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity alu2 is
6
  port (
7
    a : in  std_logic_vector(6 downto 0);
8
    b : in  std_logic_vector(6 downto 0);
9
    s : in  std_logic_vector(2 downto 0);
10
    c : out std_logic_vector(6 downto 0)
11
  );
12
end entity alu2;
13
14
architecture alu2 of alu2 is
15
signal au, bu, cu : unsigned (6 downto 0);
16
begin
17
  au <= unsigned(a);
18
  bu <= unsigned(b);
19
20
  with s select
21
    cu <= "0000001" when au > bu else "0000000" when "000",
22
    cu <= "0000001" when au = bu else "0000000" when "001",
23
    cu <= au + 1                      when "010";
24
25
  c  <= std_logic_vector(cu);
26
27
end architecture;

Fehler:
** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(21): Signal "au" is type 
ieee.NUMERIC_STD.UNSIGNED; expecting type 
ieee.std_logic_1164.STD_LOGIC_VECTOR.
** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(21): Choice in selected signal assignment must 
be locally static.
** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(21): near ">": expecting ';' or ','
** Error: D:/windows/Digitaltechnik/Altera/labore/Labor 
2/Hierarchie/1/alu2.vhd(27): VHDL Compiler exiting

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


Lesenswert?

Baxbear F. schrieb:
> allerdings funktioniert dein Vorschlag auch nicht.
Im Ernst: muss ich auch deinen Hintern wischen, nachdem ich dir die 
Toilette gezeigt habe? Ich wollte dir eine grundlegende Idee 
vermitteln. Ist dir das klar?

> Ok, danke erstmal soweit
Keine Ursache. Der '+' Operator wird übrigens herummosern, denn wen du 2 
7 Bit Werte addierst, hat das Ergebnis 8 Bit...

Es hatte mich schon stutzig gemacht, ich habe es dann aber ignoriert:
1
  with s select
2
    cu <= "0000001" when au > bu else "0000000" when "000",
Zweimal 'when' geht hier natürlich nicht...

Ich schlage deshalb statt des with-select sowas vor:
1
  cu <= "0000001"     when au > bu and s="000" else
2
        "0000001"     when au = bu and s="001" else
3
        cu <= au + 1  when             s="010" else
4
        "0000000";

BTW: Du kannst die Zuweisung an 'c' ruhig oben stehen lassen. Indem du 
die Zuweisung nach unten verschiebst gaukelst du dir nur etwas vor, das 
es in der realen Hardware nicht gibt.

: Bearbeitet durch Moderator
von berndl (Gast)


Lesenswert?

Baxbear F. schrieb:
> a>b (dann niederwertigstes auf 1 oder 0 von c)
> a==b
> a+1
> a+b
> UND
> ODER
> <<3
> a%b

Dann definiere dir halt 8 mal ein Signal, z.B. 'a_gt_b', 'a_eq_b', 
'a_inc_1', 'a_plus_b', 'a_and_b', 'a_or_b', 'a_sl_3'?, 'a_mod_b' als 
sozusagen "Zwischenergebnis" und weise den Signalen den 
arithmetischen/booleschen/logischen Wert zu.
Und dann kannst du mit dem "with s select" dein Ergebnis 
zusammenbasteln.

Und dann dreh noch dein "0 to sowieso" in "sowieso downto 0" (damit 
repraesentieren deine Bits auch die Werte 2^n) wie Lothar schon 
angemerkt hat.

Und schmeiss das ganze einfach mal in den Simulator...

von Fpgakuechle K. (Gast)


Lesenswert?

Baxbear F. schrieb:

> wir sollen mit VHDL eine ALU schreiben, dürfen in VHDL nur verwenden was
> schon thematisiert wurde. Heißt, da ich letztes mal schon alles neu
> machen musste weil ich Prozesse verwendet habe müsste es jetzt irgendwie
> ohne gelöst werden.


Guckst Du mal auf SVN-Server vom mikrocontroller.net Ab Zeile 330:

http://www.mikrocontroller.net/svnbrowser/pibla/00_hw/src/pibla.vhd?revision=2&view=markup

MfG,

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.