Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

Programmable watchdog in FPGA

Hi all..I am trying to implment a programmable (by microcontoller) watchdog using FPGA..I am using the Altera Megafunction lpm_counter for this purpose. However, my watchdog is generating a lot of warmings ('barking') some of them I don't understand how to fix...

Description: I am using the 50MHz onboard oscillator (DE2) as my clock input and put it through a PLL to generate a 10MHz clock (the lowest one can get from these buildin PLL)..then I am using counter1 to further divide this down to approximately 32787Hz (10,000,000/305) which should give me about 2 second if I am counting down from 65535 to 0 (16bit)...so here is my code...

The warming I am getting is:

Warning: Found combinational loop of 2 nodes

Warning: Node "inst1|COUNTDOWN_COUNTER|auto_generated|latch_signal[9]~995|combout"

Warning: Node "inst1|COUNTDOWN_COUNTER|auto_generated|latch_signal[9]~995|dataa"

and there are many of this kind...I am attaching the whole project zipped file to this post as well...any recommendataions are welcomed!

--------------------------------------------------------------------------------------------------------

library ieee;

use ieee.std_logic_1164.all;

LIBRARY lpm;

USE lpm.all;

entity WDT is

Generic

(

add_WDT: std_logic_vector (15 downto 0) := X"0044"

);

port

(

reset : in std_logic; -- Hardware reset line from ColdFire

timeout : out std_logic := '0';

datain : in std_logic_vector (15 downto 0);

dataout : out std_logic_vector (15 downto 0);

address : in std_logic_vector (15 downto 0);

CS : in std_logic;

RW : in std_logic;

TA : out std_logic := '1';

oe : out std_logic;

q_out : out std_logic_vector (15 downto 0);

clkin : in std_logic -- 10MHz input clock

);

end entity WDT;

architecture sys of WDT is

signal counter1: integer range 304 downto 0;

signal WDT: std_logic_vector (15 downto 0);

signal Timer: std_logic_vector (15 downto 0);

signal stop, flag, flag2, load: std_logic;

signal intclk: std_logic;

type STATE_TYPE is (S0, S1, S2, S3, S4, S5); -- Delay

signal SC, NS: STATE_TYPE;

component lpm_counter

generic

(

lpm_direction : STRING;

lpm_port_updown : STRING;

lpm_type : STRING;

lpm_width : NATURAL

);

PORT

(

aload : IN STD_LOGIC;

cnt_en : IN STD_LOGIC;

clock : IN STD_LOGIC ;

q : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);

data : IN STD_LOGIC_VECTOR (15 DOWNTO 0)

);

END COMPONENT;

begin

clock_divider: process -- this process will divide the 10MHz clock downto approximately 32787Hz

begin -- therefore, 65536 cycles corresponding to about 2 seconds.

wait until clkin'event and clkin='1';

counter1 <= counter1 + 1;

if counter1 = 304 then

intclk <= intclk xor '1';

counter1 <= 0;

end if;

end process;

SYNC_PROC: process -- These following processes take care of ColdFire writes/reads from the watchdog

begin -- to set and read the countdown time

wait until clkin'event and clkin = '1';

SC <= NS; -- move to next state

end process;

STATE_PROC: process (SC)

begin

case SC is

when S0 => -- S0 is generally a wait state

if CS = '0' and RW = '1' then -- ColdFire reads

NS <= S1;

elsif CS = '0' and RW = '0' then -- ColdFire writes

NS <= S3;

else

NS <= S0;

end if;

-- ColdFire reads (S1-S2)

when S1 =>

if (address = add_WDT ) then

NS <= S2;

else

NS <= S5;

end if;

when S2 =>

NS <= S5;

-- ColdFire writese (S3-S6)

when S3 =>

if (address = add_WDT) then

NS <= S4;

else

NS <= S5;

end if;

when S4 =>

NS <= S5;

when S5 =>

if CS = '1' then

NS <= S0;

else

NS <= S5;

end if;

end case;

end process;

READ_PROC: process

begin

wait until clkin'event and clkin='1';

case SC is

when S1=> -- ColdFire reads

TA <= '1';

oe <= '1';

when S2=>

dataout <= WDT;

TA <= '0';

oe <= '1';

when S3=> -- ColdFire writes

TA<= '1';

oe <= '0';

when S4=>

WDT <= datain;

TA <= '0';

oe <= '0';

when others =>

TA <= '1';

oe <= '0';

end case;

end process;

L0AD_PROC: process

begin

wait until clkin'event and clkin='1';

flag <= reset;

end process;

LOAD_PROC2: process

begin

wait until clkin'event and clkin='0';

flag2 <= flag;

end process;

load <= flag xor flag2; -- Create pulses when reset change states

COUNTDOWN_COUNTER : lpm_counter

generic map

(

lpm_direction => "DOWN",

lpm_port_updown => "PORT_UNUSED",

lpm_type => "LPM_COUNTER",

lpm_width => 16

)

PORT MAP (

aload => load, -- Use the previously created pulse as asynload signal to the counter.

clock => intclk,

q => Timer,

cnt_en => stop,

data => WDT

);

q_out <= timer;

stop <= '0' when timer = X"0000" else '1'; -- If counter reaches 0, stop the count down and

timeout <= not (stop); -- rise the timeout flag

end architecture;

14 Replies