R
Rob
Guest
Hello,
I have a small problem with a statemachine I am working on.
This SM is a 2 level peak detect.
When a peak is detected the oErr_reg is then loaded with that input
data.
The problem I am having is that the oErr_reg will not change even if I
force it.
I do know that the register is being hit but nothing changes. The
simulation I ran shows something strange that the oErr_reg shows
x"0000" then after a second trigger it changes to UUUU.
Any ideas?
Also could you comment on my code. I would like to know how I can
improve.
Thanks
Rob
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.std_logic_arith.all;
entity pk_det is
port
(
iClk : in std_logic; --System clk
iStart : in std_logic; --Active high to start
iRst : in std_logic; --Active high reset
iRst_uc : in std_logic; --Error reset
iData : in std_logic_vector(15 downto 0); --ADC Data reg
iLow_reg : in std_logic_vector(15 downto 0); --Low compare uC
reg
iHigh_reg : in std_logic_vector(15 downto 0); --High compare uC
reg
iZch_reg : in std_logic_vector(15 downto 0); --Max cnt no of half
zero crossing point
--fault. uC reg
oErr : out std_logic; --High compare output
oInt : out std_logic; --Low compare output
oDone : out std_logic; --Finshed flag
oZch_rst : out std_logic; --Module count reset
oErr_reg : out std_logic_vector(15 downto 0) --Error reg output
);
end pk_det;
architecture rtl of pk_det is
type state_type is (idle, high, low, cnt_fault, zch_rst_s1,
zch_rst_s2, delay_s1, delay_s2);
signal pstate: state_type;
signal sZch_cnt : std_logic_vector(15 downto 0);
signal sErr_reg : std_logic_vector(15 downto 0);
begin
process (iClk, iRst, iRst_uc, iStart)
begin
if (iRst = '1') or (iRst_uc = '1') then
oErr <= '0';
oInt <= '0';
oDone <= '0';
oZch_rst <= '0';
sZch_cnt <= (others => '0');
oErr_reg <= (others => '0');
pstate <= idle;
else
if (rising_edge(iClk)) then
case pstate is
--Idle
when idle =>
if (iStart = '1') then
pstate <= high;
else
pstate <= idle;
end if;
--High
when high =>
if (iData > iHigh_reg) then
oErr <= '1';
oErr_reg <= iData;
pstate <= delay_s1;
else
pstate <= low;
end if;
--Low
when low =>
if (iData > iLow_reg) then
sZch_cnt <= sZch_cnt + '1';
pstate <= cnt_fault;
else
pstate <= zch_rst_s1;
end if;
--Cnt_fault
when cnt_fault =>
if (sZch_cnt > iZch_reg) then
oInt <= '1';
oErr_reg <= iData;
pstate <= delay_s1;
else
pstate <= delay_s1;
end if;
--ZCH Reset
when zch_rst_s1 =>
oZch_rst <= '1';
pstate <= zch_rst_s2;
when zch_rst_s2 =>
oZch_rst <= '0';
pstate <= delay_s1;
--Delay_s1
when delay_s1 =>
oDone <= '1';
pstate <= delay_s2;
--Delay_s2
when delay_s2 =>
oDone <= '0';
pstate <= idle;
--Others
when others =>
pstate <= idle;
end case;
end if;
end if;
end process;
end rtl;
I have a small problem with a statemachine I am working on.
This SM is a 2 level peak detect.
When a peak is detected the oErr_reg is then loaded with that input
data.
The problem I am having is that the oErr_reg will not change even if I
force it.
I do know that the register is being hit but nothing changes. The
simulation I ran shows something strange that the oErr_reg shows
x"0000" then after a second trigger it changes to UUUU.
Any ideas?
Also could you comment on my code. I would like to know how I can
improve.
Thanks
Rob
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.std_logic_arith.all;
entity pk_det is
port
(
iClk : in std_logic; --System clk
iStart : in std_logic; --Active high to start
iRst : in std_logic; --Active high reset
iRst_uc : in std_logic; --Error reset
iData : in std_logic_vector(15 downto 0); --ADC Data reg
iLow_reg : in std_logic_vector(15 downto 0); --Low compare uC
reg
iHigh_reg : in std_logic_vector(15 downto 0); --High compare uC
reg
iZch_reg : in std_logic_vector(15 downto 0); --Max cnt no of half
zero crossing point
--fault. uC reg
oErr : out std_logic; --High compare output
oInt : out std_logic; --Low compare output
oDone : out std_logic; --Finshed flag
oZch_rst : out std_logic; --Module count reset
oErr_reg : out std_logic_vector(15 downto 0) --Error reg output
);
end pk_det;
architecture rtl of pk_det is
type state_type is (idle, high, low, cnt_fault, zch_rst_s1,
zch_rst_s2, delay_s1, delay_s2);
signal pstate: state_type;
signal sZch_cnt : std_logic_vector(15 downto 0);
signal sErr_reg : std_logic_vector(15 downto 0);
begin
process (iClk, iRst, iRst_uc, iStart)
begin
if (iRst = '1') or (iRst_uc = '1') then
oErr <= '0';
oInt <= '0';
oDone <= '0';
oZch_rst <= '0';
sZch_cnt <= (others => '0');
oErr_reg <= (others => '0');
pstate <= idle;
else
if (rising_edge(iClk)) then
case pstate is
--Idle
when idle =>
if (iStart = '1') then
pstate <= high;
else
pstate <= idle;
end if;
--High
when high =>
if (iData > iHigh_reg) then
oErr <= '1';
oErr_reg <= iData;
pstate <= delay_s1;
else
pstate <= low;
end if;
--Low
when low =>
if (iData > iLow_reg) then
sZch_cnt <= sZch_cnt + '1';
pstate <= cnt_fault;
else
pstate <= zch_rst_s1;
end if;
--Cnt_fault
when cnt_fault =>
if (sZch_cnt > iZch_reg) then
oInt <= '1';
oErr_reg <= iData;
pstate <= delay_s1;
else
pstate <= delay_s1;
end if;
--ZCH Reset
when zch_rst_s1 =>
oZch_rst <= '1';
pstate <= zch_rst_s2;
when zch_rst_s2 =>
oZch_rst <= '0';
pstate <= delay_s1;
--Delay_s1
when delay_s1 =>
oDone <= '1';
pstate <= delay_s2;
--Delay_s2
when delay_s2 =>
oDone <= '0';
pstate <= idle;
--Others
when others =>
pstate <= idle;
end case;
end if;
end if;
end process;
end rtl;