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

📄 receivefromutopia.vhd

📁 utopia接口接收模块,实现utopia接口接收功能.可用于utopia仿真验证
💻 VHD
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity ReceiveFromUTOPIA is -- slave mode
   generic (
     fifo_width : integer := 32;
     clock_syn  : boolean := true
   );
   Port (
     reset		  : in	std_logic;   
     rxclk		  : in	std_logic;
     sysclk     : in  std_logic;
	   rxdata  	  : in  std_logic_vector(7 downto 0);
     rxenb   	  : in  std_logic;
     rxsoc   	  : in  std_logic;
     rxclav  	  : out std_logic;
	   rxclaven 	: out std_logic; 
	   rxaddr   	: in  std_logic_vector(4 downto 0);     
	   wbf	      : in	std_logic;
	   wren  	    : out std_logic;
	   wrsop      : out std_logic;
     wreop 	    : out std_logic;
     wrd	      : out std_logic_vector(31 downto 0);     
	   phyaddr  	: in 	std_logic_vector(4 downto 0);
	   cha        : in  std_logic_vector(7 downto 0)
  );
end ReceiveFromUTOPIA;

architecture Behavioral of ReceiveFromUTOPIA is
  function Get_CRC(
    data        :   std_logic_vector; 
    CRC         :   std_logic_vector;
    CRC_ACCUM   :   std_logic_vector
  )return std_logic_vector is  
    variable NewCRC     : std_logic_vector(CRC'length - 1 downto 0);  
    variable OldCRC     : std_logic_vector(CRC'length - 1 downto 0);
    variable CRC_POLY   : std_logic_vector(CRC'length - 1 downto 0); 
  begin
    OldCRC      := CRC;
    CRC_POLY    := CRC_ACCUM;
    for i in data'length - 1 downto 0 loop
      for j in 0 to CRC_POLY'length - 1 loop
        if j = 0 then
          if CRC_POLY(j) = '1' then
            NewCRC(j) := OldCRC(CRC_POLY'length - 1) xor data(i);
          else
            NewCRC(j) := data(i);    
          end if;
        else
          if CRC_POLY(j) = '1' then
            NewCRC(j) := OldCRC(CRC_POLY'length - 1) xor data(i) xor OldCRC(j - 1);
          else
            NewCRC(j) := OldCRC(j - 1);    
          end if;          
        end if;
      end loop; 
      OldCRC    := NewCRC;   
    end loop;
    return NewCRC;
  end Get_CRC;
  
  signal rxaddr_tmp	  :   std_logic_vector(4 downto 0);
  signal rxdata_syn   :   std_logic_vector(7 downto 0);
  signal rxenb_syn    :   std_logic;
  signal rxsoc_syn    :   std_logic;
  signal rxclav_tmp   :   std_logic;
  signal rxclk_d      :   std_logic;
  signal rxclken      :   std_logic;
  signal clk,clk_en   :   std_logic;
  signal wren_tmp     :   std_logic;
  signal wrsop_tmp    :   std_logic;
  signal wreop_tmp    :   std_logic;
  signal VPIVCI       :   std_logic_vector(23 downto 0);
  signal PT           :   std_logic_vector(3 downto 0);
  signal offset       :   integer  range 0 to 63 :=0;
  signal rxd          :   std_logic_vector(31 downto 0);
  signal Receiving    :   std_logic;
  type translatestate is (idle,Receive,stop);
  signal state 		    : translatestate; 

begin
   
  inputSyn  : process(rxclk)
  begin
    if rxclk'event and rxclk = '1' then
      if rxenb = '1' then
        rxaddr_tmp  <= rxaddr;        
      end if;
    end if;
  end process;

  rxclavProc : process(rxclk)
  begin
    if reset = '1' then
      rxclav_tmp		<= '0';
    elsif rxclk'event and rxclk = '1' then
      rxclav_tmp		<= (not wbf) and not Receiving;
	  end if;
  end process;

  rxclaven_proc : process(rxclk)
  begin
    if rxclk'event and rxclk = '1' then
      if (rxaddr = phyaddr) then
        rxclaven    <= '1';
      else
        rxclaven    <= '0';
      end if;
    end if;
  end process;
    
  label1 : if clock_syn /= true generate 
  begin
    clk           <= rxclk;
    clk_en        <= '1';
    rxdata_syn    <= rxdata;
    rxenb_syn     <= rxenb;
    rxsoc_syn     <= rxsoc;  
    rxclav        <= rxclav_tmp;   
  end generate;
  
  label2 : if clock_syn = true generate
  begin
    clk           <= sysclk;
    clk_en        <= rxclken;
    rxclav        <= rxclav_tmp;     
    data_syn_proc : process(rxclk)
    begin
      if rxclk'event and rxclk = '1' then
        rxdata_syn<= rxdata;
        rxenb_syn <= rxenb;
        rxsoc_syn <= rxsoc;                     
      end if;
    end process;      
    rxclk_syn_proc : process(rxclk,rxclken)
    begin
      if (rxclken or reset) = '1' then
        rxclk_d   <= '0';
      elsif rxclk'event and rxclk = '1' then
        rxclk_d   <= '1';
      end if;
    end process;
    rxclkce_proc : process(sysclk)
    begin
      if sysclk'event and sysclk = '1' then
        rxclken   <= rxclk_d;
      end if;
    end process;        
  end generate;
  
  data_out_proc : Process(clk)
  begin
    if clk'event and clk = '1' then
      if reset  = '1' then
        wrd        <= (others=>'0');
      elsif state = Receive then
        case offset is
          when 8      =>
            wrd    <= x"0003" & cha & x"ff";
          when 9      =>
            wrd    <= x"0300" & x"0030";        
          when 10      =>
            wrd    <= "0000" & VPIVCI & PT;              
          when 11     =>
            
          when others =>
            wrd    <= rxd;
        end case;
      else
        wrd        <= rxd;
      end if;
      if clock_syn /= true then
        wren       <= wren_tmp;
        wrsop      <= wrsop_tmp;
        wreop      <= wreop_tmp;          
      else
        wren      <= wren_tmp  and rxclken;
        wrsop     <= wrsop_tmp and rxclken;    
        wreop     <= wreop_tmp and rxclken;         
      end if;
    end if;
  end Process;  
  
  stateProc : process(clk)
  begin
    if clk'event and clk = '1' then
      if reset = '1' then
        wreop_tmp	    <= '0';
        wrsop_tmp     <= '0';
        wren_tmp      <= '0';
        offset        <= 0;
        Receiving     <= '0';
        state         <= idle;
        VPIVCI        <= (others=>'0');
        PT            <= (others=>'0');
        rxd           <= (others=>'0');
      elsif clk_en = '1' then 
        rxd           <= rxd(23 downto 0) & rxdata_syn;      
        case state   is
          when idle   =>
            wreop_tmp	    <= '0';
            wrsop_tmp     <= '0';
            wren_tmp      <= '0';    
            if (rxaddr_tmp = phyaddr) and (rxenb_syn = '0') then
              if rxsoc_syn = '1' then
                offset    <= 1;
              end if;
              Receiving   <= '1';
              state       <= Receive;
            else
              offset      <= 0;  
              Receiving   <= '0';
            end if;
          when Receive  =>
            if rxenb_syn  = '0' then            
              if rxsoc_syn = '1' then
                offset    <= 1;
              else
                if offset = 4 then                
                  offset  <= 8;
                else
                  if offset = 55 then
                    offset  <= 0;
                  else
                    offset  <= offset + 1;
                  end if;
                end if;
              end if;  
              if offset = 4 then
                VPIVCI    <= rxd(27 downto 4 );
                PT        <= rxd(3 downto 0);
              end if;      
              if ((offset mod 4) = 3 and (offset > 4)) or ((offset >= 4) and (offset < 12)) then
                wren_tmp   <= '1';   
              else
                wren_tmp   <= '0';   
              end if; 
              if offset = 55 then
                wreop_tmp  <= '1';
                state         <= stop;
              else
                wreop_tmp  <= '0';
              end if;           
            else
              wren_tmp     <= '0';
            end if;
          when stop   =>
            wren_tmp       <= '0';
            wreop_tmp      <= '0';
            if offset  = 3 then
              Receiving   <= '0';
              state       <= idle;
            else
              offset      <= offset + 1;
            end if;
          when others =>
            state         <= idle;  
        end case;
      end if;  
    end if;  
  end process;

end Behavioral;

⌨️ 快捷键说明

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