I am programming in VHDL 1993 under QUARTUS II, and I just created two components in order to try solve the problem I am about to present as they weren't the solution. Before hand, the components files are included in the design and working one at a time.
So in my basic application I am trying to do two jobs, one is to blink a led and to turn on another led controlled by a switch, when I declare both components only the one controlling the led with the switch works, then when I undeclared the led-switch component and it's signals IN THE TOP LEVEL ENTITY the blinker works, I am guessing then it's a problem with the signal declarations at the top level entity "test2", but I don't understand why it works only when using one thing at a time, what I coded at the top level entity is:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity test2 is
port( clk_cpu, K2: in std_logic;
led1, led2: out std_logic);
end test2;
architecture struct of test2 is
component tmp_toogler
port( clk: in std_logic;
led: out std_logic);
end component;
component yes_driver
port( input: in std_logic;
output: out std_logic);
end component;
begin
instanciaD: yes_driver PORT MAP(
K2, led2
);
instancia1: tmp_toogler PORT MAP(
clk_cpu, led1
);
end struct;
The blinker component:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity tmp_toogler is
port( clk: in std_logic;
led: out std_logic);
end tmp_toogler;
architecture struct of tmp_toogler is
signal counter: integer range 0 to 50000000;
signal state : std_logic := '1';
begin
process(clk)
begin
if(rising_edge(clk)) then
counter <= counter + 1;
end if;
if(counter = 50000000) then
counter <= 0;
if(state = '0') then
led <= '1';
state <= '1';
else
led <= '0';
state <= '0';
end if;
end if;
end process;
end struct;
The led-switch:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity yes_driver is
port( input: in std_logic;
output: out std_logic);
end yes_driver;
architecture struct of yes_driver is
begin
process(input)
begin
output <= input;
end process;
end struct;
I feel this is a very basic question about doing multiple tasks, so I am urging for some help, thanks in advance.
Related
I'm facing problems with the following ring oscillator code:
entity OSCILLATOR is
port( OUTPUT: out std_logic
);
end entity OSCILLATOR;
architecture structural of OSCILLATOR is
component DEL_INV is
generic(D: time);
port( INPUT: in std_logic;
OUTPUT: out std_logic
);
end component DEL_INV;
signal conn: std_logic := '0';
signal conn1: std_logic := '1';
signal conn2: std_logic := '0';
signal de: time := 2 ns;
begin
INV1: DEL_INV generic map(de) port map (conn, conn1);
INV2: DEL_INV generic map(de) port map (conn1, conn2);
INV3: DEL_INV generic map(de) port map (conn2, conn);
OUTPUT <= conn;
end architecture;
In particular, while simulating it, the output is always U.
Can someone explain why?
The initial values assigned to the signals conn*, to ensure well-defined start condition in simulation, are overwritten at start by an 'U' driven by the OUTPUT on the DEL_INV module, and the simulation thus ends up stuck in all U.
One solution is to handle the initial value through the DEL_INV module with a generic that allows different initial OUTPUT values, and then use this initial value on the OUTPUT until the value is well defined as '0' or '1', which can be detected through the is_x function.
Updated code for this is shown below. Note that I added the suggestions by Renaud Pacalet for for all: DEL_INV use entity work.DEL_INV(s); and inverter (not) in DEL_INV.
library ieee;
use ieee.std_logic_1164.all;
entity DEL_INV is
generic(
D: time;
XOUT: std_logic);
port(
INPUT: in std_logic;
OUTPUT: out std_logic);
end entity DEL_INV;
architecture s of DEL_INV is
signal PRE : std_logic;
begin
PRE <= (not INPUT) after D;
OUTPUT <= XOUT when is_x(PRE) else PRE; -- Drive XOUT if is_x to clean up
end architecture s;
library ieee;
use ieee.std_logic_1164.all;
entity OSCILLATOR is
port(
OUTPUT: out std_logic);
end entity OSCILLATOR;
architecture structural of OSCILLATOR is
component DEL_INV is
generic(
D: time;
XOUT: std_logic);
port(
INPUT: in std_logic;
OUTPUT: out std_logic);
end component DEL_INV;
for all: DEL_INV use entity work.DEL_INV(s);
signal conn : std_logic;
signal conn1 : std_logic;
signal conn2 : std_logic;
constant DE : time := 2 ns;
begin
INV1: DEL_INV generic map(de, '0') port map (conn, conn1);
INV2: DEL_INV generic map(de, '1') port map (conn1, conn2);
INV3: DEL_INV generic map(de, '0') port map (conn2, conn);
OUTPUT <= conn;
end architecture;
For the following VHDL code:
library ieee;
use ieee.std_logic_1164.all;
entity dff is
port(
d, clk: in std_logic;
q: out std_logic);
end dff;
architecture behave of dff is
begin
process(clk)
begin
if(clk = '1') then
q<= d;
end if;
end process;
end behave;
---------------------------------------------------------------------
and and a testbench:
library ieee;
use ieee.std_logic_1164.all;
entity dff is
end dff;
architecture behave of dff is
component dff is
port(d, clk: in std_logic;
q: out std_logic);
end component;
signal d_in: std_logic;
signal clk_in: std_logic;
signal q_out: std_logic;
begin
d_ff : dff port map( d_in, clk_in, q_out);
process
begin
if(clk_in = '1') then
q_out<= d_in;
end if;
end process;
end behave;
When trying to simulate Modelsim is showing the following error:
#Error loading design
The following component ports are not on the entity:
q
clk
d
The entity name of your testbench is also dff. You need to give it a different name (eg dff_tb). So, when you compile your testbench, it is overwriting the other dff entity.
I want to make a D ff with a little delay on the reset, D will always be '1', clk will be controlled by a switch(it will give a command for a specific floor on an elevator) and count_aux will be a 1Hz clock, but when I try to synthesize it shows me this error "ERROR:Xst:1534 - Sequential logic for node appears to be controlled by multiple clocks.". I don't want to clk to be understood as a clock, since it will be just a switch. How can I do that?
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity D_FF is
port ( D: in std_logic;
clk: in std_logic;
count_aux: in std_logic;
reset: in std_logic;
Q: out std_logic:='0'
);
end D_FF;
architecture a1 of D_FF is
signal i: std_logic_vector(3 downto 0):="0000";
begin
proc: process (D,clk,reset)
begin
if (reset='1') then
if(count_aux'event and count_aux='1') then i<=i+1;
if (i="0001") then
q<='0';
i<="0000";
end if;
end if;
elsif (clk'event and clk='1') then
q<=d;
end if;
end process proc;
end a1;
You are using clk as a clock in the process, so it will be a clock ;) But the weird thing for the synthesis is that you want to have a clocked flipflop (sequential element or regeister or what ever) but yet you also include combinatorial logic into the reset. So it has no idea what to synthesize since it has no component in the library for this logic.
So my advise is to keep the sequential and combinatorial logic separate. Sequential logic will have only clk and reset in the sensitivity list and have the code structure of:
process(clk, reset)
begin
if reset = 1 then
foobar <= '0';
elsif rising_edge(clk) then
foobar <= foo + bar;
end if;
end process;
I have been going crazy trying to make it work but nothing been on this for the past 6 hours and still didn't solve it :/
so this the top module
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 Test is
Port ( CLKI : in STD_LOGIC;
HSO : out STD_LOGIC;
VSO : out STD_LOGIC;
RO,GO,BO : out STD_LOGIC);
end Test;
architecture Behavioral of Test is
component CLK_25Mhz_Divider
Port ( CLK : in STD_LOGIC;
CLK_OUT : out STD_LOGIC);
end component;
component VGA_Sync
Port ( CLK : in STD_LOGIC;
HS : out STD_LOGIC;
VS : out STD_LOGIC;
R,G,B : out STD_LOGIC);
end component;
signal CLKBE: STD_LOGIC;
begin
CLK_Divider_1: CLK_25Mhz_Divider port map ( CLK => CLKI,
CLK_OUT => CLKBE);
VGA_S1: VGA_Sync port map ( CLK => CLKBE,
HS => HSO,
VS => VSO,
R => RO,
G => GO,
B => BO );
end Behavioral;
the clock divider
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 CLK_25MHz_Divider is
Port ( CLK : in STD_LOGIC;
CLK_OUT : out STD_LOGIC);
end CLK_25MHz_Divider;
architecture Behavioral of CLK_25MHz_Divider is
BEGIN
PROCESS(CLK)
VARIABLE COUNT : INTEGER:=0;
VARIABLE TEMP : STD_LOGIC:='0';
BEGIN
IF RISING_EDGE(CLK)THEN
COUNT:=COUNT+1;
IF COUNT=2 THEN
TEMP:=NOT TEMP;
COUNT:=0;
END IF;
END IF;
CLK_OUT<=TEMP;
END PROCESS;
end Behavioral;
The VGA signal generation module
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 VGA_Sync is
Port ( CLK : in STD_LOGIC;
HS : out STD_LOGIC;
VS : out STD_LOGIC;
R,G,B : out STD_LOGIC);
end VGA_Sync;
architecture Behavioral of VGA_Sync is
begin
process(CLK)
Variable countH : Integer := 0;
Variable countV : Integer := 0;
begin
if (CLK'EVENT and CLK = '1') then
if countH < 800 then
countH := countH + 1;
else
countH := 0;
if countV < 500 then
countV := countV + 1;
else
countV := 0;
end if;
end if;
if countH >= 16 and countH < 112 then
HS <= '0';
else
HS <= '1';
end if;
if countV >= 10 and countV < 12 then
VS <= '0';
else
VS <= '1';
end if;
if (countH < 160) or (countV < 45) then
R <= '0';
G <= '0';
B <= '0';
else
R <= '1';
G <= '0';
B <= '1';
end if;
end if;
end process;
end Behavioral;
so tell me your thoughts on what is wrong with the code
Because you haven't actually describe the problem and because I had a testbench for a 25 MHz clocked vga generator that only required changing the type for r, g and b, I ran you sync_vga against the testbench:
library ieee;
use ieee.std_logic_1164.all;
entity vga_sync_tb is
end entity;
architecture foo of vga_sync_tb is
signal clk: std_logic := '0';
signal hs: std_logic;
signal vs: std_logic;
signal r,g,b: std_logic;
begin
DUT:
entity work.vga_sync
port map (
clk => clk,
hs => hs,
vs => vs,
r => r,
g => g,
b => b
);
CLOCK:
process
begin
wait for 20 ns; -- clock period 25 MHz = 40 ns;
clk <= not clk;
if now > 20 ms then -- one frame time plus a bit
wait;
end if;
end process;
end architecture;
It gave a vertical sync rate around 60 Hz:
Zooming in and measuring between two HS edges shows a horizontal rate of around 31.17 KHz.
You have horizontal and vertical blanking intervals and your R, G, and B does what your code says.
That sort of leaves the clock divider or something platform related.
Because a testbench for the clock is simple:
library ieee;
use ieee.std_logic_1164.all;
entity clock_tb is
end entity;
architecture foo of clock_tb is
signal clk: std_logic := '0';
signal clk25: std_logic;
begin
DUT:
entity work.clk_25mhz_divider
port map (
clk => clk,
clk_out => clk25
);
CLOCK:
process
begin
wait for 10 ns; -- half the period of 50 MHz
clk <= not clk;
if now > 130 ns then
wait;
end if;
end process;
end architecture;
It demonstrates Martin Zabel's answer:
That your divide by two actually divides by four. giving a period of 80 ns (12.5 MHz).
This demonstrates the usefulness of simulation and in simulation it can also be helpful to use signals instead of variables which have no history. Variables don't have a projected output waveform and he simulator has to attach extra code to display them in a waveform.
The simulation performance increase using variables instead of signals is traded for the ability to display them and there is no interesting distinction in synthesis.
From comments below question:
at that resolution i should use 25Mhz so i using the onboard clock
that's 50 Mhz and dividing it using the Clock divider module. –
Mostafa
Your clock divider divides the input frequency by 4 instead of 2. You toggle TEMP every two cycles of CLK which is CLKI of the top module. So a full cycle of CLK_OUT takes 4 cycles of the input clock.
To divide by two, you must toggle TEMP every clock cycle of the input clock:
architecture Behavioral of CLK_25MHz_Divider is
BEGIN
PROCESS(CLK)
VARIABLE TEMP : STD_LOGIC:='0';
BEGIN
IF RISING_EDGE(CLK)THEN
TEMP:=NOT TEMP;
END IF;
CLK_OUT<=TEMP;
END PROCESS;
end Behavioral;
Starting with TEMP = '0', it toggles to '1' at the first rising edge of CLK. At the second rising edge, TEMP toggles to '0', and at the third rising edge back to '1'. The duration between the first and third rising-edge of the 50 MHz input clock is 40 ns, which makes a frequency of 25 MHz for the output clock.
I have written two codes that successfully simulated in ISE Design Suit:
-- 2X1 Multiplexer
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package mux2to1_pkg is
component mux2to1
port(d1,d0: in std_logic;
s: in std_logic;
f: out std_logic);
end component;
end mux2to1_pkg;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity mux2to1 is
port(d1,d0: in std_logic;
s: in std_logic;
f: out std_logic);
end mux2to1;
architecture behavioral of mux2to1 is
begin
f <= (d0 and not s) or
(d1 and s);
end behavioral;
and
-- 6X1 Multiplexer
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package mux6to1_pkg is
component mux6to1
port(d: in std_logic_vector(5 downto 0);
s: in std_logic_vector(2 downto 0);
f: out std_logic);
end component;
end mux6to1_pkg;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use WORK.mux2to1_pkg.all;
entity mux6to1 is
port(d: in std_logic_vector(5 downto 0);
s: in std_logic_vector(2 downto 0);
f: out std_logic);
end mux6to1;
architecture structural of mux6to1 is
signal m1,m2,m3,m4: std_logic;
begin
mux1: mux2to1 port map(d(5),d(4),s(0),m1);
mux2: mux2to1 port map(d(3),d(2),s(0),m2);
mux3: mux2to1 port map(d(1),d(0),s(0),m3);
mux4: mux2to1 port map(m2,m3,s(1),m4);
mux5: mux2to1 port map(m1,m4,s(2),f);
end structural;
The problem is when I want to simulate the MUX6to1 in Active-HDL the output doesn't change at all. What's the secret in this program? Ty.
Using this test bench:
library ieee;
use ieee.std_logic_1164.all;
entity mdl_tb is
end entity;
library ieee;
use ieee.numeric_std.all;
architecture sim of mdl_tb is
signal s_d : std_logic_vector(8 downto 0) := (others => '0');
signal f : std_logic;
begin
dut_e : entity work.mux6to1
port map(d => s_d(5 downto 0),
s => s_d(8 downto 6),
f => f);
process is
begin
wait for 1 ns;
s_d <= std_logic_vector(unsigned(s_d) + 1);
end process;
end architecture;
it shows changes like:
based on this Active-HDL script with the above two files in mdl.vhd:
# Workspace "prod" create under current and open this workspace
workspace create prod
# Design "prod" create under current workspace
design create -a prod .
# Create to directory under workspace
cd $DSN/..
# Compile
acom ../mdl.vhd
acom ../mdl_tb.vhd
# Load module for simulation
asim work.mdl_tb
# Waveform add
add wave /mdl_tb/*
# Run
run 600 ns
Btw. you can reduce the code significantly if you skip the component declarations and related packages, through code like:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity mux2to1 is
port(d1,d0: in std_logic;
s: in std_logic;
f: out std_logic);
end mux2to1;
architecture behavioral of mux2to1 is
begin
f <= d0 when (s = '0') else d1;
end behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity mux6to1 is
port(d: in std_logic_vector(5 downto 0);
s: in std_logic_vector(2 downto 0);
f: out std_logic);
end mux6to1;
architecture structural of mux6to1 is
signal m1,m2,m3,m4: std_logic;
begin
mux1: entity work.mux2to1 port map(d(5),d(4),s(0),m1);
mux2: entity work.mux2to1 port map(d(3),d(2),s(0),m2);
mux3: entity work.mux2to1 port map(d(1),d(0),s(0),m3);
mux4: entity work.mux2to1 port map(m2,m3,s(1),m4);
mux5: entity work.mux2to1 port map(m1,m4,s(2),f);
end structural;