我发布的代码是I2s代码|我在不同的行中遇到同样的错误,请帮帮我

时间:2014-07-08 10:27:08

标签: vhdl

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    11:00:43 07/08/2014 
-- Design Name: 
-- Module Name:    i2s_3 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity i2s_3 is
    generic (constant delay :time :=10 ns);
     Port ( sck : inout  STD_LOGIC;
           sd : out  STD_LOGIC;
           ws : inout  STD_LOGIC);
end i2s_3;

architecture Behavioral of i2s_3 is

signal clk :std_logic;
signal Shift_Register : std_logic_vector(7 downto 0);
signal PL,WSP:std_logic := '0';
signal WSD :std_logic;
signal Left_Reg,Right_Reg : std_logic_vector(7 downto 0);
signal inc,inc_1,starting :std_logic;

signal count : std_logic_vector(1 downto 0);
signal Bit_Count : integer range 0 to 9; 

type state_type is (ideal,start,transmit);
signal state,next_state : state_type;

begin
    clk <= not sck;
 process(state)
 begin
  case state is 
    when ideal =>
      if rising_edge (sck) then 
        next_state <= start;
        else 
        next_state <= ideal;
      end if;
    when start =>
     IF(ws = 0) then        --error LINE 67
       next_state <= transmit; inc <= '1' after delay;
     else 
        next_state <= transmit;  inc_1 <= '1' after delay;
    end if;
    when transmit =>
    if(Bit_Count /= 8) then starting <= '1'; 
    end if;

    when others => "XXXXXXXX";  --error LINE 76
    end case;
end process;

 process(sck,count)
 begin  
    if rising_edge(sck) then 
        state <= next_state ; count <= count + 1; end if; --error LINE 83
    if(count = 4) then PL <= '1'; end if; --error LINE 84

    if rising_edge (clk) then 
      if(inc = 1) and (PL = 1) then  --error LINE 87
        Shift_Register <= Left_Reg ; end if;
      if(inc_1 = 1) and (PL = 1) then 
        Shift_Register <= Right_Reg ; end if; --error LINE 89
    end if; 

    if(starting = 1) then 
       sd   <= Shift_Register & '0';    --error LINE 94
        Bit_Count <= Bit_Count + 1;     --error LINE 93
    end if;     

 end process;   
end Behavioral;

谁能告诉我可能是什么错误?无法解码

Line 67: found '0' definitions of operator "=", cannot determine exact overloaded matching definition for "="
Line 76: Type  void does not match with a string literal
Line 83: found '0' definitions of operator "+", cannot determine exact overloaded matching definition for "+"
Line 84: found '0' definitions of operator "=", cannot determine exact overloaded matching definition for "="
Line 87: found '0' definitions of operator "=", cannot determine exact overloaded matching definition for "="
Line 89: found '0' definitions of operator "=", cannot determine exact overloaded matching definition for "="
Line 94: found '0' definitions of operator "&", cannot determine exact overloaded matching definition for "&"

2 个答案:

答案 0 :(得分:0)

第67行wsstd_logic类型,可以是以下值之一:'U''X',{{1 },'0''1''Z''W''L''H'。要使用'-'进行比较,您需要在值周围加上单引号,以将其标识为字符文字。 =(不带单引号)是整数文字。

第76行0那又怎样?你在这里错过了一个陈述。您是要与(其他=&gt; when others =>)进行比较,还是将某些内容赋值为'X'

第83/84行:使用"XXXXXXXX",您无法将数字文字添加或比较为numeric_std(在我看来,您也不应该这样做) 。将std_logic_vector的类型更改为count,您应该没问题。

(顺便说一下,你可能想考虑在那里添加换行符。短代码很好,但从长远来看,我发现清晰度更有帮助。)

第87/89/93行:与第67行相同。

第94行:此处的基本问题是您尝试将8位向量(unsigned)分配给Shift_Register & '0'类型的信号( std_logic)。你需要考虑你在这里想要完成的事情。您需要修复该行的语法,但您还需要对逻辑执行不同的操作。

答案 1 :(得分:0)

除了众多的VHDL语法错误外,fru1tbat被追赶了,你似乎已经过分分析了你的设计工作。如果您查看I2S总线规范,发送器不必知道要传输多少位,除非它是主站。位数由WS上的波特(“1”或“0”)的持续时间控制。你的发射器不是主人(它不会驱动WS)。

如果你看一下图5(1986 Spec。):

I2S Bus Specification Figure 5

发送器可以忽略信道传输中的比特数,使用WSD(您不生成)在左右声道之间进行选择,并使用WSP加载Shift_Register。 Shift_Register的D输入为'0',零填充小于请求的通道字。 WS更改并创建WS脉冲,使用下一个通道字加载shift_register(由WSP状态选择),截断长于WSD波特的通道数据

您还可以使用falling_edge(sck)并取消单独的信号clkWS高或低的右声道或左声道中的位数(并且它们不会必须具有相同的位数)。

所有这些意味着你的状态机是过度的,你需要一个计数器的唯一地方是一个生成WS的主机或一个接收机(其中一个计数器可用于截断接收机无法使用的精度) - MSB第一次传输)。

如果你想要一个通过驾驶WS来表示的I2S总线主控,那么对于时钟关闭SCK的右或左通道位数,它只是高或低。

正如fru1tbat在评论中指出的那样,您实际上并没有将Shift_Register转移到现有代码中,而代码将在SCK的下降沿运行。

<强>附录

我坐下来写了上面图5所示的模型:

library ieee;
use ieee.std_logic_1164.all;

entity i2s_transmitter is
    port (
        WS:     in  std_logic;  -- supplied by bus master
        SCK:    in  std_logic;  -- supplied by bus master
        SD:     out std_logic
    );
end entity;

architecture foo of i2s_transmitter is
    -- left and write channel words, two's complement actually
    -- and should come from port interface
    -- also should be synchronous to SCK.
    signal DATA_LEFT:   std_logic_vector(7 downto 0) := x"CB"; -- dummy
    signal DATA_RIGHT:  std_logic_vector(7 downto 0) := x"97"; -- values

    signal WSD:         std_logic;
    signal WSD1:        std_logic; -- output of second delay FF nnamed.
    signal WSP:         std_logic;
    signal SHIFT_REGISTER:  std_logic_vector (7 downto 0);

begin

SR: 
    process (SCK)
    begin
        if falling_edge(SCK) then  -- SCK OVERBAR
            if WSP = '1' then      -- load left or right channel word
                if WSD = '0' then  -- mux for parallel load
                    SHIFT_REGISTER <=  DATA_LEFT;
                 else
                    SHIFT_REGISTER <= DATA_RIGHT;
                end if;
            else
                SHIFT_REGISTER <= SHIFT_REGISTER(6 downto 0) & '0';
            end if;  
        end if;
    end process;

    SD <= SHIFT_REGISTER(7);  -- MSB first, 7 downto 0 little endian

WSD_FF:    
    process (SCK)
    begin
        if rising_edge(SCK) then
            WSD <= WS;
        end if;
    end process;

WSD1_FF:    
    process (SCK)
    begin
        if rising_edge(SCK) then
            WSD1 <= WSD;
        end if;
    end process;  

WS_PULSE:
    WSP <= WSD xor WSD1;  

end architecture;

另外,快速而肮脏的测试台可以验证它是否正确:

library ieee;
use ieee.std_logic_1164.all;

entity i2s_transmit_tb is
end entity;

architecture foo of i2s_transmit_tb is

    signal WS:      std_logic := '0';
    signal SCK:     std_logic := '1';
    signal SD:      std_logic;

    constant clk_period:    Time := 400 ns;  -- 2.5 MHz typical
    constant ws_period:     Time := 16 * clk_period;

begin

DUT:
    entity work.i2s_transmitter
        port map (
            WS => WS,
            SCK => SCK,
            SD => SD
        );
CLOCK:

    process
    begin
        wait for clk_period/2;
        SCK <= not SCK;
        if Now > 30 * clk_period then  -- bound as a demo
            wait;  
        end if;
    end process;

STIMULUS:

    process
    begin
        wait for ws_period/2;
        WS <= not WS;

        if Now > 30 * clk_period then
            wait;
        end if;
    end process;

end architecture;

了解模型取决于具有规范(参见I2S bus specification

注意SD无效,直到SHIFT_REGISTER中第一个移入'0'使其进入输出,缺少重置。在WSD的上升沿显示有效数据之前,WSD1SCK也会显示“U”。

这是一种VHDL风格,行为描述了图5中的硬件并给出了结果:

i2s_transmit_tb

这是在OS X 10.9.4上使用ghdl-0.31GTKWave完成的。