Forum: FPGA, VHDL & Co. Anfängerfrage Submodule einbinden


von Marco (Gast)


Lesenswert?

Hallo,
ich habe eine Frage, die mich die letzten Studen echt verzweifeln ließ. 
Ich habe eine Aufgabe, die ich nach Vorgaben lösen muss. Ich soll zwei 
VHDL Module erstellen die je einen 8 Bit Vector um eine Stelle nach 
links bzw, nach rechts shiften. Soweit so gut. Das war kein Problem. 
Jetzt soll ich ein Hauptmodul erstellen, das je nach Schalter an oder 
aus einen Vector zyklisch an eins der Module übergibt. Ich weiß einfach 
nicht wie ich das anstellen soll. Ich habe versucht mit einer case 
struktur sozusagen bedingtes portmapping zu betreiben mit if else gings 
auch nicht.
Ich hoffe ihr könnt an der Uhrzeit den Grad meiner Verzweiflung erkennen 
und helft mir weiter

von Bernd S. (Gast)


Lesenswert?

Hi,

deine Module sind als COMPONENT eingebunden in das Hauptmodul?

Ich nehme an deine Module haben einen Eingangsvector und einen 
Ausgangsvector? Außerdem wirst du ein Startsignal oder so was benötigen.

Im Hauptmodul machst du natürlich statische Mappings für die Signale, 
das geht imo auch nicht dynamisch.
Den Eingangsvector beider Module kannst du ja auf ein Signal im 
Hauptmodul mappen, weil 1 Treiber kann mehrere Empfänger treiben, sollte 
also kein Problem sein.

Die Ausgangsvectoren deiner beiden Module kannst du natürlich nicht 
statisch auf dasselbe Signal mappen.

Hier würde ich einen PROCESS machen im Hauptmodul der je nach deinem 
Schalter entweder den Ausgangsvector des einen Moduls oder den 
Ausgangsvector des anderen Moduls auf dein gewünschtes Signal mappt.

So fertig...

von pongo (Gast)


Lesenswert?

um die aufgabe formell zu erfüllen, könnte man da das signal tatsächlich 
nur einem modul zuführen und dem anderen nullen verpassen

von Marco (Gast)


Lesenswert?

Ist das geil da schreibt man hier nachts was herein bovor man voll 
frustriert pennen geht und am nächsten morgen hat man die Antwort.

vielen Dank!!

Ich muss sagen ich habe mich echt etwas dumm angestellt... Naja das mit 
den Submodulen habe ich jetzt glöst wie von Bernd beschrieben. Ich setze 
einfach Flags, die an die Submodule übergeben werden und dort als clock 
den jeweiligen Process auslösen.
Mein nächstes Problem bei dem ich scho wieder auf dem schlauch stehe ist 
das zyklische verschieben. wenn ich meinen vector atmp im Hauptmodul 
verändere also den geshifteten Vector darin abspeichern will, mekert der 
Compiler:

.
.
.
Xst:528 - Multi-source in Unit <Hauptmod_Aufgabe1> on signal <a<7>>; 
this signal is connected to multiple drivers.
.
.
.
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
6
entity Hauptmod_Aufgabe1 is
7
    --Vektorgröße kann eingestellt werden
8
    generic ( N: integer := 8);
9
    Port ( 
10
          lr_dir: in std_logic;
11
          clock : in STD_LOGIC;
12
        yout: out std_logic_vector (N-1 downto 0);
13
        a : in std_logic_vector (N-1 downto 0);
14
        init: in std_logic);
15
16
end Hauptmod_Aufgabe1;
17
18
architecture Behavioral of Hauptmod_Aufgabe1 is
19
signal yr ,yl ,atmp : std_logic_vector (N-1 downto 0);
20
signal leftflag, rightflag:std_logic;
21
22
begin
23
24
--Portmapping 
25
--das Flag aktiviert jeweils den shiftprocess in den Submodulen
26
left: entity work.shiftleft(Behavioral)
27
port map (a=> atmp , clock => leftflag, y=>yl);
28
right: entity work.shiftright(Behavioral) 
29
port map (a=> atmp , clock => rightflag , y=>yr);
30
31
--Vektor laden
32
process(init)
33
begin
34
atmp<=a;
35
end process;
36
37
process(clock)
38
39
begin
40
--flags loeschen
41
rightflag<='0';
42
leftflag <= '0';
43
--nach links
44
if lr_dir = '0' then
45
rightflag<='0';
46
leftflag <= '1';
47
yout<=yl;
48
atmp <=yl;
49
else 
50
--nach rechts
51
rightflag<='1';
52
leftflag <= '0';
53
yout<=yr;
54
atmp<= yr ;
55
end if;
56
57
58
end process;
59
60
end Behavioral;

beim Initialisierungsprocess darf ich atmp doch auch ändern

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


Lesenswert?

Marco schrieb:
> Jetzt soll ich ein Hauptmodul erstellen, das je nach Schalter an oder
> aus einen Vector zyklisch an eins der Module übergibt.
Ich würde das Eingangssignal immer an beide geben, und das Ergebnis 
der Schieber multiplexen. Und prompt kommt das Ergebnis:

Marco schrieb:
> Xst:528 - Multi-source in Unit <Hauptmod_Aufgabe1> on signal <a<7>>;
> this signal is connected to multiple drivers.
Da werden beide beide Ausgänge (a ist doch ein Ausgang, oder?) auf 1 
Signal geroutet:
1
  a=> atmp
Wie gesagt: du musst die Ausgänge multiplexen, nicht die Eingänge...

Hmm, seltsam, das mit dem a...
Zeig doch mal deine Schiebemodule auch noch.

Wofür ist der Takt im Prozess?
1
process(clock)
2
begin
3
--flags loeschen
4
rightflag<='0';
5
leftflag <= '0';
6
--nach links
7
if lr_dir = '0' then
8
rightflag<='0';
9
leftflag <= '1';
10
yout<=yl;
11
atmp <=yl;
12
else 
13
--nach rechts
14
rightflag<='1';
15
leftflag <= '0';
16
yout<=yr;
17
atmp<= yr ;
18
end if;
19
20
end process;
Im gesamten Prozess (der übrigens auch eingerückt werden könnte) wird 
der Takt nicht verwendet. Dafür fehlt lr_dir in der Sensitivliste. 
Fazit: die Simulation ist falsch.



BTW: was ist das für eine kuriose Aufgabe? Das ist in VHDL eigentlich 
ein Dreizeiler...
1
 yout <= a(6 downto 0) & '0' when lr_dir='1' else '0' & a(7 downto 1);

von Marco (Gast)


Lesenswert?

a ist der Vektor, der anliegt. Also ein Eingang

ich hatte mir das so gedacht:
-außen liegt ein 8 bit vector an. Diesen weise ich dem Signal atmp zu 
(wenn   das bit init gesetzt ist).
-atmp müsste jetzt ein Abbild von dem außen anligendem a enthalten ?
-atmp mappe ich wie von Bernd beschrieben auf die Eingänge der beiden 
Submodule
- kommt jetzt ein tackt (clock) wird der process stimuliert
- lr_dir bestimmt die Richtung in die geschoben werden soll. Je nach 
Zustand von lr _dir wird entweder das left oder das right flg gesetzt 
welche wiederum den process in dem jeweiligem Submodul stimulieren
(dort steht übrigens auch nichts anderes drin als das was du 
beschreibst)

ich habe die Initialisierung jetzt mit in den Process genommen und der 
fehler ist weg, alledings ist sieht mein Vector yout in der Simulation 
jetzt immer so aus: UUUUUUUU ....  0UUUUUUU oder UUUUUUOO . Das klappt 
also noch nicht so ganz mit der zuweisung von a auf atmp
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
6
entity Hauptmod_Aufgabe1 is
7
    --Vektorgröße kann eingestellt werden
8
    generic ( N: integer := 8);
9
    Port ( 
10
          lr_dir: in std_logic;
11
          clock : in STD_LOGIC;
12
        yout: out std_logic_vector (N-1 downto 0);
13
        a : in std_logic_vector (N-1 downto 0);
14
        init: in std_logic);
15
16
end Hauptmod_Aufgabe1;
17
18
architecture Behavioral of Hauptmod_Aufgabe1 is
19
signal yr ,yl ,atmp : std_logic_vector (N-1 downto 0);
20
signal leftflag, rightflag:std_logic;
21
22
begin
23
24
--Portmapping 
25
--das Flag aktiviert jeweils den shiftprocess in den Submodulen
26
left: entity work.shiftleft(Behavioral)
27
port map (a=> atmp , clock => leftflag, y=>yl);
28
right: entity work.shiftright(Behavioral) 
29
port map (a=> atmp , clock => rightflag , y=>yr);
30
31
32
33
34
process(clock)
35
36
  begin
37
38
  if init = '1' then
39
    atmp<=a;
40
  end if;
41
  
42
  --flags loeschen
43
  rightflag<='0';
44
  leftflag <= '0';
45
  --nach links
46
  if lr_dir = '0' then
47
    leftflag <= '1';
48
    yout<=yl;
49
    atmp <= yl;
50
  else 
51
  --nach rechts
52
    rightflag<='1';
53
    yout<=yr;
54
    atmp<= yr ;
55
  end if;
56
57
58
59
end process;
60
61
end Behavioral;

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


Lesenswert?

Marco schrieb:
> - kommt jetzt ein tackt (clock) wird der process stimuliert
Stimuliert? Naja, das kann man sich schön bildlich vorstellen...
Aber wichtiger ist doch: was muss wirklich rein in die Sensitivliste? 
Dort muss das rein, was eine Neuberechung nötig macht, nicht das was 
nicht wünschenswert und angenehm wäre. Un das sind alle 
Eingangssignale, deren Änderung das Ergebnis ändern können. Denn 
spätestens der Synthesizer schert sich einen feuchten Kehrricht um deine 
"Wunschsensitivliste". Den kümmert auch nicht, dass du eine Woche lang 
nur Käse zusammensimuliert hast...

Marco schrieb:
1
  begin
2
3
  if init = '1' then
4
    atmp<=a;            -- kann man ja mal ausprobieren
5
  end if;
6
  
7
  --flags loeschen
8
  rightflag<='0';
9
  leftflag <= '0';
10
  --nach links
11
  if lr_dir = '0' then
12
    leftflag <= '1';
13
    yout<=yl;
14
    atmp <= yl;         -- wird aber sofort von dem hier ....
15
  else 
16
  --nach rechts 
17
    rightflag<='1';
18
    yout<=yr;
19
    atmp<= yr ;         -- oder dem hier überschrieben
20
  end if;

1
port map (a=> atmp , clock => rightflag , y=>yr);
Was macht da ein clock?
Ist das wirklich ein Takt?
Was sollen denn diese left und right Flags?
Ich glaube nicht, dass deine bis dato unbekannten Module shiftleft und 
shiftright wirklich funktionieren...

von Marco (Gast)


Lesenswert?

clock soll ein externes Signal sein, dass den Process stimuliert 
(zyklisch shiften)

die right und left flags sind das clock Signal um die Processe der 
beiden anderen Module zu stimulieren.

Ich weiß, dass das alles von hinten durch die Brust ins Auge ist. So war 
aber die Aufgabenstellung

Hier mal exemplarisch eins der Submodule
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
use IEEE.NUMERIC_STD.ALL;
5
6
entity shiftleft is
7
generic(  N : integer := 8); --Bitbreite für den Ein- und Ausgang
8
    Port ( a : in  STD_LOGIC_VECTOR (N-1 downto 0);
9
           y : out  STD_LOGIC_VECTOR (N-1 downto 0);
10
        clock:in std_logic);
11
end shiftleft;
12
13
architecture Behavioral of shiftleft is
14
15
begin
16
-- es wird eine 0 an das Ende gesetzt und die Elemente 
17
-- von a um eine stelle nach links verschoben davor gesetzt
18
process(clock)
19
begin
20
y<= a(N-2 downto 0)& '0';
21
end process;
22
end Behavioral;

Ich bin für jede Anregung offen. Habe gerade meine zweite Vorlesung 
hinter mir und bin desshalb wie man sieht noch sehr unerfahren

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


Lesenswert?

Marco schrieb:
> clock soll ein externes Signal sein, dass den Process stimuliert
> (zyklisch shiften)
Das eine hat mit dem Anderen nichts zu tun. So wie du es beschrieben 
hast, ist in deinem Design kein Takt nötig. Das wird komplett 
kombinatorisch aufgebaut.

> Hier mal exemplarisch eins der Submodule
Wenn ichs mal direkt sagen darf: genauso ein Murks.

> Ich bin für jede Anregung offen. Habe gerade meine zweite Vorlesung
> hinter mir und bin desshalb wie man sieht noch sehr unerfahren
Leih dir das Buch "VHDL-Synthese" von Reichardt&Schwarz aus. Dir wird 
ein Licht aufgehen...

> process(clock)
Wenn ein Prozess so anfängt, dann folgt in der Praxis zwingend sowas:
1
  begin
2
     if rising_edge(clock) then ...
Oder wenigstens das:
1
  begin
2
     if clock'event and clock='1' then ...
Das gibt dann ein getaktetes Bauteil: ein Flipflop.

von Marco (Gast)


Lesenswert?

Wie gesagt ich stehe noch ziemlich am Anfang. Das Buch werde ich mir 
ausleihen.

Um ehrlich zu sein bin ich gerade nur noch viel mehr verwirrt.
Die Anforderung war es ja eine zyklische Verschiebung durchzuführen. Ich 
könnte jetzt mal einen kleinen Wink mit dem Zaunpfal vertragen wie das 
denn aussehen müsste.

von Duke Scarring (Gast)


Lesenswert?

Marco schrieb:
> use IEEE.NUMERIC_STD.ALL;
Nur für die Schönheit: Solange wie Du keine 'echten' Berechnungen 
machst, kannst Du diese Bibliothek weglassen.

Duke

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


Lesenswert?

Marco schrieb:
> Die Anforderung war es ja eine zyklische Verschiebung durchzuführen.
Was bedeutet "zyklisch"?
Eine "zyklische" Verschiebung könnte auch ein einfaches "Rotieren sein". 
Oder es könnte sein, dass um 1 Stelle pro Takt weitergeschoben wird, ob 
im Kreis oder geradeaus...

> Ich könnte jetzt mal einen kleinen Wink mit dem Zaunpfal vertragen
> wie das denn aussehen müsste.
Bisher ist nur die durch dich vorgefilterte Aufgabe zu sehen. Wie sieht 
die Originalaufgabe aus?

von Marco (Gast)


Lesenswert?

Ich glaube der Wink war genau das was du gerade als erstes geschrieben 
hast.
Nachdem ich mal nach zyklischer verschiebung gegooglet hatte, ist mir 
das auch aufgefallen

Zyklisch bedeutet wahrscheinlich, dass der Vektor rotiert bzw das 
abgeschnittene Bit wieder drankommt.

Ich gebe die Aufgabe mal sinngemäß wieder, weil ich nicht weiß was mein 
Prof. davon halten würde wenn ich sie reinkopiere oder hochlade. Auf 
wunsch könnte ich sie dir auch per Mail schicken.

Aufgabe
Allg.
Es soll ein Barrelshifter implementiert werden, der einen N-Stelligen 
Eingansbus um S Stellen !!!ZYKLISCH verschiebt!!!. Dabei soll man die 
Verschieberichtung angeben können

Aufgabe 1

1.1 Erstellen sie 2 VHDL Module die je eine rechts bzw Linksseitige 
Verschiebung durchführen
1.2 Erstellen Sie ein Hauptmodule, welches die Module um die zyklisch 
durchzuführen
(hier war mein Fehler..ich sollte die Aufgaben richtig lesen!!!)
1.3 Testbench
1.4 Isim
1.5 aufs Board

2. Erweiterung um S (Anzahl der zu versch. Stellen)
wieder aufs Board mit LCD

3.Erweiterung auf 32 Bit


ich würde jetzt aber rein aus Interesse trotzdem mal ganz gerne wissen, 
wie das auszusehen hätte, wäre mit zyklisch getacktet gemeint

Ich habe alleine heut ganze 5 Stunden meines Lebens daran verbracht :D


Meine Lösung jetzt:

Hauptmodul:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
6
7
8
entity Hauptmod_Aufgabe1 is
9
    --Vektorgröße kann eingestellt werden
10
    generic ( N: integer := 8);
11
    Port ( 
12
          lr_dir: in std_logic;
13
        yout: out std_logic_vector (N-1 downto 0);
14
        a : in std_logic_vector (N-1 downto 0));
15
16
end Hauptmod_Aufgabe1;
17
18
architecture Behavioral of Hauptmod_Aufgabe1 is
19
signal yr ,yl  : std_logic_vector (N-1 downto 0);
20
21
22
begin
23
24
--Portmapping 
25
--das Flag aktiviert jeweils den shiftprocess in den Submodulen
26
left: entity work.shiftleft(Behavioral)
27
port map (a=> a , y=>yl);
28
right: entity work.shiftright(Behavioral) 
29
port map (a=> a  , y=>yr);
30
31
with lr_dir select 
32
yout<=yl when '0',
33
yr when others;
34
35
end Behavioral;

exemplarisch Submodul links:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
use IEEE.NUMERIC_STD.ALL;
5
6
entity shiftleft is
7
generic(  N : integer := 8); --Bitbreite für den Ein- und Ausgang
8
    Port ( a : in  STD_LOGIC_VECTOR (N-1 downto 0);
9
           y : out  STD_LOGIC_VECTOR (N-1 downto 0));
10
end shiftleft;
11
12
architecture Behavioral of shiftleft is
13
14
begin
15
16
y<= a(N-2 downto 0)& a(N-1);
17
18
end Behavioral;

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


Lesenswert?

Soweit, so gut...
Jetzt ist aber ein Barrelshifter etwas, das nicht nur um 1 Position, 
sondern um beliebig viele Positionen verschieben kann. Also müsste man 
jetzt neben der Richtung noch die Anzahl der zu rotierenden Positionen 
mit angeben. Und eigentlich ist bei einer Rotation die Richtung egal, 
denn egal, ob du ein Karussell links oder rechts rum drehst, du kannst 
beides mal das selbe erreichen. Man könnte also abhängig von der Länge 
des Vektors das Richtungsbit einfach als Vorzeichen für die Rotation 
sehen...

Als Basis für so einen Rotierer käme man dann z.B. auf sowas wie im 
Beitrag "Re: Rotate BitVector"

Etwas vereinfacht sähe dein Links-Rotierer also so aus:
1
 process (inp, n) 
2
 variable i : integer;
3
 begin
4
    -- um wieviel soll rotiert werden?
5
    i := to_integer(unsigned(n));  
6
    -- los gehts: nach links rotieren
7
    outp <= inp(inp'left-i downto 0) & inp(inp'left downto inp'left+1-i);        
8
 end process;

Und mit einer kleinen Korrektur wird er bidirektional:
1
 process (inp, n, rechts) 
2
 variable i : integer;
3
 begin
4
    -- um wieviel soll rotiert werden?
5
    i := to_integer(unsigned(n));  
6
    -- bei richtungsumkehr korrigieren
7
    if (rechts=1) then 
8
       i:=inp'length-i; 
9
    end if;
10
    -- los gehts: rotieren
11
    outp <= inp(inp'left-i downto 0) & inp(inp'left downto inp'left+1-i);        
12
 end process;

Marco schrieb:
> ich würde jetzt aber rein aus Interesse trotzdem mal ganz gerne wissen,
> wie das auszusehen hätte, wäre mit zyklisch getacktet gemeint
Ja, eben genau gleich. Nur wäre noch ein Register (oder ein paar davon) 
mit drin...

von Marco (Gast)


Lesenswert?

Lothar Miller schrieb:
> Jetzt ist aber ein Barrelshifter etwas, das nicht nur um 1 Position,
> sondern um beliebig viele Positionen verschieben kann. Also müsste man
> jetzt neben der Richtung noch die Anzahl der zu rotierenden Positionen
> mit angeben

genau! Das, was ich gepostet habe war Aufgabenteil 1. Bei 2 sollte man 
das denn erweitern, sodass die Anzahl der zu verschibenen Bit angeben 
konnte. Hab das so ähnlich gemacht wie du beschreibst. Es war gefordert, 
dass man die die Anzahl mit 4 Dip Schaltern (0-7) einstellen kann.

Vielen Dank für die Hilfe

PS: Das Buch, welches du mir empfolen hattes war nicht verfügbar. Habe 
es mir vorgemerkt ;)

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.