A
alivingstone
Guest
I'm trying to make a frequency to time conversion in VHDL to help make
my testbenches more readable and I think I'm running into a language
limitation. Anyone done anything like this:
I want to have a function that takes an integer input (frequency in
hertz) and outputs the half-period of the wave so that I can use it to
generate my testbench clock. For instance:
constant F_CLK : positive := 1_544_000; --Hz
constant T_CLK : time := (1 / F_CLK / 2) * (1 sec);
...
clk <= not clk after T_CLK;
However, the above generates a T_CLK of 0ps. My assumption was that
time is stored as an integer, so result of the 1/F_CLK division (<1)
was being rounded to zero. So I tried scaling the initial division:
constant T_CLK : time := (10**9 / F_CLK / 2) * (1 ns);
The above works great, generating the correct half-period of 323ns.
The problem is that the above restricts T_CLK to an integer in
nanoseconds, leaving me with an error of ~0.8ns per half-period
(~1.6ns per clock cycle). I tried to get more resolution by changing
the division prescaler:
constant T_CLK : time := (10**12 / F_CLK / 2) * (1 ps);
but the 10**12 causes an overflow at compile time and the calculation
fails. So doing it by this method leaves me with only nanosecond
resolution --- unacceptable for most frequencies.
Has anyone successfully done this? Maybe someone more clever than
myself can anyone think of a way to do the scaling without overflowing
the language constructs.
Many thanks.
my testbenches more readable and I think I'm running into a language
limitation. Anyone done anything like this:
I want to have a function that takes an integer input (frequency in
hertz) and outputs the half-period of the wave so that I can use it to
generate my testbench clock. For instance:
constant F_CLK : positive := 1_544_000; --Hz
constant T_CLK : time := (1 / F_CLK / 2) * (1 sec);
...
clk <= not clk after T_CLK;
However, the above generates a T_CLK of 0ps. My assumption was that
time is stored as an integer, so result of the 1/F_CLK division (<1)
was being rounded to zero. So I tried scaling the initial division:
constant T_CLK : time := (10**9 / F_CLK / 2) * (1 ns);
The above works great, generating the correct half-period of 323ns.
The problem is that the above restricts T_CLK to an integer in
nanoseconds, leaving me with an error of ~0.8ns per half-period
(~1.6ns per clock cycle). I tried to get more resolution by changing
the division prescaler:
constant T_CLK : time := (10**12 / F_CLK / 2) * (1 ps);
but the 10**12 causes an overflow at compile time and the calculation
fails. So doing it by this method leaves me with only nanosecond
resolution --- unacceptable for most frequencies.
Has anyone successfully done this? Maybe someone more clever than
myself can anyone think of a way to do the scaling without overflowing
the language constructs.
Many thanks.