开发者

How to use generic parameters that depend on other generic parameters for entities?

I am trying to convert some Verilog code that produces a slower clock from a faster clock for a UART module. The original verilog code is based on the module over at fpga4fun.com, and this is my attempt to translate it for my VHDL-based design.

entity baud_generator is
generic(
    f_clk : integer := 50000000;  -- default: 50 MHz
    baud  : integer := 115200;    -- default: 115,200 baud
    accum_width : integer := 16;
    accum_inc : integer := (baud sll accum_width) / f_clk
);
port(
    clock : in std_logic;
    reset_n : in std_logic;
    enable : in std_logic;
    baud_clock : out std_logic
);  
end entity baud_generator;

However, my compiler, Aldec-HDL, doesn't like the following line:

 accum_inc : natural := (开发者_StackOverflow社区baud sll accum_width) / f_clk

Here is the exact error message:

 # Error: COMP96_0300: baud_generator.vhd : (20, 52): Cannot reference "f_clk" until the interface list is complete.
 # Error: COMP96_0300: baud_generator.vhd : (20, 28): Cannot reference "baud" until the interface list is complete.
 # Error: COMP96_0071: baud_generator.vhd : (20, 28): Operator "sll" is not defined for such operands.
 # Error: COMP96_0104: baud_generator.vhd : (20, 27): Undefined type of expression.
 # Error: COMP96_0077: baud_generator.vhd : (20, 27): Assignment target incompatible with right side. Expected type 'INTEGER'.

In verilog, I have something like this:

module baud_generator(
  input clock,
  input reset_n,
  input enable,
  output baud_clock
);
parameter f_clock = 50000000;
parameter baud    = 115200;
parameter accum_width = 16;
parameter accum_inc = (baud << accum_width) / f_clock;
//...
endmodule

What is it that I need to modify in that line to make the compiler happy? Is it possible to use generics chained together like that?


This basically says you cannot do computations with the generic values to caluclate (default values for) other generics.

Just use accum_inc as a constant, not as a generic.

Also, the SLL (shift logic left) operator is meant for bit patterns (unsigned and signed datatypes in the ieee.numeric_std and ieee.numeric_bit packages), not for integers. You can do the same by multiplying by a power of two.


It looks to me like accum_inc is a constant, not a parameter (as it's calculated from the generics, so there's no reason to override it)

So it doesn't want to be in the generic part - simply move it to the architecture and make it a constant (and as Philippe noted, do your shifting with multiplies):

constant accum_inc : integer := (baud * (2**accum_width)) / f_clk;

You may find that you overflow what integers can manage, depending on the values of the generics, so you might find you want to use unsigned vectors in the generics and/or calculation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜