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

📄 prgramdac.vhd

📁 This is interface VGA with monitor
💻 VHD
字号:
-------------------------------------------------------------------------------
-- prgramdac.vhd
--
-- Author(s):     Ashley Partis and Jorgen Peddersen
-- Created:       Dec 2000
-- Last Modified: Jan 2001
-- 
-- This code programmes the RAMDAC on the XSV-300 board with data for either
-- high-colour mode or a simple colour map.
--
-------------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity prgramdacver2 is
    port (
        clk: in STD_LOGIC;									-- Clock
        rstn: in STD_LOGIC;									-- Asynchronous active low reset
        start: in STD_LOGIC;								-- Start signal
        done: out STD_LOGIC;								-- Asserted when programming is finished
        WRn: out STD_LOGIC;									-- Write line to RAMDAC (active low)
        RDn: out STD_LOGIC;									-- Read line to RAMDAC (active low)
        RS: inout STD_LOGIC_VECTOR (2 downto 0);			-- Register select lines to the RAMDAC
        data: inout STD_LOGIC_VECTOR (7 downto 0)			-- Bidirectional data line to RAMDAC
    );
end prgramdacver2;

architecture prgramdacver2_arch of prgramdacver2 is
-- signal declarations
-- FSM states for the main mealy FSM
type STATETYPE is (stIdle, stWrite, stWrCycle, stNextWrite
		--, stSetupRGB, stWriteRGB, stNextWriteRGB		-- uncomment these states for colour map
		);
signal presState: STATETYPE;
signal nextState: STATETYPE;

-- hardcoded values for initialising the RAMDAC to the values we desire
-- location 10 down to 8 is the RS values
type TWODIMARRAYDAC is array (0 to 5) of STD_LOGIC_VECTOR (7 downto 0);
type TWODIMARRAYRS is array (0 to 5) of STD_LOGIC_VECTOR (2 downto 0);

constant initDAC: TWODIMARRAYDAC:=
  -- hard code initial control register programming values
( -- DAC(76543210)
		"10000001",			-- Command reg A gets $81 for high colour dual edged mode
--		"10100001",			-- Command reg A gets $A1 for high colour single edged mode
--		"00000001",			-- Command reg A gets $01 for colour map 
		"00000000",			-- Pallette address reg gets $00
		"11111111",			-- Read mask reg gets $FF
		"00000010",			-- Pallette address reg gets $02
		"00000010",			-- Command reg B gets $02
		"00000000"			-- Pallette address reg gets $00
);
 
constant initRS: TWODIMARRAYRS:=
(  -- RS(210)
		"110", 				-- RS gets Command reg A	
		"000", 				-- RS gets Pallette address reg
		"010", 				-- RS gets Read mask reg
		"000", 				-- RS gets Pallette address reg
		"010", 				-- RS gets Command reg B
		"000"				-- RS gets Pallette address reg
);	

-- initCnt is an integer to index the constant two dimensional arrays initDAC and initRS, 
-- and a signal to increment initCnt
signal initCnt: INTEGER range 0 to 5;
signal increment: STD_LOGIC;

-- signals to create a 12.5MHz clock from the 50MHz input clock to the entity
signal divclk: STD_LOGIC;
signal gray_cnt: STD_LOGIC_VECTOR (1 downto 0);


-- create signals so the data and RS lines can be used as tristate buffers
-- this is important as they share lines with the ethernet PHY
signal prgData: STD_LOGIC_VECTOR (7 downto 0);
signal prgRS: STD_LOGIC_VECTOR (2 downto 0);
signal latchData: STD_LOGIC;
signal latchRS: STD_LOGIC;

-- these are for programming the colourmap of the RAMDAC - to program all 256 lots
-- of 3 byte sets of RGB data - uncomment for colour map
-- also a signal to increment colourCnt to avoid a race condition
--signal prgRGB: STD_LOGIC_VECTOR (7 downto 0);
--signal colourCnt: STD_LOGIC_VECTOR (1 downto 0);
--signal incColourCnt: STD_LOGIC;

begin

-- clock divider by 4 to for a slower clock to avoid timing violations
-- uses grey code for minimized logic
A:	process (rstn, clk)
	begin
		if rstn = '0' then
			gray_cnt <= "00";
		elsif clk'EVENT and clk = '1' then
			case(gray_cnt) is
				when "00" => gray_cnt <= "01";
				when "01" => gray_cnt <= "11";
				when "11" => gray_cnt <= "10";
				when "10" => gray_cnt <= "00";
				when others => gray_cnt <= "00";
			end case;		
		end if;
	end process;
	
-- assign the clock that this entity runs off
	divclk <= gray_cnt(1);
	
-- read isn't needed, tie high
	RDn <= '1';

-- main clocked process
B:	process (rstn, divclk)
	begin
		if rstn = '0' then
			presState <= stIdle;
			initCnt <= 0;
-- add these signals for colour map
--			colourCnt <= (others => '0');
--			prgRGB <= (others => '0');
		elsif divclk'event and divclk = '1' then
			presState <= nextState;
			-- increment initCnt
			if increment = '1' then
				-- overflow initCnt when it hits 5 as integers don't overflow
				if initCnt < 5 then
					initCnt <= initCnt + 1;
				else
					initCnt <= 0;
				end if;
			end if;
-- add these signals for colour map
--			if incColourCnt = '1' then
--				if colourCnt = "10" then
--					colourCnt <= "00";
--					prgRGB <= prgRGB + 1;
--				else
--					colourCnt <= colourCnt + 1;
--				end if;
--			end if;
		end if;
	end process;

-- Main FSM process
C:	process (presState, start, initCnt)
	begin
		-- default signals and outputs for each FSM state
		-- note that the latch data and rs signals are defaulted to 1, so are
		-- only 0 in the idle state
		WRn <= '1';
		increment <= '0';
--		incColourCnt <= '0';
		prgData <= (others => '0');
		prgRS <= "001";
		latchData <= '1';
		latchRS <= '1';
		done <= '0';
						
		case presState is
			when stIdle =>
				-- wait for start signal from another process
				if start = '1' then
					nextState <= stWrite;
					-- setup for the first write to the RAMDAC for use by setting the register select
					-- lines and the data lines
					prgRS <= initRS(initCnt);
					prgData <= initDAC(initCnt);
				else 
					nextState <= stIdle;
					latchData <= '0';
					latchRS <='0';
				end if;

			when stWrite =>
				-- hold the register select and data lines for the write cycle
				-- and set the active low write signal
				nextState <= stWrCycle;
 				prgRS <= initRS(initCnt);
				prgData <= initDAC(initCnt);
				WRn <= '0';

			when stWrCycle =>
				-- continue if all 5 registers that needed programming have been written to
				if initCnt = 5 then
					nextState <= stIdle;
					done <= '1';
-- comment the two lines above and uncomment the one below for a colour map
--					nextState <= stSetupRGB;								
				-- continue writing to the registers
				else
					nextState <= stNextWrite;
				end if;
				-- hold the data to be sure the hold times aren't violated
				prgRS <= initRS(initCnt);
				prgData <= initDAC(initCnt);
				-- increment initCnt to program the next register
				increment <= '1';

			when stNextWrite =>
				nextState <= stWrite;
				-- setup for the next write cycle
				prgRS <= initRS(initCnt);
				prgData <= initDAC(initCnt);
			
			-- start programming the RGB values to the colour map
			-- note RS is defaulted to 001, which is what is required
			-- for programming the colour map
			-- These steps program the RAMDACs colour map.  To set the colours
			-- see the if statement below the end of the case statement
--			when stSetupRGB =>
--				nextState <= stWriteRGB;
--			when stWriteRGB =>
--				nextState <= stNextWriteRGB;
--				WRn <= '0';
--			when stNextWriteRGB =>
--				-- if all 256 sets of 3 byte RGB values are programmed, then go back
--				-- to the idle state and assert done
--				if prgRGB = "11111111" and colourCnt = "10" then
--					nextState <= stIdle;
--					done <= '1';
--				else
--					nextState <= stSetupRGB;
--				end if;
--				incColourCnt <= '1';			
		end case;
		
		-- the following statement will program the RAMDACs colour map.  To change the 
		-- colours it programs with, comment out different lines
--		if presState = stSetupRGB or presState = stWriteRGB or presState = stNextWriteRGB then
--			if colourCnt = "00" then				-- Red component
--				prgData <= prgRGB;						-- Full Red scaling
--				prgData <= prgRGB(7 downto 5) & "11111";-- 3:3:2 Red scaling
--				prgData <= (others => '0');				-- No Red component
--			elsif colourCnt = "01" then				-- Green component
--				prgData <= prgRGB;						-- Full Green scaling
--				prgData <= prgRGB(4 downto 2) & "11111";-- 3:3:2 Green scaling
--				prgData <= (others => '0');				-- No Green component
--			else									-- Blue component
--				prgData <= prgRGB;						-- Full Blue scaling
--				prgData <= prgRGB(1 downto 0) & "11111";-- 3:3:2 Blue scaling
--				prgData <= (others => '0');				-- No Blue component
--			end if;
-- Leave the following line commented if using the if statement above
--			prgData <= prgRGB; 							-- Full Grey scaling
--		end if;
	end process;
--	
-- assign data and RS prgData and prgRS repsectively when they need to be latched
-- otherwise keep them at high impedance to create a tri state buffer
	data <= prgData when latchData = '1' else (others => 'Z');
	RS <= prgRS when latchRS = '1' else (others => 'Z');
	
end prgramdacver2_arch;

⌨️ 快捷键说明

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