저는 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) 비트 카운터는 50MHz/100KHz 인 1에서 500까지 계산할 수 있습니다. 그래서 카운터가 500 비트가 될 때마다 정보가 전송됩니다.
2) 이것은 내가 이해할 수없는 부분입니다. 단어 카운터가 5KHz에서 실행되면, 전송중인 29 비트의 정보가 아니라 I2C 클럭 (100KHz/5KHz)의 20 펄스 만 카운트합니다.
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;
감사합니다.
참조 [I2C 클럭 속도 (https://www.i2c-bus.org/speed/)는, 당신의 목적에 맞게 것이다 전체 속도 I2C (400 kbits로/초 최대)을 보인다. 보다 빠른 I2C 사용을 중단시키는 원인은 무엇입니까? – user1155120
나는 한 번이 주제 (FPGA 로직에 I2C 및 RS232)에 자일링스의 켄 채프먼과 토론을했다. 그는 자신은 PicoBlaze 실험과 그 FPGA 패브릭에 그들을 구현 한 후, A (아주 작은) 소프트 코어 CPU에서 이러한 프로토콜을 구현하기 위해 더 적은 하드웨어를 필요로한다 발견했다. 당신은 그것을 고려할 수 있습니다. – JHBonarius
코드를 삭제하여 게시물을 파손하지 마십시오. –