entity parameterization

Guest
I have a number of discrete output modules. Each output signal drives the gate of a FET that can switch the output high or low. The modules are all very similar. Some have outputs to drive two FETs in series, some only drive the output high, and some only drive the output low. Some example entities are shown below.

Is there a way to parameterize the entity so I don't have to have a different module for each slightly different output? I was trying to think of a way to use generics that indicate if the output should be generated or something like that. When I use an entity that has all of the signals, but port map the unused outputs as open, I get a number of synthesis warnings.

entity discrete_output_drive_high_drive_low
port (
clk : in std_logic;
reset : in std_logic;
command : command_type;
protected_output_drive_high : out std_logic;
protected_output_drive_low : out std_logic
);
entity discrete_output_drive_high
port (
clk : in std_logic;
reset : in std_logic;
command : command_type;
protected_output_drive_high : out std_logic
);
entity discrete_output_dual_drive_high
port (
clk : in std_logic;
reset : in std_logic;
command : command_type;
protected_output_drive_high_a : out std_logic;
protected_output_drive_high_b : out std_logic
);

Thanks for any help you could give me.

Jim
 
On 08/12/12 11:21, james.knoll@gmail.com wrote:
I have a number of discrete output modules. Each output signal drives the gate of a FET that can switch the output high or low. The modules are all very similar. Some have outputs to drive two FETs in series, some only drive the output high, and some only drive the output low. Some example entities are shown below.

Is there a way to parameterize the entity so I don't have to have a different module for each slightly different output? I was trying to think of a way to use generics that indicate if the output should be generated or something like that. When I use an entity that has all of the signals, but port map the unused outputs as open, I get a number of synthesis warnings.

entity discrete_output_drive_high_drive_low
port (
clk : in std_logic;
reset : in std_logic;
command : command_type;
protected_output_drive_high : out std_logic;
protected_output_drive_low : out std_logic
);
entity discrete_output_drive_high
port (
clk : in std_logic;
reset : in std_logic;
command : command_type;
protected_output_drive_high : out std_logic
);
entity discrete_output_dual_drive_high
port (
clk : in std_logic;
reset : in std_logic;
command : command_type;
protected_output_drive_high_a : out std_logic;
protected_output_drive_high_b : out std_logic
);

Thanks for any help you could give me.

Jim

This probably sounds flippant, but you could just ignore the warnings -
presumably they are just telling you that the output is unused, and any
driving logic for that output is begin optimized away.

If that's not to your taste, would it be OK in your application to use a
vector of outputs? You can then parameterize the width of the vector
using a generic.

I don't know what "high" and "low" mean, but assuming high means "1 is
active level" and low means "0 is active level" perhaps you could
provide an input containing the bit pattern to indicate which outputs
are active high e.g. something like

entity thing is
generic (N : positive);
port (clk, reset : in std_logic;
command : command_type;
driveIsActiveHigh : in std_logic_vector(N-1 downto 0);
protected_output_drive : out std_logic_vector(N-1 downto 0));

end entity thing;

architecture RTL of thing is

begin


process(clk, reset)


begin

if reset = '1' then
protected_output_drive = (N-1 downto 1 => '0') xnor
driveIsActiveHigh;
elsif rising_edge(clk) then
if command = whatever then
protected_output_drive(0) <= '1' xnor driveIsActiveHigh(0);

You'd then call the module with

u1: thing generic map (N => 10, driveIsActiveHigh => "101010101010")
port map (clk => clk


etc


regards
Alan

--
Alan Fitch
 
Hmmm... in the code, driveIsActiveHigh is a port, but in the instantiation example, it is a generic?

Assuming it was intended to be a generic, I would go step further and make driveIsActiveHigh an unconstrained std_logic_vector generic, such that driveIsActiveHigh'length is used to constrain the size of the protected_output_drive port, and its values are used for the logic. Use just one generic, but get two pieces of information.

Even if it is intended as a port, you could still use an unconstrained SLV port the same way. Just beware that unconstrained ports on entities render them unsynthesizable AT THAT UNIT LEVEL. There must be something instantiating it to constrain the ports. I usually build a constrained wrapper for test synthesis at the unit level.

Generics are useful when you want to constrain multiple ports relative to that generic. Say you want to make sure that two variable-width ports are always the same width, you could use a single generic that both port declarations invoke in the type constraint. Otherwise, if you just made the two ports unconstrained, you should have an assertion that verifies their widths match.

Scalar generics, like N in the example, are also useful in that you can constrain the subtype of the generic for meaningful implementations. For example, declaring N as positive automatically creates an error if it is mapped to 0. An unconstrained SLV generic would not do that. On the other hand, it is easy enough to assert driveIsActiveHigh'length > 0.

Andy
 

Welcome to EDABoard.com

Sponsor

Back
Top