AlienObserver
Newbie level 2
- Joined
- Oct 22, 2013
- Messages
- 2
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1
- Activity points
- 26
VHDL - Strange simulation behaviour
Greetings.
I have made a simple module for controlling the motion of a robot. It takes as inputs a setpoint 'sp' (i.e. desired position), and the actual measured position 'pos'. An error is then computed as the discrepancy between the two mentioned inputs, and appropriate outputs are produced. The problem I encounter is during simulation; the outputs 'motor_cw' and 'motor_ccw' appear glitched (i.e. uninitialized, forcing unknown).
The entity:
The archictecture:
The testbench:
The waveform result of the testbench:
https://i.imgur.com/4np3Kj2.jpg
What I don't understand is the uninitialized behaviour of the outputs. For instance, at time t=0ns, the present state is IDLE and per my code the outputs are both set to '0'. The outputs aren't updated again until rst = '0' and we have a rising edge on the clock, which occurs at time t=50ns. So why are the outputs uninitialized on this time interval? At time t=50ns the outputs get correct values, i.e. '0' for both. At time t=90ns, however, motor_cw_next = '1', motor_ccw_next = '0' and we have a rising edge on the clock, so the outputs motor_cw and motor_ccw should be set to '1' and '0' respectively. Instead motor_cw becomes forcing unknown 'X'.
So my question is, what produces this weird behaviour? If it makes a difference, this is part of a homework assignment in an FPGA class I'm taking. I hope I haven't made any extremely silly errors, but I can't seem to find any at the time of writing this.
Any help is greatly appreciated.
Greetings.
I have made a simple module for controlling the motion of a robot. It takes as inputs a setpoint 'sp' (i.e. desired position), and the actual measured position 'pos'. An error is then computed as the discrepancy between the two mentioned inputs, and appropriate outputs are produced. The problem I encounter is during simulation; the outputs 'motor_cw' and 'motor_ccw' appear glitched (i.e. uninitialized, forcing unknown).
The entity:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity p_ctrl is
port (
rst : in std_logic; -- Reset
clk : in std_logic; -- Clock
sp : in signed(7 downto 0); -- Set Point
pos : in signed(7 downto 0); -- Measured position
motor_cw : out std_logic; -- Motor Clock Wise direction
motor_ccw : out std_logic -- Motor Counter Clock Wise direction
);
end p_ctrl;
The archictecture:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
architecture rtl of p_ctrl is
type state_t is (IDLE, SAMPLE, MOTOR);
signal present_st : state_t;
signal next_st : state_t;
signal sp_sync : signed(7 downto 0);
signal pos_sync : signed(7 downto 0);
signal err : signed(7 downto 0) := (others => '0');
signal err_next : signed(7 downto 0) := (others => '0');
signal motor_cw_next : std_logic := '0';
signal motor_ccw_next : std_logic := '0';
begin
STATE_REG: process(clk, rst)
begin
if (rst = '1') then
present_st <= IDLE;
elsif (rising_edge(clk)) then
-- assign to cw/ccw/err the values from the previous
-- clock cycle as per the ASM chart
err <= err_next;
motor_cw <= motor_cw_next;
motor_ccw <= motor_ccw_next;
-- synchronize inputs
sp_sync <= sp;
pos_sync <= pos;
-- change state
present_st <= next_st;
end if;
end process STATE_REG;
COMB: process(sp_sync, pos_sync, present_st)
begin
case present_st is
when IDLE =>
motor_cw <= '0';
motor_ccw <= '0';
next_st <= SAMPLE;
when SAMPLE =>
err_next <= sp_sync - pos_sync;
next_st <= MOTOR;
when MOTOR =>
if (err > 0) then
motor_cw_next <= '1';
motor_ccw_next <= '0';
elsif (err < 0) then
motor_cw_next <= '0';
motor_ccw_next <= '1';
else
motor_cw_next <= '0';
motor_ccw_next <= '0';
end if;
next_st <= SAMPLE;
end case;
end process COMB;
end rtl;
The testbench:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb_p_ctrl is
-- empty
end tb_p_ctrl;
architecture beh of tb_p_ctrl is
component p_ctrl is
port (rst : in std_logic;
clk : in std_logic;
sp : in signed(7 downto 0);
pos : in signed(7 downto 0);
motor_cw : out std_logic;
motor_ccw : out std_logic);
end component p_ctrl;
signal rst : std_logic;
signal clk : std_logic := '0';
signal sp : signed(7 downto 0);
signal pos : signed(7 downto 0);
signal motor_cw : std_logic;
signal motor_ccw : std_logic;
begin
UUT : entity work.p_ctrl(rtl)
port map (rst => rst,
clk => clk,
sp => sp,
pos => pos,
motor_cw => motor_cw,
motor_ccw => motor_ccw);
-- stimuli
clk <= not clk after 10 ns;
rst <= '1', '0' after 40 ns;
sp <= to_signed(100, 8);
pos <= to_signed(50, 8), to_signed(80, 8) after 150 ns,
to_signed(115, 8) after 300 ns;
end beh;
The waveform result of the testbench:
https://i.imgur.com/4np3Kj2.jpg
What I don't understand is the uninitialized behaviour of the outputs. For instance, at time t=0ns, the present state is IDLE and per my code the outputs are both set to '0'. The outputs aren't updated again until rst = '0' and we have a rising edge on the clock, which occurs at time t=50ns. So why are the outputs uninitialized on this time interval? At time t=50ns the outputs get correct values, i.e. '0' for both. At time t=90ns, however, motor_cw_next = '1', motor_ccw_next = '0' and we have a rising edge on the clock, so the outputs motor_cw and motor_ccw should be set to '1' and '0' respectively. Instead motor_cw becomes forcing unknown 'X'.
So my question is, what produces this weird behaviour? If it makes a difference, this is part of a homework assignment in an FPGA class I'm taking. I hope I haven't made any extremely silly errors, but I can't seem to find any at the time of writing this.
Any help is greatly appreciated.
Last edited by a moderator: