模拟中未定义的计数器值
Undefined counter value in simulation
我对 VHDL 还很陌生,作为大学项目的一部分,我正在尝试创建一个具有四个状态的状态机。我写了一些VHDL代码和一个测试台,但我还不能确认状态机是否工作,但我会在解决当前问题后验证这一点:
状态机的一部分是一个无符号计数器,它应该确定是将数据提取到高字节还是低字节。在我的测试台中,我只想确认这个计数器是否有效。现在,在用 0 初始化后,当第一次开始计数过程时,我收到一个未定义的值作为计数器值。
起初,我尝试将计数器实现为 std_logic_vector,但我明白,为什么这行不通(没有转换)。所以我切换到 unsigned 并希望计数器工作。
通过评论单个进程,我发现计数过程会产生进程 "change status" 和 "change_current_state" 的问题。但我就是想不通为什么这些进程会相互干扰。
"change_current_state" 永远不会到达我的测试台中的 "RESET" if - 语句,因此它无法为计数器赋值。此外,进程 "change_status" 永远不会到达状态为 "prepareData" 的 elsif - 语句。这是唯一将值分配给计数器的语句。
VHDL代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity readFromADC is
Port
(
CLK_IN : in std_logic;
RESET_IN_N : in std_logic;
BUSY_IN : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
ACK_ERROR_IN : in std_logic;
ENABLE_I2C : out std_logic;
ADDR_I2C : out std_logic_vector(6 downto 0);
RW_I2C : out std_logic;
DATA_WR_I2C : out std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(15 downto 0);
SHIFT_OUT_RDY : out std_logic;
SHOWSTATE : out std_logic_vector (1 downto 0); -- debugging
BYTECOUNTER: out unsigned (1 downto 0)
);
end readFromADC;
architecture readFromADC_arch of readFromADC is
constant const_data_wr : std_logic_vector(7 downto 0) := "00000000";
constant const_rw_I2C : std_logic := '1';
constant const_addr_I2C : std_logic_vector(6 downto 0) := "0101000";
constant const_da2_control : std_logic_vector (3 downto 0) := "0000";
type states is
(
idle,
read,
prepareData,
shiftOut
);
signal sign_clk : std_logic;
signal sign_HighByte : std_logic_vector(7 downto 0);
signal sign_LowByte : std_logic_vector(7 downto 0);
signal current_state : states;
signal next_state : states;
signal sign_data_out : std_logic_vector(15 downto 0);
signal sign_ena_i2c : std_logic := '0';
signal sign_count_bytes_uns : unsigned (1 downto 0) := "00";
signal prepare_data_rdy : std_logic := '0';
signal sign_shift_out_rdy : std_logic := '0';
signal debug_states : std_logic_vector (1 downto 0);
begin
--Zuweisungen
sign_clk <= CLK_IN;
ENABLE_I2C <= sign_ena_i2c;
ADDR_I2C <= const_addr_I2C;
RW_I2C <= const_rw_I2C;
DATA_WR_I2C <= const_data_wr;
DATA_OUT <= sign_data_out;
SHIFT_OUT_RDY <= sign_shift_out_rdy;
SHOWSTATE <= debug_states;
BYTECOUNTER <= sign_count_bytes_uns;
--nächsten Status zuweisen
change_current_state : process (sign_clk, RESET_IN_N)
begin
if rising_edge(sign_clk) then
if (RESET_IN_N = '0') then
current_state <= idle;
sign_shift_out_rdy <= '0';
sign_data_out <= (others => '0');
sign_count_bytes_uns <= "00";
else
current_state <= next_state;
end if;
end if;
end process change_current_state;
--Status ändern
change_status : process (current_state)
begin
if current_state = idle then
debug_states <= "00";
sign_shift_out_rdy <= '0';
prepare_data_rdy <= '0';
sign_ena_i2c <= '1';
elsif current_state = read then
debug_states <= "01";
-- sign_count_bytes <= sign_count_bytes + 1;
sign_shift_out_rdy <= '0';
elsif current_state = prepareData then
debug_states <= "10";
sign_ena_i2c <= '0';
-- sign_count_bytes <= "00";
elsif current_state = shiftOut then
sign_count_bytes_uns <= "00";
debug_states <= "11";
sign_shift_out_rdy <= '1';
end if;
end process change_status;
acquireData : process (sign_count_bytes_uns, current_state)
begin
if current_state = read then
if (sign_count_bytes_uns = 1) then
sign_HighByte <= DATA_IN;
elsif (sign_count_bytes_uns = 2) then
sign_LowByte <= DATA_IN;
end if;
end if;
end process acquireData;
gatherData : process (current_state)
begin
if current_state = prepareData then
sign_data_out <= const_da2_control & sign_HighByte(3 downto 0) & sign_LowByte;
prepare_data_rdy <= '1';
end if;
end process gatherData;
--Dekodiere den nächsten Status
next_state_decode: process (current_state, BUSY_IN, ACK_ERROR_IN, sign_count_bytes_uns, prepare_data_rdy, sign_shift_out_rdy)
begin
next_state <= current_state; --Default: behalte den aktuellen Status
case (current_state) is
when Idle =>
if (BUSY_IN = '0') AND (ACK_ERROR_IN = '0') then
next_state <= read;
end if;
when read =>
if sign_count_bytes_uns >= 2 then
-- if sign_count_bytes = "11" then
next_state <= prepareData;
end if;
when prepareData =>
if prepare_data_rdy = '1' then
next_state <= shiftOut;
end if;
when shiftOut =>
if sign_shift_out_rdy = '1' then
next_state <= Idle;
end if;
end case;
end process next_state_decode;
countBusy : process (BUSY_IN)
begin
if falling_edge(BUSY_IN) then
sign_count_bytes_uns <= sign_count_bytes_uns + 1;
-- if (sign_count_bytes_uns <= 2) then
-- sign_count_bytes <= std_logic_vector (sign_count_bytes_uns);
if (sign_count_bytes_uns > 2) then
sign_count_bytes_uns <= "00";
end if;
end if;
end process countBusy;
测试平台
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity sim_read_adc is
-- Port ( );
end sim_read_adc;
architecture sim_read_adc_arch of sim_read_adc is
component readFromADC is
Port
(
CLK_IN : in std_logic;
RESET_IN_N : in std_logic;
BUSY_IN : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
ACK_ERROR_IN : in std_logic;
ENABLE_I2C : out std_logic;
ADDR_I2C : out std_logic_vector(6 downto 0);
RW_I2C : out std_logic;
DATA_WR_I2C : out std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(15 downto 0);
SHIFT_OUT_RDY : out std_logic;
SHOWSTATE : out std_logic_vector (1 downto 0);
BYTECOUNTER: out unsigned (1 downto 0)
);
end component readFromADC;
signal sim_CLK_IN : std_logic;
signal sim_RESET_IN_N : std_logic := '1';
signal sim_BUSY_IN : std_logic := '1';
signal sim_DATA_IN : std_logic_vector(7 downto 0) := "10101010";
signal sim_ACK_ERROR_IN : std_logic := '0';
signal sim_ENABLE_I2C : std_logic;
signal sim_ADDR_I2C : std_logic_vector(6 downto 0);
signal sim_RW_I2C : std_logic;
signal sim_DATA_WR_I2C : std_logic_vector(7 downto 0);
signal sim_DATA_OUT : std_logic_vector(15 downto 0);
signal sim_SHIFT_OUT_RDY : std_logic;
signal sim_SHOWSTATE : std_logic_vector (1 downto 0);
signal sim_BYTECOUNTER : unsigned (1 downto 0);
begin
dut : readFromADC
port map
(
CLK_IN => sim_CLK_IN,
RESET_IN_N => sim_RESET_IN_N,
BUSY_IN => sim_BUSY_IN,
DATA_IN => sim_DATA_IN,
ACK_ERROR_IN => sim_ACK_ERROR_IN,
ENABLE_I2C => sim_ENABLE_I2C,
ADDR_I2C => sim_ADDR_I2C,
RW_I2C => sim_RW_I2C,
DATA_WR_I2C => sim_DATA_WR_I2C,
DATA_OUT => sim_DATA_OUT,
SHIFT_OUT_RDY => sim_SHIFT_OUT_RDY,
SHOWSTATE => sim_SHOWSTATE,
BYTECOUNTER => sim_BYTECOUNTER
);
clk_gen : process
begin
sim_CLK_IN <= '0';
wait for 0.5us;
sim_CLK_IN <= '1';
wait for 0.5us;
end process clk_gen;
generate_busy : process
begin
wait for 5us;
sim_BUSY_IN <= '0';
wait for 1us;
sim_BUSY_IN <= '1';
end process generate_busy;
end sim_read_adc_arch;
模拟(没有进程被注释掉):
Simulation(no process is commented out)
*编辑:更新的 VHDL - 代码(不必更改测试平台):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity readFromADC is
Port
(
CLK_IN : in std_logic;
RESET_IN_N : in std_logic;
BUSY_IN : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
ACK_ERROR_IN : in std_logic;
ENABLE_I2C : out std_logic;
ADDR_I2C : out std_logic_vector(6 downto 0);
RW_I2C : out std_logic;
DATA_WR_I2C : out std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(15 downto 0);
SHIFT_OUT_RDY : out std_logic;
SHOWSTATE : out std_logic_vector (1 downto 0); -- debugging
BYTECOUNTER: out unsigned (1 downto 0)
);
end readFromADC;
architecture readFromADC_arch of readFromADC is
constant const_data_wr : std_logic_vector(7 downto 0) := "00000000";
constant const_rw_I2C : std_logic := '1';
constant const_addr_I2C : std_logic_vector(6 downto 0) := "0101000";
constant const_da2_control : std_logic_vector (3 downto 0) := "0000";
type states is
(
idle,
read,
prepareData,
shiftOut
);
signal sign_clk : std_logic;
signal sign_HighByte : std_logic_vector(7 downto 0);
signal sign_LowByte : std_logic_vector(7 downto 0);
signal current_state : states;
signal next_state : states;
signal sign_data_out : std_logic_vector(15 downto 0);
signal sign_ena_i2c : std_logic := '0';
signal sign_count_bytes_uns : unsigned (1 downto 0) := "00";
signal prepare_data_rdy : std_logic := '0';
signal sign_shift_out_rdy : std_logic := '0';
signal debug_states : std_logic_vector (1 downto 0);
begin
--Zuweisungen
sign_clk <= CLK_IN;
ENABLE_I2C <= sign_ena_i2c;
ADDR_I2C <= const_addr_I2C;
RW_I2C <= const_rw_I2C;
DATA_WR_I2C <= const_data_wr;
DATA_OUT <= sign_data_out;
SHIFT_OUT_RDY <= sign_shift_out_rdy;
SHOWSTATE <= debug_states;
BYTECOUNTER <= sign_count_bytes_uns;
--nächsten Status zuweisen
change_current_state : process (sign_clk, RESET_IN_N)
begin
if rising_edge(sign_clk) then
-- if (RESET_IN_N = '0') then
-- current_state <= idle;
-- sign_shift_out_rdy <= '0';
-- sign_data_out <= (others => '0');
-- sign_count_bytes_uns <= "00";
-- else
current_state <= next_state;
-- end if;
end if;
end process change_current_state;
--Status ändern
change_status : process (current_state)
begin
if current_state = idle then
debug_states <= "00";
sign_shift_out_rdy <= '0';
prepare_data_rdy <= '0';
sign_ena_i2c <= '1';
elsif current_state = read then
debug_states <= "01";
sign_shift_out_rdy <= '0';
elsif current_state = prepareData then
debug_states <= "10";
sign_ena_i2c <= '0';
elsif current_state = shiftOut then
debug_states <= "11";
sign_shift_out_rdy <= '1';
end if;
end process change_status;
acquireData : process (sign_count_bytes_uns, current_state)
begin
if current_state = read then
if (sign_count_bytes_uns = 1) then
sign_HighByte <= DATA_IN;
elsif (sign_count_bytes_uns = 2) then
sign_LowByte <= DATA_IN;
end if;
end if;
end process acquireData;
gatherData : process (current_state)
begin
if current_state = prepareData then
sign_data_out <= const_da2_control & sign_HighByte(3 downto 0) & sign_LowByte;
prepare_data_rdy <= '1';
end if;
end process gatherData;
--Dekodiere den nächsten Status
next_state_decode: process (current_state, BUSY_IN, ACK_ERROR_IN, sign_count_bytes_uns, prepare_data_rdy, sign_shift_out_rdy)
begin
next_state <= current_state; --Default: behalte den aktuellen Status
case (current_state) is
when Idle =>
if (BUSY_IN = '0') AND (ACK_ERROR_IN = '0') then
next_state <= read;
end if;
when read =>
if sign_count_bytes_uns >= 2 then
-- if sign_count_bytes = "11" then
next_state <= prepareData;
end if;
when prepareData =>
if prepare_data_rdy = '1' then
next_state <= shiftOut;
end if;
when shiftOut =>
if sign_shift_out_rdy = '1' then
next_state <= Idle;
end if;
end case;
end process next_state_decode;
countBusy : process (BUSY_IN, RESET_IN_N)
begin
if falling_edge (RESET_IN_N) then
sign_count_bytes_uns <= "00";
elsif falling_edge(BUSY_IN) then
sign_count_bytes_uns <= sign_count_bytes_uns + 1;
if (sign_count_bytes_uns > 2) then
sign_count_bytes_uns <= "00";
end if;
end if;
end process countBusy;
end readFromADC_arch;
首先,get some 'X' 在仿真中通常意味着一个信号被同时赋值2个(或更多)值。这通常意味着您在多个并发进程中分配此信号。
在 VHDL 中,最好避免在 2 个不同的进程中分配一个信号(注意任何进程之外的行都是一个进程)。
在您的代码中,信号 sign_count_bytes_uns 在 3 个进程中受到影响。我认为您应该至少修改其中的 2 个(通过合并它们)。
但是你的'X'的真正原因有点棘手,在这个过程中:
change_status : process (current_state)
begin
if current_state = idle then
debug_states <= "00";
sign_shift_out_rdy <= '0';
prepare_data_rdy <= '0';
sign_ena_i2c <= '1';
elsif current_state = read then
debug_states <= "01";
sign_shift_out_rdy <= '0';
elsif current_state = prepareData then
debug_states <= "10";
sign_ena_i2c <= '0';
elsif current_state = shiftOut then
sign_count_bytes_uns <= "00";
debug_states <= "11";
sign_shift_out_rdy <= '1';
end if;
end process change_status;
您仅在 1 种情况下分配了 sign_count_bytes_uns,我假设您在给我们的模拟屏幕截图中不属于这种情况,而是 sign_count_bytes_uns还是要"XX"。
原因如下:
当你在一个进程中分配一个信号但不是在所有情况下,每次你在一个信号不受影响的情况下,这个信号都会取他以前的值(内存)。在综合中,将推断出一个锁存器。因此,当 countBusy 时,您的进程 change_status 将 sign_count_bytes_uns 保持为“00”试图改变它,这就是为什么你得到一些 "XX".
我对 VHDL 还很陌生,作为大学项目的一部分,我正在尝试创建一个具有四个状态的状态机。我写了一些VHDL代码和一个测试台,但我还不能确认状态机是否工作,但我会在解决当前问题后验证这一点:
状态机的一部分是一个无符号计数器,它应该确定是将数据提取到高字节还是低字节。在我的测试台中,我只想确认这个计数器是否有效。现在,在用 0 初始化后,当第一次开始计数过程时,我收到一个未定义的值作为计数器值。
起初,我尝试将计数器实现为 std_logic_vector,但我明白,为什么这行不通(没有转换)。所以我切换到 unsigned 并希望计数器工作。 通过评论单个进程,我发现计数过程会产生进程 "change status" 和 "change_current_state" 的问题。但我就是想不通为什么这些进程会相互干扰。 "change_current_state" 永远不会到达我的测试台中的 "RESET" if - 语句,因此它无法为计数器赋值。此外,进程 "change_status" 永远不会到达状态为 "prepareData" 的 elsif - 语句。这是唯一将值分配给计数器的语句。
VHDL代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity readFromADC is
Port
(
CLK_IN : in std_logic;
RESET_IN_N : in std_logic;
BUSY_IN : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
ACK_ERROR_IN : in std_logic;
ENABLE_I2C : out std_logic;
ADDR_I2C : out std_logic_vector(6 downto 0);
RW_I2C : out std_logic;
DATA_WR_I2C : out std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(15 downto 0);
SHIFT_OUT_RDY : out std_logic;
SHOWSTATE : out std_logic_vector (1 downto 0); -- debugging
BYTECOUNTER: out unsigned (1 downto 0)
);
end readFromADC;
architecture readFromADC_arch of readFromADC is
constant const_data_wr : std_logic_vector(7 downto 0) := "00000000";
constant const_rw_I2C : std_logic := '1';
constant const_addr_I2C : std_logic_vector(6 downto 0) := "0101000";
constant const_da2_control : std_logic_vector (3 downto 0) := "0000";
type states is
(
idle,
read,
prepareData,
shiftOut
);
signal sign_clk : std_logic;
signal sign_HighByte : std_logic_vector(7 downto 0);
signal sign_LowByte : std_logic_vector(7 downto 0);
signal current_state : states;
signal next_state : states;
signal sign_data_out : std_logic_vector(15 downto 0);
signal sign_ena_i2c : std_logic := '0';
signal sign_count_bytes_uns : unsigned (1 downto 0) := "00";
signal prepare_data_rdy : std_logic := '0';
signal sign_shift_out_rdy : std_logic := '0';
signal debug_states : std_logic_vector (1 downto 0);
begin
--Zuweisungen
sign_clk <= CLK_IN;
ENABLE_I2C <= sign_ena_i2c;
ADDR_I2C <= const_addr_I2C;
RW_I2C <= const_rw_I2C;
DATA_WR_I2C <= const_data_wr;
DATA_OUT <= sign_data_out;
SHIFT_OUT_RDY <= sign_shift_out_rdy;
SHOWSTATE <= debug_states;
BYTECOUNTER <= sign_count_bytes_uns;
--nächsten Status zuweisen
change_current_state : process (sign_clk, RESET_IN_N)
begin
if rising_edge(sign_clk) then
if (RESET_IN_N = '0') then
current_state <= idle;
sign_shift_out_rdy <= '0';
sign_data_out <= (others => '0');
sign_count_bytes_uns <= "00";
else
current_state <= next_state;
end if;
end if;
end process change_current_state;
--Status ändern
change_status : process (current_state)
begin
if current_state = idle then
debug_states <= "00";
sign_shift_out_rdy <= '0';
prepare_data_rdy <= '0';
sign_ena_i2c <= '1';
elsif current_state = read then
debug_states <= "01";
-- sign_count_bytes <= sign_count_bytes + 1;
sign_shift_out_rdy <= '0';
elsif current_state = prepareData then
debug_states <= "10";
sign_ena_i2c <= '0';
-- sign_count_bytes <= "00";
elsif current_state = shiftOut then
sign_count_bytes_uns <= "00";
debug_states <= "11";
sign_shift_out_rdy <= '1';
end if;
end process change_status;
acquireData : process (sign_count_bytes_uns, current_state)
begin
if current_state = read then
if (sign_count_bytes_uns = 1) then
sign_HighByte <= DATA_IN;
elsif (sign_count_bytes_uns = 2) then
sign_LowByte <= DATA_IN;
end if;
end if;
end process acquireData;
gatherData : process (current_state)
begin
if current_state = prepareData then
sign_data_out <= const_da2_control & sign_HighByte(3 downto 0) & sign_LowByte;
prepare_data_rdy <= '1';
end if;
end process gatherData;
--Dekodiere den nächsten Status
next_state_decode: process (current_state, BUSY_IN, ACK_ERROR_IN, sign_count_bytes_uns, prepare_data_rdy, sign_shift_out_rdy)
begin
next_state <= current_state; --Default: behalte den aktuellen Status
case (current_state) is
when Idle =>
if (BUSY_IN = '0') AND (ACK_ERROR_IN = '0') then
next_state <= read;
end if;
when read =>
if sign_count_bytes_uns >= 2 then
-- if sign_count_bytes = "11" then
next_state <= prepareData;
end if;
when prepareData =>
if prepare_data_rdy = '1' then
next_state <= shiftOut;
end if;
when shiftOut =>
if sign_shift_out_rdy = '1' then
next_state <= Idle;
end if;
end case;
end process next_state_decode;
countBusy : process (BUSY_IN)
begin
if falling_edge(BUSY_IN) then
sign_count_bytes_uns <= sign_count_bytes_uns + 1;
-- if (sign_count_bytes_uns <= 2) then
-- sign_count_bytes <= std_logic_vector (sign_count_bytes_uns);
if (sign_count_bytes_uns > 2) then
sign_count_bytes_uns <= "00";
end if;
end if;
end process countBusy;
测试平台
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity sim_read_adc is
-- Port ( );
end sim_read_adc;
architecture sim_read_adc_arch of sim_read_adc is
component readFromADC is
Port
(
CLK_IN : in std_logic;
RESET_IN_N : in std_logic;
BUSY_IN : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
ACK_ERROR_IN : in std_logic;
ENABLE_I2C : out std_logic;
ADDR_I2C : out std_logic_vector(6 downto 0);
RW_I2C : out std_logic;
DATA_WR_I2C : out std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(15 downto 0);
SHIFT_OUT_RDY : out std_logic;
SHOWSTATE : out std_logic_vector (1 downto 0);
BYTECOUNTER: out unsigned (1 downto 0)
);
end component readFromADC;
signal sim_CLK_IN : std_logic;
signal sim_RESET_IN_N : std_logic := '1';
signal sim_BUSY_IN : std_logic := '1';
signal sim_DATA_IN : std_logic_vector(7 downto 0) := "10101010";
signal sim_ACK_ERROR_IN : std_logic := '0';
signal sim_ENABLE_I2C : std_logic;
signal sim_ADDR_I2C : std_logic_vector(6 downto 0);
signal sim_RW_I2C : std_logic;
signal sim_DATA_WR_I2C : std_logic_vector(7 downto 0);
signal sim_DATA_OUT : std_logic_vector(15 downto 0);
signal sim_SHIFT_OUT_RDY : std_logic;
signal sim_SHOWSTATE : std_logic_vector (1 downto 0);
signal sim_BYTECOUNTER : unsigned (1 downto 0);
begin
dut : readFromADC
port map
(
CLK_IN => sim_CLK_IN,
RESET_IN_N => sim_RESET_IN_N,
BUSY_IN => sim_BUSY_IN,
DATA_IN => sim_DATA_IN,
ACK_ERROR_IN => sim_ACK_ERROR_IN,
ENABLE_I2C => sim_ENABLE_I2C,
ADDR_I2C => sim_ADDR_I2C,
RW_I2C => sim_RW_I2C,
DATA_WR_I2C => sim_DATA_WR_I2C,
DATA_OUT => sim_DATA_OUT,
SHIFT_OUT_RDY => sim_SHIFT_OUT_RDY,
SHOWSTATE => sim_SHOWSTATE,
BYTECOUNTER => sim_BYTECOUNTER
);
clk_gen : process
begin
sim_CLK_IN <= '0';
wait for 0.5us;
sim_CLK_IN <= '1';
wait for 0.5us;
end process clk_gen;
generate_busy : process
begin
wait for 5us;
sim_BUSY_IN <= '0';
wait for 1us;
sim_BUSY_IN <= '1';
end process generate_busy;
end sim_read_adc_arch;
模拟(没有进程被注释掉): Simulation(no process is commented out)
*编辑:更新的 VHDL - 代码(不必更改测试平台):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity readFromADC is
Port
(
CLK_IN : in std_logic;
RESET_IN_N : in std_logic;
BUSY_IN : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
ACK_ERROR_IN : in std_logic;
ENABLE_I2C : out std_logic;
ADDR_I2C : out std_logic_vector(6 downto 0);
RW_I2C : out std_logic;
DATA_WR_I2C : out std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(15 downto 0);
SHIFT_OUT_RDY : out std_logic;
SHOWSTATE : out std_logic_vector (1 downto 0); -- debugging
BYTECOUNTER: out unsigned (1 downto 0)
);
end readFromADC;
architecture readFromADC_arch of readFromADC is
constant const_data_wr : std_logic_vector(7 downto 0) := "00000000";
constant const_rw_I2C : std_logic := '1';
constant const_addr_I2C : std_logic_vector(6 downto 0) := "0101000";
constant const_da2_control : std_logic_vector (3 downto 0) := "0000";
type states is
(
idle,
read,
prepareData,
shiftOut
);
signal sign_clk : std_logic;
signal sign_HighByte : std_logic_vector(7 downto 0);
signal sign_LowByte : std_logic_vector(7 downto 0);
signal current_state : states;
signal next_state : states;
signal sign_data_out : std_logic_vector(15 downto 0);
signal sign_ena_i2c : std_logic := '0';
signal sign_count_bytes_uns : unsigned (1 downto 0) := "00";
signal prepare_data_rdy : std_logic := '0';
signal sign_shift_out_rdy : std_logic := '0';
signal debug_states : std_logic_vector (1 downto 0);
begin
--Zuweisungen
sign_clk <= CLK_IN;
ENABLE_I2C <= sign_ena_i2c;
ADDR_I2C <= const_addr_I2C;
RW_I2C <= const_rw_I2C;
DATA_WR_I2C <= const_data_wr;
DATA_OUT <= sign_data_out;
SHIFT_OUT_RDY <= sign_shift_out_rdy;
SHOWSTATE <= debug_states;
BYTECOUNTER <= sign_count_bytes_uns;
--nächsten Status zuweisen
change_current_state : process (sign_clk, RESET_IN_N)
begin
if rising_edge(sign_clk) then
-- if (RESET_IN_N = '0') then
-- current_state <= idle;
-- sign_shift_out_rdy <= '0';
-- sign_data_out <= (others => '0');
-- sign_count_bytes_uns <= "00";
-- else
current_state <= next_state;
-- end if;
end if;
end process change_current_state;
--Status ändern
change_status : process (current_state)
begin
if current_state = idle then
debug_states <= "00";
sign_shift_out_rdy <= '0';
prepare_data_rdy <= '0';
sign_ena_i2c <= '1';
elsif current_state = read then
debug_states <= "01";
sign_shift_out_rdy <= '0';
elsif current_state = prepareData then
debug_states <= "10";
sign_ena_i2c <= '0';
elsif current_state = shiftOut then
debug_states <= "11";
sign_shift_out_rdy <= '1';
end if;
end process change_status;
acquireData : process (sign_count_bytes_uns, current_state)
begin
if current_state = read then
if (sign_count_bytes_uns = 1) then
sign_HighByte <= DATA_IN;
elsif (sign_count_bytes_uns = 2) then
sign_LowByte <= DATA_IN;
end if;
end if;
end process acquireData;
gatherData : process (current_state)
begin
if current_state = prepareData then
sign_data_out <= const_da2_control & sign_HighByte(3 downto 0) & sign_LowByte;
prepare_data_rdy <= '1';
end if;
end process gatherData;
--Dekodiere den nächsten Status
next_state_decode: process (current_state, BUSY_IN, ACK_ERROR_IN, sign_count_bytes_uns, prepare_data_rdy, sign_shift_out_rdy)
begin
next_state <= current_state; --Default: behalte den aktuellen Status
case (current_state) is
when Idle =>
if (BUSY_IN = '0') AND (ACK_ERROR_IN = '0') then
next_state <= read;
end if;
when read =>
if sign_count_bytes_uns >= 2 then
-- if sign_count_bytes = "11" then
next_state <= prepareData;
end if;
when prepareData =>
if prepare_data_rdy = '1' then
next_state <= shiftOut;
end if;
when shiftOut =>
if sign_shift_out_rdy = '1' then
next_state <= Idle;
end if;
end case;
end process next_state_decode;
countBusy : process (BUSY_IN, RESET_IN_N)
begin
if falling_edge (RESET_IN_N) then
sign_count_bytes_uns <= "00";
elsif falling_edge(BUSY_IN) then
sign_count_bytes_uns <= sign_count_bytes_uns + 1;
if (sign_count_bytes_uns > 2) then
sign_count_bytes_uns <= "00";
end if;
end if;
end process countBusy;
end readFromADC_arch;
首先,get some 'X' 在仿真中通常意味着一个信号被同时赋值2个(或更多)值。这通常意味着您在多个并发进程中分配此信号。
在 VHDL 中,最好避免在 2 个不同的进程中分配一个信号(注意任何进程之外的行都是一个进程)。
在您的代码中,信号 sign_count_bytes_uns 在 3 个进程中受到影响。我认为您应该至少修改其中的 2 个(通过合并它们)。
但是你的'X'的真正原因有点棘手,在这个过程中:
change_status : process (current_state)
begin
if current_state = idle then
debug_states <= "00";
sign_shift_out_rdy <= '0';
prepare_data_rdy <= '0';
sign_ena_i2c <= '1';
elsif current_state = read then
debug_states <= "01";
sign_shift_out_rdy <= '0';
elsif current_state = prepareData then
debug_states <= "10";
sign_ena_i2c <= '0';
elsif current_state = shiftOut then
sign_count_bytes_uns <= "00";
debug_states <= "11";
sign_shift_out_rdy <= '1';
end if;
end process change_status;
您仅在 1 种情况下分配了 sign_count_bytes_uns,我假设您在给我们的模拟屏幕截图中不属于这种情况,而是 sign_count_bytes_uns还是要"XX"。
原因如下: 当你在一个进程中分配一个信号但不是在所有情况下,每次你在一个信号不受影响的情况下,这个信号都会取他以前的值(内存)。在综合中,将推断出一个锁存器。因此,当 countBusy 时,您的进程 change_status 将 sign_count_bytes_uns 保持为“00”试图改变它,这就是为什么你得到一些 "XX".