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

📄 usbtstpak.vhd

📁 the vhdl model of usb. it is very helpful.
💻 VHD
📖 第 1 页 / 共 2 页
字号:
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		data:        in    STD_LOGIC_VECTOR(7 downto 0)) is
	begin
		bit01(clk, xd, x0, data(0)); fieldComputeCRC16(data(0));
		bit01(clk, xd, x0, data(1)); fieldComputeCRC16(data(1));
		bit01(clk, xd, x0, data(2)); fieldComputeCRC16(data(2));
		bit01(clk, xd, x0, data(3)); fieldComputeCRC16(data(3));
		bit01(clk, xd, x0, data(4)); fieldComputeCRC16(data(4));
		bit01(clk, xd, x0, data(5)); fieldComputeCRC16(data(5));
		bit01(clk, xd, x0, data(6)); fieldComputeCRC16(data(6));
		bit01(clk, xd, x0, data(7)); fieldComputeCRC16(data(7));
	end procedure;
	
	--------------------
	procedure fieldCRC5(	
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC) is
	begin
		--	When the last bit of the checked field is sent, the CRC in the 
		--	generator is inverted and sent to the checker MSb first. When 
		--	the last bit of the CRC is received by the checker and no 
		--	errors have occurred, the remainder will be equal to the 
		--	polynomial residual.		
		bit01(clk, xd, x0, not(crc5(4)));
		bit01(clk, xd, x0, not(crc5(3)));
		bit01(clk, xd, x0, not(crc5(2)));
		bit01(clk, xd, x0, not(crc5(1)));
		bit01(clk, xd, x0, not(crc5(0)));
	end procedure;
	
	--------------------
	procedure fieldCRC16(	
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC) is
	begin
		bit01(clk, xd, x0, not(crc16(15)));
		bit01(clk, xd, x0, not(crc16(14)));
		bit01(clk, xd, x0, not(crc16(13)));
		bit01(clk, xd, x0, not(crc16(12)));
		bit01(clk, xd, x0, not(crc16(11)));
		bit01(clk, xd, x0, not(crc16(10)));
		bit01(clk, xd, x0, not(crc16(9)));
		bit01(clk, xd, x0, not(crc16(8)));
		bit01(clk, xd, x0, not(crc16(7)));
		bit01(clk, xd, x0, not(crc16(6)));
		bit01(clk, xd, x0, not(crc16(5)));
		bit01(clk, xd, x0, not(crc16(4)));
		bit01(clk, xd, x0, not(crc16(3)));
		bit01(clk, xd, x0, not(crc16(2)));
		bit01(clk, xd, x0, not(crc16(1)));
		bit01(clk, xd, x0, not(crc16(0)));
	end procedure;
	
	----------------------------------------
	-- part #4: packets
	procedure packetOUT(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		addr:        in    STD_LOGIC_VECTOR(6 downto 0);
		ep:          in    STD_LOGIC_VECTOR(3 downto 0)) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldOUTpid);
		fieldADDR (clk, xd, x0, addr);
		fieldEP   (clk, xd, x0, ep);
		fieldCRC5 (clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetIN(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		addr:        in    STD_LOGIC_VECTOR(6 downto 0);
		ep:          in    STD_LOGIC_VECTOR(3 downto 0)) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldINpid);
		fieldADDR (clk, xd, x0, addr);
		fieldEP   (clk, xd, x0, ep);
		fieldCRC5 (clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetSOF(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		frame:       in    STD_LOGIC_VECTOR(10 downto 0)) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldSOFpid);
		fieldFRAME(clk, xd, x0, frame);
		fieldCRC5 (clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetSETUP(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		addr:        in    STD_LOGIC_VECTOR(6 downto 0);
		ep:          in    STD_LOGIC_VECTOR(3 downto 0)) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldSETUPpid);
		fieldADDR (clk, xd, x0, addr);
		fieldEP   (clk, xd, x0, ep);
		fieldCRC5 (clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetDATA0(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		data:        in    packetBUF) is
		variable i: INTEGER;
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldDATA0pid);
		
		for i in data'range loop
			fieldBYTE(clk, xd, x0, data(i));
		end loop;
		
		fieldCRC16(clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetDATA0(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		data:        in    packetCHR) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldDATA0pid);
		
		fieldBYTE(clk, xd, x0, data);
		
		fieldCRC16(clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetDATA0(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC) is
		variable i: INTEGER;
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldDATA0pid);
		fieldCRC16(clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetDATA1(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		data:        in    packetBUF) is
		variable i: INTEGER;
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldDATA1pid);
		
		for i in data'range loop
			fieldBYTE(clk, xd, x0, data(i));
		end loop;
		
		fieldCRC16(clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetDATA1(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		data:        in    packetCHR) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldDATA1pid);
		
		fieldBYTE(clk, xd, x0, data);
		
		fieldCRC16(clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetDATA1(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC) is
		variable i: INTEGER;
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldDATA1pid);
		fieldCRC16(clk, xd, x0);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetACK(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldACKpid);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetNAK(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldNAKpid);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetSTALL(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC) is
	begin
		fieldSYNC (clk, xd, x0);
		fieldPID  (clk, xd, x0, fieldSTALLpid);
		fieldEOP  (clk, xd, x0);
	end procedure;
	
	--------------------
	procedure packetIDLE(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC;
		cycles:      in    INTEGER) is
		variable i: INTEGER;
	begin
		i:= 0;
		while i< cycles loop
			fieldIDLE(clk, xd, x0);
			i:= i+1;
		end loop;
	end procedure;
	
	--------------------
	procedure packetRESET(
		signal clk:  in    STD_LOGIC;
		signal xd:   out   STD_LOGIC;
		signal x0:   out   STD_LOGIC) is
	begin
		fieldSE0(clk, xd, x0);
		
		-- Reference: USB Spec 1.1
		-- * The reset signaling must be driven for a minimum of 10ms (TDRST).
		-- * Resets from root ports should be nominally 50ms (TDRSTR).
		-- * A device seeing an SE0 on its upstream port for more than 
		--   2.5us (TDETRST) may treat that signal as a reset.
		
		--wait for 50ms;
		--wait for 10ms;
		wait for 5us;
	end procedure;
	
end package body usbTSTPAK;

--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use work.usbTSTPAK.all;

entity usbTSTctrl is
	port(
		signal sim:     in    STD_LOGIC;  -- TRUE while simulating
		signal stim:    in    STD_LOGIC;  -- TRUE to stimulate UUT
		--
		signal clk48:   out   STD_LOGIC;  -- 48MHz clock
		signal rst:     out   STD_LOGIC;  -- async reset
		--
		signal uut_rxd: out   STD_LOGIC;  -- UUT rxd pin
		signal uut_rx0: out   STD_LOGIC;  -- UUT rx0 pin
		signal uut_txd: in    STD_LOGIC;  -- UUT txd pin
		signal uut_tx0: in    STD_LOGIC;  -- UUT tx0 pin
		--
		signal tb_xd:   in    STD_LOGIC;  -- testbench xd signal
		signal tb_x0:   in    STD_LOGIC;  -- testbench x0 signal
		signal tb_clk:  out   STD_LOGIC   -- testbench clock
		);
end usbTSTctrl;

architecture Test of usbTSTctrl is
	signal   pll:     STD_LOGIC;
	signal   osc:     STD_LOGIC;
	constant Tusb1:   TIME:= 84ns;
	constant Tusb2:   TIME:= 21ns;
begin
	
	--------------------
	-- UUT clock & reset
	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;
	
	--------------------
	-- stimuli clock oscillator
	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;
	
	--------------------
	-- response clock recovery
	process(uut_txd, uut_tx0, stim)
		type Tstate is (Soff, Sx1, Sx, Sse0);
		variable state: Tstate;
	begin
		if stim= '0' then
			-- clock recovery state machine
			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;
			
			-- clock recovery
			if (uut_txd'event and (uut_txd= '1' or uut_txd= '0'))
				or (uut_tx0'event) then
				case state is
					when Sx1=> -- sync pattern at start of packet
					pll<= '0',  '1' after  (1*Tusb1)/2;
					
					when Sx=>  -- normal bits
					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=>  -- se0 at end of packet
					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=> -- J at end of packet or bus idle
					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;

--------------------------------------------------------------------------------
-- end of file

⌨️ 快捷键说明

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