时钟配置——VHDL编码Altera DE1音频编解码芯片
Clock configuration - VHDL coding Altera DE1 audio codec chip
我正在做一个项目,我需要在 Altera DE1 板上编写 WM8731 音频编解码器芯片。该项目非常基础。它不需要处理输入的音频信号。来自输入的信号应直接中继到输出。
主要任务是通过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;
谢谢。
这可能不是您要找的答案,但我会 post 因为它可能有用。
如果您的主要目标只是对您的音频芯片进行编程,而不一定要与 I2C 协议作斗争,您可以使用例如 OpenCores 中的 I2C 块。你可以在那里找到很好的项目。我不能为 I2C 推荐特定的一个,但是有很多 I2C 项目,你可以尝试。
另一个您可以尝试寻找 IP 的地方是 Altera 的 IP 库。我不知道那里是否有用于 I2C 的,因为我使用 Xilinx 设备,但你可以试试。
编辑:
好吧,我也会更多地提到实际问题,因为你的任务可能是真正实现 i2c。
据我所知,你被要求有计数器,而不是时钟。这是不一样的。对于这个 5KHz - 据说它将是 about 5KHz,可能是因为你已经指出的原因。
如果你问你需要这个计数器做什么,我猜是为了:
- 发送数据时钟
- 你必须计算字数才能知道何时停止传输。
- 这是为了位长,所以也许这个50MHz应该是50KHz?会比较合理
仔细阅读这段代码的注释中给你的内容。
我正在做一个项目,我需要在 Altera DE1 板上编写 WM8731 音频编解码器芯片。该项目非常基础。它不需要处理输入的音频信号。来自输入的信号应直接中继到输出。
主要任务是通过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;
谢谢。
这可能不是您要找的答案,但我会 post 因为它可能有用。
如果您的主要目标只是对您的音频芯片进行编程,而不一定要与 I2C 协议作斗争,您可以使用例如 OpenCores 中的 I2C 块。你可以在那里找到很好的项目。我不能为 I2C 推荐特定的一个,但是有很多 I2C 项目,你可以尝试。
另一个您可以尝试寻找 IP 的地方是 Altera 的 IP 库。我不知道那里是否有用于 I2C 的,因为我使用 Xilinx 设备,但你可以试试。
编辑: 好吧,我也会更多地提到实际问题,因为你的任务可能是真正实现 i2c。 据我所知,你被要求有计数器,而不是时钟。这是不一样的。对于这个 5KHz - 据说它将是 about 5KHz,可能是因为你已经指出的原因。 如果你问你需要这个计数器做什么,我猜是为了:
- 发送数据时钟
- 你必须计算字数才能知道何时停止传输。
- 这是为了位长,所以也许这个50MHz应该是50KHz?会比较合理
仔细阅读这段代码的注释中给你的内容。