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

📄 控制器协议层.vhdl

📁 USB源代码
💻 VHDL
字号:
--控制器协议层
--file      :usbf_pd.vhd

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity usb_pd is    --实体声明
      generic(
      USBF_T_PID_OUT:std_logic_vector(3 downto 0):="0001";
      USBF_T_PID_IN:std_logic_vector(3 downto 0):="1001";
      USBF_T_PID_SOF:std_logic_vector(3 downto 0):="0101";
      USBF_T_PID_SETUP:std_logic_vector(3 downto 0):="1101";
      USBF_T_PID_DATA0:std_logic_vector(3 downto 0):="0011";
      USBF_T_PID_DATA1:std_logic_vector(3 downto 0):="1011";
      USBF_T_PID_DATA2:std_logic_vector(3 downto 0):="0111";
      USBF_T_PID_MDATA:std_logic_vector(3 downto 0):="1111";
      USBF_T_PID_ACK  :std_logic_vector(3 downto 0):="0010";
      USBF_T_PID_NACK :std_logic_vector(3 downto 0):="1010";
      USBF_T_PID_STALL:std_logic_vector(3 downto 0):="1110";
      USBF_T_PID_NYET :std_logic_vector(3 downto 0):="0110";        
      USBF_T_PID_PRE  :std_logic_vector(3 downto 0):="1100";
      USBF_T_PID_ERR  :std_logic_vector(3 downto 0):="1100";            
      USBF_T_PID_SPLIT:std_logic_vector(3 downto 0):="1000";  
      USBF_T_PID_PING :std_logic_vector(3 downto 0):="0100";      
      USBF_T_PID_RES  :std_logic_vector(3 downto 0):="0000";
      );
      
      port(clk,rst:in std_logic;
            rx_data:in std_logic_vector(7 downto 0);
            rx_valid,rx_active,rx_err:in std_logic;
            --PID数据包标试符信息输出
            
      pid_OUT,pid_IN,pid_SOF,pid_SETUP:buffer std_logic;
      pid_DATA0,pid_DATA1,pid_DATA2,pid_MDATA:buffer std_logic;
      pid_ACK,pid_NACK,pid_STALL,pid_NYET:buffer std_logic;
      pid_PRE,pid_ERR,pid_SPLIT,pid_PING:buffer std_logic;
      pid_cks_err:buffer std_logic;      --pid出错标识
        
      --令牌包信息输出接口
      token_fadr:buffer std_logic_vector(6 downto 0);    --地址信息
      token_endp:buffer std_logic_vector(3 downto 0);    --端点信息
      token_valid:buffer std_logic;                      --令牌包有效信息
      crc5_errut std_logic;                            --令牌包的CRC5错误检查
      frame_nout std_logic_vector(10 downto 0);        --SOF信息包输出信息

      --数据包信息输出接口
      rx_data_stut std_logic_vector(7 downto 0);      --数据输出
      rx_data_valid:out std_logic;                      --数据有效
      rx_data_done:out std_logic                        --数据传输结束
      crc16_err:out std_logic;                          --数据包CRC6出错检测
      seq_err:buffer std_logic;                          --状态机出错信息
      );
      end entity;

      architecture arch_usbf_pd of usbf_pd is
      

      compand usbf_crc5 port(
            crc_in:in std_logic_vector(15 downto 0);
            din:in std_logic_vector(7 downto 0);
            crc_out:out std_logic_vector(15 downto 0);
            );
      end compand;

      --状态机状态定义
      constant IDLE:std_logic_vector(3 downto 0):="0001";
      constant ACTIVE:std_logic_vector(3 downto 0):="0010";
      constant TOKEN:std_logic_vector(3 downto 0):="0100";
      constant DATA:std_logic_vector(3 downto 0):="1000";
      signal state,next_state:std_logic_vector(3 downto 0);

      signal pid:std_logic_vector(7 downto 0);      --PDI
      signal pid_le_sm:std_logic;        --状态机pid有效
      signal pid_ld_en:std_logic;        --pid有效使能
      
      signal pid_RES:std_logic;
      signal pid_TOKEN:std_logic;        --所有的令牌包统一的信号
      signal pid_DATA:std_logic;        --所有的数据包统一信号
      
      signal token0,token1:std_logic_vector(7 downto 0);  --令牌包缓存
      signal token_le_1,token_le_2:std_logic;              --令牌包缓存有效使能
      signal token_crc5:std_logic_vector(4 downto 0);

      signal d0,d1,d2:std_logic_vector(7 downto 0);    --数据通道延迟线(计算CRC5)
      signal data_valid_d:std_logic;                  --状态机输出数据有效信号
      signal data_done:std_logic;                      --数据有效信号延迟
      signal rxv1:std_logic; 
      signal rxv2:std_logic;

      signal got_pid_ack:std_logic;
      signal token_valid_r1:std_logic;
      signal token_valid_str1:std_logic;
      
      signal rx_active_r:std_logic;                  --输出有效
      
      signal crc5_out:std_logic_vector(4 doento 0);
      signal crc5_out2:std_logic_vector(4 doento 0);
      signal crc16_clr:std_logic;
      signal crc16_sum:std_logic_vector(15 down 0);
      signal crc16_out:std_logic_vector(15 down 0);  --crc5 crc16校验
    
      signal rx_data_temp:std_logic_vector(7 downto 0);
      signal token_temp:std_logic_vector(10 downto 0);
    
      begin
        
      --PID逻辑分析
      pid_ld_en<=pid_le_sm and rx_active and rx_valid;
      --PID输入寄存
      process(clk,rst)begin
            if(rst='0')then
                  pid<="11110000";
            elsif clk'event and clk='1'then
                    if(pid_ld_en='1')then
                          pdi<=rx_data;
                    end if;

          end if;
      end process;

      --PID校验,识别
      process(pid)begin
            if pid(3 downto 0)/=not(pid(7 downto 4))then pid_cks_err<='1';
            else pid_cks_err<='0';
            end if;                              --PID校验

            if pid(3 downto 0)=USBF_T_PID_OUT then pid_out<="1';
            else pid_OUT<='0';
            end if;
        
            if pid(3 downto 0)=USBF_T_PID_IN then pid_IN<='1';
            else PID_SETUP<='0';
            end if;

            if pid(3 downto 0)=USBF_T_PID_SOF then pid_SOF<='1';
            else PID_SOF<='0';
            end if;

            if pid(3 downto 0)=USBF_T_PID_SETUP then pid_setup<='1';
            else PID_SETUP<='0';
            end if;
    
            if pid(3 downto 0)=USBF_T_PID_DATA0 then pid_DATA0<='1';
            else PID_DATA0<='0';
            end if;
    
            if pid(3 downto 0)=USBF_T_PID_DATA1 then pid_DATA<='1';
            else PID_DATA1<='0';
            end if;

            if pid(3 downto 0)=USBF_T_PID_DATA2 then pid_DATA2<='1';
            else PID_DATA2<='0';
            end if;

            if pid(3 downto 0)=USBF_T_PID_MDATA then pid_MDATA<='1';
            else PID_MDATA<='0';
            end if;
            
            if pid(3 downto 0)=USBF_T_PID_ACK then pid_ACK<='1';
            else PID_ACK<='0';
            end if;  
                    
            if pid(3 downto 0)=USBF_T_PID_NACK then pid_NACK<='1';
            else PID_NACK<='0';
            end if;  
          
            if pid(3 downto 0)=USBF_T_PID_STALL then pid_STALL<='1';
            else PID_STALL<='0';
            end if;  
          
            if pid(3 downto 0)=USBF_T_PID_NYET then pid_NYET<='1';
            else PID_NYET<='0';
            end if;  

            if pid(3 downto 0)=USBF_T_PID_PRE then pid_PRE<='1';
            else PID_PRE<='0';
            end if;  

            if pid(3 downto 0)=USBF_T_PID_ERR then pid_ERR<='1';
            else PID_ERR<='0';
            end if;  

            if pid(3 downto 0)=USBF_T_PID_SPLIT then pid_SPLIT<='1';
            else PID_SPLIT<='0';
            end if;  

            if pid(3 downto 0)=USBF_T_PID_PING then pid_PING<='1';
            else PID_PING<='0';
            end if;  

            if pid(3 downto 0)=USBF_T_PID_RES then pid_RES<='1';
            else PID_ACK<='0';
            end if;  

        end process

        --令牌包数据包的统一识别
        pid_TOKEN<=pid_OUT or pid_SOF or pid_SRTUP or pid_PING;
        pid_DATA<=pid_DATA0 or pid_DATA1 or pid_DATA2 or pid_MDATA;

        --令牌包分析模块
        process(clk)begin
            if clk'event and clk='1'then
                    if(token_le_1='1')then
                          token0<=rx_data;
                    end if;
            end if
        end process;

        process(clk)begin
            if clk'event and clk='1'then
                    if(token_le_2='1')then
                          token1<=rx_data;
                    end if;
            end if
        end process;
    
        process(clk)begin
            if clk'event and clk='1'then
            token_valid_r1<=token_le_2;
            end if
        end process;

        ;

⌨️ 快捷键说明

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