Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a constant calculated from generic parameter in a port declaration in VHDL?

Tags:

vhdl

An example would be a generic register file which I'm trying to implement like this:

entity register_file is
generic(reg_width: integer := 32; reg_num: integer := 16);
constant sel_num: integer := integer(CEIL(LOG(Real(reg_num))));
port (
    data_in: in std_logic_vector(reg_width - 1 downto 0);
    data_out: out std_logic_vector(reg_width - 1 downto 0);
    rd_sel: in std_logic_vector(sel_num - 1 downto 0);
    wr_sel: in std_logic_vector(sel_num - 1 downto 0);
    rd_enable: in std_logic;
    wr_enable: in std_logic;
    clock: in std_logic;
);
end register_file;

This doesn't work because it seems generic and port have to be the first two declarations, followed by the others. If I move type and constant after the port declaration, they are not visible when the port declaration is being processed.

I'm new to VHDL and I think this should be a common problem, but I can't find the solution. Obviously, I would like to avoid the copy-paste solution.

like image 794
Miloš Rašić Avatar asked Nov 19 '13 13:11

Miloš Rašić


Video Answer


1 Answers

If there is no other use of reg_num, simply make sel_num the generic.

Otherwise, write a function called sel to convert reg_num to another natural. The question is, where to put the function?

In my designs I tend to put a lot of common datatypes, declarations, functions and the clock period (*) in a package called common.

package common is
   function sel(n : natural) return natural;
   constant clock_period : time := 1 sec / 32000000;

   constant num_regs : natural := 16;
   subtype sel_word is std_logic_vector(sel(num_regs) downto 0);
end common;  -- package body contains the function body

Then my entity looks like

use Work.common.all;

entity register_file is
generic(reg_width: integer := 32; reg_num: integer := 16);
port (
    rd_sel: in std_logic_vector(sel(reg_num) downto 0);  -- OK
    wr_sel: in sel_word;                                 -- better?
...

If different parts of a design need different values of "regnum" then the generic approach is to be preferred.

Otherwise, locating these details in "common" allows you to parameterise the whole design with a single file, and no risk of hard-coded (and possibly wrong) values for some of the generics.

(*) why the clock frequency? It's unbelievably useful to scale all the timing delays, baud rate parameters, memory wait states etc from one parameter, knowing they will all remain correct when I change the clock...

like image 72
user_1818839 Avatar answered Sep 23 '22 23:09

user_1818839