【问题标题】:Clock configuration - VHDL coding Altera DE1 audio codec chip时钟配置 - VHDL 编码 Altera DE1 音频编解码芯片
【发布时间】:2017-05-26 09:59:21
【问题描述】:

我正在进行一个项目,我需要在 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 时钟 (100KHz/5KHz) 的 20 个脉冲,而不是它发送的 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;

谢谢。

【问题讨论】:

  • 请参阅I2C Clock Speed,似乎全速 I2C(最大 400 kbits/sec)适合您的目的。是什么阻止您使用更快的 I2C?
  • 我曾经与 Xilinx 的 Ken Chapman 讨论过这个话题(FPGA 逻辑上的 I2C 和 RS232)。他用他的 PicoBlaze 进行了试验,发现在(非常小的)软核 CPU 中实现这些协议所需的硬件更少,然后在 FPGA 架构上实现它们。你可以考虑一下。
  • 请不要通过删除代码来破坏帖子。

标签: vhdl fpga intel-fpga


【解决方案1】:

这可能不是您正在寻找的答案,但我会发布它,因为它可能有用。

如果您的主要目标只是对您的音频芯片进行编程,而不必与 I2C 协议作斗争,您可以使用来自例如 OpenCores 的 I2C 模块。你可以在那里找到相当不错的项目。对于 I2C,我不能推荐特定的,但是有很多 I2C 项目,你可以尝试。

另一个您可以尝试寻找 IP 的地方是 Altera 的 IP 库。我不知道那里是否有用于 I2C 的,因为我使用的是 Xilinx 设备,但您可以尝试。

编辑: 好的,我还将更多地参考实际问题,因为您的任务可能是真正实现 i2c。 据我所知,你被要求有计数器,而不是时钟。这不一样。而对于这个 5KHz - 据说它将是大约 5KHz,可能是因为您已经指出的原因。 如果你问你需要这个计数器做什么,我猜是:

  1. 发送数据的时钟
  2. 您必须计算字数才能知道何时停止传输。
  3. 这是为了位长,所以也许这个 50MHz 应该是 50KHz?会更合理。

仔细阅读此代码的 cmets 中提供给您的内容。

【讨论】:

  • 我的回答稍作修改,请看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
  • 2012-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多