Line 65... |
Line 65... |
|
|
port (
|
port (
|
i_clk : in std_logic; -- must be 50MHz
|
i_clk : in std_logic; -- must be 50MHz
|
i_reset : in std_logic;
|
i_reset : in std_logic;
|
|
|
-- background color (b/w)
|
|
i_background : in std_logic;
|
|
|
|
-- cross cursor
|
|
i_cursor_color : in std_logic_vector(2 downto 0);
|
|
i_cursor_x : in std_logic_vector(10 downto 0);
|
|
i_cursor_y : in std_logic_vector(9 downto 0);
|
|
|
|
-- vga horizontal and vertical sync
|
-- vga horizontal and vertical sync
|
o_h_sync : out std_logic;
|
o_h_sync : out std_logic;
|
o_v_sync : out std_logic;
|
o_v_sync : out std_logic;
|
|
|
-- horizontal and vertical sync enable (allow power saving on ?VESA? Monitors)
|
-- horizontal and vertical sync enable (allow power saving on ?VESA? Monitors)
|
Line 98... |
Line 90... |
i_chr_rst : in std_logic;
|
i_chr_rst : in std_logic;
|
|
|
-- waveform RAM memory
|
-- waveform RAM memory
|
i_wav_d : in std_logic_vector(15 downto 0);
|
i_wav_d : in std_logic_vector(15 downto 0);
|
i_wav_we : in std_logic;
|
i_wav_we : in std_logic;
|
--i_clockA : IN std_logic;
|
i_wav_clk : IN std_logic;
|
i_wav_addr : in std_logic_vector(9 downto 0) --;
|
i_wav_addr : in std_logic_vector(9 downto 0) --;
|
--o_DOA : OUT std_logic_vector(15 downto 0)
|
--o_DOA : OUT std_logic_vector(15 downto 0)
|
);
|
);
|
end vga_ctrl;
|
end vga_ctrl;
|
|
|
Line 170... |
Line 162... |
-- constant c_CHARS_ROWS: std_logic_vector(5 downto 0) := "100100";
|
-- constant c_CHARS_ROWS: std_logic_vector(5 downto 0) := "100100";
|
|
|
--
|
--
|
signal s_h_count : std_logic_vector(10 downto 0); -- horizontal pixel counter
|
signal s_h_count : std_logic_vector(10 downto 0); -- horizontal pixel counter
|
signal s_v_count : std_logic_vector(9 downto 0); -- verticalal line counter
|
signal s_v_count : std_logic_vector(9 downto 0); -- verticalal line counter
|
|
signal s_v_count_d_4 : std_logic_vector(3 downto 0); -- verticalal line counter
|
signal s_h_sync : std_logic; -- horizontal sync trigger
|
signal s_h_sync : std_logic; -- horizontal sync trigger
|
signal s_h_sync_pulse : std_logic; -- 1-clock pulse on sync trigger
|
signal s_h_sync_pulse : std_logic; -- 1-clock pulse on sync trigger
|
|
|
--
|
--
|
-- signals for the charmaps Block RAM component...
|
-- signals for the charmaps Block RAM component...
|
|
signal s_charmaps_en : std_logic;
|
signal s_charmaps_ADDR : std_logic_vector (10 downto 0);
|
signal s_charmaps_ADDR : std_logic_vector (10 downto 0);
|
signal s_charmaps_DO : std_logic_vector (7 downto 0);
|
signal s_charmaps_DO : std_logic_vector (7 downto 0);
|
signal s_charmaps_DO_l : std_logic_vector (7 downto 0);
|
|
|
|
--
|
--
|
-- to manage the outside display region's blanking
|
-- to manage the outside display region's blanking
|
signal s_display : std_logic;
|
signal s_display : std_logic;
|
--
|
--
|
|
|
--
|
--
|
-- to manage the cursor position
|
-- to manage the chars ram address and the ram ascii
|
signal s_cursor_x : std_logic_vector(10 downto 0);
|
|
signal s_cursor_y : std_logic_vector(9 downto 0);
|
|
|
|
--
|
|
-- to manage the chars ram address and th ram ascii
|
|
signal s_chars_ram_addr : std_logic_vector(12 downto 0);
|
signal s_chars_ram_addr : std_logic_vector(12 downto 0);
|
signal s_chars_ascii : std_logic_vector(7 downto 0);
|
signal s_chars_ascii : std_logic_vector(7 downto 0);
|
|
signal s_chars_EN_r : std_logic;
|
|
|
--
|
-- to manage the waveform ram address and data
|
signal s_waveform_ADDRB : std_logic_vector (9 downto 0);
|
signal s_waveform_ADDRB : std_logic_vector (9 downto 0);
|
signal s_waveform_DOB : std_logic_vector (15 downto 0);
|
signal s_waveform_DOB : std_logic_vector (15 downto 0);
|
|
|
|
|
|
|
-- charmaps
|
-- charmaps
|
-- |------| |-----------------|
|
-- |------| |-----------------|
|
-- | P | | D D D D D D D D |
|
-- | P | | D D D D D D D D |
|
-- |======| |=================|
|
-- |======| |=================|
|
-- | 8 | | 7 6 5 4 3 2 1 0 |
|
-- | 8 | | 7 6 5 4 3 2 1 0 |
|
Line 210... |
Line 200... |
-- | Free | | Row char pixels |
|
-- | Free | | Row char pixels |
|
-- |------| |-----------------|
|
-- |------| |-----------------|
|
--
|
--
|
component charmaps_rom
|
component charmaps_rom
|
port(
|
port(
|
|
i_EN : in std_logic;
|
i_clock : in std_logic;
|
i_clock : in std_logic;
|
i_ADDR : in std_logic_vector(10 downto 0); -- 16 x ascii code (W=8 x H=16 pixel)
|
i_ADDR : in std_logic_vector(10 downto 0); -- 16 x ascii code (W=8 x H=16 pixel)
|
o_DO : out std_logic_vector(7 downto 0) -- 8 bit char pixel
|
o_DO : out std_logic_vector(7 downto 0) -- 8 bit char pixel
|
);
|
);
|
end component;
|
end component;
|
Line 253... |
Line 244... |
i_ADDR_rw : in std_logic_vector(10 downto 0);
|
i_ADDR_rw : in std_logic_vector(10 downto 0);
|
i_DI_rw : in std_logic_vector(31 downto 0);
|
i_DI_rw : in std_logic_vector(31 downto 0);
|
o_DI_rw : out std_logic_vector(31 downto 0);
|
o_DI_rw : out std_logic_vector(31 downto 0);
|
i_SSR : in std_logic;
|
i_SSR : in std_logic;
|
i_clock_r : in std_logic;
|
i_clock_r : in std_logic;
|
|
i_EN_r : in std_logic;
|
i_ADDR_r : in std_logic_vector(12 downto 0);
|
i_ADDR_r : in std_logic_vector(12 downto 0);
|
o_DO_r : out std_logic_vector(7 downto 0)
|
o_DO_r : out std_logic_vector(7 downto 0)
|
);
|
);
|
end component;
|
end component;
|
|
|
Line 264... |
Line 256... |
attribute U_SET : string;
|
attribute U_SET : string;
|
attribute U_SET of "u0_chars_RAM" : label is "u0_chars_RAM_uset";
|
attribute U_SET of "u0_chars_RAM" : label is "u0_chars_RAM_uset";
|
attribute U_SET of "u1_charmaps_rom" : label is "u1_charmaps_rom_uset";
|
attribute U_SET of "u1_charmaps_rom" : label is "u1_charmaps_rom_uset";
|
attribute U_SET of "u2_waveform_ram" : label is "u2_waveform_ram_uset";
|
attribute U_SET of "u2_waveform_ram" : label is "u2_waveform_ram_uset";
|
|
|
|
-- to read some configuration params from the char ram
|
|
signal s_config_time : std_logic;
|
|
--
|
|
-- to manage the background and cursor colors
|
|
constant c_BG_CUR_COLOR_ADDR : std_logic_vector(12 downto 0) := "0000001101100"; -- 108 BG:5..3 CUR:2..0
|
|
signal s_cursor_color : std_logic_vector(2 downto 0):= "000";
|
|
signal s_bg_color : std_logic_vector(2 downto 0):= "000";
|
|
--
|
|
-- to manage the cursor position
|
|
constant c_CURS_XY1 : std_logic_vector(12 downto 0) := "0000001101101"; -- 109
|
|
constant c_CURS_XY2 : std_logic_vector(12 downto 0) := "0000001101110"; -- 110
|
|
constant c_CURS_XY3 : std_logic_vector(12 downto 0) := "0000001101111"; -- 111
|
|
signal s_cursor_x : std_logic_vector(10 downto 0);
|
|
signal s_cursor_y : std_logic_vector(9 downto 0);
|
|
|
|
begin
|
|
-- read config params from ram...
|
|
p_config : process(i_clk)
|
begin
|
begin
|
|
if rising_edge(i_clk) then
|
|
case s_chars_ram_addr is
|
|
when c_BG_CUR_COLOR_ADDR =>
|
|
s_config_time <= '1';
|
|
s_cursor_color <= s_chars_ascii(2 downto 0);
|
|
s_bg_color <= s_chars_ascii(5 downto 3);
|
|
when c_CURS_XY1 =>
|
|
s_config_time <= '1';
|
|
s_cursor_x(10 downto 6) <= s_chars_ascii(4 downto 0);
|
|
when c_CURS_XY2 =>
|
|
s_config_time <= '1';
|
|
s_cursor_x(5 downto 0) <= s_chars_ascii(7 downto 2);
|
|
s_cursor_y(9 downto 8) <= s_chars_ascii(1 downto 0);
|
|
when c_CURS_XY3 =>
|
|
s_config_time <= '1';
|
|
s_cursor_y(7 downto 0) <= s_chars_ascii(7 downto 0);
|
|
when others =>
|
|
s_config_time <= '0';
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
s_chars_ram_addr <= s_v_count(9 downto 4) & s_h_count(9 downto 3);
|
-- enable the ram both
|
|
-- - during the display time
|
|
-- - to read configuration params
|
|
s_chars_EN_r <= s_display or s_config_time;
|
|
|
|
-- modify the chars_ram address
|
|
s_chars_ram_addr <= s_v_count(9 downto 4) & s_h_count(9 downto 3);
|
u0_chars_RAM : chars_RAM port map(
|
u0_chars_RAM : chars_RAM port map(
|
i_clock_rw => i_chr_clk,
|
i_clock_rw => i_chr_clk,
|
i_EN_rw => i_chr_en,
|
i_EN_rw => i_chr_en,
|
i_WE_rw => i_chr_we,
|
i_WE_rw => i_chr_we,
|
i_ADDR_rw => i_chr_addr,
|
i_ADDR_rw => i_chr_addr,
|
i_DI_rw => i_chr_data,
|
i_DI_rw => i_chr_data,
|
o_DI_rw => o_chr_data,
|
o_DI_rw => o_chr_data,
|
i_SSR => i_chr_rst,
|
i_SSR => i_chr_rst,
|
i_clock_r => i_clk,
|
i_clock_r => not i_clk,
|
|
i_EN_r => s_chars_EN_r,
|
i_ADDR_r => s_chars_ram_addr,
|
i_ADDR_r => s_chars_ram_addr,
|
o_DO_r => s_chars_ascii
|
o_DO_r => s_chars_ascii
|
);
|
);
|
|
|
|
|
|
-- modify the charmaps address (each 8 s_h_count - chars are 8 pixel tall)
|
|
-- v----- ascii code ------v v-- vert px mod 16 --v (chars are 8 pixel tall)
|
|
--s_charmaps_ADDR <= (s_chars_ascii(6 downto 0) & s_v_count(3 downto 0));
|
|
s_charmaps_ADDR <= (s_chars_ascii(6 downto 0) & s_v_count_d_4);
|
|
s_charmaps_en <=
|
|
'1' when s_h_count(2 downto 0) = "111" -- each 8 h_count (chars are 8 pixel wide)
|
|
else '0';
|
|
|
u1_charmaps_rom : charmaps_rom port map(
|
u1_charmaps_rom : charmaps_rom port map(
|
i_clock => i_clk,
|
i_en => s_charmaps_en,
|
|
i_clock => not i_clk,
|
i_ADDR => s_charmaps_ADDR,
|
i_ADDR => s_charmaps_ADDR,
|
o_DO => s_charmaps_DO
|
o_DO => s_charmaps_DO
|
);
|
);
|
|
|
-- modify the charmaps address
|
|
p_MGM_CHARMAPS_ADDR : process(i_clk) --, i_reset) --, s_v_count, i_cursor_color)
|
|
begin
|
|
if rising_edge(i_clk) then
|
|
if i_reset = '1' then -- sync reset
|
|
s_charmaps_ADDR <= "01000000000"; -- (others => '0');
|
|
else
|
|
if (s_h_count(2 downto 0) = "110") then -- each 8 h_count
|
|
s_charmaps_DO_l <= s_charmaps_DO;
|
|
end if;
|
|
-- here start char 'a' ---v v----- ascii code ------v v-- vert char row --v
|
|
--s_charmaps_ADDR <= "01000000000" + ( s_h_count(9 downto 3) & s_v_count(3 downto 0) );
|
|
s_charmaps_ADDR <= (s_chars_ascii(6 downto 0) & s_v_count(3 downto 0));
|
|
-- here start char 'a' ---^ ^----- ascii code ------^ ^-- vert char row --^
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
|
|
|
-- modify the waveform address
|
|
s_waveform_ADDRB <= s_h_count(9 downto 0);
|
|
|
u2_waveform_ram : waveform_ram port map(
|
u2_waveform_ram : waveform_ram port map(
|
i_DIA => i_wav_d,
|
i_DIA => i_wav_d,
|
i_WEA => i_wav_we,
|
i_WEA => i_wav_we,
|
--i_clockA => i_clockA,
|
i_clockA => i_wav_clk,
|
i_clockA => i_clk,
|
|
i_ADDRA => i_wav_addr,
|
i_ADDRA => i_wav_addr,
|
--o_DOA => o_DOA,
|
--o_DOA => o_DOA,
|
--
|
--
|
i_DIB => "1111111111111111",
|
i_DIB => "1111111111111111",
|
i_WEB => '0',
|
i_WEB => '0',
|
i_clockB => i_clk,
|
i_clockB => not i_clk,
|
-- i_ADDRB => s_waveform_ADDRB,
|
i_ADDRB => s_waveform_ADDRB,
|
i_ADDRB => s_waveform_ADDRB, --s_h_count(9 downto 0),
|
|
o_DOB => s_waveform_DOB
|
o_DOB => s_waveform_DOB
|
);
|
);
|
|
|
p_WaveFormAddr : process (i_clk)
|
-- generate a single clock pulse on hsync falling
|
begin
|
|
if rising_edge(i_clk) then
|
|
s_waveform_ADDRB <= s_h_count(9 downto 0);
|
|
end if;
|
|
end process;
|
|
|
|
p_pulse_on_hsync_falling : process(i_clk)
|
p_pulse_on_hsync_falling : process(i_clk)
|
variable v_h_sync1 : std_logic;
|
variable v_h_sync1 : std_logic;
|
begin
|
begin
|
if rising_edge(i_clk) then
|
if rising_edge(i_clk) then
|
s_h_sync_pulse <= not s_h_sync and v_h_sync1;
|
s_h_sync_pulse <= not s_h_sync and v_h_sync1;
|
v_h_sync1 := s_h_sync;
|
v_h_sync1 := s_h_sync;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
|
-- set the cursor position
|
|
s_cursor_x <= i_cursor_x; -- 400
|
|
s_cursor_y <= i_cursor_y; -- 300
|
|
|
|
-- control the reset, increment and overflow of the horizontal pixel count
|
-- control the reset, increment and overflow of the horizontal pixel count
|
p_H_PX_COUNT : process(i_clk) --, i_reset)
|
p_H_PX_COUNT : process(i_clk) --, i_reset)
|
begin
|
begin
|
if rising_edge(i_clk) then
|
if rising_edge(i_clk) then
|
if i_reset = '1' or s_h_count = c_H_PERIODpx then -- sync reset
|
if i_reset = '1' or s_h_count = c_H_PERIODpx then -- sync reset
|
Line 359... |
Line 376... |
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
|
|
-- control the reset, increment and overflow of the vertical pixel count
|
p_V_LN_COUNT : process(i_clk)
|
p_V_LN_COUNT : process(i_clk)
|
begin
|
begin
|
if rising_edge(i_clk) then
|
if rising_edge(i_clk) then
|
if i_reset = '1' or s_v_count = c_V_PERIODln then -- sync reset
|
if i_reset = '1' or s_v_count = c_V_PERIODln then -- sync reset
|
s_v_count <= (others => '0');
|
s_v_count <= (others => '0');
|
|
s_v_count_d_4 <= s_v_count(3 downto 0);
|
elsif s_h_sync_pulse = '1' then
|
elsif s_h_sync_pulse = '1' then
|
s_v_count <= s_v_count + 1;
|
s_v_count <= s_v_count + 1;
|
|
s_v_count_d_4 <= s_v_count(3 downto 0);
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- set the horizontal sync high time and low time according to the constants
|
-- set the horizontal sync high time and low time according to the constants
|
Line 385... |
Line 404... |
end if;
|
end if;
|
end process;
|
end process;
|
o_h_sync <= s_h_sync and i_h_sync_en;
|
o_h_sync <= s_h_sync and i_h_sync_en;
|
|
|
|
|
|
-- set the vertical sync high time and low time according to the constants
|
p_MGM_V_SYNC : process(i_clk) --, i_reset)
|
p_MGM_V_SYNC : process(i_clk) --, i_reset)
|
begin
|
begin
|
--if falling_edge(i_clk) then
|
--if falling_edge(i_clk) then
|
if rising_edge(i_clk) then
|
if rising_edge(i_clk) then
|
if i_v_sync_en = '0' or
|
if i_v_sync_en = '0' or
|
Line 398... |
Line 418... |
o_v_sync <= '1';
|
o_v_sync <= '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
|
-- asserts the blaking signal (active low)
|
-- asserts the blaking signal (active low)
|
p_MGM_BLANK : process (i_clk) --, i_reset)
|
p_MGM_BLANK : process (i_clk) --, i_reset)
|
begin
|
begin
|
if rising_edge(i_clk) then
|
if rising_edge(i_clk) then
|
-- if we are outside the visible range on the screen then tell the RAMDAC to blank
|
-- if we are outside the visible range on the screen then tell the RAMDAC to blank
|
Line 413... |
Line 434... |
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
|
|
-- generates the r g b signals and show the green cursor
|
-- generates the r g b signals showing chars, grid and "cross cursor"
|
p_MGM_RGB : process (i_clk) --, i_reset) --, i_cursor_color, s_display)
|
p_MGM_RGB : process (i_clk)
|
variable v_previous_pixel : std_logic_vector(9 downto 0) := "0100101100";
|
variable v_previous_pixel : std_logic_vector(9 downto 0) := "0100101100";
|
begin
|
begin
|
if rising_edge(i_clk) then -- not async reset
|
if rising_edge(i_clk) then -- not async reset
|
if i_reset = '1' then -- sync reset
|
if i_reset = '1' then -- sync reset
|
o_r <= '0';
|
o_r <= '0';
|
Line 431... |
Line 452... |
(s_h_count(c_GRID_BIT downto 0) = c_GRID_SIZE(c_GRID_BIT downto 0)) or
|
(s_h_count(c_GRID_BIT downto 0) = c_GRID_SIZE(c_GRID_BIT downto 0)) or
|
(s_v_count(c_GRID_BIT downto 0) = c_GRID_SIZE(c_GRID_BIT downto 0))
|
(s_v_count(c_GRID_BIT downto 0) = c_GRID_SIZE(c_GRID_BIT downto 0))
|
)
|
)
|
and (s_v_count(9) = '0') -- < 512
|
and (s_v_count(9) = '0') -- < 512
|
then -- draw the cursor and/or WaveForm Grid references
|
then -- draw the cursor and/or WaveForm Grid references
|
o_r <= i_cursor_color(2);
|
o_r <= s_cursor_color(2);
|
o_g <= i_cursor_color(1);
|
o_g <= s_cursor_color(1);
|
o_b <= i_cursor_color(0);
|
o_b <= s_cursor_color(0);
|
elsif
|
elsif
|
((s_v_count(9 downto 0) >= s_waveform_DOB(9 downto 0)) and
|
((s_v_count(9 downto 0) >= s_waveform_DOB(9 downto 0)) and
|
(s_v_count(9 downto 0) <= v_previous_pixel)
|
(s_v_count(9 downto 0) <= v_previous_pixel)
|
) or
|
) or
|
((s_v_count(9 downto 0) <= s_waveform_DOB(9 downto 0)) and
|
((s_v_count(9 downto 0) <= s_waveform_DOB(9 downto 0)) and
|
Line 449... |
Line 470... |
o_b <= s_waveform_DOB(10) or s_waveform_DOB(13); -- unused signals
|
o_b <= s_waveform_DOB(10) or s_waveform_DOB(13); -- unused signals
|
else -- draw the background and charmaps
|
else -- draw the background and charmaps
|
--if s_v_count > 512 then
|
--if s_v_count > 512 then
|
--FULL_SCREEN if (s_v_count(9) = '1') then -- >= 512
|
--FULL_SCREEN if (s_v_count(9) = '1') then -- >= 512
|
case (s_h_count(2 downto 0)) is
|
case (s_h_count(2 downto 0)) is
|
when "000" => o_g <= s_charmaps_DO_l(7) xor i_background;
|
when "000" => o_g <= s_charmaps_DO(7) xor s_bg_color(1);
|
when "001" => o_g <= s_charmaps_DO_l(6) xor i_background;
|
when "001" => o_g <= s_charmaps_DO(6) xor s_bg_color(1);
|
when "010" => o_g <= s_charmaps_DO_l(5) xor i_background;
|
when "010" => o_g <= s_charmaps_DO(5) xor s_bg_color(1);
|
when "011" => o_g <= s_charmaps_DO_l(4) xor i_background;
|
when "011" => o_g <= s_charmaps_DO(4) xor s_bg_color(1);
|
when "100" => o_g <= s_charmaps_DO_l(3) xor i_background;
|
when "100" => o_g <= s_charmaps_DO(3) xor s_bg_color(1);
|
when "101" => o_g <= s_charmaps_DO_l(2) xor i_background;
|
when "101" => o_g <= s_charmaps_DO(2) xor s_bg_color(1);
|
when "110" => o_g <= s_charmaps_DO_l(1) xor i_background;
|
when "110" => o_g <= s_charmaps_DO(1) xor s_bg_color(1);
|
when "111" => o_g <= s_charmaps_DO_l(0) xor i_background;
|
when "111" => o_g <= s_charmaps_DO(0) xor s_bg_color(1);
|
when others => o_g <= 'X';
|
when others => o_g <= 'X';
|
--when others => o_g <= i_background;
|
|
end case;
|
end case;
|
--FULL_SCREEN else
|
|
--FULL_SCREEN o_g <= i_background;
|
o_r <= s_bg_color(2);
|
--FULL_SCREEN end if;
|
--o_g <= s_bg_color(1);
|
o_r <= i_background;
|
o_b <= s_bg_color(0);
|
--o_g <= i_background;
|
|
o_b <= i_background;
|
|
end if;
|
end if;
|
else -- blank zone
|
else -- blank zone
|
-- the blanking zone
|
-- the blanking zone
|
o_r <= '0';
|
o_r <= '0';
|
o_g <= '0';
|
o_g <= '0';
|