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

📄 prgramdac.vhd

📁 vhdl code for GIF Image Viewer
💻 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
		  oen: out STD_LOGIC;
		  wen: out STD_LOGIC;
		  readAddr: out STD_LOGIC_VECTOR(19 downto 0);
		  readData: in STD_LOGIC_VECTOR(15 downto 0);
		  startAddr : in STD_LOGIC_VECTOR(19 downto 0);
          tableSize : in std_logic_vector(2 downto 0)
    );
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, stSetup2RGB, stSetup3RGB, stWriteRGB, stNextWriteRGB
		);
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)
		"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
-- 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;

signal currAddr: STD_LOGIC_VECTOR (19 downto 0);
signal incCurrAddr: STD_LOGIC;
signal byteData : STD_LOGIC_VECTOR(7 downto 0);

signal tableSizeInt : integer;
signal two, maxColor10 : std_logic_vector(9 downto 0);
signal maxColor : std_logic_vector(7 downto 0);

begin

-- always read from memory, never write
	oen <= '0';
	wen <= '1';
	
	readAddr <= currAddr;

-- compute the ending address of the color table
	tableSizeInt <= conv_integer(tableSize);
	two <= "0000000010";
	maxColor10 <= SHL(two, tableSize) - 1;
    maxColor <= maxColor10(7 downto 0);

-- clock divider by 4 to for a slower clock to avoid timing violations
-- uses grey code for minimized logic
	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 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;

		elsif divclk'event and divclk = '1' then
            if start = '1' then
                currAddr <= startAddr;
        		initCnt <= 0;
        		colourCnt <= (others => '0');
        		prgRGB <= (others => '0');
            end if;

			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;
			if incColourCnt = '1' then
				if colourCnt = "10" then
					colourCnt <= "00";
					prgRGB <= prgRGB + 1;
				else
					colourCnt <= colourCnt + 1;
				end if;
			end if;

			if incCurrAddr = '1' then
				currAddr <= currAddr + 1;
			end if;
		end if;
	end process;

	byteData <= readData(7 downto 0);
	--byteData <= prgRGB when colourCnt = "00" else
	--				x"00";

	prgData <= initDAC(initCnt) when presState = stIdle or presState = stWrite or
	 											presState = stWrCycle or presState = stNextWrite
										 else byteData;

-- 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';
		prgRS <= "001";
		latchData <= '1';
		latchRS <= '1';
		done <= '0';
		incCurrAddr <= '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);
				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);
				WRn <= '0';

			when stWrCycle =>
				-- continue if all 5 registers that needed programming have been written to
				if initCnt = 5 then
					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);
				-- increment initCnt to program the next register
				increment <= '1';

			when stNextWrite =>
				nextState <= stWrite;
				-- setup for the next write cycle
				prgRS <= initRS(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 <= stSetup2RGB;
			when stSetup2RGB =>
				nextState <= stSetup3RGB;
			when stSetup3RGB =>
				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 = maxColor and colourCnt = "10" then
					nextState <= stIdle;
					done <= '1';
				else
					nextState <= stSetupRGB;
				end if;
				incColourCnt <= '1';			
				incCurrAddr <= '1';
		end case;
		
	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 + -