0
\$\begingroup\$

I'm having inconsistent times on my timer, can be anywhere from 300ms - 4 seconds, what could be causing this?

The code logic looks good to me but the oscope shows different times almost everytime I run it. Here's how I set up the code for the timer. I'm using an arduino as a clock at about 256Hz. The timer should go off at 4 seconds not any sooner like it is.

library ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all; 

constant C_2SEC_TC : integer := 1023;
signal tmr_cnt  : std_logic_vector(11 downto 0) := (others => '0');
signal tc_2sec  : std_logic;

begin
   -- counter for internal timer
   second_cntr_proc: process(CLK)
   begin
      if (rising_edge(CLK)) then
            tmr_cnt <= tmr_cnt + 1;
            if (tc_2sec='1') then
               tmr_cnt <= (others => '0');
            end if;
      end if;
   end process second_cntr_proc;

   tc_2sec <= '1' when tmr_cnt = C_2SEC_TC else '0';

I initialize a pin high and when tc_2sec goes high I set that pin low. The high time of that pin isn't always the same.

\$\endgroup\$
16
  • \$\begingroup\$ (1) What FPGA pin is the Arduino sending the "clock" into? Is it just a regular FPGA pin? Or is it actually an FPGA clock pin with a dedicated clock network? (2) Why are you involving in this at all instead of just using the FPGA's oscillator? (3) If you are inputting things onto an actual FPGA clocking pin, does the FPGA even support a clock as slow as 256Hz? (4) If you are inputting things onto a regular FPGA pin, are you at least synchronizing it to the FPGA's clock domain first? \$\endgroup\$
    – DKNguyen
    Commented Aug 26, 2019 at 19:22
  • \$\begingroup\$ (5) Why does it seem like your FPGA doesn't have an oscillator? You have not shown us all your code. What is CLK exactly? Is it the Arduino signal? If so, then what is your FPGA's REAL clock? You cannot use rising_edge() blindly. It is ONLY for REAL clocks that run the entire FPGA that connect to a dedicated clock network. Not for something trivial like a signal being produced by an Arduino. \$\endgroup\$
    – DKNguyen
    Commented Aug 26, 2019 at 19:25
  • \$\begingroup\$ @DKNguyen (1) I'm connecting this to a general I/O pin on board my atf1502 asv CPLD. Its not connected to the clock pin because im using it on a Dev board that uses a 2MHz clk, the problem with that is this chip only has 32 macro cells, my std_logic_vector would have to be much higher for 4 seconds and it will not fit with 32 macro cells. (2) To my knowledge there is no oscillator inside this chip. (3) Using an I/O pin. (4) Not sure what this means, I'm new to VHDL. (5) Yes, clk is an input pin, signal is coming from the arduino digital signal that goes high and low. I though rising_edge was \$\endgroup\$
    – Sean Kerr
    Commented Aug 26, 2019 at 20:33
  • \$\begingroup\$ @DKNguyen okay to use on any digital signal \$\endgroup\$
    – Sean Kerr
    Commented Aug 26, 2019 at 20:33
  • \$\begingroup\$ What you're doing looks fine at first glance and a clock input can be any frequency below the FPGA's specified maximum. So, next, how sure are you that your Arduino's clock into the FPGA is noise-free and at the right frequency? \$\endgroup\$
    – TonyM
    Commented Aug 26, 2019 at 20:57

2 Answers 2

2
\$\begingroup\$

You should know that the kind of initialization you are using for tmr_cnt may not be synthesizable. If you don't explicitly reset this counter it could power up with an unknown value. If that value happens to be greater than C_2SEC_TC then your 12-bit counter will have to count up until it rolls over and reaches 1023 before tc_2sec will go low.

If the problem is occurring on the first pulse after power up then I would suspect this kind of problem. You will need to add a reset signal to your design and use it to clear the counter. It would be helpful if you included a link to the manufacturer's datasheet for your CPLD.

\$\endgroup\$
5
  • \$\begingroup\$ Not sure about other FPGAs but Xilinx and Altera FPGA docs say all initial values are synthesisable in their FPGAs for years now. This is to avoid the overhead of global resets in FPGA designs. \$\endgroup\$
    – Mitu Raj
    Commented Aug 27, 2019 at 6:10
  • \$\begingroup\$ @MituRaj Agreed, but the OP says they are using a CPLD from Microchip and didn't provide a link to the datasheet. I'm not familiar with those particular devices. \$\endgroup\$ Commented Aug 27, 2019 at 14:20
  • \$\begingroup\$ @elliotalderson Didnt I initialize it to 0 with the statement := (others => '0')? Sorry the data sheet can be found here. ww1.microchip.com/downloads/en/DeviceDoc/doc1615.pdf \$\endgroup\$
    – Sean Kerr
    Commented Aug 27, 2019 at 17:35
  • 1
    \$\begingroup\$ @MituRaj, VHDL designs should use resets, and never initial values, to keep those designs portable. RAM-based FPGAs allow initial values whereas flash-based FPGAs/CPLDs and ASICs don't. Initial value designs won't work in the latter. That's why vendor IP, for example, uses resets. It's better practice and little overhead, with nearly all FPGAs/CPLDs I've seen supporting asynchronous resets in hardware and using little routing to employ them. Ensure the asynchronous reset is synchronously negated and they're fine. \$\endgroup\$
    – TonyM
    Commented Aug 27, 2019 at 18:38
  • 1
    \$\begingroup\$ @TonyM Good to know. I was not aware of that since I only work with FPGAs, nearly all of which are SRAM. When does VHDL reset code stopped being interpreted as a reset? (i.e. After you have the signal sensitivity list, but not under a rising_edge(), what types of VHDL lines will cause the synthesizer to no longer interpret it as a reset and therefore no longer use the reset hardware. Is it just anything that is not a direct signal assignment? (i.e. such as IF statements, etc)? \$\endgroup\$
    – DKNguyen
    Commented Aug 27, 2019 at 22:46
0
\$\begingroup\$

SOLVED: Updated the proc as follows appeared to fix my issue

`

   library ieee;
   USE ieee.std_logic_1164.all;
   USE ieee.numeric_std.all;
   USE ieee.std_logic_arith.all;
   USE ieee.std_logic_unsigned.all; 

   constant C_2SEC_TC : integer := 1023;
   signal tmr_cnt  : std_logic_vector(11 downto 0);
   signal tc_2sec  : std_logic : = '0';

   begin
   -- counter for internal timer
   second_cntr_proc: process(CLK)
        begin
        if (RST = '0') then
            tmr_cnt  <= (others => '0');
        elsif (clk'event and clk = '1') then
           tmr_cnt <= tmr_cnt + 1;
           if (tc_2sec='1') then
                tmr_cnt <= (others => '0');
           end if;
         end if;
      end process second_cntr_proc;

    tc_2sec <= '1' when tmr_cnt = C_2SEC_TC else '0';`
\$\endgroup\$
4
  • 1
    \$\begingroup\$ It looks like changing the initialization fixed the issue. So it seems like it was the initial value vs reset that pointed out by Elliot and TonyM was the problem which would make sense since you are working off a Flash/EEPROM device and not an FPGA which runs from SRAM. You really should use rising_edge() though and not (clk'event and clk = '1'). That is the old way and is obsolete. \$\endgroup\$
    – DKNguyen
    Commented Aug 27, 2019 at 22:41
  • \$\begingroup\$ You can't answer your own question. Please follow guidance of @SamGibson before this gets deleted by an administrator. \$\endgroup\$
    – TonyM
    Commented Aug 28, 2019 at 4:42
  • 1
    \$\begingroup\$ @TonyM Actually, I think I read somewhere you could answer your own question if you were the one who found the solution. Though this doesn't really qualify since it is implementing suggestions from other answers. \$\endgroup\$
    – DKNguyen
    Commented Aug 28, 2019 at 20:20
  • \$\begingroup\$ @DKNguyen - Hi, Yes , question askers can answer their own questions (see here). The issue here was that, until it was edited, this answer also asked a question. After asking questions within an "answer", other people then answer in comments on that "answer", and I've seen a very confusing mess as a result. Now the question has been removed from this answer, I'll delete my original comment. (IMHO if a self-answer is based on info provided by someone else's answer, then that answer should usually be "accepted", not the self-answer.) \$\endgroup\$
    – SamGibson
    Commented Aug 29, 2019 at 1:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.