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

📄 cardbus_wrapper.vhd

📁 VHDLVERILOG语言实现的CARDBUS的IP源码,已经实现现场应用
💻 VHD
字号:

-----------------------------------------------------------------------
--	  File : cardbus_wrapper.vhd
--   
--    DESCRIPTION: 
--			This file provides all CardBus signals (in addition to PCI signals),
--			as well as registers and logic to support those new signals.
--
--    HIERARCHY:  
--			 This file is used in the top-level design, to "wrap-around" the PCI core
--
--    AUTHOR: Claire Pian Tu
--
--    HISTORY: 
--    Date	        Author					Version
--    02/04/04		Claire Pian Tu			1.0
--		- Initial release, translated from verilog version
--		
-- Copyright (C) 2004, Licensed Customers of QuickLogic may copy and modify this
-- file for use in designing QuickLogic devices only.
--
-- IMPORTANT NOTICE: DISCLAIMER OF WARRANTY
-- This design is provided without warranty of any kind.
-- QuickLogic Corporation does not warrant, guarantee or make any representations
-- regarding the use, or the results of the use, of this design. QuickLogic
-- disclaims all implied warranties, including but not limited to implied
-- warranties of merchantability and fitness for a particular purpose. In addition
-- and without limiting the generality of the foregoing, QuickLogic does not make
-- any warranty of any kind that any item developed based on this design, or any
-- portion of it, will not infringe any copyright, patent, trade secret or other
-- intellectual property right of any person or entity in any country. It is the
-- responsibility of the user of the design to seek licenses for such intellectual
-- property rights where applicable. QuickLogic shall not be liable for any
-- damages arising out of or in connection with the use of the design including
-- liability for lost profit, business interruption, or any other damages whatsoever.
--
-----------------------------------------------------------------------*/
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--use work.cfgtaddr_5632_280_pkg.all;

entity cardbus_wrapper is

port (
	-- outputs
	CINT_n : 		out std_logic;
	CSTSCHG : 		out std_logic;
	CAUDIO : 		out std_logic;
	clk_stopped : 	out std_logic;
	locked :	   	out std_logic;
	owner_access :	out std_logic;
	cstschg_rdy : 	out std_logic;
--	CIS_Hit		: 	out std_logic;

	-- inouts
	cstschg_regs_in:	in std_logic_vector(31 downto 0);
	CCLKRUN_n_in:		in std_logic;	
	CBLOCK_n:			in std_logic;
	cstschg_regs_out:	out std_logic_vector(31 downto 0);
	CCLKRUN_n_out:		out std_logic;
	cstschg_regs_oe:	out std_logic;
	CCLKRUN_n_oe:		out std_logic;

	-- inputs
	BAM_in: 	in std_logic;
	PWM_in: 	in std_logic;
	clk:		in std_logic;
	reset:		in std_logic;
	clk_resume:	in std_logic;
	addr_phase:	in std_logic;
 --   last_cycle : in std_logic;
	framen_d1:	in std_logic;
	usr_read:	in std_logic;
	usr_write: 	in std_logic;
	user_addr:	in std_logic_vector(9 downto 0);
	intr_ps:	in std_logic;
	gwake_ps:	in std_logic;
	bvd_ps:		in std_logic_vector(2 downto 1);
	ready_ps:	in std_logic;
	wp_ps:		in std_logic;
	BAR_match:	in std_logic
		   );

end cardbus_wrapper;

architecture behavioral of cardbus_wrapper is

--signal declaration
--constants
-- CAUDIO internal signals
signal BAM_en: std_logic; -- bit 5 of FcnEvenMaskReg
signal PWM_en: std_logic; -- bit 6 of FcnEvenMaskReg
signal BAM_PWM: std_logic_vector(1 downto 0);

-- CBLOCK# internal signals
signal cblockn_d1: std_logic;
signal find_lock: std_logic_vector(1 downto 0);

--CCLKRUN# internal signals
signal clk_cnt: std_logic_vector(1 downto 0);
signal locked_int: std_logic;
signal owner_access_int: std_logic;
signal clk_stopped_int: std_logic;

-- CSTSCHG internal signals
signal FcnEventReg: std_logic_vector(15 downto 0);
signal FcnMaskReg: std_logic_vector(15 downto 0);
signal gwake_ls: std_logic;
signal bvd_ls: std_logic_vector(2 downto 1);
signal ready_ls: std_logic;
signal wp_ls: std_logic;
--signal cstschg_regs_out_int: std_logic_vector(31 downto 0);
signal xfer_on_going: std_logic;	-- flag to indicate xfer going on
signal gwake_intr: std_logic; 		--masked GWAKE
signal bvd_intr: std_logic;			--masked BVD
signal ready_intr: std_logic;		--masked READY
signal wp_intr: std_logic;			--masked WP
signal event_reg_cs: std_logic;		-- addr decoding for FcnEvent related regs
									-- regs are located in mem space indicated by
									-- CISTPL_CONFIG_CB in CIS
signal cstschg_rdy_int: std_logic;


begin
	-- CIS interface implemented externally to this module	
	-- CIS FLASH data bus connected to core, via large data mux
	-- read CIS FLASH when BAR5 matches, starting offset 0x00
	-- ie config space usr_addr = addr to CIS
	-- bAR_match is also select for the MUX

	--assigns

	clk_stopped <= clk_stopped_int;
	locked <= locked_int;
	cstschg_rdy <= cstschg_rdy_int;

	CINT_n <= not ((FcnEventReg(15) or intr_ps) and FcnMaskReg(15));

	-- CSTSCHG PC Card Spec Chapter 2, section 5.2.11
	gwake_intr <= FcnEventReg(4) and FcnMaskReg(4);
	bvd_intr <= FcnMaskReg(2) and FcnMaskReg(3) and (FcnEventReg(2) or FcnEventReg(3));
    ready_intr <= FcnEventReg(1) and FcnMaskReg(1);
    wp_intr <= FcnEventReg(0) and FcnMaskReg(0);
    --		WKUP enable			GWAK			BVD[2:1]	READY		Write Protect    
    CSTSCHG <= FcnMaskReg(14) and (gwake_intr or bvd_intr or ready_intr or wp_intr);

	-- see metaformat volumn, 3.3.5 and 3.3.5.3
	event_reg_cs <= '1' when (xfer_on_going = '1') and (user_addr(9 downto 4) = "110000") else '0';
	-- note: comparison width depends on desired BAR width
	--		comparison value depends on the value specified
	--		in the CISTPL_CONFIG_CB tuple

	process (clk, reset)
	begin
		if reset = '1' then
			xfer_on_going <= '0';
		elsif clk'event and clk = '1' then
			if (BAR_match = '1') then
				xfer_on_going <= '1';
			elsif (usr_read = '0' and usr_write = '0') then
				xfer_on_going <= '0';
			end if;
		end if;
	end process;

	cstschg_regs_oe <= usr_read and event_reg_cs;

	process (clk, reset)
	begin
		if reset = '1' then
			FcnEventReg(15) <= '0';
			FcnEventReg(4 downto 0) <= "00000";
			FcnMaskReg(15 downto 14) <= "00";
			FcnMaskReg(6 downto 0) <= "0000000";
			cstschg_regs_out <= x"00000000";
			gwake_ls <= '0';
			bvd_ls <= "00";
			ready_ls <= '0';
			wp_ls <= '0';
			cstschg_rdy_int <= '0';
			FcnEventReg(14 downto 5) <= "0000000000";
			FcnMaskReg(13 downto 7) <= "0000000";
		elsif clk'event and clk = '1' then
			if event_reg_cs = '1' then
				cstschg_rdy_int <= '1'; --ensure Usr_Rdy is not stuck high
				case user_addr(3 downto 2) is
				when "00" =>  -- 0x0: Function Event
					
					if usr_read = '1' then -- return FcnEventReg value
						cstschg_regs_out <= x"0000" & 
											FcnEventReg(15) & 
											x"00" & "00" & 
											FcnEventReg(4 downto 0);
						elsif usr_write = '1' and cstschg_rdy_int = '1' then --write 1 to clear, 0 has no effect
							FcnEventReg(15) <= not cstschg_regs_in(15) and FcnEventReg(15);
							FcnEventReg(4) <= not cstschg_regs_in(4) and FcnEventReg(4);
							FcnEventReg(3) <= not cstschg_regs_in(3) and FcnEventReg(3);
							FcnEventReg(2) <= not cstschg_regs_in(2) and FcnEventReg(2);
							FcnEventReg(1) <= not cstschg_regs_in(1) and FcnEventReg(1);
							FcnEventReg(0) <= not cstschg_regs_in(0) and FcnEventReg(0);
					end if;																		

				when "01" =>  -- 0x4: Function Event Mask

					if usr_read = '1' then 
						cstschg_regs_out <= x"0000" & 
											FcnMaskReg(15 downto 14) & 
											"0000000" & 
											FcnMaskReg(6 downto 0);
						elsif usr_write = '1' then
							FcnMaskReg(15 downto 14) <= cstschg_regs_in(15 downto 14);
							FcnMaskReg(6 downto 0) <= cstschg_regs_in(6 downto 0);
							-- note that the mask for BVD[2:1] should be "11" or "00"
							-- value of "01" or "10" will be treated as "00"
						end if;

					when "10" =>  -- 0x8: Function Present State					
						if usr_read = '1' then
							cstschg_regs_out <= x"0000" &
												intr_ps & 
												x"00" & "00" & 
												gwake_ps & 
												bvd_ps(1) & 
												bvd_ps(2) & 
												ready_ps & 
												wp_ps; 
						end if;
					-- these values are not affected by CRST#
					when "11" =>  --0x12 Function Force Event
								-- this is an address port where FcnEventReg can be modified for debug
						if usr_read = '1' then
							cstschg_regs_out <= x"0000" & 
												FcnEventReg(15) & 
												x"00" & "00" &
												FcnEventReg(4 downto 0);
						elsif usr_write = '1' and cstschg_rdy_int = '1' then
						--// write 1 to set; write 0 has no effect
							FcnEventReg(15) <= cstschg_regs_in(15) or FcnEventReg(15);
							FcnEventReg(4) <= cstschg_regs_in(4) or FcnEventReg(4);
							FcnEventReg(3) <= cstschg_regs_in(3) or FcnEventReg(3);
							FcnEventReg(2) <= cstschg_regs_in(2) or FcnEventReg(2);
							FcnEventReg(1) <= cstschg_regs_in(1) or FcnEventReg(1);
							FcnEventReg(0) <= cstschg_regs_in(0) or FcnEventReg(0);
						end if;
					when others	=> null;
				end case;
			else
				-- when PCI is not accessing CSTSCHG registers
				-- register the last state of present status 
				gwake_ls <= gwake_ps;
				bvd_ls <= bvd_ps;
				ready_ls <= ready_ps;
				wp_ls <= wp_ps;
				cstschg_rdy_int <= '0';

				-- if present state changed, update the bits accordingly in FcnEventReg
				if gwake_ls /= gwake_ps then
					FcnEventReg(4) <= '1';
				end if;
				if bvd_ls(1) /= bvd_ps(1) then
					FcnEventReg(3) <= '1';
				end if;
				if bvd_ls(2) /= bvd_ps(2) then
					FcnEventReg(2) <= '1';
				end if;
				if ready_ls /= ready_ps then
					FcnEventReg(1) <= '1';
				end if;
				if wp_ls /= wp_ps then
					FcnEventReg(0) <= '1';
				end if;
			end if;
		end if;
	end process;

	-- CAUDIO	5.2.12

	BAM_en <= FcnMaskReg(5);
	PWM_en <= FcnMaskReg(6);
	BAM_PWM <= BAM_en & PWM_en;

	process (BAM_in, PWM_in, BAM_PWM)
	begin
		case BAM_PWM is
			when "01" => CAUDIO <= PWM_in;
			when "10" => CAUDIO <= BAM_in;
			when others => CAUDIO <= '0';
		end case;			
	end process;	

	-- CCLKRUN#	5.2.10

	clk_stopped_int <= clk_cnt(1);
	CCLKRUN_n_oe <= clk_resume and clk_stopped_int;
	CCLKRUN_n_out <= '0';
	-- CCLKRUN_n_out is always set to 0 
	-- assert (ie OE = 1) if need to resume, else it's input
	-- if FGPA wants clk to remain normal (ie running), it must respond
	-- within 2 clock cycles of sampling clk_stopped high
	-- by driving clk_resume

	process(clk, reset)
	begin
		if reset = '1' then
			clk_cnt <= "00";
		elsif clk'event and clk = '1' then
			case clk_cnt is
				when "00" =>
					if CCLKRUN_n_in = '1' then
						clk_cnt <= "01";
					end if;
				when "01" =>
					if CCLKRUN_n_in = '1' then
						clk_cnt <= "10";
					else
						clk_cnt <= "00";
					end if;
				when "10" =>
					if CCLKRUN_n_in = '0' then
						clk_cnt <= "11";
					end if;
				when "11" =>
					if CCLKRUN_n_in = '0' then
						clk_cnt <= "00";
					else
						clk_cnt <= "10";
					end if;
				when others => null;
			end case;
		end if;													
	end process;


-- CBLOCK#	5.2.6
	process(clk, reset)
	begin
		if reset = '1' then
			find_lock <= "00";
			cblockn_d1 <= '0';
			locked_int <= '0';
			owner_access <= '0';
		elsif clk'event and clk = '1' then
			cblockn_d1 <= CBLOCK_n;

			case find_lock is
				when "00" =>
					if addr_phase = '1' and cblockn_d1 = '1' then
						find_lock <= "01";
					end if;
					if framen_d1 = '1' and cblockn_d1 = '1' then
						locked_int <= '0';
					end if;
				when "01" =>
					if (usr_read or usr_write) = '1' and cblockn_d1 = '0' then
						locked_int <= '1';
						find_lock <= "10";
					else
						find_lock <= "00";
					end if;						
				when "10" =>
					find_lock <= "00";
				when others => null;
			end case;

			if locked_int = '1' and find_lock(1) = '1' then
				owner_access <= '1';
			elsif framen_d1 = '1' and not (usr_read or usr_write) = '1' then
				owner_access <= '0';
			end if;

		end if;
	end process;

end behavioral;

⌨️ 快捷键说明

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