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.

VHDL: simple 10ms Timer design, how can a VHDL entity know the system clock frequency

Status
Not open for further replies.

matrixofdynamism

Advanced Member level 2
Joined
Apr 17, 2011
Messages
593
Helped
24
Reputation
48
Reaction score
23
Trophy points
1,298
Activity points
7,681
When writing a Timer code, the idea is for it to count certain number of clock cycles to be able to count a given time duration. When dealing with timer in C code we can define a header file with a #define for the clock frequency. The code deep down will use to figure out how many clock cycles shall be equal to 10ms for example and this way we can use a 10ms Timer interrupt.

How can we achieve the same effect in VHDL? Is it possible lets in Quartus for the design entity to know what frequency the design shall run at through SDC file, or can we describe it another way such that all entities deep down the hierarchy can use it?
 

Collecting system parameters in a package is a convenient way, I think. Or passs it as generic down the hierarchy.
 

Hi,

To develop on FvM reply. You can declare both the timer length and its size in bits in a VHDL package.
The timer code would look like the following:

Code:
Library ieee;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all;

Entity generic_tmr is
Generic
  ( G_TMR_TC  := C_TMR_DEFAULT_TC;     -- Threshold count value
    G_TMR_SIZE:= C_TMR_DEFAULT_SIZE); -- size in bits 
Port
  (i_clk : in std_logic;
   i_rst : in _std_logic;
   i_en : in std_logic;
   o_tc : out std_logic);

end generic_tmr;

Architecture rtl of generic_tmr is

s_tmr : unsigned(G_TMR_LEN - 1 downto 0);

begin

P_TMR: process(i_clk)
begin
  if (i_clk'event and i_clk = '1') then  
    if (i_rst = '1') then 
      s_tmr <= (others => '0');
      o_tc  <= '1';
    else
      o_tc <= '0';
      
      if (i_en = '1') then  
        if (s_tmr < to_unsigned(G_TMR_LEN, G_TMR_SIZE)) then 
          s_tmr <= s_tmr + 1;
        else
          s_tmr <= (others => '0');
          o_tc  <= '1';
        end if;
      end if;
    end if;
  end if;
end process P_TMR;
  
end rtl;
Trying to answer to your other questions:

1) You must specify the period for each clock domain you use, that includes the clock of your timer.
Each FPGA vendor has complete manuals on how to do do that for their IDEs.

2) The component described above can be instantiated throughout the design , giving different values to the parameters (generics).

3) Advice with timers & FPGAs. Don't make them to big (in bits). The FPGA synthesis/place and route will try to fit the equivalent combinatorial logic to compute the next value so that a new value is computed in a clock cycle.
A method to avoid big timers is to use that clock enable (i_en in the VHDL code above) so that it is a pulsed signal with the time resolution of your timer.
 

A method to avoid big timers is to use that clock enable (i_en in the VHDL code above) so that it is a pulsed signal with the time resolution of your timer.

What does that mean?
 

In simple example if you want to count to 256 you can do it straightforward as a 8bit counter or you can build two 4 bit counters -> the first one counts to 16 and then generates signal to increase the second counter ( this signal is preferable the clock enable for the 2nd counter).
 

A method to avoid big timers is to use that clock enable (i_en in the VHDL code above) so that it is a pulsed signal with the time resolution of your timer.

What does that mean?


To be more dramatic than the 8 bit timer example exposed by axcdd. Suppose you want to count 1 ms and your FPGA has a 50 MHz clock.

Your timer should count up to 500.00. The next value logic of your timer should be of 16 bits. Many FPGAs (Cyclone II, Spartan 3) will find trouble fitting the logic at this frequency.

In this case, as exposed by axcdd you can define a first timer with 1 us (50 clock ticks = 6 bits) being run by the 50 MHz clock and with no enable and connect its threshold count signal to the clock enable of a second timer (1000 clock enable ticks, 10 bits). This scheme would fit synthesis/P&R nicely. The trade-off is that you have 1 us time resolution in the output of your 1 ms timer.

zermelo
 

To be more dramatic than the 8 bit timer example exposed by axcdd. Suppose you want to count 1 ms and your FPGA has a 50 MHz clock.

Your timer should count up to 500.00. The next value logic of your timer should be of 16 bits. Many FPGAs (Cyclone II, Spartan 3) will find trouble fitting the logic at this frequency.

Not actually. The 50000:1 clock divider will run at 220 MHz with slowest Cyclone II and a 500000:1 divider (10 ms tick) at 180 MHz. That's because these FPGAs can utilize the fast carry chain for the comparator.

Nevertheless it's no bad idea to use a slower clock enable in a design, particularly if multiple timers are involved.
 

OK, one last clarification. I want the timer clock to be able to figure out how many cycles to count. This can be done by passing the system clock frequency in Hertz and the required time delay is seconds, as generics to the design entity. We can just multiply these two to find out how many clock cycles are required at the given clock frequency to achieve the required delay.

Now, what data type should I declare these generics as? It must be possible to give decimal values too you see. And besides, when we perform a product of these two numbers, the answer must be round off to the closest higher integer. Is it possible than to declare a constant or variable in the architecture which shall store the product of these two values and than use a loop to generate as many 4 bit counters as needed and connected their clock enables together?

How do I do this?
 

You can use something like this:
1. add ieee.math_real.all library
2. generics
F_CLK_MHZ_G : in real := 125 .0 ; --! clock in Mhz
Count_to_G : in time := 10 us ; --! time to count

3. constant COUNT_TO_TICKS_C : integer := integer(ceil(real(Count_to_G /1 ns) / (1000.0/F_CLK_MHZ_G)));

to generate as much as needed 4 bit counter you should write some function that will return the COUNT_TO_TICKS_C value divided by 2**4-1 and a rest, and do some generic coding with it.
 

aha, I have never used this math_real library before. hmmm
 

FYI, you can only use it to compute constants if you want to synthesize with it. Don't expect to be able to build hardware that does floating point math using that library. (I could almost here the light switch turning on and the bulb exploding when you say: aha, I have never used this math_real library before. hmmm

Regards
 

thanks dude, I just spent some tens of minutes searching about what this is used for on google.

I assume that we can use this for the purpose of testbenches and constants in RTL code?
 

thanks dude, I just spent some tens of minutes searching about what this is used for on google.

I assume that we can use this for the purpose of testbenches and constants in RTL code?
Exactly for that, nothing else. If you absolutely need floating point then you should get a IEEE 754 floating point IP core and use that.
 

IEEE 754 floating point IP core? So this would be an IP core provided by the FPGA vendor itself or by a 3rd party that meets the IEEE 754 specifications. Is this correct?

I have read before that floating point maths is not for FPGAs, it is too complex. Now with hard DSP blocks this may be easy though. But the question still remains. Why not go for a DSP instead of FPGA to solve the design problem, or better yet, why not do fixed point maths instead?

DSPs are built for floating point calculations. So, I would expect that people use them instead. I am still not sure how much they cost but it should still be quite cheap like we buy micrprocessors all that time.
 

How do you think DSPs do floating point? 1. built in IEEE 754 floating point IP core, 2. software libraries.

For 1. If the IP can be synthesized into an ASIC there isn't anything stopping you from putting it in an FPGA. The problem isn't that it can't be done or is too complex. It is how much of the FPGA's resources are required to implement it, when fixed point is adequate for the majority of cases and uses significantly less resources.
 

What I meant to say is that DSPs and now the GPUs are dedicated for floating point calculations and thus it would make more sense to use them as I have heard that floating point is hard for an FPGA as we might even run of out routing resources in our design if not the programmable logic that is. But than again I have never actually implemented a floating point on an FPGA yet.

In any case, in this era of SoC FPGA from Altera and Zynq from Xilinx, I think that the ARM Cortex processor in the connected to the FPGA can do a lot of floating point too maths too.

Thanks for your reply.
 

Altera 10 series family will have hard IEEE 754 floating point units
 

This turns into an off-topic chat.

The original topic isn't related to floating point at all. math_real has been brought in as a tool to calculate time constants, neither related to floating point.

Please stay on topic.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top