Я запускаю датчик через линию inout. После этого я жду, когда датчик подтянет линию inout к высокому уровню, но у меня возникают проблемы с чтением обратного сигнала inout без искажения моего выходного сигнала. Писать работает, читать нет.
Всякий раз, когда линия
elsif state = sensor_answer_0 AND trigger_sensor = '1' then
для параметра ouput_signal установлено значение "X".
Но когда я закомментирую trigger_sensor:
elsif state = sensor_answer_0 then
output_signal фактически принимает присвоенное ему значение.
Я уже пытался использовать сигнал внутреннего буфера, который считывается в отдельном процессе, но это дает тот же результат.
В приведенном ниже коде я использую output_signal также для отладки и устанавливаю его в каждом состоянии, чтобы увидеть, какое состояние выполняется на самом деле. Я проверил свой тестовый стенд и не обнаружил конфликта записи-записи с output_signal. Однако я устанавливаю trigger_sensor. Но только после того, как для trigger_sensor уже установлено значение «Z» в моем основном коде.
Почему я вижу это странное поведение? Разве я не могу просто прочитать сигнал inout?
Я использую Quartus II 15.0 и ModelSim для моделирования.
ibrary ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sensor_read is port(
clk_50: in std_logic;
enable : in std_logic; -- enable sensor read
trigger_sensor: inout std_logic; -- 1. trigger sensor, 2. read sensor value
output_sensor : out std_logic_vector(7 downto 0)
);
end sensor_read;
architecture behavior of sensor_read is
--
type state_type is (init, trigger_0, trigger_1, sensor_answer_0 );
signal state : state_type := init;
signal icnt : std_logic_vector( 18 downto 0 ) := ( others => '0' ); -- counter
----------------------------------------------------------------------
--- wait for enable
--- trigger sensor
--- wait for sensor to pull trigger line HIGH and assign output
----------------------------------------------------------------------
begin
process (clk_50 )
begin
if rising_edge( clk_50 ) then
-- start here
if state = init AND unsigned( icnt ) = 0 then
icnt <= ( others => '0' );
if enable = '1' then -- start trigger process
state <= trigger_0;
trigger_sensor <= '0';
else
state <= init;
trigger_sensor <= 'Z';
end if;
-- TRIGGER SENSOR
elsif state = trigger_0 AND unsigned( icnt ) = 50 then
state <= trigger_1;
trigger_sensor <= '1';
output_sensor <= "00000001"; -- debug
elsif state = trigger_1 AND unsigned( icnt ) = 550 then -- 500 clk cycle
state <= sensor_answer_0;
icnt <= ( others => '0' );
trigger_sensor <= 'Z'; -- set trigger to high impedance to let sensor drive line
output_sensor <= "00001111"; -- debug
-- WAIT FOR SENSOR TO PULL TRIGGER=HIGH
-- ERROR HERE -> when trigger_sensor is used in if statement output_sensor becomes xxx
-- when trigger_sensor = not('1') is commented out, output_sensor is set correctly to "00011111"
elsif state = sensor_answer_0 AND trigger_sensor = '1' then
state <= init;
icnt <= ( others => '0' );
output_sensor <= "00011111"; -- assign final output
else
icnt <= std_logic_vector ( unsigned( icnt ) + 1 );
end if;
end if;
end process;
end behavior;
Изменить: добавить тестовый стенд по запросу
-- clock generation
process
begin
clk_50 <= '1';
wait for 10 ns;
clk_50 <= '0';
wait for 10 ns;
end process;
-- input data
process
begin
enable <= '0';
trigger_sensor <= 'Z';
wait for 1 ms;
-- start the meassurement
enable <= '1';
-- wait for the trigger signal to be over
while trigger_sensor /= '1' loop wait for 1 us; end loop;
while trigger_sensor = '1' loop wait for 1 us; end loop;
-- now send response
wait for 100 us;
trigger_sensor <= '1';
wait for 1 ms;
trigger_sensor <= '0';
wait for 10 us;
trigger_sensor <= 'Z';
wait;
end process;
inout
в первую очередь? Логика открытого коллектора? VHDL и FPGA это не очень нравится. Лучше использовать отдельные входы и выходы: это обычно предотвращает подобные ошибки.X
часто означает, что сигнал имеет несколько драйверов. - person JHBonarius   schedule 13.03.2017inout
очень хорошо поддерживается в инструменте синтеза Altera. - person TriceratopsMagician   schedule 13.03.2017