Brad,
I do a variation of the 2nd method for counters in one of my designs:
entity ClkPrescale is
generic (
SCALE_FACTOR : integer := 0 -- value 1 runs Pulse1ms faster 10,000 faster
) ;
port (
Clk : In std_logic ;
nReset : In std_logic ;
. . .
Pulse1ms : Out std_logic
);
end ClkPrescale ;
architecture RTL of ClkPrescale is
constant CLOCK_FREQ : integer := 50E6 ; -- 50 MHz
constant Pulse1MS_FREQ : integer := 1E3 ; -- 1 KHz
constant CNT_1MS_INIT : integer := CLOCK_FREQ/(Pulse1MS_FREQ * (1+9999*SCALE_FACTOR));
constant CNT_1MS_WIDTH : integer := 16 ;
In your case, simplifying by using a single integer generic:
constant mem_size : integer := 2**7 * (sim_false*2**18) ;
-- or
constant mem_size : integer := 2**7 * ((1 - sim_true)*2**18) ;
I haven't checked Synopsys lately, but in the past they only
supported integer generics. So I have always limited myself
to only integer generics anyway.
Cheers,
Jim
In the general case, you can probably also try something based on
classical mathematics and curve-fitting through polynomials: with
generic values g in the set {1,2,3,...,N} that you want to yield a
value V(g) in {V1,V2,V3,...,VN} you can write an expression :
constant k : integer
:= ((V1)* (g-2)*(g-3)...(g-N) / ((1-2)*(1-3)*(1-4)...(1-N)) +
(V2)*(g-1)* (g-3)...(g-N) / ((2-1)*(2-3)*(2-4)...(2-N) +
... +
(VN)*(g-1)...(g-(N-1) / ((N-1)*(N-2)* ... *(N-
(N-1)) ) );
I.e. the idea is that for any given term in the sum, only one term is
ever non-zero, because if you have the "wrong: value of g, one of the
factors will be zero. But if you have the "right" value of g in your
term, all the stuff on the denominator cancels out the (G-k) terms,
leaving you with Vk.
Caveat: I've never tried this myself in VHDL, but for small values of
N, and some attention to precision and overflow, it might just be
crazy enough to work
You might need to cast most of the operands
to real, as well, to avoid errors due to using integer division.
All of the operators (+,*,/) must be the implicit operators (not
overloaded) so that the initializer is still technically static.
An obvious improvement is to try to use an ordinary VHDL function f
(which might use 'if' and 'case' statements) to map g to V(g), and
initialize the constant with f(g). But I think means that the
initializer is no longer a static expression and most synthesizers
will complain, although you might be might get lucky and wind up with
tool-dependent non-portable code :-( In the past I've seen Tool #1
gallantly accept fancy initializers that another Tool #2 later
complained about.
Apologies in advance if I messed up some of the subscripts above -- do
what I meant, not what I said!
- Kenn