Register will not change

R

Rob

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;
 
Joined
Apr 3, 2007
Messages
1
Reaction score
0
Rob said:
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;


Initialise all the output signals in the "idle" state and you need to assign values for oErr, oErr_reg when (iData > iHigh_reg) is false. otherwise synthesis tools will generate some other equations for these output.so try to assign all the outputs in each state.
- psh.
 
J

Jonathan Bromley

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.

The basic layout of your code seems OK except that the main
clocked process has a bizarre sensitivity list - it should
not have iStart in it at all, and I think it would be safer
for synthesis if you were to form the logical OR of the two
resets and apply it as a single reset signal.

However, I suspect the detailed design of the state machine
is flawed - but without a slightly clearer description of
the spec, and more time than I really can spare, it's
kinda hard to tell. I *think* that your FSM always
gets pushed into one of the states where it can't
affect oErr_reg. Have you tried tracing the state
register value as simulation progresses? I suspect
you'll find it spends much less time in the High
state than you had intended. But, as I say, I can't
really understand what the thing is trying to do, so
I can't be sure. Do you have a testbench?

One small gripe: please don't use hard-tabs in the
code - it makes it very hard to read! My personal
preference is for 2-space indentation in VHDL.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top