----------------------------------------------------------------------------------
-- 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 "&"
答案 0 :(得分:0)
第67行:ws
是std_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。):
发送器可以忽略信道传输中的比特数,使用WSD
(您不生成)在左右声道之间进行选择,并使用WSP
加载Shift_Register
。 Shift_Register的D输入为'0',零填充小于请求的通道字。 WS
更改并创建WS
脉冲,使用下一个通道字加载shift_register(由WSP
状态选择),截断长于WSD
波特的通道数据
您还可以使用falling_edge(sck)
并取消单独的信号clk
。WS
高或低的右声道或左声道中的位数(并且它们不会必须具有相同的位数)。
所有这些意味着你的状态机是过度的,你需要一个计数器的唯一地方是一个生成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
的上升沿显示有效数据之前,WSD1
和SCK
也会显示“U”。
这是一种VHDL风格,行为描述了图5中的硬件并给出了结果: