process(clk)begin
if clk'event and clk='1'then
token_valid_str1<=token_valid_r1 or got_pid_ack;
end if
end process;
token_valid<=token_valid_str1;
--CRC5数据校验模块,时序需要一个时钟周期
process(token_valid,crc5_out2,token_crc5)begin
if(crc5_out2/=token_crc5)then
crc5_err<=token_valid;
else crc5_err<='0';
end if;
end process
token_temp<=token_fadr(0)&token_fadr(1)&token_fadr(2)&token_fadr(3)&token_fadr(4) &token_fadr(5)&token_fadr(6)&token_endp(0)&token_endp(1)&token_endp(2)
&token_endp(03);
usbf_crc5_u0:usbf_crc5 port map(
"11111",
token_temp,
crc5_out
);
--CRC5校验输出
crc5_out2<=not(crc5_out(0)&crc5_out(1)&crc5_out(2)&crc5_out(3)&crc5_out(4);
frame_no<=token1(2 downto 0)&token0;
token_fadr<=token0(6 downto 0);
token_endp<=token1(2 downto 0)&token0(7);
token_crc5<=token1(7 downto 3);
--数据接收逻辑
--rxv1 rxv2的作用是对数据有效信号做2个时钟的延迟
process(clk,rst)begin
if(rst='0') then
rxv1<='0';
elsif clk'event and clk='1'then
if(data_valid_d='1')then
rxv1<='1';
elsif(data_done='1')then
rxv1<='0';
end if;
end if;
end process;
process(clk,rst)begin
if(rst='0') then
rxv2<='0';
elsif clk'event and clk='1'then
if(rxv1='1' and data_valid_d='1')then
rxv2<='1';
elsif(data_done='1')then
rxv2<='0';
end if;
end if;
end process;
process(clk)begin
if clk'event and clk='1'then
data_valid0<=rxv2 and data_valid_d;
end if;
end process;
process(clk)begin
if clk'event and clk='1'then
if(data_valid_d='1')then d0<=rx_data;end if;
if(data_valid_d='1')then d1<=d0;end if;
if(data_valid_d='1')then d2<=d1;end if; --数据2个时钟延迟
end if;
end process;
rx_data_st<=d2;
rx_data_valid<=data_vlid0;
rx_data_done<=data_done;
--crc16数据校验
process(clk)begin
if clk'event and clk='1'then
rx_active_r<=rx_active;
end if;
end process;
crc16_clr<=rx_active and not(rx_active_r);
process(clk)begin
if clk'event and clk='1'then
if(crc16_clr='1')then
crc16_sum<='1111111111111111";
else
if(data_valid_d='1')then crc16_sum<=crc16_out;
end if;
end if;
end if;
end process;
rx_data_temp<=rx_data(0)&rx_data(1)&rx_data(2)&rx_data(3)
&rx_data(4)&rx_data(5)&rx_data(6)&rx_data(7);
usbf_crc16_u1:usb_crc16 port map(
crc16_sum,
rx_data_temp,
crc16_out
);
process(data_done,crc16_sum)begin
if crc16_sum/="1000000000001101"then
crc16_err<=data_done;
else crc16_err<='0';
end if;
end process;
--状态机设计
process(clk,rst)begin
if(rst='0') then
state<=IDLE;
elseif clk'event and clk='1'then
state<=next_state;
end if;
end process;
process(state,rx_valid,rx_active,rx_err,pid_ACK,pid_TOKEN,pid_DATA)
begin
next_state<=state; --默认状态不改变状态机状态
pid_le_sm<='0';
token_le_1<='0';
token_le_2<='0';
data_valid_d<='0';
data_done<='0';
seq_err<='0';
got_pid_ack<='0';
case state is ---状态机
when IDLE=>
pid_le_sm<='1';
if(rx_valid='1' and rx_active='1')then
next_state<=ACTIVE;
end if;
when ACTIVE=>
--收到数据包标识符号
if(pid_ACK='1' and rx_err='0')then
got_pid_ack<='1';
if(rx_active='0')then
next_atate<=IDLE;
end if;
--收到令牌token数据包标识符
elsif(pid_TOKEN='1' and rx_valid='1' and rx_ctive='1' and rx_err='0')then
token_le_1<='1';
next_state<=TOKEN;
--收到data数据包标识符
elsif(pid_TOKEN='1' and rx_valid='1' and rx_ctive='1' and rx_err='0')then
data_valid_d<='1';
next_state<=DATA;
elsif(rx_active='0' or rx_err='1'or
(rx_valid='1' and not(pid_TOKEN='1' or pid_DATA='1')))then
seq_err<==not(rx_err);
if(rx_active='0')then next_state<=IDLE;
end if;
end if;
--令牌token数据包处理
when TOKEN=>
if(rx_valid='1' and rx_active='1' and rx_err='0')then
token_le_2<='1';
next_state<=IDLE;
elsif(rx_active='0' or rx_err='1')then
seq_err<=not(rx_err);
if(rx_active='0')then
next_state<=IDLE;
end if;
end if;
--DATA数据包处理
when DATA=>
if(rx_valid='1' and rx_active='1' and rx_err='0') then
data_vlid_d<='1';
end if;
if(rx_active='0' or rx_err='1')then
data_done<='1';
if(rx_active='0')then
next_state<=IDLE;
end if;
end if;
when other=>
null;
end case;
end process;
end architecture;