I've got 3 main architectures for vhdl top in conf_gate.vhd. In each of architecture I want to choose one of two architecture of instantion (depends on value of constant). Can I choose one of architecture by using configure keywords from the same top (conf_gate.vhd)? Example is listed below (configuration statement is at end of file)
Pastebin 3_architecture_vhdl
-- configuration gate
-- File: conf_gate.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity xor_gate is
generic(
DATA_WIDTH : natural := 3
);
port(
a : in std_logic_vector(DATA_WIDTH-1 downto 0);
b : in std_logic_vector(DATA_WIDTH-1 downto 0);
c : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end xor_gate;
architecture arch of xor_gate is
begin
c <= a xor b;
end arch;
architecture not_arch of xor_gate is
begin
c <= a xnor b;
end not_arch;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity or_gate is
generic(
DATA_WIDTH : natural := 3
);
port(
a : in std_logic_vector(DATA_WIDTH-1 downto 0);
b : in std_logic_vector(DATA_WIDTH-1 downto 0);
c : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end or_gate;
architecture arch of or_gate is
begin
c <= a or b;
end arch;
architecture not_arch of or_gate is
begin
c <= a nor b;
end not_arch;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity and_gate is
generic(
DATA_WIDTH : natural := 3
);
port(
a : in std_logic_vector(DATA_WIDTH-1 downto 0);
b : in std_logic_vector(DATA_WIDTH-1 downto 0);
c : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end and_gate;
architecture arch of and_gate is
begin
c <= a and b;
end arch;
architecture not_arch of and_gate is
begin
c <= a nand b;
end not_arch;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity conf_gate is
generic(
DATA_WIDTH : natural := 3
);
port(
a : in std_logic_vector(DATA_WIDTH-1 downto 0);
b : in std_logic_vector(DATA_WIDTH-1 downto 0);
c : out std_logic_vector(DATA_WIDTH-1 downto 0)
);
end conf_gate;
architecture and_gate_arch of conf_gate is
constant negated : boolean := true ;
begin
negated_gate : if negated = true generate
mod_inst : and_gate(not_arch)
generic map (
DATA_WIDTH => DATA_WIDTH
)
port map (
a => a,
b => b,
c => c
);
end generate negated_gate;
gate : if negated = false generate
mod_inst : entity work.and_gate(arch)
generic map (
DATA_WIDTH => DATA_WIDTH
)
port map (
a => a,
b => b,
c => c
);
end generate gate;
end and_gate_arch;
architecture or_gate_arch of conf_gate is
constant negated : boolean := true ;
begin
negated_gate : if negated = true generate
mod_inst : entity work.or_gate(not_arch)
generic map (
DATA_WIDTH => DATA_WIDTH
)
port map (
a => a,
b => b,
c => c
);
end generate negated_gate;
gate : if negated = false generate
mod_inst : entity work.or_gate(arch)
generic map (
DATA_WIDTH => DATA_WIDTH
)
port map (
a => a,
b => b,
c => c
);
end generate gate;
end or_gate_arch;
architecture xor_gate_arch of conf_gate is
constant negated : boolean := true ;
begin
negated_gate : if negated = true generate
mod_inst : entity work.xor_gate(not_arch)
generic map (
DATA_WIDTH => DATA_WIDTH
)
port map (
a => a,
b => b,
c => c
);
end generate negated_gate;
gate : if negated = false generate
mod_inst : entity work.xor_gate(arch)
generic map (
DATA_WIDTH => DATA_WIDTH
)
port map (
a => a,
b => b,
c => c
);
end generate gate;
end xor_gate_arch;
configuration CONF of conf_gate is
for and_gate_arch
for mod_inst : entity work.and_gate
use entity work.conf_gate;
end for;
end for;
end CONF;
Component binding deferred to a configuration declaration:
configuration conf of conf_gate is
for and_gate_arch
for negated_gate
for mod_inst: and_gate
use entity work.and_gate(not_arch);
end for;
end for;
end for;
end configuration conf;
requires component instantiation:
architecture and_gate_arch of conf_gate is
constant negated: boolean := true ;
component and_gate is
generic ( DATA_WIDTH: natural := 3 );
port (
a: in std_logic_vector(DATA_WIDTH - 1 downto 0);
b: in std_logic_vector(DATA_WIDTH - 1 downto 0);
c: out std_logic_vector(DATA_WIDTH - 1 downto 0)
);
end component;
begin
negated_gate:
if negated = true generate
mod_inst:
-- entity work.and_gate (not_arch)
and_gate
generic map ( DATA_WIDTH => DATA_WIDTH )
port map (
a => a,
b => b,
c => c
);
end generate negated_gate;
gate:
if negated = false generate
mod_inst:
entity work.and_gate(arch)
generic map ( DATA_WIDTH => DATA_WIDTH )
port map (
a => a,
b => b,
c => c
);
end generate gate;
end architecture and_gate_arch;
You should be aware configuration declarations are not widely supported by synthesis vendors. It's worth checking your vendor's supported VHDL constructs (e.g. Xilinx Vivado User Guide 901 for synthesis).
The alternative can be providing the configuration specifications in the enclosing declarative region for the component instantiation.
See IEEE Std 1076-2008 3.4 Configuration declarations and 7.3 Configuration specification. It's also useful to understand the difference between an explicit binding indication (7.3.2 Binding indication) and a default binding indication (7.3.3 Default binding indication).
Related
I have a type declared in a package which I use in the port entity:
Package:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package ports_type is
constant N: positive := 3;
type t_ports_types is array(0 to N-1) of std_logic_vector (N-1 downto 0);
end package ports_type;
Module:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ports_type.all;
entity ports is
generic (
N : positive := 3
);
port(
inp : in t_ports_types;
outp : out std_logic_vector(N-1 downto 0)
);
end ports;
architecture Behavioral of ports is
begin
process(inp)
variable result : std_logic;
begin
for y in 0 to N-1 loop
result := '0';
for x in 0 to N-1 loop
result := result or inp(x)(y);
end loop;
outp(y) <= result;
end loop;
end process;
end Behavioral;
The problem is that I have to manually change the value of Nin the package, which is a problem if I want to instantiate the ports entity in another module, like:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.ports_type.all;
entity ports_top is
generic (
N : positive := 3
);
Port (
A : in std_logic_vector(N-1 downto 0);
B : in std_logic_vector(N-1 downto 0);
C : in std_logic_vector(N-1 downto 0);
Outp : out std_logic_vector(N-1 downto 0)
);
end ports_top;
architecture Behavioral of ports_top is
signal s_ports : t_ports_types;
begin
s_ports(0) <= A;
s_ports(1) <= B;
s_ports(2) <= C;
ports_0: entity work.ports(Behavioral)
generic map (
N => N
)
port map(
inp => s_ports,
outp => Outp
);
end Behavioral;
The goal would be to only change N in the top module and not in the package as well. Is that possible with vhdl'93?
Thanks for the help.
I am trying to define a type inside a package whose size is dependent on the component generics. Here is what I am trying to do, but synthesis is complaining:
package DcoPack is
component SinCosDco
generic
(
g_LUT_DEPTH : integer := 2**10;
g_LUT_BIT_RES : integer := 15
);
port
(
reset : in std_logic;
lClk : in std_logic;
InFreqCtrl : in std_logic_vector(31 downto 0) := X"028F5C28";
InStartPhse : in std_logic_vector(31 downto 0) := X"00000000";
OutDco : out signed((g_LUT_BIT_RES - 1) downto 0)
);
type LutSinT is array(0 to g_LUT_DEPTH - 1) of
std_logic_vector(g_LUT_BIT_RES-1 downto 0);
function f_QuantizationSgn(nbit : integer; max_abs : real; dval : real)
return std_logic_vector;
function f_InitLutSin
return LutSinT;
end package DcoPack;
package body DcoPack is
function f_QuantizationSgn(nbit : integer; max_abs : real; dval : real)
return std_logic_vector is
<function body>
end function;
function f_InitLutSin return LutSinT is
<function body>
end function;
end package body DcoPack;
and my component
library DCO_lib;
use DCO_lib.DcoPack.all;
entity Dco is
generic
(
g_LUT_DEPTH : integer := 2**10;
g_LUT_BIT_RES : integer := 15
);
port
(
reset : in std_logic;
lClk : in std_logic;
InDcoEn : in std_logic;
InFreqCtrl : in std_logic_vector(31 downto 0) := X"028F5C28";
InStartPhse : in std_logic_vector(31 downto 0) := X"00000000";
OutDco : out signed((g_LUT_BIT_RES - 1) downto 0)
);
end entity Dco;
architecture zDco of Dco is
-- want to reference LutSinT in numerous components, it varies depending
-- on generics
constant c_SinCosLut : LutSinT := f_InitLutSin;
... <rest of code is irrelevant
As the code above shows, I am trying to reference this type inside each component. However, I need to be able to easily vary the generic parameters depending on the project, so is there a way for VHDL to infer the correct array size? Or am I locked into defining the g_LUT_DEPTH/g_LUT_BIT_RES in the package or hard-coding the type inside each component?
EDIT: Added clarifying code snippets and explanation.
Yes there now is. VHDL-2008 supports package generics. So you can write
library ieee;
use ieee.numeric_std.all;
entity SinCosDco is
generic (
g_LUT_DEPTH : positive;
g_LUT_BIT_RES : positive
);
port (
OutDco : out signed((g_LUT_BIT_RES - 1) downto 0)
);
end entity;
architecture tmp of SinCosDco is
use ieee.std_logic_1164.all;
begin
OutDco <= to_signed(-1, g_LUT_BIT_RES);
end architecture;
library ieee;
package DcoPack is
generic (
g_LUT_DEPTH : positive := 2**10;
g_LUT_BIT_RES : positive := 15
);
use ieee.numeric_std.all;
component SinCosDco
generic (
g_LUT_DEPTH : positive := g_LUT_DEPTH;
g_LUT_BIT_RES : positive := g_LUT_BIT_RES
);
port (
OutDco : out signed((g_LUT_BIT_RES - 1) downto 0)
);
end component;
use ieee.std_logic_1164.all;
type LutSinT is array(0 to g_LUT_DEPTH - 1) of std_logic_vector(g_LUT_BIT_RES-1 downto 0);
end package DcoPack;
entity e is end entity;
library ieee;
architecture a of e is
constant g_LUT_DEPTH: positive := 2**7; -- remember integer is only 32 bits
constant g_LUT_BIT_RES : positive := 8;
package myDcoPack is new work.DcoPack
generic map (
g_LUT_DEPTH => g_LUT_DEPTH,
g_LUT_BIT_RES => g_LUT_BIT_RES);
-- use work.myDcoPack.all; -- optional
use ieee.numeric_std.all;
signal output : signed((g_LUT_BIT_RES - 1) downto 0);
use ieee.std_logic_1164.all;
signal lut : myDcoPack.LutSinT;
begin
comp_inst : myDcoPack.SinCosDco
port map ( OutDco => output );
lut(0) <= std_logic_vector(output);
end architecture;
However, this was not supported in Vivado 2 years ago. Don't know if it's supported now.
I am looking at this example and below answer which is a nice solution to produce two's complement:
library ieee;
use ieee.numeric_std.all;
entity twoscomplement is
generic
(
Nbits : positive := 8
);
port
(
A : in unsigned (Nbits-1 downto 0);
Y : out signed (Nbits downto 0)
);
end entity twoscomplement;
architecture a1 of twoscomplement is
begin
Y <= -signed(resize(A, Y'length));
end architecture;
I want to use the said example to have two's complement and then make a "16-bit subtractor". The code will look like the following:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity subtractor_16bit is
Port ( a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end subtractor_16bit;
architecture Behavioral of subtractor_16bit is
component fulladder_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end component;
component twoscomplement is
Port (
A : in unsigned (15 downto 0);
C : out signed (15 downto 0)
);
end component;
signal n1 : STD_LOGIC_VECTOR(15 downto 0);
begin
twoscomplement_1: twoscomplement port map (a => a ,c => n1); --ERROR
fulladder_16bit_1: fulladder_16bit port map (a => a, b => n1, sum => sum , cin => cin, cout => cout, over => over);
end Behavioral;
However, I am receiving an error saying:
Error: type error near a; current type std_logic_vector; expected type unsigned.
Kindly help me to solve this problem.
As nobody is answering this and nobody is down voting it, I will answer.
Look at the error
Error: type error near a; current type std_logic_vector; expected type unsigned.
Now look at entity subtractor_16bit.
[...]
entity subtractor_16bit is
Port ( a : in STD_LOGIC_VECTOR(15 downto 0);
[...]
component twoscomplement is
Port (
A : in unsigned (15 downto 0);
[...]
twoscomplement_1: twoscomplement port map (a => a ,c => n1);
[...]
What do you see? twoscomplement expects an unsigned, while a is std_logic_vector! Just like the error says.
std_logic_vector and unsigned are two separate types. As VHDL is a strongly typed language, you cannot just put the data from one type to another. You need to use type conversion.
For unrelated types, you should implement a type conversion function. Or functions, if you want bidirectional conversion. E.g.
function (input : type_a) return type_b;
But in this case, std_logic_vector and unsigned have the same underlying type, std_logic. (std_ulogic actually since VHDL-2008 I believe.)
In that case you can convert from one type to another explicitly. E.g.
signal a_u : unsigned(y downto 0);
signal a_slv : std_logic_vector(y downto 0);
begin
a_u <= unsigned(a_slv);
Next, your not instantiating the twoscomplement component properly. The entity has a generic Nbits. By default you set it to 8. But in your architecture Behavioral of subtractor_16bit, you feed it with 16 bits, without changing the generic value. That doesn't work.
Also: twoscomplement has two ports: A and Y. But in subtractor_16bit you start using A and C. That's bad coding practice.
Finally, you can drop the component declarations. Just instantiate the entities from the library. E.g.
twoscomplement_1: entity work.twoscomplement [...]
So, subtractor_16bit should look something like this:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity subtractor_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
cin : in STD_LOGIC;
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end entity;
architecture structural of subtractor_16bit is
use IEEE.NUMERIC_STD.ALL;
signal n1 : signed(a'range);
begin
twoscomplement_1: entity work.twoscomplement
generic map(
NBits => a'length
)
port map (
a => unsigned(a),
y => n1
);
fulladder_16bit_1: entity work.fulladder_16bit
port map (
a => a,
b => std_logic_vector(n1),
sum => sum,
cin => cin,
cout => cout,
over => over
);
end architecture;
...
HOWEVER this will still not work.
As you see on your entity twoscomplement, port A has a size of NBits, and port Y has a size of NBits+1. That is because you seem to want to keep 16-bit value precision. So when converting unsigned to signed, you need to add a 17th bit for the sign. As a result, the rest of you code will need to be modified!
.... But this can be fixed a different way. I will learn you something about two's complement: -a = not(a) + 1.
Proof (Take 4 bits signed precision):
0 = b'0000 => -0 is not(b'0000)+1 = b'1111'+1 = b'0000'
7 = b'0111 => -7 is not(b'0111)+1 = b'1000'+1 = b'1001'
-6 = b'1010' => 6 is not(b'1010)+1 = b'0101'+1 = b'0110'
See?
So now I will solve your puzzle for you:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity subtractor_16bit is
Port (
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
sum : out STD_LOGIC_VECTOR(15 downto 0);
cout : out STD_LOGIC;
over : out STD_LOGIC
);
end entity;
architecture structural of subtractor_16bit is
begin
fulladder_16bit_1: entity work.fulladder_16bit
port map (
a => a,
b => not(b),
sum => sum,
cin => '1',
cout => cout,
over => over
);
end architecture;
You will still need to change/fix the cout and over behavior...
Please tell me how to correctly describe the structural component of LUT5 on the basis of the LUT4 component, the problem is precisely in the correct mapping of ports.
Entity LUT5 is
Port(
A,B,C,D,E : in std_logic;
Z : out std_logic;
);
End LUT5;
Architecture Behaviour of LUT5 is
Component LUT4
Port(
A,B,C,D : in std_logic;
Z : out std_logic;
);
End Component;
Begin
??????
End
End Architecture
You can represent a five input lookup table by using two four input lookup tables with a selector choosing between the outputs based on the fifth bit:
library ieee;
use ieee.std_logic_1164.all;
entity lut5 is
generic (
LUTVAL: std_logic_vector (0 to 31)
);
port (
a, b, c, d, e: in std_logic;
z : out std_logic
);
end entity lut5;
architecture behaviour of lut5 is
component mux2 is
port (
a: in std_logic;
b: in std_logic;
s: in std_logic;
y: out std_logic
);
end component;
component lut4 is
generic (
LUTVAL: std_logic_vector (0 to 15)
);
port (
a, b, c, d: in std_logic;
z: out std_logic
);
end component;
signal z0, z1: std_logic;
begin
LUT4_0:
lut4
generic map (
LUTVAL => LUTVAL(0 to 15)
)
port map (
a => a,
b => b,
c => c,
d => d,
z => z0
);
LUT4_1:
lut4
generic map (
LUTVAL => LUTVAL(16 to 31)
)
port map (
a => a,
b => b,
c => c,
d => d,
z => z1
);
MUX_2_1:
mux2
port map (
a => z0,
b => z1,
s => e,
y => z
);
end architecture;
The generics are a method of delivering the lookup table contents from the top level of the design model.
Add it a small testbench:
library ieee;
use ieee.std_logic_1164.all;
entity lut5_tb is
end entity;
architecture foo of lut5_tb is
signal a, b, c, d, e: std_logic := '0';
signal z: std_logic;
constant LUTVAL: std_logic_vector (0 to 31) := x"A2201000";
signal index: natural;
begin
DUT:
entity work.lut5
generic map (
LUTVAL => LUTVAL
)
port map (
a => a,
b => b,
c => c,
d => d,
e => e,
z => z
);
STIMULI:
process
use ieee.numeric_std.all;
begin
for i in LUTVAL'RANGE loop
(e, d, c, b, a) <= to_unsigned(i,5);
index <= i;
wait for 10 ns;
end loop;
wait;
end process;
end architecture;
And we can see that it performs as a five input lookup table:
You can count the bits across the z output over time using the added index signal and find the output reconstructs the 32 bit LUTVAL (x"A2201000").
Here's the missing bits and pieces:
library ieee;
use ieee.std_logic_1164.all;
entity mux2 is
port (
a: in std_logic;
b: in std_logic;
s: in std_logic;
y: out std_logic
);
end entity;
architecture foo of mux2 is
begin
y <= a when s = '0' else
b;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity lut4 is
generic (
LUTVAL: std_logic_vector (0 to 15)
);
port (
a, b, c, d: in std_logic;
z: out std_logic
);
end entity;
architecture foo of lut4 is
constant lut: std_logic_vector := LUTVAL;
use ieee.numeric_std.all;
begin
LOOKUP:
z <= lut(to_integer(unsigned'(d,c,b,a)));
end architecture;
I try to generate a multiple componnt by using the generic map , but i dont know if my code VHDL is correct or no ?
here the programm generate 5 parallel component ( comp) for forming bascule
entity bascule is
Port ( X1,X2,X3,X4,X5: in STD_LOGIC;
Y1,Y2, Y3,Y4,Y5 : in STD_LOGIC;
Z1,Z2,Z3,Z4,Z5 : in STD_LOGIC;
S1,S2,S3,S4,S5 : out STD_LOGIC);
end bascule;
architecture Behavioral of bascule is
component comp
Generic( N: integer :=1);
Port ( X : in STD_LOGIC;
Y : in STD_LOGIC;
Z: in STD_LOGIC;
S : out STD_LOGIC);
end component;
begin
m1 : comp generic map (5)
port map ( X1,Y1,Z1, S1);
m2 : comp generic map (5)
port map ( X2,Y2,Z2, S2);
m3 : comp generic map (5)
port map ( X3,Y3,Z3, S3);
m4 : comp generic map (5)
port map ( X4,Y4,Z4, S4);
m5 : comp generic map (5)
port map ( X5,Y5,Z5, S5);
end Behavioral;
i want to know the way to generate any number of component ?
my best regards
i want to know the way to generate any number of component ?
The key is the word "generate"...
you can use a for..generate loop. In order to do this, you need to express your top entity with the same number of vector inputs as the number of components you expect:
entity bascule is
generic ( number_of_comps : positive)
port ( X,Y,Z: in STD_LOGIC_VECTOR(number_of_comps downto 1);
S : out STD_LOGIC_VECTOR(number_of_comps downto 1));
end bascule;
Then in the architecture you can wire up your components like this:
for i in 1 to number_of_comps generate
inst : entity work.comp
generic map (5)
port map ( X(i),Y(i),Z(i), S(i));
end generate;
I think you may still have a confusion, as you have a generic of 5 on your lower level comp, but it sounds to me like that generic should only be in the top entity, to specify how many comps you want (unless you are then doing the same in the comp entity?)
library ieee;
use ieee.std_logic_1164.all;
-- dummy comp this analyzes and elaborates
entity comp is
Generic( N: integer :=1);
Port (
X: in STD_LOGIC;
Y: in STD_LOGIC;
Z: in STD_LOGIC;
S: out STD_LOGIC
);
end entity;
architecture behave of comp is
begin
S <= X and Y and Z;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity bascule is
Port (
-- X1,X2,X3,X4,X5: in STD_LOGIC;
-- Y1,Y2, Y3,Y4,Y5: in STD_LOGIC;
-- Z1,Z2,Z3,Z4,Z5: in STD_LOGIC;
-- S1,S2,S3,S4,S5: out STD_LOGIC
-- and yes, you could pass the number of elements in these as a generic:
X: in std_logic_vector (1 to 5);
Y: in std_logic_vector (1 to 5);
Z: in std_logic_vector (1 to 5);
S: out std_logic_vector (1 to 5)
);
end bascule;
architecture Behavioral of bascule is
component comp
Generic( N: integer :=1);
Port (
X: in STD_LOGIC;
Y: in STD_LOGIC;
Z: in STD_LOGIC;
S: out STD_LOGIC
);
end component;
begin
M_gen:
-- and use the same generic as above in the generate iteration scheme:
for i in 1 to 5 generate
M:
comp generic map (5)
port map (
X(i), Y(i), Z(i), S(i)
);
end generate;
-- m1 : comp generic map (5)
-- port map ( X1,Y1,Z1, S1);
-- m2 : comp generic map (5)
-- port map ( X2,Y2,Z2, S2);
-- m3 : comp generic map (5)
-- port map ( X3,Y3,Z3, S3);
-- m4 : comp generic map (5)
-- port map ( X4,Y4,Z4, S4);
-- m5 : comp generic map (5)
-- port map ( X5,Y5,Z5, S5);
end Behavioral;
Using a generic to control a generate statement interation instantiating comp
Because you appear confused about how to use generics to control the number of components, I'll demonstrate:
library ieee;
use ieee.std_logic_1164.all;
-- dummy comp
entity comp is
Port (
X: in STD_LOGIC;
Y: in STD_LOGIC;
Z: in STD_LOGIC;
S: out STD_LOGIC
);
end entity;
architecture behave of comp is
begin
S <= X and Y and Z;
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity bascule is
generic (MSIZE: natural := 1);
Port (
X: in std_logic_vector (1 to MSIZE);
Y: in std_logic_vector (1 to MSIZE);
Z: in std_logic_vector (1 to MSIZE);
S: out std_logic_vector (1 to MSIZE)
);
end bascule;
architecture Behavioral of bascule is
component comp
Port (
X: in STD_LOGIC;
Y: in STD_LOGIC;
Z: in STD_LOGIC;
S: out STD_LOGIC
);
end component;
begin
Mgen:
for i in 1 to MSIZE generate
M:
comp
port map (
X(i), Y(i), Z(i), S(i)
);
end generate;
end Behavioral;
library ieee;
use ieee.std_logic_1164.all;
entity bascule_tb is
end entity;
architecture foo of bascule_tb is
constant MSIZE: natural :=5;
signal X: std_logic_vector (1 to MSIZE);
signal Y: std_logic_vector (1 to MSIZE);
signal Z: std_logic_vector (1 to MSIZE);
signal S: std_logic_vector (1 to MSIZE);
begin
DUT: entity work.bascule
generic map (MSIZE)
port map (
X => X,
Y => Y,
Z => Z,
S => S
);
end architecture;
We get MSIZE number of comp components based on the generic MSIZE, which is passed the constant MSIZE where bascule is instantiated in the test bench bascule_tb. This analyzes, elaborates and runs (though it doesn't actually do anything).