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

📄 ac97_core.vhd

📁 Viertex 2 开发板的接口程序
💻 VHD
📖 第 1 页 / 共 2 页
字号:
              register_write_cmd <= '0';
            end if;
          end if;

          -- Wait for the end of the current frame. During the last cycle of
          -- this state (last_frame_cycle = 1), all the signals are
          -- latched into slot 0 and a valid request is on its way out.
        when WAIT_FOR_NEW_FRAME =>
          if last_frame_cycle = '1' then
            reg_if_state <= SEND_REQUEST_FRAME;
          end if;

          -- Wait for the request to be completely sent to the codec.
        when SEND_REQUEST_FRAME =>
          if last_frame_cycle = '1' then
            reg_if_state <= RESPONSE_SLOT0;
          end if;
          
          -- Wait for the response in slot 0 and make sure the
          -- appropriate response bits are set
        when RESPONSE_SLOT0 =>
          if slot_No = 0 and slot_end = '1' then
            if register_write_cmd = '0' then
              if (data_in(14) /= '1' or data_in(13) /= '1') then
                -- Bit 14 of Slot 0 indicates a valid slot 1 data
                -- (echo the requested address). If this is not a
                -- '1' then there is was an error. Bit 13 of Slot 0
                -- indicates a valid data response. If the transaction
                -- was a read and it is not true, an error.
                ac97_reg_error_i <= '1';
                reg_if_state <= END_STATE;
              else
                reg_if_state <= RESPONSE_SLOT1;
              end if;
            else
              -- Nothing else to do for writes
              reg_if_state <= END_STATE;
            end if;
          end if;

          -- Check the data in slot 1 and make sure it matches
          -- the address sent
        when RESPONSE_SLOT1 =>
          if slot_No = 1 and slot_end = '1' then
            if data_in(18 downto 12) /= register_addr then
              ac97_reg_error_i <= '1';
              reg_if_state <= END_STATE;
            else 
              -- we need to get the data for read commands
              reg_if_state <= RESPONSE_SLOT2;
            end if;
          end if;

        when RESPONSE_SLOT2 =>
          if slot_No = 2 and slot_end = '1' then
            AC97_Reg_Read_Data <= data_in(19 downto 4);
            AC97_Reg_Read_Data_Valid <= '1';
            reg_if_state <= END_STATE;
          end if;
          
        when END_STATE =>
          ac97_reg_busy_i <= '0';
          reg_if_state <= IDLE;

        when others => NULL;

      end case;
    end if;
  end process register_if_PROCESS;
  AC97_Reg_Busy <= ac97_reg_busy_i;
  AC97_Reg_Error <= ac97_reg_error_i;

  with reg_if_state select 
    debug(0 to 2) <= "000" when IDLE,
                       "001" when  WAIT_FOR_NEW_FRAME,
                       "010" when  SEND_REQUEST_FRAME,
                       "011" when  RESPONSE_SLOT0,
                       "100" when  RESPONSE_SLOT1,
                       "101" when  RESPONSE_SLOT2,
                       "110" when  END_STATE,
                       "000" when others;
  debug(3 to 15) <= (others => '0');
    
  -- This signal indicates that we are sending a request command
  -- and that the address send to the codec is valid
  valid_Control_Addr <= '1' when reg_if_state = WAIT_FOR_NEW_FRAME
                        else '0';


  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------
  -- Output Section
  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------

  -----------------------------------------------------------------------------
  -- Setup slot0 data at start of frame
  --
  -- Slot 0 is the TAG slot. The bits of this slot are defined as
  -- follows:
  -- bit 15: Valid frame
  -- bit 14: valid control address (slot 1)
  -- bit 13: valid control data (slot 2)
  -- bit 12: valid PCM playback data Left (slot 3)
  -- bit 11: valid PCM playback data Right (slot 4)
  -- bot 10-2: ignored - fill with zeros
  -- bit 1-0: 2-bit codec ID (assigned to '00' for primary)
  --
  -- The slot 0 signals are created directly from the inputs
  -- of the module rather than using the "registered" versions
  -- (i.e. ac97_reg_write instead of ac97_reag_write_i). The
  -- slot0 signal is latched on the clock edge following
  -- the frame signal into the shift register signal "data_out".
  -- 
  -----------------------------------------------------------------------------

  -- temporary
  
  valid_Frame <= valid_Control_Addr or
                 pcm_playback_left_valid or
                 pcm_playback_right_valid;

  slot0(15)         <= valid_Frame;
  slot0(14)         <= valid_Control_Addr;
  slot0(13)         <= register_write_cmd;  -- valid data only during write
  slot0(12)         <= PCM_Playback_Left_Valid;
  slot0(11)         <= PCM_Playback_Right_Valid;
  slot0(10 downto 2) <= "000000000";
  slot0(1 downto 0) <= "00";
  
  -----------------------------------------------------------------------------
  -- Slot 1
  --
  -- Slot 1 is the Command Address:
  -- Bit 19: Read/Write (1=read,0=write)
  -- Bit 18-12: Control register index/address
  -- Bit 11:0 reserved (stuff with 0)
  -----------------------------------------------------------------------------
  slot1(19)           <= not register_write_cmd;
  slot1(18 downto 12) <= register_addr;
  slot1(11 downto 0) <= (others => '0');

  -----------------------------------------------------------------------------
  -- Slot 2
  --
  -- Slot 2 is the Command Data Port:
  -- Bit 19-4: Control register write data 
  -- Bit 3-0: reserved (stuff with 0)
  -----------------------------------------------------------------------------
  slot2(19 downto 4) <= register_data;
  slot2( 3 downto 0) <= (others => '0');

  -----------------------------------------------------------------------------
  -- Setup slot3 data (PCM play left)
  -----------------------------------------------------------------------------
  process (PCM_Playback_Left) is
  begin
    slot3((20 - C_PCM_DATA_WIDTH-1) downto 0) <= (others => '0');
    slot3(19 downto (20 - C_PCM_DATA_WIDTH)) <= PCM_Playback_Left;
  end process;

  -----------------------------------------------------------------------------
  -- Setup slot4 data (PCM play right)
  -----------------------------------------------------------------------------
  process (PCM_Playback_Right) is
  begin
    slot4((20 - C_PCM_DATA_WIDTH-1) downto 0) <= (others => '0');
    slot4(19 downto (20 - C_PCM_DATA_WIDTH)) <= PCM_Playback_Right;
  end process;

  -----------------------------------------------------------------------------
  -- Output data multiplexer for AC97_SData_Out signal
  --
  -- Choose the appropriate data to send out the shift register
  -- (new_data_out)
  -----------------------------------------------------------------------------
  process (last_frame_cycle, slot_end, slot_No, slot0,
           slot1, slot2, slot3, slot4) is
  begin  -- process
    new_data_out <= (others => '0');
    if (last_frame_cycle = '1') then
      new_data_out(19 downto 4) <= slot0;
    elsif (slot_end = '1') then
      case slot_No is
        when 0 => new_data_out(slot1'range) <= slot1;
        when 1 => new_data_out(slot2'range) <= slot2;
        when 2 => new_data_out <= slot3;
        when 3 => new_data_out <= slot4;
        when others => null;
      end case;
    end if;
  end process;

  -----------------------------------------------------------------------------
  -- AC97 data out shift register
  -----------------------------------------------------------------------------
  Data_Out_Handle : process (AC97_Bit_Clk) is
  begin  -- process Data_Out_Handle
    if reset = '1' then
      data_out <= (others => '0');
    elsif AC97_Bit_Clk'event and AC97_Bit_Clk = '1' then  -- rising clock edge
      if (last_frame_cycle = '1') or (slot_end = '1') then
        data_out <= New_Data_Out;
      else
        data_out(19 downto 0) <= data_out(18 downto 0) & '0';
      end if;
    end if;
  end process Data_Out_Handle;
  AC97_SData_Out <= data_out(19);

  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------
  -- Input Section
  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------

  -----------------------------------------------------------------------------
  -- AC97 data in shift register
  -----------------------------------------------------------------------------
  Shifting_Data_Coming_Back : process (AC97_Bit_Clk) is
  begin  -- process Shifting_Data_Coming_Back
    if AC97_Bit_Clk'event and AC97_Bit_Clk = '0' then  -- falling clock edge
      data_in(19 downto 0) <= data_in(18 downto 0) & AC97_SData_In;
    end if;
  end process Shifting_Data_Coming_Back;

  -----------------------------------------------------------------------------
  -- Get slot 0 data (TAG - which slots are valid)
  -----------------------------------------------------------------------------
  process (AC97_Bit_Clk) is
  begin
    if AC97_Bit_Clk'event and AC97_Bit_Clk = '1' then  -- rising clock edge
      if (slot_no = 0 and slot_end = '1') then
        codec_rdy_i           <= data_in(15);
        -- data_in(14) and data(13) are used directly in the reg_if
        -- state machine
        --return_status_address_valid <= data_in(14);
        -- return_status_data_valid <= data_in(13);
        record_pcm_left_valid <= data_in(12);
        record_pcm_right_valid <= data_in(11);
      end if;
    end if;
  end process;

  PCM_Record_Left_Valid <= record_pcm_left_valid and last_frame_cycle;
  PCM_Record_Right_Valid <= record_pcm_right_valid and last_frame_cycle;
                           
  codec_rdy <= codec_rdy_i;

  -----------------------------------------------------------------------------
  -- Get slot 1 PCM request bit
  -----------------------------------------------------------------------------
  process (AC97_Bit_Clk) is
  begin
    if AC97_Bit_Clk'event and AC97_Bit_Clk = '1' then
      if (slot_end = '1' and slot_No = 1 ) then
        accept_pcm_left <= not data_in(11);
        accept_pcm_right <= not data_in(10);
      end if;
    end if;
  end process;

  PCM_Playback_Left_Accept <= accept_pcm_left and last_frame_cycle;
  PCM_Playback_Right_Accept <= accept_pcm_right and last_frame_cycle;
  
  -----------------------------------------------------------------------------
  -- Get slot 3 and 4 data
  -----------------------------------------------------------------------------
  Get_Record_Data : process (AC97_Bit_Clk) is
    -- synthesis translate_off
    variable my_line : LINE;
    -- synthesis translate_on
  begin  -- process Get_Record_Data
    if AC97_Bit_Clk'event and AC97_Bit_Clk = '1' then  -- rising clock edge
      if (slot_end = '1' and slot_No = 3 ) then
        PCM_Record_Left_i   <= data_in(19 downto (20 - C_PCM_DATA_WIDTH));
        -- synthesis translate_off
        write(my_line, string'("AC97 Core: Received Left Value "));
        write(my_line, bit_vector'( To_bitvector(PCM_Record_Left_i)  ));
        writeline(output, my_line);
        -- synthesis translate_on
      elsif (slot_end = '1' and slot_No = 4 ) then
        PCM_Record_Right_i   <= data_in(19 downto (20 - C_PCM_DATA_WIDTH));
        -- synthesis translate_off
        write(my_line, string'("AC97 Core: Received Right Value "));
        write(my_line, bit_vector'( To_bitvector(PCM_Record_Right_i)  ));
        writeline(output, my_line);
        -- synthesis translate_on
      end if;
    end if;
  end process Get_Record_Data;
  PCM_Record_Left <= PCM_Record_Left_i;
  PCM_Record_Right <= PCM_Record_Right_i;

  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------
  -----------------------------------------------------------------------------

end architecture IMP;

⌨️ 快捷键说明

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