Forum: FPGA, VHDL & Co. Probleme mit std_logic_vector und unsigned


von Nobbi (Gast)


Lesenswert?

Hallo,
ich habe vor kurzem gelesen, dass man bei der Verwendung von 
ieee.numeric_std.all die Signale in der Entity trotzdem als 
std_logic_vector definieren sollte. Nun habe ich mein Modul umgebaut und 
aus meinen unsigned Signale std_logic_vector gemacht. Prinzipiell sollte 
das doch das Selbe sein, oder? Immerhin wird doch der std_logic_vector 
in diesem Fall auch als unsigned deklariert. Liege ich da richtig?
Jetzt habe ich bei meiner Berechnung immer wieder eine Fehlermeldung:
"RESIZE type specified in Qualified Expression must match 
std_logic_vector type that is implied for expression by context"
Bei folgender Berechnung:
1
ENTITY 
2
...
3
ta       : IN STD_LOGIC_VECTOR(BIT_SIZE - 1 DOWNTO 0);
4
kr       : IN STD_LOGIC_VECTOR(BIT_SIZE - 1 DOWNTO 0);
5
dividend : OUT STD_LOGIC_VECTOR(BIT_SIZE - 1 DOWNTO 0);
6
...
7
END ENTITY;
8
...
9
dividend <= RESIZE(kr * ta, BIT_SIZE); -- BIT_SIZE := 16
Bei der vorherigen Deklaration aller Signale als unsigned gab es keine 
Probleme.
Des weiteren hätte ich noch eine prinzipielle Frage zu numeric_std.
Wie programmiert man am Besten mit dieser library? Also sollte man alle 
Signaldeklarationen in der Entity als std_logic beschreiben und dann im 
Code den cast machen oder schon zu beginn unterscheiden ob signed oder 
unsigned?
Vielen Dank.

von Nobbi (Gast)


Lesenswert?

So, habe nur selbst eine Möglichkeit gefunden das Problem zu lösen.
1
dividend <= std_logic_vector(RESIZE(UNSIGNED(kr) * UNSIGNED(tv), BIT_SIZE));

Nur kommt mir die Lösung nicht sonderlich geschickt vor. Immerhin, wenn 
ich das nun durch meinen gesamten Code so durchziehe, dann besteht der 
ja zur hälfte nur noch aus typecasts. Ist es hier nicht sinnvoller die 
Entity wie folgt zu deklarieren?
1
ENTITY 
2
...
3
ta       : IN UNSIGNED(BIT_SIZE - 1 DOWNTO 0);
4
kr       : IN UNSIGNED(BIT_SIZE - 1 DOWNTO 0);
5
dividend : OUT UNSIGNED(BIT_SIZE - 1 DOWNTO 0);
6
...
7
END ENTITY;

Das Synthesetool macht das mit, aber bei der Simulation mit ModelSim 
bekomme ich Probleme, da mein TopDesign diesem Modul Signale vom Typ 
std_logic_vector zuweist und ich in dem Modul bis vor kurzem noch 
UNSIGNED verwendet habe.
Wäre super wenn mir da vielleicht jemand bisschen helfen könnte.
Danke

von Matthias (Gast)


Lesenswert?

Der Typfehler sollte klar sein, die resize will vmtl einen unsigned und 
du gibst einen std_logic_vector. Du kannst problemlos einen 
std_logic_vector slv mit unsigned(slv) zu einem unsigned machen.

Bzgl prinzipiellem Umgang würde ich innerhalb von entities alles, bei 
dem ein numerischer Datentyp Sinn macht als unsigned deklarieren, den 
Rest als std_logic_vector. Also zb Zähler auf die du Inkrement- oder 
andere numerische Operationen machst als unsigned, dann geht die 
Rechnerei ohne casten. Ein Register, in dem du einzelne Bits abfragst 
als std_logic_vector.

An Port-Grenzen würde ich nur std_logic_vector verwenden.

lg
Matthias

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


Lesenswert?

Nobbi schrieb:
> Nur kommt mir die Lösung nicht sonderlich geschickt vor.
Warum? Ist doch sauber... ;-)
VHDL ist eben mit der strengen Typprüfung etwas geschwätzig.

> Das Synthesetool macht das mit,
Die Synthese kann einiges, was nicht ganz VHDL-konform ist...
> aber bei der Simulation mit ModelSim
> bekomme ich Probleme, da mein TopDesign diesem Modul Signale vom Typ
> std_logic_vector zuweist und ich in dem Modul bis vor kurzem noch
> UNSIGNED verwendet habe.
Klar, wieder die Typprüfung: unsigned /= std_logic_vector

Ich mache das normalerweise ganz einfach nach einem strengen 
Formalismus:
1
ENTITY 
2
...
3
ta       : IN STD_LOGIC_VECTOR(BIT_SIZE - 1 DOWNTO 0);
4
kr       : IN STD_LOGIC_VECTOR(BIT_SIZE - 1 DOWNTO 0);
5
dividend : OUT STD_LOGIC_VECTOR(BIT_SIZE - 1 DOWNTO 0);
6
...
7
END ENTITY;
8
...
9
signal lta       : UNSIGNED(BIT_SIZE - 1 DOWNTO 0);
10
signal lkr       : UNSIGNED(BIT_SIZE - 1 DOWNTO 0);
11
signal ldividend : UNSIGNED(BIT_SIZE - 1 DOWNTO 0);
12
...
13
-- Signalumwandlungen
14
lta <= unsigned(ta);         
15
lkr <= unsigned(kr);
16
dividend <= std_logic_vector(ldividend);
17
...
18
ldividend <= RESIZE(lkr * lta, BIT_SIZE); -- BIT_SIZE := 16
19
...

von Nobbi (Gast)


Lesenswert?

Vielen Dank für die Antworten.
Ich denke ich werde das jetzt auch so durchführen, dass ich in der 
Entity die Signale als std_logic_vector deklariere und dann im Modul das 
so erledige wie lkmiller.
Danke nochmal ;-).

von Duke Scarring (Gast)


Lesenswert?

@Nobbi:
Solange wie Du im FPGA bleibst, würde ich unsigned/signed verwenden, 
wenn das Signal als Zahl interpretiert wird.

1. Spart man sich das casten und

2. weiss dann der nächste Designer (das könntest auch Du sein), der was 
am Modul ändern muß, gleich wie das Signal zu interpretieren ist.

Ich habe inzwischen immer ein top.vhd in dem die ganzen Pins deklariert 
sind. Die Logik wird in einem eigenen Block zusammengefasst und im 
top-Level instanziiert. Die Castings zwischen der Außenwelt (std_logic) 
und der inneren Logik erfolgen dann im top-Level.
Außerdem lassen sich dort wunderbar DDR- und Tristate-Treiber 
unterbringen.

Somit sind das ucf-File und die Entity von dem top-Modul für 
verschiedene Projekte (auf der selben Hardware) nutzbar.

Duke

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.