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

📄 translatetoutopia.vhd

📁 VHDL写一个转换到utopia接口的转换源程序.可以进行utopia接口的仿真试验
💻 VHD
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity TranslateToUTOPIA is  -- slave mode 
  generic(
    fifo_width: integer := 32;
    Pclass    : integer := 4;
    clock_syn : boolean := true     
  );
  Port (  
    reset     : in  std_logic;
    txclk     : in  std_logic;  
    sysclk    : in  std_logic;
    txaddr    : in  std_logic_vector(4 downto 0);
    txenb     : in  std_logic;
    txclav    : out std_logic;
    txclaven  : out std_logic;
    txdata    : out std_logic_vector(7 downto 0);   
    txdataen  : out std_logic;
    txsoc     : out std_logic;
    txsocen   : out std_logic;  
    rbe       : in  std_logic_vector(Pclass - 1 downto 0);  
    rdd       : in  std_logic_vector(fifo_width - 1 downto 0);
    rdeop     : out std_logic;  
    rden      : out std_logic;   
    rdport    : out std_logic_vector(Pclass - 1 downto 0);   
    timerset  : in  std_logic_vector((Pclass * 16) - 1 downto 0);                     
    phyaddr   : in  std_logic_vector(4 downto 0)
  );
end TranslateToUTOPIA;

architecture Behavioral of TranslateToUTOPIA 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;

  type translatestate is (idle,waiting,translating,stop,pause,pause1,pause2);
  signal state        : translatestate;
  signal dataout      :   std_logic_vector(7 downto 0);
  signal offset       :   integer  range 0 to 63 :=0;
  signal crc8         :   std_logic_vector(7 downto 0);
  signal rden_tmp     :   std_logic;
  signal rdeop_tmp    :   std_logic;
  signal txclk_d      :   std_logic;
  signal txclken      :   std_logic;  
  signal clk,clk_en   :   std_logic;
  signal txenb_syn    :   std_logic;
  signal txaddr_tmp   :   std_logic_vector(4 downto 0);
  signal txclav_tmp   :   std_logic;
  signal txdata_tmp   :   std_logic_vector(7 downto 0);
  signal txdataen_tmp :   std_logic;
  signal txsoc_tmp    :   std_logic;
  signal txsocen_tmp  :   std_logic;
  signal temp         :   std_logic_vector(31 downto 0);

  signal txrbe        :   std_logic;
  type timertype is array(Pclass -1 downto 0) of std_logic_vector(15 downto 0);
  signal timer        :   timertype;
  signal txenable     :   std_logic_vector(Pclass -1 downto 0):=(others=>'0');
  signal rdport_tmp   :   std_logic_vector(Pclass - 1 downto 0);

begin
  
  txrbeProc : Process(rbe)
    variable  temp : std_logic;
  begin
    temp := '1';
    for i in 0 to Pclass - 1 loop
      temp  := temp and rbe(i);
    end loop;
    txrbe  <= temp;
  end Process;
  
  in_syn_proc : process(txclk)
  begin
    if txclk'event and txclk = '1' then
      txenb_syn <= txenb;
      if txenb = '1' then
        txaddr_tmp <= txaddr;
      end if;
    end if;
  end process;
  
  txclav_tmp_Proc : process(txclk)
  begin
    if txclk'event and txclk = '1' then
      if txaddr = phyaddr then
        txclaven    <= '1';
      else
        txclaven    <= '0';
      end if;
    end if;
  end process;     

  label1 : if clock_syn /= true generate 
  begin
    clk           <= txclk;
    clk_en        <= '1';
    txdata        <= txdata_tmp;
    txdataen      <= txdataen_tmp;
    txclav        <= txclav_tmp;
    txsoc         <= txsoc_tmp;
    txsocen       <= txsocen_tmp;  
    txdata_tmp    <= crc8 when offset = 4 else dataout;
    txdataen_tmp  <= not txenb_syn when (txaddr_tmp = phyaddr) and (state /= idle) else '0';  
    rden          <= rden_tmp;
    rdeop         <= rdeop_tmp;
    rdport        <= rdport_tmp;          
  end generate;
  
  label2 : if clock_syn = true generate
  begin
    clk           <= sysclk;
    clk_en        <= txclken;    
    txdata_tmp    <= crc8 when offset = 4 else dataout;
    txdataen_tmp  <= not txenb_syn when (txaddr_tmp = phyaddr) and (state /= idle) else '0';          
    data_syn_proc : process(txclk)
    begin
      if txclk'event and txclk = '1' then
        txdata    <= txdata_tmp;
        txdataen  <= txdataen_tmp;
        txclav    <= txclav_tmp;
        txsoc     <= txsoc_tmp;
        txsocen   <= txsocen_tmp;                   
      end if;
    end process;      
    txclk_syn_proc : process(txclk,txclken)
    begin
      if (txclken or reset) = '1' then
        txclk_d   <= '0';
      elsif txclk'event and txclk = '1' then
        txclk_d   <= '1';
      end if;
    end process;
    rxclkce_proc : process(sysclk)
    begin
      if sysclk'event and sysclk = '1' then
        txclken   <= txclk_d;
      end if;
    end process;        
    rd_proc : process(sysclk)
    begin
      if sysclk'event and sysclk = '1' then
        rden      <= rden_tmp and txclken;
        rdeop     <= rdeop_tmp and txclken;
        rdport    <= rdport_tmp;                
      end if;
    end process;
  end generate;
     
  stateProc : process(clk)
  begin  
    if clk'event and clk = '1' then
      if reset = '1' then
        state         <= idle;
        rdeop_tmp     <= '0';
        txclav_tmp    <= '0';
        txsoc_tmp     <= '0';
        txsocen_tmp   <= '0';  
        rden_tmp      <= '0'; 
        offset        <= 0;    
        temp          <= (others=>'0');    
        crc8          <= (others=>'0');         
        for i in 0 to Pclass - 1 loop
          timer(i)       <= (others=>'0');
          txenable(i)    <= '1';
          rdport_tmp(i)  <= '0';
        end loop;
      elsif clk_en = '1' then       
        for i in 0 to Pclass - 1 loop
          if (txenable(i)and not rbe(i)) = '1' then
            timer(i)      <= timerset((16 * i) + 15 downto 16 * i);  
          else
            if timer(i) /= x"0000" then
              timer(i)    <= timer(i) - 1;
            end if;        
          end if; 
          if timer(i) = x"0000" then
            txenable(i)   <= '1';
          else
            txenable(i)   <= '0';
          end if;        
        end loop;  
        case state is
          when idle      =>
            rdeop_tmp   <= '0';   
            rden_tmp    <= '0';                  
            offset      <= 0;                    
            for i in 0 to Pclass - 1 loop
              if (txenable(i) and not rbe(i)) = '1' then
                state         <= waiting;                                        
                rdport_tmp(i) <= '1';                                            
                exit;              
              else
                rdport_tmp(i) <= '0';               
              end if;
            end loop;
          when waiting     =>              
            if (txaddr_tmp = phyaddr) and (txenb_syn = '0') then         
              txsoc_tmp    <= '1';       
              txsocen_tmp  <= '1';
              temp         <= rdd;
              rden_tmp     <= '1';
              state        <= translating;
            else
              txsoc_tmp    <= '0';
              txsocen_tmp  <= '0';           
            end if;    
            offset         <= 0; 
            txclav_tmp     <= '1';
            crc8           <= (others=>'0');                
          when translating =>       
            txclav_tmp     <= '0';
            txsoc_tmp      <= '0';
            txsocen_tmp    <= '0'; 
            if clock_syn = true then
              if (((offset mod 4) = 3) and (offset > 4)) or ( offset = 4) then
                rden_tmp   <= '1';
                temp       <= rdd;                   
              else
                rden_tmp   <= '0';
              end if;            
            else
              if ((offset mod 4) = 3) or (offset = 4) then
                temp       <= rdd;                   
              end if;                                   
              if ((offset mod 4) = 2) then
                rden_tmp   <= '1';
              else
                rden_tmp   <= '0';
              end if;            
            end if;
            if offset = 4 then
              offset     <= 8;
            else               
              offset     <= offset + 1;  
            end if;
            if offset < 4 then
              CRC8       <= Get_CRC(dataout,CRC8,x"35");              
            end if;                               
            if txenb_syn = '1' then                       
              state      <= stop;                    
            end if;  
          when stop      =>
            rden_tmp     <= '1';         
            rdeop_tmp    <= '1';                
            state        <= pause;
          when pause     =>
            rdeop_tmp    <= '0';    
            rden_tmp     <= '0';  
            state        <= pause1;   
          when pause1    =>
            state        <= pause2;   
            for i in 0 to Pclass - 1 loop
              rdport_tmp(i)<= '0'; 
            end loop;
          when pause2    =>
            state        <= idle;     
          when others    => 
            state        <= idle;                                
        end case;
      end if; 
    end if;
  end process;
  
  dataout_Proc : process(offset,temp)
  begin  
    case offset mod 4 is
      when 0      =>
        dataout   <= temp(31 downto 24);
      when 1      =>
        dataout   <= temp(23 downto 16);
      when 2      =>
        dataout   <= temp(15 downto 8);    
      when others =>
        dataout   <= temp(7 downto 0);
    end case;
  end process;
  
end Behavioral;

⌨️ 快捷键说明

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