Forum: FPGA, VHDL & Co. VGA Core - Problem mit Text


von Kampi (Gast)


Lesenswert?

Hallo,

ich habe meinen VGA-Core weiter gebaut und eine Textausgabe 
implementiert.
Allerdings werden die Buchstaben spiegelverkehrt angezeigt und ich kann 
mir keinen Reim drauf machen woran das liegt.... :(

Mein Font-ROM sieht so aus:
1
----------------------------------------------------------------------------------
2
-- Company:         www.kampis-elektroecke.de
3
-- Engineer:        Daniel Kampert
4
-- 
5
-- Create Date:     10.08.2014 23:24:19
6
-- Design Name: 
7
-- Module Name:     Font_ROM - Font_ROM
8
-- Project Name: 
9
-- Target Devices:  XC7Z010CLG400-1
10
-- Tool Versions:   Vivado 2014.2
11
-- Description:     ASCII ROM
12
-- 
13
-- Dependencies: 
14
-- 
15
-- Revision:
16
-- Revision         0.01 - File Created
17
-- Additional Comments:
18
-- 
19
----------------------------------------------------------------------------------
20
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
use IEEE.NUMERIC_STD.ALL;
24
25
-- Uncomment the following library declaration if instantiating
26
-- any Xilinx leaf cells in this code.
27
--library UNISIM;
28
--use UNISIM.VComponents.all;
29
30
entity Font_ROM is
31
    Port (  Clock : in STD_LOGIC;
32
            Adresse : in STD_LOGIC_VECTOR(4 downto 0);
33
            Data : out STD_LOGIC_VECTOR(7 downto 0)    
34
            );
35
end Font_ROM;
36
37
architecture Font_ROM_Arch of Font_ROM is
38
39
    constant Addr_Width : integer := 5;
40
    constant Data_Width : integer := 8;
41
42
    signal ROM_Adresse : std_logic_vector((Addr_Width - 1) downto 0);
43
    type Character_Array is array(0 to (2**Addr_Width) - 1) of std_logic_vector((Data_Width - 1) downto 0); 
44
45
    constant Character : Character_Array := 
46
    ( 
47
        "00011000",
48
        "00111100",
49
        "01111110",
50
        "11111111",
51
        "11111111",
52
        "01111110",    
53
        "00111100", 
54
        "00011000", 
55
        
56
        "00000000",
57
        "00111100",
58
        "11000011",
59
        "11000011",
60
        "11000011",
61
        "11111111",    
62
        "11000011", 
63
        "11000011", 
64
        
65
        "00000000",
66
        "11111100",
67
        "11000011",
68
        "11000011",
69
        "11111100",
70
        "11000011",
71
        "11000011",    
72
        "11111100", 
73
        
74
        "00000000",
75
        "00111100",
76
        "11000011",
77
        "11000000",
78
        "11000000",
79
        "11000000",    
80
        "11000011", 
81
        "00111100"                        
82
    );
83
84
begin
85
    process(Clock)
86
    
87
    begin
88
        if(rising_edge(Clock)) then
89
            ROM_Adresse <= Adresse;
90
        end if;
91
    end process;
92
    
93
    Data <= Character(to_integer(unsigned(ROM_Adresse)));
94
    
95
end Font_ROM_Arch;

Und meine Bildausgabe so:
1
----------------------------------------------------------------------------------
2
-- Company:         www.kampis-elektroecke.de
3
-- Engineer:        Daniel Kampert
4
-- 
5
-- Create Date:     02.08.2014 13:17:51
6
-- Design Name: 
7
-- Module Name:     VGA_Top - VGA_Top_Arch
8
-- Project Name: 
9
-- Target Devices:  XC7Z010CLG400-1
10
-- Tool Versions:   Vivado 2014.2
11
-- Description:     VGA Interface for a 640 x 480 Pixel Screen
12
-- 
13
-- Dependencies: 
14
-- 
15
-- Revision:
16
-- Revision         0.01 - File Created
17
-- Additional Comments:
18
-- 
19
----------------------------------------------------------------------------------
20
21
library IEEE;
22
use IEEE.STD_LOGIC_1164.ALL;
23
24
-- Uncomment the following library declaration if using
25
-- arithmetic functions with Signed or Unsigned values
26
use IEEE.NUMERIC_STD.ALL;
27
28
-- Uncomment the following library declaration if instantiating
29
-- any Xilinx leaf cells in this code.
30
--library UNISIM;
31
--use UNISIM.VComponents.all;
32
33
entity VGA_Top is
34
    Port (  Color : out STD_LOGIC_VECTOR(15 downto 0);
35
            HSync : out STD_LOGIC;
36
            VSync : out STD_LOGIC;
37
            Output : out STD_LOGIC_VECTOR(2 downto 0);
38
            Reset : in STD_LOGIC;
39
            Clock : in STD_LOGIC;
40
            Button : in STD_LOGIC_VECTOR(3 downto 0)           
41
            );
42
end VGA_Top;
43
44
architecture VGA_Top_Arch of VGA_Top is
45
46
    constant Char_Size : integer := 8;
47
48
    -- Clocksignale
49
    signal Clock_VGA : std_logic;
50
    signal Clock_1250 : std_logic;
51
52
    -- Koordinaten des Zeigers auf dem Bildschirm
53
    signal Pos_x : std_logic_vector(9 downto 0) := "0001100100";                
54
    signal Pos_y : std_logic_vector(9 downto 0) := "0001100100"; 
55
    
56
    -- Font ROM
57
    signal Character_No : std_logic_vector(1 downto 0);
58
    signal Row_Addr : std_logic_vector(2 downto 0);
59
    signal ROM_Col : std_logic_vector(2 downto 0);
60
    signal ROM_Addr : std_logic_vector(4 downto 0);
61
    signal ROM_Data : std_logic_vector(7 downto 0);
62
    signal ROM_Bit : std_logic;
63
    
64
    -- Positionen
65
    signal Pos_x_l : integer := 8;
66
    signal Pos_y_t : integer := 8;
67
    signal Pos_x_r : integer := Pos_x_l + Char_Size - 1;
68
    signal Pos_y_b : integer := Pos_y_t + Char_Size - 1;
69
     
70
    -- Enable Signale für die Formen
71
    signal Text_on : std_logic;
72
    
73
    -- Button 
74
    signal Button_Deb1 : std_logic;
75
    signal Button_Deb2 : std_logic;
76
    signal Button_Deb3 : std_logic;
77
    signal Button_Deb4 : std_logic;   
78
79
    signal Zaehler : integer;
80
    
81
    -- Systemsignale
82
    signal Lock : std_logic;
83
    signal Test : std_logic;
84
85
    -- Erzeugung des 25,175MHz Taktes
86
    component System is
87
        Port (  Clock_In : in STD_LOGIC;
88
                Clock_Reset : in STD_LOGIC;
89
                Clock_Locked : out STD_LOGIC;
90
                Clock_Out : out STD_LOGIC
91
                );
92
    end component System;
93
    
94
    -- Einbinden des VGA-Controllers
95
    component VGA_Controller is
96
        Port (  HSync : out STD_LOGIC;
97
                VSync : out STD_LOGIC;
98
                Clock_VGA : in STD_LOGIC;
99
                Reset : in STD_LOGIC;
100
                x_out : out STD_LOGIC_VECTOR(9 downto 0);                
101
                y_out : out STD_LOGIC_VECTOR(9 downto 0) 
102
                );
103
    end component VGA_Controller;  
104
    
105
    component Clock_Div is
106
        Port (  Clock_In : in STD_LOGIC;
107
                Clock_Out : out STD_LOGIC;
108
                Divider : in integer
109
                );
110
    end component Clock_Div;  
111
    
112
    component Font_ROM is
113
        Port (  Clock : in STD_LOGIC;
114
                Adresse : in STD_LOGIC_VECTOR(4 downto 0);
115
                Data : out STD_LOGIC_VECTOR(7 downto 0)    
116
                );
117
    end component Font_ROM;
118
    
119
    component Debounce is
120
        Port (  Input : in  STD_LOGIC;
121
                Output : out  STD_LOGIC;
122
                Clock : in  STD_LOGIC;
123
                Debouncetime : in integer
124
                );
125
    end component Debounce;
126
127
begin
128
    
129
    Clock_25MHz     : System port map (Clock, '1', Lock, Clock_VGA);
130
    VGA_Core        : VGA_Controller port map (HSync, VSync, Clock_VGA, Reset, Pos_x, Pos_y);
131
    Clock_1k2Hz     : Clock_Div port map (Clock_VGA, Clock_1250, 10000);    
132
    Font            : Font_ROM port map (Clock_VGA, ROM_Addr, ROM_Data);
133
    
134
    Button_1        : Debounce port map (Button(0), Button_Deb1, Clock_1250, 50);
135
    Button_2        : Debounce port map (Button(1), Button_Deb2, Clock_1250, 50);
136
    
137
    -- Wenn Position erreicht, Enable-Signal auf High setzen
138
    Text_on <=
139
        '1' when (Pos_x_l <= to_integer(unsigned(Pos_x))) and (to_integer(unsigned(Pos_x)) <= Pos_x_r) and
140
                 (Pos_y_t <= to_integer(unsigned(Pos_y))) and (to_integer(unsigned(Pos_y)) <= Pos_y_b) else '0';
141
    
142
    -- ROM auslesen
143
    Row_Addr <= Pos_y(2 downto 0);
144
    ROM_Addr <= Character_No & Row_Addr;
145
    
146
    ROM_Col <= Pos_x(2 downto 0);
147
    ROM_Bit <= ROM_Data(to_integer(unsigned(ROM_Col)));
148
    
149
    Character_No <= std_logic_vector(to_unsigned(Zaehler, Character_No'length));  
150
    
151
    process(Button_Deb1)
152
    begin
153
        if(rising_edge(Button_Deb1)) then
154
            Zaehler <= Zaehler + 1;
155
        end if;
156
    end process;
157
    
158
    -- Formen am Bildschirm ausgeben
159
    process(Clock_VGA) 
160
    begin 
161
        if(rising_edge(Clock_VGA)) then
162
163
            Color <= x"0000";
164
            
165
            if((ROM_Bit = '1') and (Text_on = '1')) then
166
                Color <= x"FC00";
167
            end if;
168
           
169
        end if;
170
    end process;
171
172
    -- Betriebsstatus
173
    Output(2) <= Button_Deb1;
174
    Output(1) <= Lock;
175
    Output(0) <= Reset;
176
    
177
end VGA_Top_Arch;

Hat jemand eine Idee warum die Buchstaben spiegelverkehrt auf dem 
Display angezeigt werden?
Danke schön :)

Gruß
Daniel

von Lattice User (Gast)


Lesenswert?

In deiner Character_Array ist das linke Bit, das mit der höcshten 
Bitnummern, ausgegeben wird aber Bit 0 zuerst.

Also entweder den Character_Array umdefinieren:
1
type Character_Array is array(0 to (2**Addr_Width) - 1) of std_logic_vector(0 to (Data_Width - 1));

oder in der anderen Reihenfolge ausgeben:
1
ROM_Bit <= ROM_Data(7-to_integer(unsigned(ROM_Col)));

von Kampi (Gast)


Lesenswert?

Ahhh :o
Und ich suche mir am Code einen Wolf...
Danke für den Hinweis :)

von Kampi (Gast)


Lesenswert?

Alles klar, das war das Problem.
Dann habe ich direkt noch eine weitere Frage...
Ich gebe im Moment ja nur einen einzelnen Buchstaben aus.
Wie könnte ich das am besten realisieren, wenn ich einen Text ausgeben 
will?
Für die Textausgabe müsste ich ja nach dem ersten Buchstaben in der 
Position um 8 Stellen (sprich 1 Zeichen) weiter springen und dann die 
Buchstabennummer verändern (was ich jetzt durch einen Taster mache).
Wie könnte ich dieses Weiterhüpfen um 8 Stellen bewerkstelligen, bzw. 
mit was?
Da fehlt mir im Moment so etwas die Idee wie ich da ran gehen kann...

Danke nochmals für die Hilfe!

von J. S. (engineer) Benutzerseite


Lesenswert?

Du brauchst ein Zeichen-RAM, in welches der Code eingegeben wird. In 
meinem Fall mache ich das so, dass ich es in Echtzeit ausserhalb des 
aktiven Videos bescheiben lasse. Das RAM musst Du dann mit 1/8tel oder 
1/16 der Video-Adressen einblenden und den Code durch einen Interpreter 
schicken. Der produziert in Echtzeit den Pixel und entscheidet oder er 
an oder aus ist. Gepüft wird mit einer Maske, aus der jeweils das 0...1 
Bit verglichen wird.

von Kampi (Gast)


Lesenswert?

mmh verstehe nicht so ganz wie du das meinst...

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


Lesenswert?

Kampi schrieb:
> mmh verstehe nicht so ganz wie du das meinst...
Du musst die nötigen Zeichen darstellen können, und dann musst du dir 
einen Text anlegen, der mit diesen Zeichen dargestellt wird. Genau so 
wird es z.B. auch bei diesem Text, den du hier gerade liest, auch 
gemacht: ich tippe keinen Pixelhaufen ein, sondern ASCII-Zeichen. Über 
eine ASCII-Tabelle kann dann dein Computer nachsehen, was er darstellen 
muss, wenn im Text ein 'a' kommt, oder wenn ein 'b' kommt.

Du kannst bisher die Zeichen darstellen. Und jetzt brauchst du einen 
Speicher, der beinhaltet, in welcher Reihenfolge diese zeichen 
dargestellt werden müssen.

Denk nochmal nach. Du kommst sicher drauf. Es ist nicht allzu 
schwierig...

: Bearbeitet durch Moderator
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.