Use VHDL Generics To Choose Entity - vhdl

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;

Related

why my shift register show the result in one clock instead of 4?

this is my code for dff and multiplexer and shift register, which should rich the output in 4 clocks but it does it in one clock and I could not fix it myself.
this is my dff code:
use IEEE.STD_LOGIC_1164.ALL;
entity DFLipFlop is
Port ( d : in STD_LOGIC;
clock : in STD_LOGIC;
reset : in STD_LOGIC;
q : out STD_LOGIC);
end DFLipFlop;
architecture Behavioral of DFLipFlop is
begin
process(clock,reset)
begin
if(reset ='1')then
q <= '0';
elsif(CLOCK='1' and CLOCK'EVENT)then
q <= d;
end if;
end process;
end Behavioral;
this is my multiplexer code:
-- Company:
-- Engineer:
--
-- Create Date: 08:37:48 04/27/2022
-- Design Name:
-- Module Name: multiplexer - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity multiplexer is
Port ( DataIn : in STD_LOGIC;
P_in : in STD_LOGIC;
Selector : in STD_LOGIC;
Output : out STD_LOGIC);
end multiplexer;
architecture Behavioral of multiplexer is
begin
process(Selector)
begin
if Selector = '0' then
Output <= DataIn ;
else
OutPut <= P_in ;
end if;
end process;
end Behavioral;
this is my shift register code:
-- Company:
-- Engineer:
--
-- Create Date: 08:35:05 04/27/2022
-- Design Name:
-- Module Name: shiftRegister - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity shiftRegister is
Port ( DataIn : in STD_LOGIC;
Selector : in STD_LOGIC;
P_in : in STD_LOGIC_VECTOR (3 downto 0);
Clk : in STD_LOGIC;
OutPut : out STD_LOGIC);
end shiftRegister;
architecture structural of shiftRegister is
component DFLipFlop is
Port ( d : in STD_LOGIC;
clock : in STD_LOGIC;
reset : in STD_LOGIC;
q : out STD_LOGIC);
end component DFLipFlop;
component multiplexer is
Port ( DataIn : in STD_LOGIC;
P_in : in STD_LOGIC;
Selector : in STD_LOGIC;
Output : out STD_LOGIC);
end component multiplexer;
signal DFFOutput : STD_LOGIC_VECTOR(3 downto 0);
signal MuxOutput : STD_LOGIC_VECTOR(3 downto 0);
begin
multiplexer0 : multiplexer Port map( DataIn => DataIn , P_in => P_in(3) , Selector => Selector , Output => MuxOutput(0) );
dff_interface0 : DFLipFlop port map( d => MuxOutput(0) , clock => Clk , reset => '0' , q => DFFOutput(0));
multiplexer1 : multiplexer Port map( DataIn => DFFOutput(0) , P_in => P_in(2) , Selector => Selector , Output => MuxOutput(1) );
dff_interface1 : DFLipFlop port map( d => MuxOutput(1) , clock => Clk , reset => '0' , q => DFFOutput(1));
multiplexer2 : multiplexer Port map( DataIn => DFFOutput(1) , P_in => P_in(1) , Selector => Selector , Output => MuxOutput(2) );
dff_interface2 : DFLipFlop port map( d => MuxOutput(2) , clock => Clk , reset => '0' , q => DFFOutput(2));
multiplexer3 : multiplexer Port map( DataIn => DFFOutput(2) , P_in => P_in(0) , Selector => Selector , Output => MuxOutput(3) );
dff_interface3 : DFLipFlop port map( d => MuxOutput(3) , clock => Clk , reset => '0' , q => Output);
end structural;
and this is my test bench:
-- Company:
-- Engineer:
--
-- Create Date: 09:12:38 04/27/2022
-- Design Name:
-- Module Name: C:/Users/ABTIN/Documents/amirkabir un/term 4/Computer Architecture/Lab/HW8/HW8/TestBench.vhd
-- Project Name: HW8
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: shiftRegister
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY TestBench IS
END TestBench;
ARCHITECTURE behavior OF TestBench IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT shiftRegister
PORT(
DataIn : IN std_logic;
Selector : IN std_logic;
P_in : IN std_logic_vector(3 downto 0);
Clk : IN std_logic;
OutPut : OUT std_logic
);
END COMPONENT;
--Inputs
signal DataIn : std_logic := '0';
signal Selector : std_logic := '0';
signal P_in : std_logic_vector(3 downto 0) := "1011";
signal Clk : std_logic := '0';
--Outputs
signal OutPut : std_logic;
-- Clock period definitions
constant Clk_period : time := 5 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: shiftRegister PORT MAP (
DataIn => DataIn,
Selector => Selector,
P_in => P_in,
Clk => Clk,
OutPut => OutPut
);
-- Clock process definitions
Clk_process :process
begin
Clk <= '0';
wait for Clk_period/2;
Clk <= '1';
wait for Clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for Clk_period*10;
DataIn <= '0' ; P_in <= "1011" ; Selector <= '1' ;wait for Clk_period*1;
DataIn <= '1' ; P_in <= "1001" ;wait for Clk_period*2;
-- insert stimulus here
wait;
end process;
END;
I can not figure out what the problem is.
please help.
Your data input signal is not propagated across the shift register in a single clock.
When looking at this simulation, you can see it is the upper bit of your preload data that gets loaded at the clock edge where the cursor is placed. The behavior is consistent with the code.
The detailled explanation is:
at the cursor, Selector is 1, which means the multiplexer will select the P_in value
because the DFF gets the P_in value, it loads it at the cursor and the bit 4 of P_in is 1 so DFFOutput becomes 1 too
If you wanted to propagate a 1 across the shift-register, you should first reset it (to set it to zero) and then give it a 1 on the input.
You should use a proper reset at the begin of the testbench. This way your design gets into a known state.
In your testbench, you assign initial values to the signals but use them in sensitivity lists (the main culprit is selector). Because of this, the output of the multiplexers are undefined as the process was not triggered by a change on the signal.
You should change the testbench to look like this:
-- hold reset state for 100 ns.
wait for Clk_period * 10;
selector <= '0'; -- this assignment triggers the multiplexer processes
p_in <= "1011";
I would also strongly suggest simulating your entire design and exploring the signals inside (I see you use Vivado, it has an integrated simulator; otherwise Intel provides a free Modelsim license if you need it).
If you want to use the Vivado simulator, have a look at UG937.
To get examples of how to implement a particular component in Vivado, you can also look at the Synthesis Guide (UG901). There is an example of the implementation to use for shift registers to make optimal use of the FPGA's resources (other FPGA manufacturers have similar guides, look for synthesis guide in your favorite search engine).
For Vivado, there are also integrated code examples under Tools > Language templates.

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;

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.

Lattice Fpga Internal clock

I'm trying to configure a lattice MachX03's internal Oscillator. I read the MachXO3 sysCLOCK PLL Design and Usage Guide* and tried using the vhdl code found on page 31 of the documente, but I keep getting this error (VHDL-1261) syntax error near COMPONENT. Can someone tell me how I can get the clock to work using VHDL? here is the code I'm trying to use:
LIBRARY lattice;
library machXO3;
use machXO3.all;
COMPONENT OSCH
GENERIC(
NOM_FREQ: string := "53.20"); --53.20MHz, or can select other supported frequencies
PORT(
STDBY : IN STD_LOGIC; --'0' OSC output is active, '1' OSC output off
OSC : OUT STD_LOGIC; --the oscillator output
SEDSTDBY : OUT STD_LOGIC); --required only for simulation when using standby
END COMPONENT;
OSCInst0: OSCH
GENERIC MAP (NOM_FREQ => "53.20")
PORT MAP (STDBY => '0', OSC => clk, SEDSTDBY => OPEN);
and here is the code found in the manual:
library machXO3;
use machXO3.all;
COMPONENT OSCH
-- synthesis translate_off
GENERIC (NOM_FREQ: string := "2.56");
-- synthesis translate_on
PORT (STDBY:INstd_logic;
OSC:OUTstd_logic;
SEDSTDBY:OUTstd_logic);
END COMPONENT;
attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCinst0 : label is "2.56";
begin
OSCInst0: OSCH
-- synthesis translate_off
GENERIC MAP( NOM_FREQ => "2.56" )
-- synthesis translate_on
PORT MAP (STDBY=> stdby,
OSC => osc_int,
SEDSTDBY => stdby_sed
);
*http://www.latticesemi.com/view_document?document_id=50124
to Use the internal Osc basically use the code in the menu, mentioned above. to get a simple osc working write the following in vhdl. the code sets up a 2.56 Mhz clock, the slowest the internal clock can generate. the highest frequency the interal generator can output is 133 Mhz, refer to pages 30-20 of the document http://www.latticesemi.com/view_document?document_id=50124
library ieee;
use ieee.std_logic_1164.all;
-- For Main Clock --
library machXO3l;
use machXO3l.all;
--------------------
entity Clock is
port (stdby : in std_logic;
osc_int: out std_logic
);
end Clock;
architecture Clock_behav of Clock is
COMPONENT OSCH
-- synthesis translate_off
GENERIC (NOM_FREQ: string := "2.56");
-- synthesis translate_on
PORT (STDBY : IN std_logic;
OSC : OUT std_logic
);
END COMPONENT;
attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCinst0 : label is "2.56";
begin
Clock: OSCH
-- synthesis translate_off
GENERIC MAP( NOM_FREQ => "2.56" )
-- synthesis translate_on
PORT MAP ( STDBY => stdby,
OSC => osc_int
);
end Clock_behav;

IBUFDS simulation in vivado

I need to check my device wrapper logic, and one of the issue that I have is that IBUFDS instance not simulating correctly. I written simple test to check and to show what I mean.
Device.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Device is
Port (
CLK_P: in std_logic;
CLK_N: in std_logic;
CLK: out std_logic
);
end Device;
architecture arch of Device is
component IBUFDS
port (
O: out std_logic;
I: in std_logic;
IB: in std_logic
);
end component;
begin
D: IBUFDS
port map (
O => CLK,
I => CLK_P,
IB => CLK_N
);
end arch;
Device_tb.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Device_tb is
-- Port ( );
end Device_tb;
architecture Behavioral of Device_tb is
signal CLK, CLK_P, CLK_N: std_logic := '0';
begin
DEV: entity work.Device(arch)
port map(
CLK => CLK,
CLK_P => CLK_P,
CLK_N => CLK_N
);
CLK_gen: process
begin
CLK_P <= not CLK_P;
CLK_N <= CLK_P;
wait for 5 ns;
end process;
end Behavioral;
And the resulting simulation is
As you can see CLK out is always undefined. Don't know how to solve this, and is it solvable at all. I already thought about to architectures of my wrapper, but don't like this soulution, and maybe there are some better way to simulate this this. I tried to write generic map for IBUFDS instance but, elaborating step failing with error, that generic parameters not defined for IBUFDS.

Resources