VHDL - How to Define Port Map of a component with a package in its entity? - vhdl

I am trying to use packages to shift block of data within different components via top level entity.
I have defined a package with array as
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package my_array_pkg is
type my_array is array ( 0 to 9) of std_logic_vector(3 downto 0);
end my_array_pkg;
Then in top level entity I have declared my components as,
COMPONENT Array_Count is
Port ( C_1Hz : in std_logic;
reset : in std_logic;
digit : out my_array
);
end COMPONENT;
Now can someone help me about how to declare this "digit : out my_array" in the port map.
C2 : Array_Count
PORT MAP ( CLK1HZ, RESET, ????);
The array package needed to be updated in other component.
Thanks.

You need to "use" the package before the entity declaration :
use work.my_array_pkg.all;
or
library my_library;
use my_library.my_array_pkg.all;
to make the package contents visible.
Then you need to declare a signal of that type before you instantiate the component, for example:
signal my_digit : my_array;
and now connect the port to that signal
C2 : Array_Count
PORT MAP (
C_1Hz => CLK1HZ,
reset => RESET,
digit => my_digit);

Related

Can we write to two signals from a port map statement?

This is perhaps more of a hypothetical VHDL question as opposed to a real-life/case study question.
Say I have a component declaration as follows...
component my_comp is
port (
A : in std_logic;
--...other input/outputs
B : out std_logic_vector(9 downto 0)
);
end component my_comp;
And within the same entity containing my_comp i have the signals
signal my_comp_full_scale_output : std_logic_vector(9 downto 0);
signal my_comp_8_scale_output : std_logic_vector(7 downto 0);
Is there a way which I can assign these two signals both the value of B in the port map statement of the component instantiation? Something like this maybe...
my_comp_isnt : my_comp
port map (
A => some_signal,
-- other signal assignments
B => my_comp_full_scale_output,
B(9 downto 2) => my_comp_8_scale_output
);
Once again I stress that this is totally playing with VHDL's logic and I am not using this in any design!!! I do know that this can easily be done with an assignment of my_comp_full_scale_output to my_comp_8_scale_output outside of the component instantiation such as below and this is simply a sake of code for code's sake.
my_comp_isnt : my_comp
port map (
A => some_signal,
-- other signal assignments
B => my_comp_full_scale_output
);
my_comp_8_scale_output <= my_comp_full_scale_output(9 downto 2);
No.
1076-2008 - IEEE Standard VHDL Language Reference Manual states:
Each association element in an association list associates one
actual designator with the corresponding interface element in the
interface list of a subprogram declaration, component declaration,
entity declaration, block statement, or package.
So you can only map it once.

Composite Files/ Component Instantiation

I am new(ish) to VHDL. I am trying to understand how to use different component .vhd files to build a complete structure. I am working with a Digilent PmodA7, and want to have two LEDs blink alternately.
What I have tried is Inverter.vhd and LedBlink.vhd
Inverter.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Inverter is
Port (
Inv_in : in std_logic;
Inv_out : out std_logic
);
end Inverter;
architecture Behavioral of Inverter is
begin
Inv_out <= not Inv_in;
end Behavioral;
Ledblink-1.vhd:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
entity LedBlink is
Port (
clk: in std_logic;
rst: in std_logic;
led_0 : out std_logic;
led_1 : out std_logic
);
end LedBlink;
architecture Behavioral of LedBlink
-- Inverter.vhd
component Inverter is
port (
Inv_in : in std_logic;
Inv_out : out std_logic
);
end component;
constant CLK_FREQ : integer := 12500000;
constant BLINK_FREQ : integer := 1;
constant CNT_MAX : integer := CLK_FREQ/BLINK_FREQ/2 - 1;
signal cnt : unsigned(24 downto 0);
signal blink_0 : std_logic := '1';
signal blink_1 : std_logic := '1';
begin
process(clk)
begin
if (rst = '1') then
blink_0 <= '0';
blink_1 <= '0';
elsif (clk='1' and clk'event ) then
if cnt = CNT_MAX then
cnt <= (others => '0');
-- blink_1 <= blink_0;
A1: Inverter
Port map ( Inv_in => blink_0, Inv_out => blink_1);
blink_0 <= not blink_0;
else
cnt <= cnt + 1;
end if;
end if;
end process;
led_0 <= blink_0;
led_1 <= blink_1;
end Behavioral;
To understand how to combine files, I want to replace the line
blink_1 <= blink_0;
with a inverter component, ie 7404, but can’t figure out how to do this. The example I am following does not use libraries, so I am most interested in that method, although how to a library to accomplish this would be helpful.
What I have is:
You haven't provided a Minimal, Complete, and Verifiable example with an error. Questions asking for programming help on stackoverflow are practical, not theoretical. This implies a specific problem here.
Analysis (compiling) won't complete o with the missing is in the architecture bodyr or component instantiation in the unlabelled process.
You can't instantiate a component (a concurrent statement) in a process (which can only contain sequential statements). Move the component instance outside the process.
The flip flop output blink_0 is inverter's input. It's output blink_1 is then assigned to blink_0 in the process instead of not blink_0.
blink_1 is only assigned in the elaborated process from the concurrent assignment statement in the architecture of inverter. Each process in a design hierarchy has a driver. The value of multiple drivers are resolved during simulation. The equivalent post synthesis is having two devices driving the same signal and would generate a synthesis error.
Analyze Inverter.vhd before elaborating LedBlink.
cnt must be reset for simulation for the increment, adding 1 to all 'U's will result in all 'U's. You don't use package std_logic_unsigned.
library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity ledblink is
port (
clk: in std_logic;
rst: in std_logic;
led_0: out std_logic;
led_1: out std_logic
);
end entity ledblink;
architecture behavioral of ledblink is -- ADDED is
component inverter is
port (
inv_in: in std_logic;
inv_out: out std_logic
);
end component;
constant clk_freq: integer := 12500000;
constant blink_freq: integer := 1;
constant cnt_max: integer := clk_freq/blink_freq/2 - 1;
signal cnt: unsigned(24 downto 0);
signal blink_0: std_logic := '1';
signal blink_1: std_logic := '1';
begin
process (clk) -- contains counter cnt and flip flop blink_0
begin
if rst = '1' then
blink_0 <= '0';
-- blink_1 <= '0'; -- ONLY one driver for blink_1, the component
cnt <= (others => '0'); -- ADD cnt to reset
elsif clk = '1' and clk'event then -- OR rising_edge(clk)
if cnt = cnt_max then
cnt <= (others => '0');
-- blink_1 <= blink_0;
-- a1: inverter MOVED to architecture body
-- port map ( inv_in => blink_0, inv_out => blink_1);
-- blink_0 <= not blink_0; CHANGED
blink_0 <= blink_1;
else
cnt <= cnt + 1;
end if;
end if;
end process;
a1:
inverter -- MOVED to architecture body a place for concurrent statements
port map ( inv_in => blink_0, inv_out => blink_1);
led_0 <= blink_0;
led_1 <= blink_1;
end architecture behavioral;
After which your design analyzes and with a testbench providing clock and reset, elaborates and simulates:
Note cnt only requires a length of 23 (22 downto 0), cnt(24) and cnt(23) are always '0' with a 12.5 MHz clock (12500000).
The question notes "The example I am following does not use libraries, so I am most interested in that method, although how to a library to accomplish this would be helpful."
The first clause isn't exactly accurate. See IEEE Std 1076-2008 13.2 Design libraries:
A design library is an implementation-dependent storage facility for previously analyzed design units. A given implementation is required to support any number of design libraries.
...
There are two classes of design libraries: working libraries and resource libraries. A working library is the library into which the library unit resulting from the analysis of a design unit is placed. A resource library is a library containing library units that are referenced within the design unit being analyzed. Only one library is the working library during the analysis of any given design unit; in contrast, any number of libraries (including the working library itself) may be resource libraries during such an analysis.
Every design unit except a context declaration and package STANDARD is assumed to contain the following implicit context items as part of its context clause:
library STD, WORK; use STD.STANDARD.all;
Library logical name STD denotes the design library in which packages STANDARD, TEXTIO, and ENV reside (see Clause 16). (The use clause makes all declarations within package STANDARD directly visible within the corresponding design unit; see 12.4.) Library logical name WORK denotes the current working library during a given analysis. Library logical name IEEE denotes the design library in which the mathematical, multivalue logic and synthesis packages, and the synthesis context declarations reside (see Clause 16).
A design specification is analyzed into the working library which can be referenced by work and can be implementation dependent method redirected.
There are rules for determining the default binding indication (in lieu of a binding indication in a configuration specification as a block declarative item for a block (including an architecture body) containing a component instantiation or in a configuration declaration (not widely used by synthesis tools, if at all). See 11.7 Component instantiation and 3.4.3 Component configuration.
Without an explicit binding indication as here VHDL relies on a default binding indication (7.3.3 Default binding indication):
In certain circumstances, a default binding indication will apply in the absence of an explicit binding indication. The default binding indication consists of a default entity aspect, together with a default generic map aspect and a default port map aspect, as appropriate.
If no visible entity declaration has the same simple name as that of the instantiated component, then the default entity aspect is open. A visible entity declaration is the first entity declaration, if any, in the following list:
a) An entity declaration that has the same simple name as that of the instantiated component and that is directly visible (see 12.3),
b) An entity declaration that has the same simple name as that of the instantiated component and that would be directly visible in the absence of a directly visible (see 12.3) component declaration with the same simple name as that of the entity declaration, or
c) An entity declaration denoted by L.C, where L is the target library and C is the simple name of the instantiated component. The target library is the library logical name of the library containing the design unit in which the component C is declared.
These visibility checks are made at the point of the absent explicit binding indication that causes the default binding indication to apply.
In this case because inverter was analyzed into the same resource library (an unchanging work) following rule b). You can note that these rules are set up to be as painless as possible. There can be only one primary unit (here an entity) with the same name in a library.
Anyway the point is that there are libraries involved in the original post's code. Here without a configuration specification inverter is expected to be found in library work, regardless of what resource library it references in an implementation defined manor.
It's out of the scope of the vhdl tag and the original post does not identify a particular tool implementation, and VHDL tools are varied in methods for associating working and resource libraries with library logical names.
For a resource library made visible by a library clause a use clause of the form 'use library_logical_name.all;' can make all named entities in a resource library directly visible (See 12.4 Use Clauses, 12.3 Visibility, 12.5 The context of overload resolution). Otherwise a selected name for an instantiated entity can be used (8.3 Selected names).

how to have the vdhl code add text to itself

While trying to see if I could come up with a way to make the number of outputs variable by setting a "generic" I came up with the following thought. The idea would be to have a routine in the VHDL code inside the "port" declaration such that the routine would add the text "output(X) : out std_logic_vector(bits-1 downto 0); inside the "port" declaration. Please note that (X) represents the number of the output ports, i.e. output1, output2, etc. The idea being that when the VHDL parser reads the code it would see the required number of outputs when compiled. Is this something that can be done?
If I understood you correctly, you want to do meta-programming and have a generic number of ports. That's not possible in VHDL. However, you can just use a multidimensional array for that:
-- declare array type VHDL-2008-style
-- put this in a package
type slv_array is array(natural range<>) of std_logic_vector;
entity test is
generic (
-- number of outputs, at least one output
num_outputs : positive := 1
);
port (
my_inputs : in std_logic_vector(1 downto 0);
my_outputs : out slv_array(num_outputs - 1 downto 0)(1 downto 0)
);
end entity test;
You would then be able to use the component like this:
comp0 : component test
generic map (
num_outputs => 1
)
port map (
my_inputs => "10",
my_outputs(0) => my_output0
);
comp1 : component test
generic map (
num_outputs => 2
)
port map (
my_inputs => "00",
my_outputs(0) => my_output1
my_outputs(1) => my_output2
);

Generate ports in VHDL?

Is there a way to generate port declarations in VHDL? I would like to do something similar to #IFDEF for debug signals out to pins for an oscope. That way I can quickly enable or disable debug logic. For example:
entity my_entity is
port (
debug_label: if debug_on = 1 generate
debug1: out;
end debug_label;
....
);
end component;
When I try something like this is doesn't work. Is there any way to make it work? Or an alternative way to do something similar?
The ports can't be conditional, but the length of for example a
std_logic_vector can be configurable through a generic, and the length may
even be 0, resulting in null range. An entity showing this is:
entity mdl is
generic(
DEBUG_LEN : natural := 0);
port(
...
debug_o : out std_logic_vector(DEBUG_LEN - 1 downto 0));
end entity;
You should run a test synthesis to see how the your selected synthesis tool
handles null range when assigning to pins.

I don't understand what's wrong with this VHDL code?

I have the following code:
entity wave_select is
port( address:in std_logic_vector(6 downto 0);
ws1: in std_logic;
ws0: in std_logic;
wave_out: out std_logic_vector(6 downto 0));
end wave_select;
architecture choose_arch of wave_select is
signal internal_sine:std_logic_vector(6 downto 0);
signal internal_tri:std_logic_vector(6 downto 0);
signal internal_sqr:std_logic_vector(6 downto 0);
begin
U0: entity sine_tbl port map(addr=>address, sine_val=>internal_sine);
U1: entity triangle_tbl port map(addr=>address, tri_val=>internal_tri);
U2: entity square_tbl port map(addr=>address, square_val=>internal_sqr);
process (std_logic_vector'(ws1, ws0))
begin
case ws_combo is
when "01" => wave_out<=internal_sine;
when "10" => wave_out<=internal_tri;
when "11" => wave_out<=internal_sqr;
when others =>wave_out<=(others => '-');
end case;
end process;
end choose_arch;`
Whenever I try to compile this, I get the following errors:
Identifier/keyword expected (for the process line)
Keyword end expected (for the when "10" line)
Design unit declaration expected (for the same line as keyword error)
FIXED THE QUESTION
As it stands right now, this has a number of problems, mostly with fairly basic syntax.
Although it seems likely you mean the combination of ws0 and ws1 to be treated as ws_combo, you haven't done anything to tell the synthesizer that, so it treats ws_combo as simply undefined.
At least as far as I know, you can't combine signals in the process sensitivity list like you've done. The sensitivity list is to tell what external signals this process responds to, not much else.
You don't have a definition of wave_out (unless it's also in your entity declaration).
You don't have definitions of internal_sine, internal_tri, or internal_sqr. Hard to guess what type they should be without knowing the type of wave_out.
As an interim idea of how this might turn out, I've fixed some of the syntax errors, added an entity declaration that declares ws0, ws1 and wave_out, then sets wave_out to values suitable to the type I've given it (in this case, just took binary input and produced Grey code output).
entity controller1 is
port (
ws1 : in std_logic;
ws0 : in std_logic;
wave_out : out std_logic_vector(1 downto 0)
);
end;
architecture whatever of controller1 is
begin
impl: process(ws0, ws1)
begin
case std_logic_vector'(ws1,ws0) is
when "01" => wave_out<="01";
when "10" => wave_out<="11";
when "11" => wave_out<="10";
when others =>wave_out<=(others => '-');
end case;
end process;
end whatever;
Of course, this also needs the typical library and using to get declarations for std_logic and std_logic_vector, but with those added the synthesizer seems to accept it. Of course, some other synthesizer (I'm checked it with Synplify) might find a problem I missed, but I think that probably covers at least most of the obvious problems.
What are you attempting to achieve with the std_logic_vector' in this line?
process (std_logic_vector'(ws1, ws0))
If you just change that for the more conventional
process (ws1, ws0)
I imagine it will help.
But I assume ws_combo is a signal like
ws_combo = ws1&ws0;
so
process (ws_combo)
would be better still.

Resources