cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Contributor
Contributor
1,546 Views
Registered: ‎05-14-2008

Is this bad design practice. Clearing a counter and latching is value before clearing into a register on the same clock edge

Jump to solution

Hello

 

Please let me know if this is not the best forum to post this question in. I will then post it in the appropriate forum that you suggest.

 

 

I am using a spartan 3 200k device running at 15MHz system clock. My design environment is ISE14.7

 

 

Attached is a circuit used to measure the time (in clocks) between any two events on the pulse input. When pulse is high on the rising edge of clk it clears the counter to 1 and it clocks the output of the counter into the register. The implementation functions as it should as you can see from the scope screen capture.

 

I have a concern though. I am wondering if this could be a problem depending on how ISE maps the hardware i.e. different routing delays etc. Or even worse; this could just be bad design practice. 

 

I am worried about the hold time requirement on the register (U_TEST_FDE_1) input i.e. the time after the clock edge that the input of the register must be held constant to clock in the correct counter value. Lets call this T_d_hold.

 

T_d_hold should be less that the time (T_cnt_rst_prop) it take for the synchronous reset to propagate the reset value to the counter output  + the time it take for the signal CNT[3..0] to propagate from the counter output to the register input  i.e. (T_interconnect_delay)

 

T_d_hold < T_cnt_rst_prop + T_interconnect_delay

 

My questions

  1. Is this good design practice? It can only be safe under all circumstances if T_d_hold is always less than T_cnt_rst_prop so that this circuit can always work even with T_interconnect_delay = 0. Or am I to stringent?
  2. What parameter in the Spartan 3 datasheet reflect T_d_hold
  3. What parameter in the Spartan 3 datasheet reflect T_cnt_rst_prop

Thank you very mush for your help

CvT 

circuit signals.jpg
0 Kudos
Reply
1 Solution

Accepted Solutions
avrumw
Guide
Guide
1,927 Views
Registered: ‎01-23-2009

It is send through a double synchronizer. So by the time pulse reach this circuit in the diagram it is synchronous to the system clk. 

 

This is a separate issue from whether the reset is synchronous or asynchronous. Xilinx flip-flops support two styles of resets

  - a synchronous reset - the reset does not take effect until the next rising edge of the clock

  - an asynchronous clear - the clear takes place immediately

 

If the "R" is a synchronous reset, then this is fine. If the R is an asynchronous clear then it is bad practice.

 

Regardless of which this is (reset or clear), the input needs to be synchronized to the clock - a double synchronizer (possibly with 0->1 or 1->0 transition detector) is required.

 

Avrum

View solution in original post

0 Kudos
Reply
5 Replies
avrumw
Guide
Guide
1,533 Views
Registered: ‎01-23-2009

The only question is whether this is a synchronous reset or an asynchronous reset (in the FPGA world, an asynchronous reset would be referred to as a clear).

 

If this is a synchronous reset, then this is a normal synchronous circuit - things only happen on the rising edge of CLK. All designs, be they implemented in ASIC, FPGA or any other synchronous device are designed to deal with synchronous circuits, including ensuring that any possible hold time issues are addressed by the tool. If you want to think about this differently, you can think about the fact that the "R" of the counter (assuming it is synchronous) can be changed to a synchronous load of a fixed value - you probably wouldn't think twice about having a load simultaneous with registering the output...

 

If this is an asynchronous reset, then, yes, this is extremely bad practice. You don't even need to think about what you are doing with it - FPGAs strongly discourage any "local reset" - a reset that is used as part of the functionality (i.e. generated by logic so that it can affect the state of some logic as part of the normal operation of that logic). The asynchronous preset/clear inputs of flip-flops should only be used as part of a true "reset" - returning the entire system (or at least a significant subsystem) to a power-up like state.

 

Avrum

0 Kudos
Reply
Contributor
Contributor
1,521 Views
Registered: ‎05-14-2008

Hello avrumw

 

Thank you for your feedback.

 

Yes this is a completely synchronous design. The pulse signal comes from outside the FPGA i.e. it is asynchronous to the system clock. It is send through a double synchronizer. So by the time pulse reach this circuit in the diagram it is synchronous to the system clk.  

 

[QUOTE]

you probably wouldn't think twice about having a load simultaneous with registering the output...

[END QUOTE]

The synchronous load with 1 would be the same as a synchronous reset to 1 which is actually the correct way to do it then.

I assume that you mean (in a synchronous design) registering the output of the counter on the same clock edge as loading it with a new value will always result in storing the final counter value in the register before the counter is updated with the new load value.

 

Thank you very much

0 Kudos
Reply
avrumw
Guide
Guide
1,928 Views
Registered: ‎01-23-2009

It is send through a double synchronizer. So by the time pulse reach this circuit in the diagram it is synchronous to the system clk. 

 

This is a separate issue from whether the reset is synchronous or asynchronous. Xilinx flip-flops support two styles of resets

  - a synchronous reset - the reset does not take effect until the next rising edge of the clock

  - an asynchronous clear - the clear takes place immediately

 

If the "R" is a synchronous reset, then this is fine. If the R is an asynchronous clear then it is bad practice.

 

Regardless of which this is (reset or clear), the input needs to be synchronized to the clock - a double synchronizer (possibly with 0->1 or 1->0 transition detector) is required.

 

Avrum

View solution in original post

0 Kudos
Reply
Contributor
Contributor
1,498 Views
Registered: ‎05-14-2008

@avrumwwrote:

 

If the "R" is a synchronous reset, then this is fine. If the R is an asynchronous clear then it is bad practice.

Avrum



You are correct in making sure that I understand what you mean. Yes. The counter's reset is synchronous as you can see in the counter implementation below.

 

-- CBnRLE[B]:
-- C = Counter?
-- B = Binary?
-- n = Size in bits i.e. binary counter
-- R = Synchronous Reset (R)
-- L = Synchronous Load(L) with data(D)
-- E = Clock Enable (CE)
-- [B] = Counter I\O (Q,D) is not discrete but in a bus format

-- Possible implementations:
-- CBnRE
-- CBnRLE
----------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
----------------------------------------------------------------------------------

---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity CB32REB_RESET1 is --CHANGE
Port ( CE : in STD_LOGIC;
C : in STD_LOGIC;
R : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (31 downto 0); --CHANGE
CEO : out STD_LOGIC;
TC : out STD_LOGIC);
end CB32REB_RESET1; --CHANGE

architecture Behavioral of CB32REB_RESET1 is --CHANGE

signal count : std_logic_vector (31 downto 0); --CHANGE
signal s_tc : std_logic;

begin
process (C) begin
if (rising_edge(C)) then
if (R = '1') then
count <= X"00000001";
elsif (CE = '1') then
count <= count + '1';
end if;
end if;
end process;
Q <= count;

process (count) begin
if (count = X"FFFFFFFF") then --CHANGE
s_tc <= '1';
else
s_tc <= '0';
end if;
end process;

TC <= s_tc;
CEO <= s_tc and CE; --As defined FPGA Generic Libraries Guide of Altium Designer. Example Page 134

end Behavioral;

0 Kudos
Reply
jmcclusk
Mentor
Mentor
1,470 Views
Registered: ‎02-24-2014

My eyes are burning from this VHDL code..  Let me rewrite this for you:

 

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL; -- ALWAYS USE THIS PACKAGE FOR DOING ARITHMETIC, EVEN COUNTERS

entity CB32REB_RESET1 is Port (
CE : in STD_LOGIC; C : in STD_LOGIC; R : in STD_LOGIC; Q : out STD_LOGIC_VECTOR; -- notice this vector is unconstrained. This can be ANY length now. CEO : out STD_LOGIC; TC : out STD_LOGIC); end CB32REB_RESET1; architecture Behavioral of CB32REB_RESET1 is signal count : unsigned(Q'length-1 downto 0); signal s_tc : std_logic; constant C_tc : unsigned(count'range) := (others => '1');
begin process (C) begin if (rising_edge(C)) then if (R = '1') then count <= to_unsigned(1,Q'length); elsif (CE = '1') then count <= count + 1; end if; end if; end process;
Q <= std_logic_vector( count ); s_tc <= '1' when count = C_tc else '0'; -- There are better ways to do this, especially by using a down counter.
TC <= s_tc; CEO <= s_tc and CE; --As defined FPGA Generic Libraries Guide of Altium Designer. Example Page 134 end Behavioral;

 

Don't forget to close a thread when possible by accepting a post as a solution.
0 Kudos
Reply