Optional PORTs in VHDL? - vhdl

I am writing an IP-Core and depending on which generic parameters user chooses not all OUT/IN Ports are needed. Is it possible to have optional Ports? I know something similar should be possible, since when I use Xilinx IP-Cores, depending on parameters not all PORTs are included.

Ports can't be optional, but usage of ports can be, which for the designer is as if they are not there.
Input ports that are not mapped (used) must have a default value in the entity, and output ports can simply be left unmapped.
If an entity is declared like for example:
entity mdl_sub is
generic(
A_C_USE : boolean := FALSE;
B_D_USE : boolean := FALSE);
port(
clk_i : in std_logic;
rst_i : in std_logic;
a_i : in std_logic := 'X';
b_i : in std_logic := 'X';
c_o : out std_logic;
d_o : out std_logic);
end entity;
Then the module can be used in the different configuration like below, where the use of ports can then differ based on the configuration:
-- Using port a_i and c_o
mdl_sub_0 : entity work.mdl_sub
generic map(
A_C_USE => TRUE)
port map(
clk_i => clk_i,
rst_i => rst_i,
a_i => m0_a_i,
c_o => m0_c_o);
-- Using port b_i and d_o
mdl_sub_1 : entity work.mdl_sub
generic map(
B_D_USE => TRUE)
port map(
clk_i => clk_i,
rst_i => rst_i,
b_i => m1_b_i,
d_o => m1_d_o);
All signals and ports are std_logic.

Related

Importing Custom VHDL IP but not able to use or view IP

I'm new to VHDL, and currently am working on applying a few filters to a hdmi pass through example code I found. I managed to get everything working (HDMI Pass Through with RGB Switch Filter) so I'm trying to migrate the code over to a piece of IP using Vivado.
I declared the component and instance like so:
component TestIP
port (
vid_pData : in std_logic_vector(23 downto 0);
vid_pData_new : out std_logic_vector(23 downto 0);
aRst : in std_logic;
PixelClk : in std_logic;
sw0 : in std_logic;
sw1 : in std_logic;
sw2 : in std_logic;
sw3 : in std_logic
);
TestIP_inst : TestIP
port map(
vid_pData => vid_pData_new,
aRst => async_reset_i,
PixelClk => pixelclk,
sw0 => sw0,
sw1 => sw1,
sw2 => sw2,
sw3 => sw3
);
The rest of the code was kept the same. I packaged the IP using the IP wizard, and exported it to the default IP repository. It created a file called TestIP_0, with two files, TestIP_0 and Top_IP, both are .vhd files.
In the source hierarchy in vivado, I can see in the IP my instance, TestIP_inst: TestIP(Behavioral)(TestIP_0.vhd)
The issue is I cannot find this in my IP catalogue, and even though I can create a bitstream successfully on my schematic I was expecting to find my IP inbetween the DVI2RGB and RGB2DVI block, but instead my IP doesnt appear and the data stream isn't connecting the input to the output so when I program the board the screen is just black.
I apologise in advance for what is probably a stupid question, but any idea how to correct this?
Thanks
EDIT
Here is my entity declaration of TestIP
entity TestIP is
Port ( vid_pData : in STD_LOGIC_Vector(23 downto 0);
vid_pData_new : out STD_LOGIC_Vector(23 downto 0);
aRst : in std_logic;
PixelClk : in std_logic;
sw0 : in STD_LOGIC;
sw1 : in STD_LOGIC;
sw2 : in STD_LOGIC;
sw3 : in STD_LOGIC);
end TestIP;
The correct way to initiate the component was by defining a new set of variables, it must've been getting mixed up as there were multiple instances of vid_pData and vid_pData new, so there was no "order" to the flow of data.
TestIP_inst : TestIP
port map(
vid_pData1 => vid_pData,
vid_pData2 => vid_pData_new,
aRst => async_reset_i,
PixelClk => pixelclk,
sw0 => sw0,
sw1 => sw1,
sw2 => sw2,
sw3 => sw3
);

VHDL: Conditionally Instantiate Components using Generics

I'd like to conditionally instantiate components using generics set on the command line. I'd prefer to have a string as the generic (i.e. fast or slow) rather than a number.
I can't find any examples of this on stackOverflow so I thought I'd ask.
Here is an example of conditionally instantiating architectures of a component using generics. The same code would work for instantiating different components:
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity dut is
generic (
SPEED : string := "fast"
);
port(
clk : in std_logic;
reset: in std_logic;
start: in std_logic;
done: out std_logic);
end entity dut;
architecture dutarch of dut is
component delay is
port (
clk : in std_logic;
reset: in std_logic;
start: in std_logic;
done: out std_logic
);
end component delay;
begin
d1g: if (SPEED = "fast") generate
d1f : entity work.delay(fast)
port map (
clk => clk,
reset => reset,
start => start,
done => done
);
else generate
d1s : entity work.delay(slow)
port map (
clk => clk,
reset => reset,
start => start,
done => done
);
end generate;
end architecture dutarch;

Use VHDL Generics To Choose Entity

I have a VHDL design with two architectures named fast and slow. I'd like to be able to choose between them at simulation/elaboration time using the command line and generics.
I cannot figure out how to choose a configuration, that is to instantiate a component with the architecture I want, using VHDL generics.
Is there a way to do this or do I need to use a generate statement and hardcode the chosen architecture?
Turns out you cannot use the generic to control a configuration statement. Instead use generate to pick architectures using a generic:
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity dut is
generic (
SPEED : string := "fast"
);
port(
clk : in std_logic;
reset: in std_logic;
start: in std_logic;
done: out std_logic);
end entity dut;
architecture dutarch of dut is
component delay is
port (
clk : in std_logic;
reset: in std_logic;
start: in std_logic;
done: out std_logic
);
end component delay;
begin
d1g: if (SPEED = "fast") generate
d1 : entity work.delay(fast)
port map (
clk => clk,
reset => reset,
start => start,
done => done
);
else generate
d1 : entity work.delay(slow)
port map (
clk => clk,
reset => reset,
start => start,
done => done
);
end generate;
end architecture dutarch;

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 - direct instantiation for PLL

I am trying to make a VGA controller on a DE0 board and have made the following code:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY VGA is
PORT (clk : IN std_logic;
vga_hs, vga_vs : OUT std_logic;
vga_r, vga_g, vga_b : OUT std_logic_vector(3 DOWNTO 0));
END ENTITY VGA;
ARCHITECTURE A1 OF VGA IS
SIGNAL rst, clk25 : std_logic;
BEGIN
SYNC1 : ENTITY work.sync(A1)
PORT MAP (clk25, vga_hs, vga_vs, vga_r, vga_g, vga_b);
CLK_25 : ENTITY work.pll(rtl)
PORT MAP (clk, rst, clk25);
END ARCHITECTURE A1;
When I compile the model I get the following error message:
Error (12006): Node instance "altpll_0" instantiates undefined entity "PLL_altpll_0"
I'm instantiating two components the first SYNC1 is the synchronisation counts for a 640 x 480 display the second (CLK_25) is PLL clock generated by quartus II. With the following model:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity PLL is
port (
clk_clk : in std_logic := '0'; -- clk.clk
rst_reset : in std_logic := '0'; -- rst.reset
clk_25_clk : out std_logic -- clk_25.clk
);
end entity PLL;
architecture rtl of PLL is
component PLL_altpll_0 is
port (
clk : in std_logic := 'X'; -- clk
reset : in std_logic := 'X'; -- reset
read : in std_logic := 'X'; -- read
write : in std_logic := 'X'; -- write
address : in std_logic_vector(1 downto 0) := (others => 'X'); -- address
readdata : out std_logic_vector(31 downto 0); -- readdata
writedata : in std_logic_vector(31 downto 0) := (others => 'X'); -- writedata
c0 : out std_logic; -- clk
areset : in std_logic := 'X'; -- export
locked : out std_logic; -- export
phasedone : out std_logic -- export
);
end component PLL_altpll_0;
begin
altpll_0 : component PLL_altpll_0
port map (
clk => clk_clk, -- inclk_interface.clk
reset => rst_reset, -- inclk_interface_reset.reset
read => open, -- pll_slave.read
write => open, -- .write
address => open, -- .address
readdata => open, -- .readdata
writedata => open, -- .writedata
c0 => clk_25_clk, -- c0.clk
areset => open, -- areset_conduit.export
locked => open, -- locked_conduit.export
phasedone => open -- phasedone_conduit.export
);
end architecture rtl; -- of PLL
How can i directly instantiate pll(rtl) from the working library ?
Generate the PLL with the MegaWizard in Quartus Prime, and then include the generated .qip file in the design. I assume that the MegaWizard is used to generate PLL_altpll_0 in your example.
The generated PLL entity is then compiled into work (or another library which is then shown in the .qip file), and you can then instantiate the PLL with entity instantiation, and thus leave out the redundant component declaration in the architecture that uses the generated PLL. Code like, assuming workPLL_altpll_0 is compiled to work library:
altpll_0 : entity work.PLL_altpll_0
port map (

Resources