So this code generates a 200 Hz clock based on a 100 Mhz clock.
We note that: 100 MHz / 500000 = 200 Hz
So, we need to take our 100 Mhz clock, and every 500000 cycles, we would have a full cycle of the 200 Hz clock that we would like to generate. Since we want the high time and low time to be the same, we know that we should oscillate the new clock every 500000 / 2
cycles.
From the perspective of the code, we will use hexadecimal, so it's worth noting that 500000 / 2 == 0x3D090
.
architecture foo of blah is
signal clk_200Hz : std_logic := '0';
signal counter : unsigned(19 downto 0) := x"00000";
begin
clkdiv : process (clk_100Mhz)
begin
if rising_edge(clk_100Mhz) then
if counter = x"00000" then
counter <= X"3D090"
clk_200Hz <= not clk_200Hz;
else
counter <= counter - 1;
end if;
end if;
end process clkdiv;
end architecture;
First delete the non-standard std_logic_arith
and std_logic_unsigned
libraries, leaving std_logic and numeric_std.
As well as being non-standard, they cause problems through a VHDL rule that - if two definitions of a type (or procedure or operator or whatever) are visible - like unsigned
or <=
- VHDL will try to discover which you intended (e.g. by the parameter types of the operator, because overloaded operators are legal).
But if two definitions are visible and indistinguishable - both are considered to be hidden. This makes you FIX the problem instead of allowing the compiler to pick one - probably wrong - at random.
So with only the standard libraries, things get a lot simpler.
Now another basic rule is that if you are fighting with lots of type conversions, something is declared the wrong type, which points to a design error.
I'm going to guess the mistake : min
should be declared as unsigned
but isn't. (Ditto d3 etc). It represents an unsigned number in bit (std_logic) form. So declare it as such.
Fix that and see what happens. But first, find the source for the numeric_std
package (the package spec, don't bother with the package body). You will see a lot of operators that allow unsigned
and integer
to interact directly.
Then I would expect your code snippet to work directly, without any type conversions.
If you don't actually need the bits of min
, go further and declare it as a subtype of natural
with range 0 to 59. There is no reason not to do so, even for synthesis, and for ports on a component.
It is usually appropriate to use unsigned
(or even std_logic_vector
if you must) for ports at the very top level, where you need to connect each bit to an FPGA pin. But internally, convert to the types most appropriate to the design as soon as you can.
Best Answer
This answer isn't what you're looking for, but the basic solution to this problem is this: Don't use division.
Many processor architectures and even DSP chips do not have a division instruction at all, and where they do have division, it is usually a multi-cycle operation, because division is fundamentally iterative. Division is expensive in terms of area, and slow, so it is usually avoided if possible.
I strongly suggest that yourself or anybody reading this question tries very hard to avoid implementing a hardware divide function of any sort, let alone a single-cycle one. As some comments have said, the standard approach would be to implement a multiplication by the reciprocal of the divisor. Even here, if you expect good performance in your FPGA, this would be implemented using a pipelined architecture, and so would not have single-cycle latency.
An even better solution would be to revise your design such that there is no need for any division or an equivalent. However, without knowing what your design is supposed to do, it's impossible to suggest alternatives.
As a footnote, and as a comment noted, division by a power of two is relatively simple, because it boils down to a shift operation.