Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Counter with asynchronous edge-triggered reset in VHDL

Status
Not open for further replies.

kender

Advanced Member level 4
Joined
Jun 19, 2005
Messages
1,425
Helped
138
Reputation
276
Reaction score
39
Trophy points
1,328
Location
Stanford, SF Bay Peninsula, California, Earth, Sol
Activity points
10,035
Colleagues,

Here’s another VHDL problem. I want to put a one-shot timer into the CPLD. It will serve a safety purpose, if it’s not reset (strobed) on time, it will cut the power. To improve fault-tolerance, I want the reset to be edge-triggered (most of the flip-flops have level-triggered resets, though). So, I wrote the following VHDL code:

Code:
 architecture Behavioral of watch_dog_timer is 
	signal wdt_clk_cnt: unsigned(23 downto 0);
begin

process (wdt_clk, wdi) begin
	if (wdt_clk'event and wdt_clk = '1' and wdt_clk_cnt < 16777215) then
		wdt_clk_cnt <= wdt_clk_cnt + 1;		
		if (wdt_clk_cnt = 16777215) then
			wdo <= '0';
		end if;	
	elsif (wdi'event and wdi = '1') then -- reset on positive edge
		wdt_clk_cnt <= (others => '0');		
		wdo <= '1';
	end if;
end process; 

end Behavioral;

But Xilinx WebPack gives me an error:
Code:
 ERROR:Xst:827 - "E:/Relievant/Gen2/PLD_firmware/watch_dog_timer.vhd" line 41: Signal wdo cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.

How can I get around this problem?

Thanks,
- Nick
 

in electronic design you basicaly can't trigger one process with more than one edge-trigger, so reset can be only asynchronous:
Code:
if(reset = '1')then
  ...
elsif(rising_edge(clk))then
  ...
end if;
or synchronous:
Code:
if(rising_edge(clk))then
  if(reset = '1')then
    ...
  else
    ...
  end if;
end if;

Added after 2 minutes:

better way is to use synchronous reset, and one more thing
Code:
if (wdt_clk'event and wdt_clk = '1' and wdt_clk_cnt < 16777215) then
gating clock is very bad idea you should put this like:
Code:
if(rising_edge(wdt_clk))then
  if(wdt_clk_cnt < ...)then
    ...
  end if;
end if;
 
You are trying to control the counter from two edge sensitive expressions at the same time. That doesn't work. Flip-Flops with two clock inputs would be needed.

Assuming sufficient wdi pulse width, a synchronous edge detection for wdi can be implemented. Otherwise a second wdi edge sensitive process and a handshake would be needed. But I don't expect it's necessary here.

Another point is synchronization of wdi signal. If it's unrelated to wdt_clock, it may coincide with it. With a certain likelihood, wdt_clk_cnt would be reset only partially. Ignoring asynchrounous character of signals is a common source of nasty occasional logic errors. By synchronizing wdi before further processing, such effects are avoided.

Code:
architecture Behavioral of watch_dog_timer is 
  signal wdt_clk_cnt: unsigned(23 downto 0); 
  wdi_sync: std_logic;
  wdi_sync_p: std_logic;
begin 

process (wdt_clk) begin 
   if (wdt_clk'event and wdt_clk = '1' then
     wdi_sync <= wdi; -- synchronized to wdt_clock
     wdi_sync_p <= wdi_sync; -- remember previous state
     if wdi_sync = '1' and wdi_sync_p = '0' then
        wdt_clk_cnt <= (others => '0');
        wdo <= '1'; 
     elsif wdt_clk_cnt < 16777215) then 
        wdt_clk_cnt <= wdt_clk_cnt + 1;
        wdo <= '1'; 
     else
        wdo <= '0'; 
     end if;    
   end if; 
end process;
 
  • Like
Reactions: Tard

    kender

    Points: 2
    Helpful Answer Positive Rating

    Tard

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top