kureigu
Member level 2
- Joined
- Jan 14, 2013
- Messages
- 49
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,286
- Location
- Scotland
- Activity points
- 1,779
I've recently ripped apart some of my code to cut it into modular chunks, and I'm experiencing a problem that I've seen before but never found a way around...
When I change an output of my component inside the case statement, it doesn't seem to propagate out at all. I've got round this in the past by setting a flag and using a concurrent statement outside the process to apply the signal I wanted, but to do that in this situation would just be silly, especially when there's likely a fix.
Here's the code where the problem is:
The LATCH_WAIT and WAIT_FOR_COMPLETE states are just handshaking with the motor driver component. The two are linked through a higher level component that controls the signal linkages to the motor driver... essentially a multiplexer.
This component is supposed to drive a stepper in a back and forth motion, but what I've noticed is that the direction ('dir') output is always low, unless I set it outside the process. Same applies for 'steps'; If i set that inside one of the cases, it just ignores it and uses the default value.
When I change an output of my component inside the case statement, it doesn't seem to propagate out at all. I've got round this in the past by setting a flag and using a concurrent statement outside the process to apply the signal I wanted, but to do that in this situation would just be silly, especially when there's likely a fix.
Here's the code where the problem is:
Code:
-- Search_pattern.vhd --
------------------------
-- Carries out the search motion
-- Use with Control_arbiter.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity search_pattern is
generic (step_inc: unsigned(7 downto 0) := "00010000" );
port (clk: in std_logic;
enable: in std_logic;
dir: out std_logic;
steps, speed, hold_time: out integer;
Az_rdy, El_rdy: in std_logic;
Az_run, El_run: out std_logic;
lock: in std_logic
);
end search_pattern;
architecture behavioural of search_pattern is
type action is (LATCH_WAIT, WAIT_FOR_COMPLETE, MOVE_AZ_CW, MOVE_EL_CW, MOVE_AZ_CCW, MOVE_EL_CCW, FINAL_MOVE, RESET, LOCKED);
signal search_state: action := WAIT_FOR_COMPLETE;
signal last_state: action := MOVE_EL_CCW;
begin
hold_time <= 30;
speed <= 250000;
steps <= 50;
process(enable, Az_rdy, El_rdy)
begin
if rising_edge(clk) then
if(enable = '1') then
case search_state is
when LATCH_WAIT =>
-- Make sure a GPMC has registered the command before waiting for it to complete
if(Az_rdy = '0' OR El_rdy = '0') then -- xx_rdy will go low if a stepper starts moving
search_state <= WAIT_FOR_COMPLETE; -- Go to waiting state and get ready to issue next cmd
end if;
when WAIT_FOR_COMPLETE =>
-- De-assert run commands
El_run <= '0';
-- Wait for the movement to complete before making next
if(Az_Rdy = '1' and El_rdy = '1') then
-- Choose next command based on the last
case last_state is
when MOVE_EL_CCW => search_state <= MOVE_EL_CW;
when MOVE_EL_CW => search_state <= MOVE_EL_CCW;
when others => null; -- when locked wait for unlock?
end case;
end if;
-- Constantly check for lock as well
if(lock = '1') then
search_state <= LOCKED;
end if;
when MOVE_EL_CW =>
dir <= '1';
El_run <= '1';
last_state <= MOVE_EL_CW;
search_state <= LATCH_WAIT;
when MOVE_EL_CCW =>
dir <= '0';
El_run <= '1';
last_state <= MOVE_EL_CCW;
search_state <= LATCH_WAIT;
when others =>
null;
end case;
else
-- need to add reset and tracking functionality here.
end if;
end if;
end process;
end behavioural;
The LATCH_WAIT and WAIT_FOR_COMPLETE states are just handshaking with the motor driver component. The two are linked through a higher level component that controls the signal linkages to the motor driver... essentially a multiplexer.
This component is supposed to drive a stepper in a back and forth motion, but what I've noticed is that the direction ('dir') output is always low, unless I set it outside the process. Same applies for 'steps'; If i set that inside one of the cases, it just ignores it and uses the default value.
Last edited: