📄 usbctrl.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 + -