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

📄 headers.vhd

📁 vhdl code for GIF Image Viewer
💻 VHD
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity headers is
    Port (
		clk : in std_logic;
	 	rstL : in std_logic;
		start : in std_logic;
		paletteProgDone : in std_logic;
 	 	readData : in std_logic_vector(15 downto 0);
		addr : out std_logic_vector(19 downto 0);
		writeData : out std_logic_vector(15 downto 0);
		oen : out std_logic;
		wen : out std_logic;
		height : out std_logic_vector(9 downto 0);
		width : out std_logic_vector(9 downto 0);
		codesize : out std_logic_vector(3 downto 0);
		coltablecode : out std_logic_vector(2 downto 0);
		startPaletteProg : out std_logic;
		done : out std_logic
	);
end headers;

architecture Behavioral of headers is
	COMPONENT reg
	 Generic ( size : integer := 8 );
	PORT(
		d : IN std_logic_vector(size-1 downto 0);
		rstL : IN std_logic;
		clk : IN std_logic;
		ce : IN std_logic;          
		q : OUT std_logic_vector(size-1 downto 0)
		);
	END COMPONENT;
	component adder
		Generic ( size : integer := 8);
		Port ( a : in std_logic_vector(size-1 downto 0);
           b : in std_logic_vector(size-1 downto 0);
           s : out std_logic_vector(size-1 downto 0));
	end component;
	COMPONENT mux2
	GENERIC ( size : integer := 8);
	PORT(
		d0 : IN std_logic_vector(size-1 downto 0);
		d1 : IN std_logic_vector(size-1 downto 0);
		s : IN std_logic;          
		o : OUT std_logic_vector(size-1 downto 0)
		);
	END COMPONENT;
	component mux6 
		 Generic ( size : integer := 8 );
	    Port ( d0 : in std_logic_vector(size-1 downto 0);
	           d1 : in std_logic_vector(size-1 downto 0);
	           d2 : in std_logic_vector(size-1 downto 0);
	           d3 : in std_logic_vector(size-1 downto 0);
				  d4 : in std_logic_vector(size-1 downto 0);
				  d5 : in std_logic_vector(size-1 downto 0);
	           s : in std_logic_vector(2 downto 0);
	           o : out std_logic_vector(size-1 downto 0));
	end component;
	component decoder3
	    Port ( i : in std_logic_vector(2 downto 0);
	           o : out std_logic_vector(7 downto 0));
	end component;

	signal inaddr, outaddr, next_inaddr, next_outaddr, inaddr_addend,
			 sum_inaddr, coltablesize20, inc_data, inc_outaddr
					: std_logic_vector(19 downto 0);
	signal data, blksize, dec_blksize, next_blksize, halfcoltablesize,
			 height_low, width_low
					: std_logic_vector(7 downto 0);
	signal data9, inc_data9
					: std_logic_vector(8 downto 0);
	signal height_high, width_high : std_logic_vector(1 downto 0);
	signal sel_inaddr_addend : std_logic_vector(2 downto 0);
	signal write_height_low, write_height_high, write_width_low,
			 write_width_high, write_codesize, write_data, write_inaddr,
			 write_outaddr, write_blksize, sel_blksize, sel_inaddr, sel_addr,
             sel_outaddr
			 		: std_logic;

	type statetype is (stIdle, stInit, stLoadScreenFlags, stCheckGlobalPalette,
			stBeginExtensionLoop, stWaitGlobalPalette, stSkipGPalette1,
			stSkipGPalette2, stSkipLPalette1, stSkipLPalette2,
			stCheckExtensionBlock, stLoadExtensionSubblock, stCheckExtensionSubblock,
			stReadWidthLow, stReadWidthHigh, stReadHeightLow, stReadHeightHigh,
			stReadLocalFlags, stCheckLocalPalette, stWaitLocalPalette, stReadCodeSize,
			stBeginDataLoop, stCheckBlockSize, stBeginCopyLoop, stWriteByte,
			stDone
	);

	signal presState, nextState : statetype;
begin

process (clk, rstL)
begin
	if (rstL = '0') then
		presState <= stIdle;
	elsif (clk'event and clk = '1') then
		presState <= nextState;
	end if;
end process;

process (presState, start, paletteProgDone, data, blksize)
begin
	write_height_low <= '0';
	write_height_high <= '0';
	write_width_low <= '0';
	write_width_high <= '0';
	write_codesize <= '0';
	write_data <= '0';
	write_inaddr <= '0';
	write_outaddr <= '0';
	write_blksize <= '0';
	sel_blksize <= '1';
	sel_inaddr <= '1';
	sel_inaddr_addend <= "001";
	sel_addr <= '0';
    sel_outaddr <= '1';
	oen <= '0';
	wen <= '1';
	startPaletteProg <= '0';
	done <= '0';

	case presState is
		when stIdle =>
			if start = '1' then
				nextState <= stInit;
			else
				nextState <= stIdle;
			end if;
		when stInit =>
			sel_inaddr <= '0';
			write_inaddr <= '1';					-- inaddr = $8000a
            sel_outaddr <= '0';
            write_outaddr <= '1';                   -- outaddr = $03000
			nextState <= stLoadScreenFlags;
		when stLoadScreenFlags =>
			write_data <= '1';					    -- data = readData
			sel_inaddr_addend <= "011";
			write_inaddr <= '1';					-- inaddr += 3
			nextState <= stCheckGlobalPalette;
		when stCheckGlobalPalette =>
			if data(7) = '1' then
				startPaletteProg <= '1';
				nextState <= stWaitGlobalPalette;
			else
				nextState <= stBeginExtensionLoop;
			end if;
		when stWaitGlobalPalette =>
			if paletteProgDone = '1' then
				sel_inaddr_addend <= "000";
				write_inaddr <= '1';				-- inaddr += coltablesize
				nextState <= stSkipGPalette1;
			else
				nextState <= stWaitGlobalPalette;
			end if;
		when stSkipGPalette1 =>
			sel_inaddr_addend <= "000";
			write_inaddr <= '1';
			nextState <= stSkipGPalette2;
		when stSkipGPalette2 =>
			sel_inaddr_addend <= "000";
			write_inaddr <= '1';
			nextState <= stBeginExtensionLoop;
		when stBeginExtensionLoop =>
			write_data <= '1';					-- data = readData
			nextState <= stCheckExtensionBlock;
		when stCheckExtensionBlock =>
			if (data = x"21") then
				sel_inaddr_addend <= "010";
				write_inaddr <= '1';				-- inaddr += 2
				nextState <= stLoadExtensionSubblock;
			else
				sel_inaddr_addend <= "101";
				write_inaddr <= '1';				-- inaddr += 5
				nextState <= stReadWidthLow;
			end if;
		when stLoadExtensionSubblock =>
			write_data <= '1';					-- data = readData
			nextState <= stCheckExtensionSubblock;
		when stCheckExtensionSubblock =>
			if data = x"00" then
				write_inaddr <= '1';				-- inaddr += 1
				nextState <= stBeginExtensionLoop;
			else
				sel_inaddr_addend <= "100";
				write_inaddr <= '1';				-- inaddr += data + 1
				nextState <= stLoadExtensionSubblock;
			end if;
		when stReadWidthLow =>
			write_width_low <= '1';				-- width_low = readData
			write_inaddr <= '1';					-- inaddr += 1
			nextState <= stReadWidthHigh;
		when stReadWidthHigh =>
			write_width_high <= '1';			-- width_high = readData
			write_inaddr <= '1';					-- inaddr += 1
			nextState <= stReadHeightLow;
		when stReadHeightLow =>
			write_height_low <= '1';			-- height_low = readData
			write_inaddr <= '1';					-- inaddr += 1
		 	nextState <= stReadHeightHigh;
		when stReadHeightHigh =>
			write_height_high <= '1';			-- height_high = readData
			write_inaddr <= '1';					-- inaddr += 1
			nextState <= stReadLocalFlags;
		when stReadLocalFlags =>
			write_data <= '1';					-- data = readData
			write_inaddr <= '1';					-- inaddr += 1
			nextState <= stCheckLocalPalette;
		when stCheckLocalPalette =>
			if data(7) = '1' then
				startPaletteProg <= '1';
				nextState <= stWaitLocalPalette;
			else
				nextState <= stReadCodeSize;
			end if;
		when stWaitLocalPalette =>
			if paletteProgDone = '1' then
				sel_inaddr_addend <= "000";
				write_inaddr <= '1';				-- inaddr += coltablesize
				nextState <= stSkipLPalette1;
			else
				nextState <= stWaitLocalPalette;
			end if;
		when stSkipLPalette1 =>
			sel_inaddr_addend <= "000";
			write_inaddr <= '1';
			nextState <= stSkipLPalette2;
		when stSkipLPalette2 =>
			sel_inaddr_addend <= "000";
			write_inaddr <= '1';
			nextState <= stReadCodeSize;
		when stReadCodeSize =>
			write_codesize <= '1';				-- codesize = readData
			write_inaddr <= '1';					-- inaddr += 1
			nextState <= stBeginDataLoop;
		when stBeginDataLoop =>
			sel_blksize <= '0';
			write_blksize <= '1';				-- blksize = readData
			nextState <= stCheckBlockSize;
		when stCheckBlockSize =>
			if blksize = x"00" then
				nextState <= stDone;
			else
				write_inaddr <= '1';				-- inaddr += 1
				nextState <= stBeginCopyLoop;
			end if;
		when stBeginCopyLoop =>
			write_data <= '1';					-- data = readData
			write_inaddr <= '1';					-- inaddr += 1
			nextState <= stWriteByte;
		when stWriteByte =>
			sel_addr <= '1';
			wen <= '0';								-- write data to outaddr
			write_outaddr <= '1';				-- outaddr += 1
			write_blksize <= '1';				-- blksize -= 1
			if blksize = x"01" then
				nextState <= stBeginDataLoop;
			else
				nextState <= stBeginCopyLoop;
			end if;
		when stDone =>
			done <= '1';
			nextState <= stIdle;
	end case;
end process;

reg_inaddr : reg
	generic map (size => 20)
	port map (
		d => next_inaddr,
		q => inaddr,
		rstL => rstL,
		clk => clk,
		ce => write_inaddr
	);

reg_outaddr : reg
	generic map (size => 20)
	port map (
		d => next_outaddr,
		q => outaddr,
		rstL => rstL,
		clk => clk,
		ce => write_outaddr
	);

mux_outaddr : mux2
    generic map (size => 20)
    port map (
        d0 => x"03000",
        d1 => inc_outaddr,
        s => sel_outaddr,
        o => next_outaddr
    );

reg_blksize : reg
	generic map (size => 8)
	port map (
		d => next_blksize,
		q => blksize,
		rstL => rstL,
		clk => clk,
		ce => write_blksize
	);

reg_data : reg
	generic map (size => 8)
	port map (
		d => readData(7 downto 0),
		q => data,
		rstL => rstL,
		clk => clk,
		ce => write_data
	);

writeData <= x"00" & data;
coltablecode <= data(2 downto 0);

reg_codesize : reg
	generic map (size => 4)
	port map (
		d => readData(3 downto 0),
		q => codesize,
		rstL => rstL,
		clk => clk,
		ce => write_codesize
	);

reg_width_low : reg
	generic map (size => 8)
	port map (
		d => readData(7 downto 0),
		q => width_low,
		rstL => rstL,
		clk => clk,
		ce => write_width_low
	);

reg_width_high : reg
	generic map (size => 2)
	port map (
		d => readData(1 downto 0),
		q => width_high,
		rstL => rstL,
		clk => clk,
		ce => write_width_high
	);

width <= width_high & width_low;

reg_height_low : reg
	generic map (size => 8)
	port map (
		d => readData(7 downto 0),
		q => height_low,
		rstL => rstL,
		clk => clk,
		ce => write_height_low
	);

reg_height_high : reg
	generic map (size => 2)
	port map (
		d => readData(1 downto 0),
		q => height_high,
		rstL => rstL,
		clk => clk,
		ce => write_height_high
	);

height <= height_high & height_low;

adder_outaddr : adder
	generic map (size => 20)
	port map (
		a => x"00001",
		b => outaddr,
		s => inc_outaddr
	);

adder_blksize : adder
	generic map (size => 8)
	port map (
		a => x"ff",
		b => blksize,
		s => dec_blksize
	);

mux_blksize : mux2
	generic map (size => 8)
	port map (
		d0 => readData(7 downto 0),
		d1 => dec_blksize,
		s => sel_blksize,
		o => next_blksize
	);

mux_inaddr : mux2
	generic map (size => 20)
	port map (
		d0 => x"8000a",
		d1 => sum_inaddr,
		s => sel_inaddr,
		o => next_inaddr
	);

adder_inaddr : adder
	generic map (size => 20)
	port map (
		a => inaddr_addend,
		b => inaddr,
		s => sum_inaddr
	);

data9 <= "0" & data;

adder_data : adder
	generic map (size => 9)
	port map (
		a => data9,
		b => "000000001",
		s => inc_data9
	);

inc_data <= "00000000000" & inc_data9;

mux_addend_inaddr : mux6
	generic map (size => 20)
	port map (
		d0 => coltablesize20,
		d1 => x"00001",
		d2 => x"00002",
		d3 => x"00003",
		d4 => inc_data,
		d5 => x"00005",
		s => sel_inaddr_addend,
		o => inaddr_addend
	);

decode_tablesize : decoder3
	port map (
		i => data(2 downto 0),
		o => halfcoltablesize
	);

addr_mux : mux2
	generic map (size => 20)
	port map (
		d0 => inaddr,
		d1 => outaddr,
		s => sel_addr,
		o => addr
	);

coltablesize20 <= "00000000000" & halfcoltablesize & "0";

end Behavioral;

⌨️ 快捷键说明

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