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

📄 usbctrl.vhd

📁 《CPLD开发实例》的配套光盘文件
💻 VHD
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity usbctrl is
	port(
		signal sim:     in    STD_LOGIC;  -- 仿真时为真值
		signal stim:    in    STD_LOGIC;  -- 仿真UUT
		--
		signal clk48:   out   STD_LOGIC;  -- 48MHz时钟
		signal rst:     out   STD_LOGIC;  -- 异步复位
		--
		signal uut_rxd: out   STD_LOGIC;  -- rxd管脚
		signal uut_rx0: out   STD_LOGIC;  -- rx0管脚
		signal uut_txd: in    STD_LOGIC;  -- txd管脚
		signal uut_tx0: in    STD_LOGIC;  -- tx0管脚
		--
		signal tb_xd:   in    STD_LOGIC;  -- xd基准信号
		signal tb_x0:   in    STD_LOGIC;  -- x0基准信号
		signal tb_clk:  out   STD_LOGIC   -- 时钟基准信号
		);
end usbctrl;

architecture Test of usbctrl is
	signal   pll:     STD_LOGIC;
	signal   osc:     STD_LOGIC;
	constant Tusb1:   TIME:= 84ns;
	constant Tusb2:   TIME:= 21ns;
begin
	
	--时钟和复位
	process
	begin
		if sim= '0' then
			wait;
		else
			clk48<= '0', '1' after 10ns;
			wait for Tusb2;
		end if;
	end process;
	rst<= '1', '0' after 5ns;
	
	--------------------
	--晶振
	process(osc, stim)
	begin
		if stim= '1' then
			if osc= 'U' then
				osc<= '0';
			else
				osc<= not(osc) after Tusb1/2;
			end if;
		end if;
	end process;
	
	--------------------
	-- 时钟恢复
	process(uut_txd, uut_tx0, stim)
		type Tstate is (Soff, Sx1, Sx, Sse0);
		variable state: Tstate;
	begin
		if stim= '0' then
			-- 时钟恢复状态机
			case state is
				when Soff=> 
				if uut_txd'event and uut_txd= '0' then
					state:= Sx1;
				end if;
				
				when Sx1=>
				if uut_txd'event then
					state:= Sx;
				end if;
				
				when Sx=>
				if uut_tx0= '1' then
					state:= Sse0;
				end if;
				
				when Sse0=>
				if uut_txd= '1' then
					state:= Soff;
				end if;
			end case;
			
			-- 时钟恢复
			if (uut_txd'event and (uut_txd= '1' or uut_txd= '0'))
				or (uut_tx0'event) then
				case state is
					when Sx1=> -- 同步模式
					pll<= '0',  '1' after  (1*Tusb1)/2;
					
					when Sx=>  -- 正常位
					pll<= 
					'0',                    '1' after  (1*Tusb1)/2,  -- 1
					'0' after  (2*Tusb1)/2, '1' after  (3*Tusb1)/2,  -- 2
					'0' after  (4*Tusb1)/2, '1' after  (5*Tusb1)/2,  -- 3
					'0' after  (6*Tusb1)/2, '1' after  (7*Tusb1)/2,  -- 4
					'0' after  (8*Tusb1)/2, '1' after  (9*Tusb1)/2,  -- 5
					'0' after (10*Tusb1)/2, '1' after (11*Tusb1)/2,  -- 6
					'0' after (12*Tusb1)/2, '1' after (13*Tusb1)/2;  -- 7
					
					when Sse0=>  -- 包尾
					pll<= 
					'0',                    '1' after  (1*Tusb1)/2,  -- 1
					'0' after  (2*Tusb1)/2, '1' after  (3*Tusb1)/2;  -- 2
					'0' after  (4*Tusb1)/2, '1' after  (5*Tusb1)/2;  -- 3
					
					when others=> -- 包尾或空闲
					pll<= '0',  '1' after  (1*Tusb1)/2;
				end case;
			end if;
		else
			state:= Soff;
		end if;
	end process;
	
	tb_clk <= osc   when stim= '1' else pll;
	uut_rxd<= tb_xd when stim= '1' else '1';
	uut_rx0<= tb_x0 when stim= '1' else '0';
	
	--------------------
	process
	begin
		wait until rising_edge(pll);
		wait for 1ns;
		
		assert(tb_xd= '-' or uut_txd= tb_xd) report "xd mismatch" severity FAILURE;
		assert(tb_x0= '-' or uut_tx0= tb_x0) report "x0 mismatch" severity FAILURE;
		
	end process;
end Test;

⌨️ 快捷键说明

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