2017-04-27 35 views
0

我正在開發一個項目,我需要在Altera DE1開發板上編碼WM8731音頻編解碼器芯片。該項目非常基礎。它不需要處理輸入音頻信號。來自輸入端的信號應該直接傳送到輸出端。時鐘配置 - VHDL編碼Altera DE1音頻編解碼器芯片

主要任務是通過I2C協議設置編解碼芯片。我是VHDL的新手,我有一些理解這個概念的問題。

在使用之前,編解碼芯片需要被初始化。這包括通過I2C傳遞數據組。下面給出了要傳遞的數據和說明。

constant sdin_load : std_logic_vector (11*24-1 downto 0) 
    --this contains codec configuration data 

問題 -主時鐘頻率爲50MHz,且I2C總線頻率爲100KHz。所以項目要求:
1)聲明位計數器; - 位計數器,在100kHz下運行,
2)聲明字計數器; - 字計數器,運行在5kHz左右
3)聲明位長的計數器; - 運行在50MHz的分頻計數器

我的理解是,由於主時鐘和I2C時鐘的頻率不同,我們需要有一個計數器來跟蹤事件。我的理解:
1)位計數器可以計數從1到500,這是50MHz/100KHz。所以每當計數器進入500時,下一個信息位就被傳送。
2)這是我不明白的部分。如果字計數器運行在5KHz,那麼它將只計數I2C脈衝的20個脈衝(100KHz/5KHz),而不是它發送的29位信息。
3)最後,爲什麼我們需要聲明一個以50MHz運行的位長計數器?我們已經有了這個頻率的時鐘。

我們已經給出了一個示例代碼。爲櫃檯的執行。我附上完整的體系結構以供參考。

library ieee; 
use ieee.std_logic_1164.all; 

entity codec_init is 
    port 
    (
     CLOCK_50 : in std_logic; -- master clock 
     RES_N  : in std_logic; -- reset, active 0 
     SCLK  : out std_logic; -- serial clock 
     SDIN  : out std_logic  -- serial data 
    ); 

end entity; 

architecture rtl of codec_init is 

    constant sdin_load : std_logic_vector (11*24-1 downto 0) 
    --this contains codec configuration data 

begin 

    process (CLOCK_50) 
    begin 
     if (rising_edge(CLOCK_50)) then 
     -- reset actions 
      if (RES_N = '0') then 
      -- reset the counters to an appropriate state 
       ...; -- load the frequency divider, 
        -- 50MHz/500=100kHz bus speed 
       ...; -- load the shift register 
       ...; -- load the bit counter, 
        -- 29 bits in the word protocol 
       ...; -- load the word counter, 11 words 
      -- reset the outputs to an appropriate state 
       ...; 
       ...; 

      elsif (...) then -- deadlock in the end 
       -- do nothing, wait for the next reset 

     -- modify reference counters 
     -- for frequency divider, bits and words 
      elsif (...) then -- at the end of each bit 
       ...; -- reload the frequency divider counter 

       if (bcnt = 0) then -- at the end of each word 
        ...; -- reset the bit counter 
        ...; --modify the word counter 
       else -- the bit is not the end of a word 
        ...; --modify the bit counter 
       end if; 

      else -- if not the end of the bit 
       ...; -- modify the frequency divider 
      end if; 

     -- generating SCLK, it is going up and then down inside each bit 
      if (...) then -- condition when SCLK goes up 
       ...; 
      elsif (...) then -- condition when SCLK goes down 
       ...; 
      end if; 

     -- generating serial data output 
      if (...) then -- start transition condition 
       ...; 
      elsif (...) then -- ack bit condition 
       ...; 
      elsif (...) then -- stop transition condition 
       ...; 
      elsif(...) then -- condition for the non-special bits 
       ...; -- shifting 
       ...; 
      end if; 

     -----------------------------  
     end if; 
    end process; 

    -- forming the output with high impedance states for ack-s 
    SDIN <= 'Z' when (...condition for ack bits...) 
        else (sdout); 

end rtl; 

謝謝。

+0

請參閱[I2C時鐘速度](https://www.i2c-bus.org/speed/),它似乎是一個全速I2C(最大400 kbits/sec)將適合您的目的。什麼阻止你使用更快的I2C? – user1155120

+0

我曾經與賽靈思的Ken Chapman就此主題進行了討論(FPGA邏輯上的I2C和RS232)。他曾嘗試過使用PicoBlaze,並發現需要較少的硬件來在一個(非常小的)軟核CPU中實現這些協議,然後在FPGA架構上實現這些協議。你可以考慮這一點。 – JHBonarius

+1

請不要通過刪除代碼破壞帖子。 –

回答

1

這可能不是您正在尋找的答案,但我會發布它,因爲它可能有用。

如果你的主要目標是編程你的音頻芯片,而不一定與I2C協議打架,你可以使用I2C模塊,例如OpenCores。你可以找到相當不錯的項目。我不能推薦特定的I2C,但有許多I2C項目,您可以嘗試。

有另一個地方,你可以嘗試尋找IP地址是Altera的IP庫。我不知道是否有I2C,因爲我使用Xilinx器件,但您可以嘗試。

編輯: 好吧,我也將把更多的實際問題,因爲很可能你的任務真正落實I2C。 據我所見,你被要求有計數器,而不是時鐘。這是不一樣的。而對於這個5KHz的 - 據說,這將是 5KHz的,可能是因爲你已經指出的原因。 如果你問你需要什麼這個計數器,我猜:

  1. 時鐘用於發送數據
  2. 你要算的話來判斷何時停止傳輸。
  3. 這是位長度,所以也許這50MHz應該是50KHz?這會更合理。

請仔細閱讀本代碼的評論內容。

+0

我修改了我的答案,請看一下。 – Staszek