I have a rather large project, comprised of many modules integrated into one top-level component. I've created test-benches for these modules which make use of API packages (which I've created alongside them). I also have a top-level test-bench that tests the integrated system as a whole.
For one of the components, I'm interested in using VHDL-2008 Hierarchical Names within its MyModuleAPIPackage in order to access the internal signals from the top level testbench. Since I'm trying to write modular and re-usable code, I'd like to be able to instantiate the package so that it references the signals of the module within the component-level test (where the module is at the top level)
<<signal .MyComponent.MySignal : std_logic>>
and also within the top-level test (where there is an underlying structure)
<<signal .MySystem.MySubSystem.MyComponent.MySignal : std_logic>>
Perhaps this could be attainable through a combination of Hierarchical Names and generics?
Here is some (pseudo) code exemplifying what I'm trying to achieve.
MyModule.vhd
-- MyModule.vhd
entity MyModule is
port(
CLK : in std_logic;
RST : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(7 downto 0)
);
end entity MyModule;
architecture behavioral of MyModule is
-- Signal and constant definitions here.
begin
-- Describes how MyModule behaves.
end architecture behavioral;
----------------------
-- MyModule Test-Bench
----------------------
entity MyModule_tb is
end entity MyModule_tb;
architecture test of MyModule_tb is
-- Signal and constant definitions here
signal CLK, RST : std_logic := '0';
signal DATA_IN, DATA_OUT : std_logic_vector(7 downto 0) := (others = '0');
procedure DoComplexStuff(
InstructionCode : natural
)
is
begin
case InstructionCode is
when 0 =>
DATA_IN <= "01010101";
wait until CLK = '1';
DATA_IN <= "00110011";
wait until CLK = '1';
-- Lots of pretty complex stimuli
assert DATA_OUT = "00110011"
report "Output mismatch!"
severity failure;
when 1 =>
-- Lots of pretty complex stimuli
-- when ... =>
-- Plenty more instruction codes
others =>
null;
end procedure DoComplexStuff;
begin
CLK <= not CLK after 1 ms;
MainTestProc:
process
begin
for i in 0 to 99 loop
DoComplexStuff(i);
end loop;
end;
DUT: entity work.MyModule(behavioral)
port map(
CLK => CLK,
RST => RST,
DATA_IN => DATA_IN,
DATA_OUT => DATA_OUT
);
end architecture test;
I wish for procedure DoComplexStuff to be available at the top-level.
MyModuleApi.vhd
package MyModuleAPI is
generic(
-- Programatically defined aliases
PATH : path;
)
alias CLK is <<signal PATH.CLK : std_logic);
alias RST is <<signal PATH.RST : std_logic);
alias DATA_IN is <<signal PATH.DATA_IN : std_logic_vector(7 downto 0));
alias DATA_OUTis <<signal PATH.DATA_OUT : std_logic_vector(7 downto 0));
procedure DoComplexStuff(
InstructionCode : in natural
);
end package;
package body MyModuleAPI is
-- I can now include this package within MyModule_tb and
-- MyTopLevelComponent_tb and call DoComplexStuff to interact with the signals
-- from MyModule
procedure DoComplexStuff(
InstructionCode : natural
)
is
begin
case InstructionCode is
when 0 =>
DATA_IN <= "01010101";
wait until CLK = '1';
DATA_IN <= "00110011";
wait until CLK = '1';
-- Lots of pretty complex stimuli
assert DATA_OUT = "00110011"
report "Output mismatch!"
severity failure;
when 1 =>
-- Lots of pretty complex stimuli
-- when ... =>
-- Plenty more instruction codes
others =>
null;
end procedure DoComplexStuff;
end package body MyModuleAPI;
Therefore, MyModule_tb would include the package MyModuleAPI with a parameter specifying itself as the top level component and MyTopLevel_tb would include the same package with a parameter properly specifying the path to MyModule. (?)
NOTE: yes, my intention is to modify (bit-bang) internal signals during a top-level test. This would be similar to using ModelSim's "signal_force" and "signal_release" commands.
Thanks in advance for your guidance!
Related
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.
I'm using a CMOD A7 (Artix 7) and I need to trigger a process based on a pulse of around 10ns duration (blue line):
Normally I'd do triggering like this by having a process constantly compare the current value of the input line with the last value using a temporary register to hold the last value. However, I believe the oscillator on this board has a period of around 83ns which is far too slow for this approach.
If I was using pure digital electronics, this would be easy, connect a flipflop to the trigger, poll the output of that flipflop (which would change and latch with the input) and then reset it once I've read it and started my actions. So I would imagine there's a way to do this in VHDL but I'm led to believe using if rising_edge() on non-clock signals is a no-go.
Where do I start with this?
So the solution here is twofold:
Firstly, I can derive a 100MHz clock using the onboard MCCM and Vivado's ClockWiz IP.
I can also use the FDCE component provided by Vivado to utilise one of the onboard flipflops to extend the pulses and reset it after passing it through a few flipflops for synchronisation.
I've not tested this yet but I believe it should work:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.vcomponents.all;
entity input_syncroniser is
generic
(
in_pipe_len: in positive := 5
);
port
(
clk : in STD_LOGIC;
rst : in STD_LOGIC;
din : in STD_LOGIC;
dfo : out STD_LOGIC
);
end input_syncroniser;
architecture behavioural of input_syncroniser is
signal delayed_pulse: std_logic := '0';
signal in_pipe: std_logic_vector(in_pipe_len - 1 downto 0) := (others => '0');
signal pipe_head: std_logic := '0';
begin
FDCE_inst : FDCE
generic map
(
INIT => '0'
)
port map
(
Q => delayed_pulse,
C => din,
CE => '1',
CLR => pipe_head,
D => '1'
);
input_synchroniser: process(clk)
begin
if (rising_edge(clk)) then
in_pipe <= in_pipe(in_pipe'high downto in_pipe'low) & delayed_pulse;
end if;
end process;
pipe_head <= in_pipe(in_pipe'high);
dfo <= pipe_head;
end behavioural;
I'm trying to make a Blink-LED program for a Lattice MachXO3L breakout board. I believe I have the internal-oscillator set up, I just don't know how to connect to its output and make use of it, I get errors when I try. This is on a breakout board which has an LED and a switch. It should oscillate at 1Hz when the switch is flipped one way, and be off when the switch is flipped the other way.
I'e read the PLL usage guide and searched for answers on the internet. I believe I'm close, and just hung up on some syntax issue due to being new to VHDL & FPGAs. Basically, my main code is the 'process and all code below it. Anything above that is basically stuff from the PLL usage guide.
library ieee;
use ieee.std_logic_1164.all;
library machxo3l;
use machxo3l.all;
entity led_blink is
port (
i_switch_1 : in std_logic;
o_led_1 : out std_logic;
i_clock : in std_logic;
osc_int : out std_logic
);
end led_blink;
architecture rtl of led_blink is
COMPONENT OSCH
-- synthesis translate_off
GENERIC (NOM_FREQ: string := "12.09");
-- synthesis translate on
PORT ( STDBY:IN std_logic;
OSC:OUT std_logic);
END COMPONENT;
attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCHinst0 : label is "12.09";
constant C_CNT_1HZ : natural := 6000000;
signal R_CNT_1HZ : natural range 0 to C_CNT_1HZ;
signal R_1HZ : std_logic := '0';
begin
OSCHInst0: OSCH
-- synthesis translate_off
GENERIC MAP(NOM_FREQ => "12.09")
-- synthesis translate on
PORT MAP (STDBY => '0',
OSC => osc_int
);
p_1HZ : process (i_clock) is
begin
if rising_edge(i_clock) then
if R_CNT_1HZ = C_CNT_100HZ-1 then
R_1HZ <= not R_1Hz;
R_CNT_1HZ <= 0;
else
R_CNT_1HZ <= R_CNT_1HZ + 1;
end if;
end if;
end process;
osc_int <= i_clock;
o_led_1 <= R_1HZ when (i_switch_1 = '0') else not R_1HZ;
end rtl;
If I try and assign osc_int to the sensitivity list of the p_1Hz process, I get an error stating that I can not read from an output.
Just a side-note in case other viewers get confused like me, driving i_clock from osc_int appears illogical, because it uses an assignment that seems to suggest the reverse occurs osc_int <= i_clock. Correct me if I'm wrong, but it's assigning an input, to an output, which appears confusing to non-hdl programmers because the direction is decided by the input/output types, rather than the assignment operator itself.
When I do this (link i_clk to osc_int), it saves without giving me errors, it isn't until I try to synthesize the code that it says there are multiple non-tristate drivers for i_clock. The only way I can imagine this being true is if the 'port' from the 'component' section named OSC, being mapped to osc_int, creates two driving signals both linked to i_clock in that single osc_int <= i_clock; statement. But if that's true, how would you access the clock's output at all?
If I just remove the osc_int <= i_clock statement, it works, just with the LED constantly-on/constantly-off, not oscillating/constantly-off.
The clock generated came from inside the OSCH component. Then you don't need any i_clock to achieve what you want. The output of the internal oscillator is the OUT port of the OSCH component.
you can try this :
entity led_blink is
port (
i_switch_1 : in std_logic; -- from the input switch : OK
o_led_1 : out std_logic -- to the blinking led : OK
);
end led_blink;
architecture rtl of led_blink is
COMPONENT OSCH
-- synthesis translate_off
GENERIC (NOM_FREQ: string := "12.09");
-- synthesis translate on
PORT ( STDBY:IN std_logic;
OSC:OUT std_logic);
END COMPONENT;
attribute NOM_FREQ : string;
attribute NOM_FREQ of OSCHinst0 : label is "12.09";
constant C_CNT_1HZ : natural := 6000000;
signal R_CNT_1HZ : natural range 0 to C_CNT_1HZ := 0;
signal R_1HZ : std_logic := '0';
begin
OSCHInst0: OSCH
-- synthesis translate_off
GENERIC MAP(NOM_FREQ => "12.09")
-- synthesis translate on
PORT MAP (STDBY => '0',
OSC => osc_int -- <= this is the 12.09MHz internal clock from the internal oscillator
);
p_1HZ : process (osc_int) is
begin
if rising_edge(osc_int) then
if R_CNT_1HZ = C_CNT_100HZ-1 then
R_1HZ <= not R_1Hz;
R_CNT_1HZ <= 0;
else
R_CNT_1HZ <= R_CNT_1HZ + 1;
end if;
end if;
end process;
o_led_1 <= R_1HZ when (i_switch_1 = '0') else '0';
end rtl;
Warning: this is going to be long. Sorry if it's too verbose.
I'm just starting out on learning FPGAs and VHDL using Quartus Prime. Over the past few days I've taught myself:
How to write VHDL
How to make a component
How to write a testbench
How to use previously created and tested components - knitted together - to create a new component
What I can't work out though is how I would create a testbench that tests a new component that uses two existing components, when some of the signals that are in this new component are only internal signals.
So, here are two super-simple components that I have successfully written and tested with test benches. I realise this is not real world by the way, I'm just trying to take baby steps.
1. A four bit register
library ieee;
use ieee.std_logic_1164.all;
entity four_bit_reg is
port
(
bcd_in: in std_logic_vector(3 downto 0);
clk: in std_logic;
clr: in std_logic;
bcd_out: out std_logic_vector(3 downto 0)
);
end four_bit_reg;
architecture behaviour of four_bit_reg is
begin
process (clk,clr)
begin
if (clr = '1') then
bcd_out <= "0000";
elsif rising_edge(clk) then
bcd_out <= bcd_in;
end if;
end process;
end behaviour;
2. A BCD to seven segment converter
library ieee;
use ieee.std_logic_1164.all;
entity sev_seg is
port
(
bcd_value : in std_logic_vector(3 downto 0);
sev_seg_value : out std_logic_vector(6 downto 0)
);
end sev_seg;
architecture behaviour of sev_seg is
begin
sev_seg_process : process (bcd_value)
begin
case bcd_value is
when "0000" => sev_seg_value <="0111111"; -- 0
when "0001" => sev_seg_value <="0000110"; -- 1
when "0010" => sev_seg_value <="0111011"; -- 2
when "0011" => sev_seg_value <="1001111"; -- 3
when "0100" => sev_seg_value <="1100110"; -- 4
when "0101" => sev_seg_value <="1101101"; -- 5
when "0110" => sev_seg_value <="1111101"; -- 6
when "0111" => sev_seg_value <="0000111"; -- 7
when "1000" => sev_seg_value <="1111111"; -- 8
when "1001" => sev_seg_value <="1101111"; -- 9
when others => sev_seg_value <= "0000000"; -- A to F should show blank
end case;
end process sev_seg_process;
end behaviour;
First question: What do you call the two things above? Components? Modules? Entities? Something else?
I then use these two in another new component/entity/module (as applicable) as below:
library ieee;
use ieee.std_logic_1164.all;
entity two_modules is
port
(
bcd_pins : in std_logic_vector(3 downto 0);
sev_seg_pins : out std_logic_vector(6 downto 0)
);
end two_modules;
architecture behaviour of two_modules is
-- Internal signals
signal int_clk: std_logic;
signal int_bus: std_logic_vector(3 downto 0);
-- List any components used in the design
component four_bit_reg is
port
(
bcd_in: in std_logic_vector(3 downto 0);
clk: in std_logic;
clr: in std_logic;
bcd_out: out std_logic_vector(3 downto 0)
);
end component;
component sev_seg is
port
(
bcd_value : in std_logic_vector(3 downto 0);
sev_seg_value : out std_logic_vector(6 downto 0)
);
end component;
begin -- start the instances
fbr: four_bit_reg port map
(
clk => int_clk,
bcd_in => bcd_pins,
clr => '0',
bcd_out => int_bus
);
sseg: sev_seg port map
(
bcd_value => int_bus,
sev_seg_value => sev_seg_pins
);
end behaviour;
So, for this thing I have called two_modules, the framework for the test bench created by Quartus is as follows:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY two_modules_vhd_tst IS
END two_modules_vhd_tst;
ARCHITECTURE two_modules_arch OF two_modules_vhd_tst IS
-- constants
-- signals
SIGNAL bcd_pins : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL sev_seg_pins : STD_LOGIC_VECTOR(6 DOWNTO 0);
signal internal_clock : std_logic := '0';
COMPONENT two_modules
PORT (
bcd_pins : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
sev_seg_pins : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
);
END COMPONENT;
BEGIN
i1 : two_modules
PORT MAP (
-- list connections between master ports and signals
bcd_pins => bcd_pins,
sev_seg_pins => sev_seg_pins
);
internal_clock <= not internal_clock after 500 us;
init : PROCESS
-- variable declarations
BEGIN
-- code that executes only once
WAIT;
END PROCESS init;
always : PROCESS
-- optional sensitivity list
-- ( )
-- variable declarations
BEGIN
-- code executes for every event on sensitivity list
WAIT;
END PROCESS always;
END two_modules_arch;
As you can see I have created an internal clock and I would like to, purely for the purposes of learning how to do this type of thing, I stress I realise this is not a complete design, join the internal_clock (that I can see works and is a waveform in the waveform editor of Model Sim) to clk in the four_bit_reg.
I think and hope once I know how to do this I'll be able to plough on and get a real world, more complicated test bench knocked up. However, after much Googling I can find no reference on how to bind together signals from subcomponents. This may be because I am using completely the wrong terminology and there may be a perfect tutorial somewhere out there.
So:
How can I just for a start get my internal_clock connected to subcomponent, four_bit_reg's clk input?
What is the correct teminology for when you use and knit together things like four_bit_reg and sev_seg? Subcomponents? Something else?
Many thanks if you got this far!
With the comments, I understand that you are using an internal oscillator from Altera in your CPLD.
I suggest to add a third module named "internal_oscillator" which can be described as follow :
library ieee;
use ieee.std_logic_1164.all;
entity internal_oscillator is
port (
CLK : out std_logic
);
end entity;
architecture for_simulation_only of internal_oscillator is
constant C_HALF_PERIOD : time := 5 ns; -- 100MHz
signal clk_internal : std_logic := '0';
begin
clk_internal <= not clk_internal after C_HALF_PERIOD;
CLK <= clk_internal;
end architecture;
You can now add this module in your design and you'll get a clock without adding a new pin on your top level entity :
osc_inst : entity work.internal_oscillator
port map (CLK => int_clk);
In your two_models entity, add a new port for the clock signal:
entity two_modules is
port
(
clk : in std_logic;
bcd_pins : in std_logic_vector(3 downto 0);
sev_seg_pins : out std_logic_vector(6 downto 0)
);
end two_modules;
Remove the int_clk signal in the two_models architecture. Replace it with the previously defined input signal instead when you are connecting the submodules:
fbr: four_bit_reg port map
(
clk => clk_in,
bcd_in => bcd_pins,
clr => '0',
bcd_out => int_bus
);
In your testbench, connect the internal clock signal internal_clock into that port of the two_modules:
PORT MAP (
-- list connections between master ports and signals
clk_in => internal_clock,
bcd_pins => bcd_pins,
sev_seg_pins => sev_seg_pins
);
In most cases the clock is an input to the module. Often accompanied by a reset.
If you look around on the www for example VHDL code you will notice that every module, has a clock input.
There are general two exceptions:
Test-benches generate an artificial clock inside to drive the Device Under test.
Modules which simulate a real clock generating circuit e.g. a Crystal oscillator.
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 (