Quartus Prime VHDL component instantiation compile error - vhdl

I am having an issue when trying to compile the following code:
----------------
----------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity adder_top is
Port ( a_in : in STD_LOGIC_VECTOR (3 downto 0);
b_in : in STD_LOGIC_VECTOR (3 downto 0);
clk : in STD_LOGIC;
clk_en : in STD_LOGIC;
carry_in : in STD_LOGIC;
carry_out : out STD_LOGIC;
c_out : out STD_LOGIC_VECTOR (3 downto 0));
end adder_top;
architecture Behavioral of adder_top is
COMPONENT c_addsub_0
PORT (
A : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
CLK : IN STD_LOGIC;
C_IN : IN STD_LOGIC;
CE : IN STD_LOGIC;
C_OUT : OUT STD_LOGIC;
S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT c_addsub_0;
begin
inst_1 : COMPONENT c_addsub_0
port map
(
A => a_in,
B => b_in,
CLK => clk,
C_IN => carry_in,
CE => clk_en,
C_OUT => carry_out,
S => c_out
);
end Behavioral;
---------------------------
---------------------------
I receive the following error code when trying to compile:
Error (12006): Node instance "inst_1" instantiates undefined entity
"c_addsub_0". Ensure that required library paths are specified
correctly, define the specified entity, or change the instantiation.
If this entity represents Intel FPGA or third-party IP, generate the
synthesis files for the IP.
I am entirely unsure why I am receiving this error. Any help would be greatly appreciated.

The synthesis tool (Quartus) used to analyze and elaborate (a.k.a. compile) your design is complaining that it has not found an entity to bind the component c_addsub_0 with. You need to point the tool, in a tool defined way, to a library that contains the desired entity.
If you intended c_addsub_0 to be a block that you created then maybe it did not analyze into the work library as expected (unexpected syntax errors), or the library path to the work library is not established correctly (unlikely for a synthesis tool). If you wrote c_addsub_0 then it may be easier to use direct entity instantiation -- it saves the hassle of writing the component declaration and keep it in sync with the instance and the entity in another file. For example:
inst_1 : ENTITY work.c_addsub_0(<arch_name>)
port map
(
A => a_in,
B => b_in,
CLK => clk,
C_IN => carry_in,
CE => clk_en,
C_OUT => carry_out,
S => c_out
);
If the c_addsub_0 block is meant to be unbound through elaboration, as a black box until place-and-route, then you need to tell Quartus by decorating the instance with the appropriate syn_black_box attribute.
architecture Behavioral of adder_top is
COMPONENT c_addsub_0
PORT (
A : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
CLK : IN STD_LOGIC;
C_IN : IN STD_LOGIC;
CE : IN STD_LOGIC;
C_OUT : OUT STD_LOGIC;
S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT c_addsub_0;
attribute syn_black_box : boolean;
attribute syn_black_box of c_addsub_0: component is true;
begin
...
It then knows to synthesize a black box representation in the post synthesis netlist for that component. You then need to insure the Quartus back end can find a netlist for the given component in a netlist library path somewhere.
VHDL provides for a variety of ways to create hierarchy with incredibly precise control over binding, signal connections, naming/renaming of blocks and other features which are rarely used in ordinary designs. Unless your synthesis tool only supports one style of instantiation using component declarations or you need a black box, then I would stick with direct entity instantiation.
P.S.: Your use clause use ieee.std_logic_unsigned; should be use synopsys.std_logic_unsigned; -- The IEEE standards body never approved the std_logic_unsigned package. Though, if analyzing with the 1076-2008 standard, it is allowed now to analyze anything you want into the IEEE library. That permits defacto vendor, but not formally standardized, packages to be used without modification of your source code. Only the STD library is now actually a standard. Just be aware that Mentor Graphics and Synopsys versions of this package are different so your code may not achieve the portability that use of the standards based numeric_std package will achieve.

Related

Trouble Instantiating PLL of Lattice iCE40

I have Lattice iCE40 HX8K FPGA in 256 BGA package. I want to use one of the available PLL modules to transform external clock frequency of 37MHz to internal clock for use inside of the FPGA of 74MHz.
I used the "Configure PLL Module" in IceCube2 and used the following configuration:
- PLL Type section:
- GlobalNetworks to be Driven by PLL Output : 1;
- Dedicated Clock Pad;
- PLL Operation Modes:
- No Compensation Mode;
- Additional Delay Settings : No;
- Frequency:
- Input - 37MHz;
- Output - 74MHz;
- Others - nothing selected;
Then I get the two VHDL files - SO_pll.vhd and SO_pll_inst.vhd. I have file Design.vhd where my code is supposed to go.
If I understand correctly Lattice documentation, I need to specify that my Design.vhd (its Entity) is top Level Module, which I did. I need to include
SO_pll.vhd in the list of design files in IceCube2, which I did. And last - I need to use the template provided in SO_pll_inst.vhd to instantiate in my main code the PLL by port mapping the PLL signals to signals in my Design.vhd. Here comes the trouble - how to do it?
---Design.vhd---
library IEEE;
use IEEE.std_logic_1164.all;
entity Design is
port(
I_CLK: in std_logic
);
end entity Design;
architecture RTL of Design is
signal S_CLK : std_logic;
signal S_RESET : std_logic;
begin
SO_pll_inst: SO_pll
port map(
REFERENCECLK => I_CLK,
PLLOUTCORE => open,
PLLOUTGLOBAL => S_CLK,
RESET => S_RESET
);
end RTL;
---SO_pll_inst.vhd---Generated by IceCube2
SO_pll_inst: SO_pll
port map(
REFERENCECLK => ,
PLLOUTCORE => ,
PLLOUTGLOBAL => ,
RESET =>
);
---SO_pll.vhd---Generated by IceCube2
library IEEE;
use IEEE.std_logic_1164.all;
entity SO_pll is
port(
REFERENCECLK: in std_logic;
RESET: in std_logic;
PLLOUTCORE: out std_logic;
PLLOUTGLOBAL: out std_logic
);
end entity SO_pll;
architecture BEHAVIOR of SO_pll is
signal openwire : std_logic;
signal openwirebus : std_logic_vector (7 downto 0);
component SB_PLL40_CORE
generic (
--- Feedback
FEEDBACK_PATH : string := "SIMPLE"; -- String (simple, delay,
phase_and_delay, external)
DELAY_ADJUSTMENT_MODE_FEEDBACK : string := "FIXED";
DELAY_ADJUSTMENT_MODE_RELATIVE : string := "FIXED";
SHIFTREG_DIV_MODE : bit_vector(1 downto 0) := "00";
-- 0-->Divide by 4, 1-->Divide by 7, 3 -->Divide by 5
FDA_FEEDBACK : bit_vector(3 downto 0) := "0000";
-- Integer (0-15).
FDA_RELATIVE : bit_vector(3 downto 0) := "0000";
-- Integer (0-15).
PLLOUT_SELECT : string := "GENCLK";
--- Use the spread sheet to populate the values below
DIVF : bit_vector(6 downto 0);
-- Determine a good default value
DIVR : bit_vector(3 downto 0);
-- Determine a good default value
DIVQ : bit_vector(2 downto 0);
-- Determine a good default value
FILTER_RANGE : bit_vector(2 downto 0);
-- Determine a good default value
--- Additional C-Bits
ENABLE_ICEGATE : bit := '0';
--- Test Mode Parameter
TEST_MODE : bit := '0';
EXTERNAL_DIVIDE_FACTOR : integer := 1
-- Not Used by model, Added for PLL config GUI
);
port (
REFERENCECLK : in std_logic; -- Driven by core logic
PLLOUTCORE : out std_logic; -- PLL output to core logic
PLLOUTGLOBAL : out std_logic; -- PLL output to global network
EXTFEEDBACK : in std_logic; -- Driven by core logic
DYNAMICDELAY : in std_logic_vector (7 downto 0); -- Driven by core
logic
LOCK : out std_logic; -- Output of PLL
BYPASS : in std_logic; -- Driven by core logic
RESETB : in std_logic; -- Driven by core logic
LATCHINPUTVALUE : in std_logic; -- iCEGate Signal
-- Test Pins
SDO : out std_logic; -- Output of PLL
SDI : in std_logic; -- Driven by core logic
SCLK : in std_logic -- Driven by core logic
);
end component;
begin
SO_pll_inst: SB_PLL40_CORE
-- Fin=37, Fout=74
generic map(
DIVR => "0000",
DIVF => "0001111",
DIVQ => "011",
FILTER_RANGE => "011",
FEEDBACK_PATH => "SIMPLE",
DELAY_ADJUSTMENT_MODE_FEEDBACK => "FIXED",
FDA_FEEDBACK => "0000",
DELAY_ADJUSTMENT_MODE_RELATIVE => "FIXED",
FDA_RELATIVE => "0000",
SHIFTREG_DIV_MODE => "00",
PLLOUT_SELECT => "GENCLK",
ENABLE_ICEGATE => '0'
)
port map(
REFERENCECLK => REFERENCECLK,
PLLOUTCORE => PLLOUTCORE,
PLLOUTGLOBAL => PLLOUTGLOBAL,
EXTFEEDBACK => openwire,
DYNAMICDELAY => openwirebus,
RESETB => RESET,
BYPASS => '0',
LATCHINPUTVALUE => openwire,
LOCK => open,
SDI => openwire,
SDO => open,
SCLK => openwire
);
end BEHAVIOR;
I just added Design.vhd and SO_pll.vhd to the list of design files. If I run synthesis with Lattice LSE the synthesis is successful, but the placer report says 0/2 PLLs used. If I run Synthesys with Synplify Pro placer report says 1/2 PLLs used,but I really cannot use it since I have not mapped the signals.
When I get the template from SO_pll_inst.vhd and place it inside of the architecture of Design.vhd I get the error message:
"ERROR - synthesis: design.vhd(19): so_pll is not declared. VHDL-1241"
Well, apparently I am missing something. If it is a template, I would expect just to map my signal and have it running. But no. Either I am doing something wrong, or...I am doing something wrong :) Please help.
Funny - I posted the question and I am posting the answer! :) here it goes:
---Design.vhd---
library IEEE;
use IEEE.std_logic_1164.all;
entity Design is
port(
I_CLK: in std_logic;
I_RESET: in std_logic;
O_PLLOUTGLOBAL : out std_logic
);
end entity Design;
architecture RTL of Design is
begin
SO_pll_inst: entity SO_pll
port map(
REFERENCECLK => I_CLK,
PLLOUTCORE => open,
PLLOUTGLOBAL => O_PLLOUTGLOBAL,
RESET => I_RESET
);
end RTL;
So, as obvious from the file above the key is in the instantiating of the entity of the PLL file. I was missing the keyword "entity" before the name of the entity specified in the PLL file. As expected, I was doing something wrong.

VHDL: When can ports be used as signals?

Please help me understand when ports can be used as signals in VHDL.
I am asking this question because I am using ports to move data from one component to another in Xilinx ISim, but the data remains undefined at it's destination. My problems could be caused if I am inferring data transfer by wiring port to port as in my first and third examples below without an explicity assignment statement.
I believe this is valid use of a ports from the entity as a signals wired to the ports of an included component.
-- Example 1 - Use ports instead of signals
entity user is
port(
data_bus : inout std_logic_vector(15 downto 0);
address_bus: in std_logic_vector(12 downto 0)
);
end user;
architecture Behavioral of user is
-- Component Port Definitions
component memory
port(
mem_data_bus : inout std_logic_vector(15 downto 0);
mem_address_bus: in std_logic_vector(12 downto 0)
);
end component memory;
begin
-- some logic
-- Instantiate thing
a_memory : memory
port map(
mem_data_bus => data_bus,
mem_address_bus => address_bus
);
end architecture;
I am not sure this is valid. Are extra signals required to wire components together or can the entity ports be used? (I realise there could be a problem joining to inout ports together, but this question is about when ports can be used as signals).
-- Example 2 - connect ports to multiple components
entity user is
port(
data_bus : inout std_logic_vector(15 downto 0);
address_bus: in std_logic_vector(12 downto 0)
);
end entity user;
architecture Behavioral of user is
-- Component Port Definitions
component memory_a
port(
ma_data_bus : inout std_logic_vector(15 downto 0);
ma_address_bus: in std_logic_vector(12 downto 0)
);
end component memory_a;
component memory_b
port(
mb_data_bus : inout std_logic_vector(15 downto 0);
mb_address_bus: in std_logic_vector(12 downto 0)
);
end component memory_b;
begin
-- some logic
-- Instantiate memories
a_memory_a : memory_a
port map(
ma_data_bus => data_bus,
ma_address_bus => address_bus
);
a_memory_b : memory_b
port map(
mb_data_bus => data_bus,
mb_address_bus => address_bus
);
end architecture
If the entity port definition does not include the ports, signals are required and cannot be inferred from ports.
-- Example 3 - Use signals for inteconnection as no suitable ports available
entity user is
end user;
architecture Behavioral of user is
-- Component Port Definitions
component memory_a
port(
data_bus : inout std_logic_vector(15 downto 0);
address_bus: in std_logic_vector(12 downto 0)
);
end component memory_a;
component memory_b
port(
data_bus : inout std_logic_vector(15 downto 0);
address_bus: in std_logic_vector(12 downto 0)
);
end component memory_b;
signal data_bus_sig : std_logic_vector(15 downto 0);
signal address_bus_sig : std_logic_vector(12 downto 0);
begin
-- some logic
-- Instantiate memories
a_memory_a : memory_a
port map(
data_bus => data_bus_sig,
address_bus => address_bus_sig
);
a_memory_b : memory_b
port map(
data_bus => data_bus_sig,
address_bus => address_bus_sig
);
end architecture
This is wrong because neither signals nor entity ports are defined.
-- Example 4 - WRONG? - Try to infer ports
entity user is
end user;
architecture Behavioral of user is
-- Component Port Definitions
component memory_a
port(
data_bus : inout std_logic_vector(15 downto 0);
address_bus: in std_logic_vector(12 downto 0)
);
end component memory_a;
component memory_b
port(
data_bus : inout std_logic_vector(15 downto 0);
address_bus: out std_logic_vector(12 downto 0)
);
end component memory_b;
begin
-- some logic
-- Instantiate memories
a_memory_a : memory_a
port map(
data_bus => data_bus,
address_bus => address_bus
);
a_memory_b : memory_b
port map(
data_bus => data_bus,
address_bus => address_bus
);
end architecture
I will refer to your example codes as 1, 2 3 and 4.
1) Example 1 is correct. This is a viable way to connect port in a hierarchical way.
2) For sure you will have compilation/synthesis errors in particular for the output ports.
In fact you will have multiple drivers (each of the out ports of the instantiated components) impacting on the same signal/port of the top entity. It will be easy to see in a simulation too, since you will see 'X's appear at that port (indicating multiple driver to the same signal). Please note that multiple input ports can be connected to a single driver (e.g. same input port of top entity, same signal, etc...)
3) It is partially correct! You have the same issue as in example 2 with the multiple drivers acting on the same signal.
4) This is definitely wrong!. You have not defined neither ports nor signals to be bonded to
UPDATE after changes in entity:
1) It is still correct, entity port can be used as (implicit) signal in this way. You can imagine the top entity just as a container for the 2 sub-component where you have "soldered" the pin of the components to the pins of the top-entity/container (the soldering material provides the electrical continuity)
2) This might be OK when the inout ports are used as input, but when you try to use then as outputs, there might be issues. There is a heavy dependency on how they component are described. If the components use weak logic values ('L' & 'H') then if you drive strong values ('0' & '1') then it might behave OK. It would be better to use intermediate signal end probably some sort of mux/demux to select/steer the data to/from the proper internal component.
3) From the pure interconnect point of view, this is OK. However, from the functional point of view you have to be sure that there is always on component that is acting as a driver and the other as a receiver. Otherwise you will have either undefined value on the internal signal or 'X' due to multiple drivers. However, for the address signal, no one is driving it, so it will be always 'U' (undifined). You need something (a port in top entity, a process, etc...) this si driving some kind of value on it.
4) As before, this is incorrect. The port of the component are connected to nothing. Please note that VHDL (but the same is valid for verilog) is a description language; you try to describe an actual circuit (like one made of chips on a PCB). Like in a real circuit you need some sort of wire to connect one pin of a chip to another pin in another IC, then also in VHDL/verilog you need an equivalent "object" to enabel the interconnection.Thus, you need to define the object (in this case the signal) and then describe its behavior (in this case bind together 2 ports of 2 components).
I hope this time is a bit clearer

structural vhdl: creating a "main function"

I would like to create a structural VHDL file that implements a "main" function. The "top-level" file would be design and the program that runs the code would be prog. Assuming that fulladd_pack contains the fulladd component, how do I "link" the two VHDL files?
*I also don't get the arguments in main in order for this to work.
-- design.vhdl
library ieee;
use ieee.std_logic_1164.all;
use work.fulladd_pack.all;
ENTITY design IS
port(Cin : IN STD_LOGIC;
X,Y : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
S : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
Cout, Over : OUT STD_LOGIC);
END design;
ARCHITECTURE struct OF design IS
SIGNAL C,temp : STD_LOGIC_VECTOR(1 TO 15);
BEGIN
main: prog PORT MAP(Cin,X,Y,S,C,Cin);
END struct;
-- prog.vhdl
library ieee;
use ieee.std_logic_1164.all;
use work.fulladd_pack.all;
ENTITY prog IS
port(Cin : IN STD_LOGIC;
X,Y : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
S : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
Cout, Over : OUT STD_LOGIC);
END prog;
ARCHITECTURE struct OF prog IS
SIGNAL C,temp : STD_LOGIC_VECTOR(1 TO 15);
BEGIN
instance0: fulladd PORT MAP(Cin,X,Y,S,C,Cin);
output: fulladd PORT MAP(Cin,X,Y,S,C,Cin);
END struct;
You've missed the point. VHDL, as a "programming language", models concurrency, dataflow, and the passage of time. A model is composed of large numbers of elements ('processes') with data ('signals') flowing between them. A built-in kernel in your simulator handles the concurrency and time flow.
At the "top level", you write a testbench, which instantiates the model, and you apply stimulus (by driving signals which are inputs to the model). The stimulus forces data around the model. This carries on until you stop providing stimulus, at which point everthing else (should) stop.
So, no main. Write a testbench. 'Linking' is an internal concept in the simulator; forget it. Just simulate your source files together.

ALTFP_ADD_SUB megafunction in ALTERA

I have the following entity calling the add_sub megafunction created by megafunction wizard under Quartus II :
library ieee;
use ieee.std_logic_1164.all;
library altera_mf;
use altera_mf.altera_mf_components.all;
entity fp_adder is
port(clock : in std_logic;
dataa : in STD_LOGIC_VECTOR (31 DOWNTO 0);
datab : in STD_LOGIC_VECTOR (31 DOWNTO 0);
result : out STD_LOGIC_VECTOR (31 DOWNTO 0));
end fp_adder;
architecture fp_adder_impl of fp_adder is
begin
add: altfp_add_sub
generic map(width_exp => 8, width_man => 23)
port map(clock => clock, dataa => dataa, datab => datab,
result => result);
end fp_adder_impl;
The code synthesises fine but when I launch a waveform to simulate it I always end up with an empty result output. Is there anything I'm missing ?
The ModelSim-Altera pre-build libraries do not contain a model for altfp_add_sub, which is probably the reason why it cannot simulate right away.
Take a look at Floating-Point Megafunctions User Guide page 27 / 4-4, where the reference to "altfp_add_sub_ex_msim.zip (ModelSim-Altera files)" probably points to the megafunction files that you must compile to get a simulation model for altfp_add_sub.

Passing Generics to Record Port Types

I did recently start to use records for my port definitions, especially if I want to group signals that belong to a certain interface. However, the problem I'm facing here is that I cannot pass, say the width of a std_logic_vector, to the entity by means of a generic. So what I basically want to do is the following:
library ieee;
use ieee.std_logic_1164.all;
use work.math_pkg.all;
package fifo_pkg is
type fifo_in_type is record
data_in : std_logic_vector(DATA_WIDTH_??- 1 downto 0);
rd : std_logic;
wr : std_logic;
end record;
type fifo_out_type is record
data_out : std_logic_vector(DATA_WIDTH_?? - 1 downto 0);
empty : std_logic;
full : std_logic;
end record;
component fifo is
generic
(
MIN_DEPTH : integer;
DATA_WIDTH : integer
);
port
(
clk : in std_logic;
res_n : in std_logic;
i : in fifo_in_type;
o : out fifo_out_type
);
end component fifo;
end fifo_pkg;
So the ideal solutions would be when i can use the same generic in my record as i did in the entity. (So that DATA_WIDTH is the same as DATA_WIDTH_??). I know that this should work somehow with vhdl 2008, however my quartus II 11sp1 does not support generics in records.
Is there an elegant way to achieve that kind of "generic passing" that is synthesizable? I know that one could just store a constant in the package, but then I cannot use the same fifo package to instantiate several fifo's with different widths.
Thanks a million,
T
Can you use type generics with Quartus?
Then you leave the type completely unspecified, so that you can create a FIFO of integers or any other data type:
package fifo_pkg is
generic (type element_type);
type fifo_in_type is record
data_in : element_type;
rd : std_logic;
wr : std_logic;
end record;
type fifo_out_type is record
data_out : element_type;
empty : std_logic;
full : std_logic;
end record;
component fifo is
generic
(
MIN_DEPTH : integer;
DATA_WIDTH : integer
);
port
(
clk : in std_logic;
res_n : in std_logic;
i : in fifo_in_type;
o : out fifo_out_type
);
end component fifo;
end fifo_pkg;
Then when you want to use it:
package wide_fifo_pkg is new fifo_pkg
generic map (type => std_logic_vector(31 downto 0));
and then you can use fifo_in_type and fifo_out_type:
signal i : fifo_in_type;
If you have more than one FIFO in a design unit you can create several versions of the package and use the package prefix to get the right type:
package narrow_fifo_pkg is new fifo_pkg
generic map (type => std_logic_vector(3 downto 0));
signal i32 : wide_fifo_pkg.fifo_in_type;
signal i4 : narrow_fifo_pkg.fifo_in_type;
Another VHDL 2008 option: you can have an unconstrained record type:
type fifo_in_type is record
data_in : std_logic_vector;
rd : std_logic;
wr : std_logic;
end record;
which you can then create subtypes of for your various uses:
subtype fifo1_data_type is fifo_in_type(data_in(31 downto 0));
subtype fifo2_data_type is fifo_in_type(data_in(15 downto 0));
No idea if Quartus supports either of those options - please let us know!
Generics in packages is supported in Xilinx's Vivado toolset currently. Ref their document UG901, the section titled "Generics in Packages" for details and a code sample. Need to make sure the source code properties are set up for VHDL-2008, as explained elsewhere in the same document.

Resources