Altera_Forum
Honored Contributor
17 years agoProgrammable 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;