⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdu8.vhd

📁 BurchED B5-X300 Spartan2e using XC2S300e device Top level file for 6809 compatible system on a chi
💻 VHD
字号:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;

--
--
-- Video Display terminal
-- John Kent
-- 11th February 2004 
-- Assumes a pixel chock of 19.8 MHz
-- with a character display of 64 characters across
-- by 30 characters down.
--
entity vdu is
      port(
		-- control register interface
      vdu_clk_in   : in  std_logic;
		vdu_clk_out  : out std_logic;
      vdu_rst      : in  std_logic;
		vdu_cs       : in  std_logic;
		vdu_rw       : in  std_logic;
		vdu_addr     : in  std_logic_vector(2 downto 0);
      vdu_data_in  : in  std_logic_vector(7 downto 0);
      vdu_data_out : out std_logic_vector(7 downto 0);

      -- vga port connections
      vga_red0_o    : out std_logic;
      vga_red1_o    : out std_logic;
      vga_green0_o  : out std_logic;
      vga_green1_o  : out std_logic;
      vga_blue0_o   : out std_logic;
      vga_blue1_o   : out std_logic;
      vga_hsync_o   : out std_logic;
      vga_vsync_o   : out std_logic
   );
end vdu;

architecture arch of vdu is

	constant HI:	std_logic := '1';
	constant LO:	std_logic := '0';

	signal horiz_sync    : std_logic;
	signal vert_sync     : std_logic;
   signal cursor_on_v   : std_logic;
   signal cursor_on_h   : std_logic;
   signal video_on_v    : std_logic;
   signal video_on_h    : std_logic;
	signal h_count       : std_logic_vector(9 downto 0);
	signal v_count       : std_logic_vector(9 downto 0);
   signal blink_count   : std_logic_vector(22 downto 0);
   --
	-- Character generator ROM	
	--
	signal char_cs       : std_logic;
	signal char_rw       : std_logic;
	signal char_addr     : std_logic_vector(9 downto 0);
	signal char_data_in  : std_logic_vector(7 downto 0);
	signal char_data_out : std_logic_vector(7 downto 0);

	--
	-- Control Registers
	--
	signal reg_character : std_logic_vector(7 downto 0);
	signal reg_colour    : std_logic_vector(7 downto 0);
	signal reg_hcursor   : std_logic_vector(5 downto 0); -- 64 columns
	signal reg_vcursor   : std_logic_vector(4 downto 0); -- 32 rows
	signal reg_voffset   : std_logic_vector(4 downto 0); -- 32 rows
	--
	-- Video Shift register
	--
	signal vga_shift     : std_logic_vector(7 downto 0);
	signal vga_colour    : std_logic_vector(7 downto 0);
	signal vga_colour1   : std_logic_vector(7 downto 0);
	signal cursor_on     : std_logic;
	signal cursor_on1    : std_logic;
	signal video_on      : std_logic;
	signal video_on1     : std_logic;
	--
	-- vga character ram access bus
	--
   signal vga_cs        : std_logic;
	signal vga_rw        : std_logic;
	signal vga_addr      : std_logic_vector(10 downto 0); -- 2K byte character buffer
	signal vga_data_out  : std_logic_vector(7 downto 0);
	signal attr_data_out : std_logic_vector(7 downto 0); -- 2K byte atrribute buffer
	--
	-- Character write handshake signals
	--
	signal req_write : std_logic; -- request character/attribute write
	signal ack_write : std_logic;

	component char_rom
   port (
       clk   : in  std_logic;
       rst   : in  std_logic;
       cs    : in  std_logic;
       rw    : in  std_logic;
       addr  : in  std_logic_vector (9 downto 0);
       wdata : in  std_logic_vector (7 downto 0);
       rdata : out std_logic_vector (7 downto 0)
   );
	end component;

	component ram_2k
   port (
       clk   : in  std_logic;
       rst   : in  std_logic;
       cs    : in  std_logic;
       rw    : in  std_logic;
       addr  : in  std_logic_vector (10 downto 0);
       wdata : in  std_logic_vector (7 downto 0);
       rdata : out std_logic_vector (7 downto 0)
   );
	end component;

   component BUFG 
   port (
     i: in std_logic;
	  o: out std_logic
   );
	end component;

begin

--
-- instantiate Character generator ROM
--
vdu_char_rom: char_rom
		port map(
       clk   => vdu_clk_in,
       rst   => vdu_rst,
       cs    => char_cs,
       rw    => char_rw,
       addr  => char_addr,
       wdata => char_data_in,
       rdata => char_data_out
    );

--
-- Character buffer RAM
--
char_buff_ram: ram_2k
		port map(
       clk   => vdu_clk_in,
       rst   => vdu_rst,
       cs    => vga_cs,
       rw    => vga_rw,
       addr  => vga_addr,
       wdata => reg_character,
       rdata => vga_data_out
    );

--
-- Attribute (colour) RAM buffer
--
attr_buff_ram: ram_2k
		port map(
       clk   => vdu_clk_in,
       rst   => vdu_rst,
       cs    => vga_cs,
       rw    => vga_rw,
       addr  => vga_addr,
       wdata => reg_colour,
       rdata => attr_data_out
    );

clk_buffer : BUFG port map(
    i => h_count(0),
	 o => vdu_clk_out
    );	 

--
-- CPU Write interface
--
vga_cpu_write : process( vdu_clk_in, vdu_rst, vdu_cs, vdu_rw, vdu_addr, vdu_data_in,
								 reg_character, reg_colour, reg_hcursor, reg_vcursor,
								 req_write, ack_write )
begin
  if( vdu_rst = '1' ) then
		  reg_character <= "00000000";
		  reg_colour    <= "00001111";
		  reg_hcursor   <= "000000";
		  reg_vcursor   <= "00000";
		  reg_voffset   <= "00000";
		  req_write     <= '0';
  elsif vdu_clk_in'event and vdu_clk_in='0' then
    if (vdu_cs = '1') and (vdu_rw = '0') then
      case vdu_addr is
	   when "000" =>
		  reg_character <= vdu_data_in;
		  reg_colour    <= reg_colour;
		  reg_hcursor   <= reg_hcursor;
		  reg_vcursor   <= reg_vcursor;
		  reg_voffset   <= reg_voffset;
		  req_write     <= '1';
		when "001" =>
		  reg_character <= reg_character;
		  reg_colour    <= vdu_data_in;
		  reg_hcursor   <= reg_hcursor;
		  reg_vcursor   <= reg_vcursor;
		  reg_voffset   <= reg_voffset;
		  req_write     <= '1';
		when "010" =>
		  reg_character <= reg_character;
		  reg_colour    <= reg_colour;
		  reg_hcursor   <= vdu_data_in(5 downto 0);
		  reg_vcursor   <= reg_vcursor;
		  reg_voffset   <= reg_voffset;
		  req_write     <= req_write;
  	   when "011" =>
		  reg_character <= reg_character;
		  reg_colour    <= reg_colour;
		  reg_hcursor   <= reg_hcursor;
		  reg_vcursor   <= vdu_data_in(4 downto 0);
		  reg_voffset   <= reg_voffset;
		  req_write     <= req_write;
		when others =>
		  reg_character <= reg_character;
		  reg_colour    <= reg_colour;
		  reg_hcursor   <= reg_hcursor;
		  reg_vcursor   <= reg_vcursor;
		  reg_voffset   <= vdu_data_in(4 downto 0);
		  req_write     <= req_write;
		end case;
	 else
		  reg_character <= reg_character;
		  reg_colour    <= reg_colour;
		  reg_hcursor   <= reg_hcursor;
		  reg_vcursor   <= reg_vcursor;
		  reg_voffset   <= reg_voffset;

		  if (req_write = '1') and (ack_write = '1') then
		     req_write <= '0';
		  else
		     req_write <= req_write;
		  end if;

	 end if;
  end if;
end process;
--
-- CPU Read interface
--
vga_cpu_read : process( vdu_addr, vdu_cs,
			   				reg_character, reg_colour, reg_hcursor, reg_vcursor )
begin
      case vdu_addr is
	   when "000" =>
		  vdu_data_out <= reg_character;
		when "001" =>
		  vdu_data_out <= reg_colour;
		when "010" =>
		  vdu_data_out <= "00" & reg_hcursor;
  	   when "011" =>
		  vdu_data_out <= "000" & reg_vcursor;
		when others =>
		  vdu_data_out <= "000" & reg_voffset;
		end case;
end process;

--
-- Video memory access
--
vga_addr_proc : process(  reg_hcursor, reg_vcursor, reg_character, reg_colour,
								  h_count, v_count, req_write )
begin
    case h_count(2 downto 0) is
	 when "001" => -- always write cursor data on 1 count
		vga_cs  <= req_write;
		vga_rw  <= '0';
		vga_addr(5 downto 0)  <= reg_hcursor;
		vga_addr(10 downto 6) <= reg_vcursor;
	 when "110" => -- always read display character on 6 count
		vga_cs  <= '1';
		vga_rw  <= '1';
		vga_addr(5 downto 0)  <= h_count(8 downto 3);
		vga_addr(10 downto 6) <= v_count(8 downto 4) + reg_voffset(4 downto 0);
    when others => -- other 6 cycles free
		vga_cs  <= '0';
		vga_rw  <= '1';
		vga_addr(5 downto 0)  <= h_count(8 downto 3);
		vga_addr(10 downto 6) <= v_count(8 downto 4) + reg_voffset(4 downto 0);
    end case;
end process;
--
-- Video shift register
--
vga_shift_proc : process( vdu_clk_in, char_data_out, 
								  video_on, video_on1, cursor_on, cursor_on1,
                          vga_colour, vga_colour1, vga_shift,
								  reg_hcursor, reg_vcursor, reg_character, reg_colour,
								  h_count, v_count,
							     req_write, ack_write )
begin
  if (vdu_rst = '1') then
     ack_write     <= '0';
	  vga_colour    <= "00001111";
     vga_shift     <= "00000000";
     vga_red0_o    <= '0';
     vga_green0_o  <= '0';
     vga_blue0_o   <= '0';
	  vga_red1_o    <= '0';
	  vga_green1_o  <= '0';
	  vga_blue1_o   <= '0';
  -- Put all video signals through DFFs to elminate any delays that cause a blurry image
  elsif vdu_clk_in'event and vdu_clk_in='0' then

    case h_count(2 downto 0) is
	 when "001" => -- always write cursor data on 1 count
	   if (req_write = '1') and (ack_write = '0') then
        ack_write <= '1';
		else
        ack_write <= '0';
		end if;
    when others => -- other 4 cycles CPU is free to run.
		ack_write <= ack_write;
    end case;

    if h_count(2 downto 0) = "111" then
		vga_colour1 <= attr_data_out;
	 else
		vga_colour1 <= vga_colour1;
	 end if;

    if h_count(2 downto 0) = "000" then
      video_on    <= video_on1;
      cursor_on   <= cursor_on1;
		vga_colour  <= vga_colour1;
      vga_shift   <= char_data_out;
	 else
      video_on    <= video_on;
      cursor_on   <= cursor_on;
		vga_colour  <= vga_colour;
      vga_shift <= vga_shift(6 downto 0) & '0';
	 end if;

    --
	 -- Colour mask is
	 --  7  6  5  4  3  2  1  0
	 -- BI BG BB BR FI FG FB FR
	 --
	 if vga_shift(7) = (not cursor_on) then
	   if vga_colour(3) = '0' then
        vga_red0_o    <= video_on and vga_colour(0);
        vga_green0_o  <= video_on and vga_colour(1);
        vga_blue0_o   <= video_on and vga_colour(2);
	     vga_red1_o    <= '0';
	     vga_green1_o  <= '0';
	     vga_blue1_o   <= '0';
		else
        vga_red0_o    <= '0';
        vga_green0_o  <= '0';
        vga_blue0_o   <= '0';
	     vga_red1_o    <= video_on and vga_colour(0);
	     vga_green1_o  <= video_on and vga_colour(1);
	     vga_blue1_o   <= video_on and vga_colour(2);
		end if;
	 else
	   if vga_colour(7) = '0' then
        vga_red0_o    <= video_on and vga_colour(4);
        vga_green0_o  <= video_on and vga_colour(5);
        vga_blue0_o   <= video_on and vga_colour(6);
	     vga_red1_o    <= '0';
	     vga_green1_o  <= '0';
	     vga_blue1_o   <= '0';
		else
        vga_red0_o    <= '0';
        vga_green0_o  <= '0';
        vga_blue0_o   <= '0';
	     vga_red1_o    <= video_on and vga_colour(4);
	     vga_green1_o  <= video_on and vga_colour(5);
	     vga_blue1_o   <= video_on and vga_colour(6);
		end if;
    end if;
  end if;
end process;


--
-- Sync generator & timing process
-- Generate Horizontal and Vertical Timing Signals for Video Signal
--
vga_sync: PROCESS(vdu_clk_in, h_count, v_count, horiz_sync, vert_sync )
BEGIN
  if vdu_clk_in'event and vdu_clk_in='0' then
--
-- H_count counts pixels (256 + extra time for sync signals)
-- 
--  Horiz_sync  ------------------------------------__________--------
--  H_count       0                512              528       604    639
--
  	 IF (h_count = 639) THEN
   		h_count <= "0000000000";
	 ELSE
   		h_count <= h_count + 1;
	 END IF;
--
-- Generate Horizontal Sync Signal using H_count
--
	 IF (h_count <= 604) AND (h_count >= 528) THEN
 	  	  horiz_sync <= '0';
	 ELSE
 	  	  horiz_sync <= '1';
	 END IF;
--
-- V_count counts rows of pixels (480 + extra time for sync signals)
--  
--  Vert_sync      -----------------------------------------------_______------------
--  V_count         0                                      480    493-494          524
--
	 IF (v_count >= 588) AND (h_count >= 566) THEN
   		v_count <= "0000000000";
	 ELSIF (h_count = 283) THEN
   		v_count <= v_count + 1;
	 END IF;
--
-- Generate Vertical Sync Signal using V_count
--
	 IF (v_count <= 558) AND (v_count >= 557) THEN
   		vert_sync <= '0';
	 ELSE
  		   vert_sync <= '1';
	 END IF;

-- Generate Video on Screen Signals for Pixel Data
	 IF (h_count <= 511) THEN
   		video_on_h <= '1';
	 ELSE
	   	video_on_h <= '0';
	 END IF;

	 IF (v_count <= 511) THEN
   		video_on_v <= '1';
	 ELSE
   		video_on_v <= '0';
	 END IF;


	 if (h_count(8 downto 3) = reg_hcursor(5 downto 0)) then
	     cursor_on_h <= '1';
	 else
	     cursor_on_h <= '0';
	 end if;

	 if (v_count(8 downto 4) = reg_vcursor(4 downto 0)) then
	     cursor_on_v <= '1';
	 else
	     cursor_on_v <= '0';
	 end if;
    -- cursor_on is only active when on selected character
	 blink_count <= blink_count + 1;
  end if;
END PROCESS;

	 char_cs <= '1';
	 char_rw <= '1';
    char_addr(2 downto 0) <= v_count(3 downto 1);
	 char_addr(9 downto 3) <= vga_data_out(6 downto 0);
	 char_data_in <= "00000000";

    -- video_on is high only when RGB data is displayed
    video_on1 <= video_on_H AND video_on_V;
    cursor_on1 <= cursor_on_h and cursor_on_v and blink_count(21);

	 vga_hsync_o <= horiz_sync;
	 vga_vsync_o <= vert_sync;

end arch;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -