Bauen Sie Ihren Chip! (5) Juni 2013

Forum zum ELEKTOR-FPGA-Projekt

Postby ag » Mon May 20, 2013 12:00 am

die Behandlung bzw. das Übergehen von das Umsetzung in den Sieben-Segment-Code ist mir doch zu kurz ausgefallen. Da ich keine common cathode Anzeigen habe und daher common anode Anzeigen verwende, habe ich im bcd_to_7segment.vhd entsprechende Negationen wie folgt eingesetzt:

entity bcd_to_7segment is
Port ( bcd : in STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0) );
end bcd_to_7segment;

architecture Behavioral of bcd_to_7segment is

begin
with bcd select
-- A=bit0, G=bit6
segments <= not "0111111" when "0000",
not "0000110" when "0001",
not "1011011" when "0010",
not "1001111" when "0011",
not "1100110" when "0100",
not "1101101" when "0101",
not "1111101" when "0110",
not "0000111" when "0111",
not "1111111" when "1000",
not "1101111" when "1001",
not "1000000" when others;
end Behavioral;


Dies funktioniert zwar einwandfrei, aber diese Umsetzung finde ich unästhetisch und auch ökonomisch wenig zufriedenstellend. Lieber hätte ich eine Umsetzung die in etwa so aussieht:

entity bcd_to_7segment is
Port ( bcd : in STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0) );
end bcd_to_7segment;

architecture Behavioral of bcd_to_7segment is

begin
with bcd select
-- A=bit0, G=bit6
segments <= "0111111" when "0000",
"0000110" when "0001",
"1011011" when "0010",
"1001111" when "0011",
"1100110" when "0100",
"1101101" when "0101",
"1111101" when "0110",
"0000111" when "0111",
"1111111" when "1000",
"1101111" when "1001",
"1000000" when others;
-- Bits umkippen für common anode Anzeigen
segments <= not segments;

end Behavioral;


Bei dieser Versuch bekomme ich folgende Fehlermeldung:

Parameter segments of mode out can not be associated with a formal parameter of mode in.


Wenn ich versuche ein Variable für die Negation zu deklarieren:


entity bcd_to_7segment is
Port ( bcd : in STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0) );
end bcd_to_7segment;

architecture Behavioral of bcd_to_7segment is
variable negation : std_logic_vector (6 downto 0);
begin
with bcd select
-- A=bit0, G=bit6
segments <= "0111111" when "0000",
"0000110" when "0001",
"1011011" when "0010",
"1001111" when "0011",
"1100110" when "0100",
"1101101" when "0101",
"1111101" when "0110",
"0000111" when "0111",
"1111111" when "1000",
"1101111" when "1001",
"1000000" when others;
-- Bits umkippen für common anode Anzeigen
negation <= not segments;
segments <= negation;

end Behavioral;


bekomme ich folgende Fehlermeldung:

Only SHARED variables can be declared here.


und wenn ich die Variable definiere nach dem begin:


entity bcd_to_7segment is
Port ( bcd : in STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0) );
end bcd_to_7segment;

architecture Behavioral of bcd_to_7segment is

begin
variable negation : std_logic_vector (6 downto 0);

with bcd select
-- A=bit0, G=bit6
segments <= "0111111" when "0000",
"0000110" when "0001",
"1011011" when "0010",
"1001111" when "0011",
"1100110" when "0100",
"1101101" when "0101",
"1111101" when "0110",
"0000111" when "0111",
"1111111" when "1000",
"1101111" when "1001",
"1000000" when others;
-- Bits umkippen für common anode Anzeigen
negation <= not segments;
segments <= negation;

end Behavioral;

bekomme ich folgende Fehlermeldung:

parse error, unexpected VARIABLE

Desselbe Fehler auch beim definieren der Variable nach der "with bcd select" Umsetzung.

Wenn ich die Deklaration zwischen "with bcd select" und "segemts <= "0111111" when ...." einsetzt, bekomme ich:

parse error, unexpected VARIABLE, expecting OPENPAR or IDENTIFIER or STRING_LITERAL


Es muss doch möglich sein, einfache Negation durchzuführen, oder? Hat jemand eine Idee?

Nachtrag:

ich habe es herausgefunden:

entity bcd_to_7segment is
Port ( bcd : in STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0) );
end bcd_to_7segment;

architecture Behavioral of bcd_to_7segment is
signal common_cathode : std_logic_vector (6 downto 0);

begin
with bcd select
-- A=bit0, G=bit6
common_cathode <= "0111111" when "0000",
"0000110" when "0001",
"1011011" when "0010",
"1001111" when "0011",
"1100110" when "0100",
"1101101" when "0101",
"1111101" when "0110",
"0000111" when "0111",
"1111111" when "1000",
"1101111" when "1001",
"1000000" when others;

-- Bits umkippen für common anode Anzeigen
segments <= not common_cathode;

end Behavioral;




Vielen Dank und viele Grüße,
Ag
Attachments
20130520-194203.jpg
20130520-211804.jpg
Ag
ag
 
Posts: 532
Joined: Thu Jan 02, 2014 10:37 am

Postby moki » Fri Jun 21, 2013 12:00 am

Hallo Ag,

eine weitere Möglichkeit wäre es, deine segments-Zuweisung zu verändern (in diesem Falle zu negieren):

entity bcd_to_7segment is
Port ( bcd : in STD_LOGIC_VECTOR (3 downto 0);
segments : out STD_LOGIC_VECTOR (6 downto 0) );
end bcd_to_7segment;

architecture Behavioral of bcd_to_7segment is

begin

with bcd select
-- A=bit0, G=bit6
segments <= "1000000" when "0000", -- vorher: "0111111" when "0000",
"1111001" when "0001", -- vorher: "0000110" when "0001",
"0100100" when "0010", -- vorher: "1011011" when "0010",
"0110000" when "0011", -- vorher: "1001111" when "0011",
"0011001" when "0100", -- vorher: "1100110" when "0100",
"0010010" when "0101", -- vorher: "1101101" when "0101",
"0000010" when "0110", -- vorher: "1111101" when "0110",
"1111000" when "0111", -- vorher: "0000111" when "0111",
"0000000" when "1000", -- vorher: "1111111" when "1000",
"0010000" when "1001", -- vorher: "1101111" when "1001",
"0111111" when others; -- vorher: "1000000" when others;
end Behavioral;


Ich hoffe, ich hab mich jetzt nicht vertippt.

Viele Grüße
moki
 
Posts: 2
Joined: Fri Jan 03, 2014 2:02 pm

Postby ag » Fri Jun 21, 2013 12:00 am

Hallo Moki,

Ich hoffe, ich hab mich jetzt nicht vertippt.


Ja, genau! Zu viele Möglichkeiten, etwas falsch to machen Deine Lösung entspricht meine erste Ansatz. Da habe ich es mir allerdings mit "not" noch viel einfacher gemacht, aber selbst das war mir zu unästhetisch Deshalb habe ich nach eine elegantere Lösung gesucht (und gefunden).

Viele Grüße,
Ag
Ag
ag
 
Posts: 532
Joined: Thu Jan 02, 2014 10:37 am

Postby moki » Sat Jun 29, 2013 12:00 am

Wenn ich den Beitrag vorher gesehen hätte, wärst du eher schlauer gewesen.

In VHDL haben OUTs die Angewohnheit, dass man sie nicht lesen kann sondern nur zuweisen.
Es gibt eigentlich drei Möglichkeiten, das Problem zu lösen (die mir im Moment einfallen):
- du definierst statt einem Ausgang ein INOUT (was aber ziemlich unschön ist)
- du machst es mit einer variable (wie dein Versuch auch war), musst diese aber im Prozess definieren, in etwa so:

count: process (x)  variable cnt : integer := -1;begin  cnt:=cnt+1;end process;


Diese Lösung gefällt mir persönlich auch nicht so wirklich

- oder du machst es mit einem Signal, wie du es am Ende gelöst hast

Viele Grüße,
Moki
moki
 
Posts: 2
Joined: Fri Jan 03, 2014 2:02 pm


Return to Rund um FPGAs

Who is online

Users browsing this forum: No registered users and 1 guest