I am new to VHDL. I have this entity (shortened):
entity foo is
port (CLK : in std_logic;
out_A : out std_logic;
);
end foo;
architecture Structure of foo is
component D_Flipflop
port (
D : in std_logic;
CLK : in std_logic;
Q : out std_logic;
not_Q : out std_logic);
end component;
signal D_A, qA, not_qA : std_logic;
begin
my_Flipflop : D_Flipflop
port map(
not_qA,
CLK,
qA,
not_qA
);
end Structure;
As you can see, I want to use the D_Flipflop like a Toggle-Flipflop, so I redirected the output to the input by the signal not_qA (is that possible?). The problem is that from outside, only the port CLK of foo is visible as input and - at least in the Vivado Simulator - the signals qA and not_qA are never evaluated.
This is the architecture of D_Flipflop:
architecture Behavioral of D_Flipflop is
begin
set_state : process(CLK, D)
variable state : std_logic := '0';
begin
if falling_edge(CLK) then
state := D;
Q <= state;
not_Q <= not state;
end if;
end process set_state;
end Behavioral;
I googled a lot for this. No chance. Any solutions?
It's not as you indicate in the title to the question that the internal signal to component my_Flipflop didn't trigger, it's that there is no method to provide a known non-meta value state - the not of 'U' is 'U'.
This is caused by the not operator. Refer to the not_table in the
body of package std_logic_1164:
-- truth table for "not" function
CONSTANT not_table: stdlogic_1d :=
-- -------------------------------------------------
-- | U X 0 1 Z W L H - |
-- -------------------------------------------------
( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' );
See the changes and the added testbench:
library ieee; -- Added Context clause (MCVe)
use ieee.std_logic_1164.all;
entity D_Flipflop is
port (
D: in std_logic;
CLK: in std_logic;
Q: out std_logic;
not_Q: out std_logic := '0'
);
end entity;
architecture behavioral of D_Flipflop is
begin
set_state:
process (CLK) -- removed D from sensitivity list
variable state: std_logic := '0';
begin
if falling_edge(CLK) then
state := D;
Q <= state;
not_Q <= not state;
end if;
end process;
end architecture;
library ieee; -- added context clause
use ieee.std_logic_1164.all;
entity foo is
port (
CLK: in std_logic;
out_A: out std_logic -- removed extra ';'
);
end entity;
architecture Structure of foo is
component D_Flipflop is
port (
D: in std_logic;
CLK: in std_logic;
Q: out std_logic;
not_Q: out std_logic
);
end component;
-- signal D_A: std_logic; -- not used
signal qA: std_logic;
signal not_qA: std_logic := '1'; -- notice this didn't matter
begin
my_Flipflop:
D_Flipflop
port map (
not_qA,
CLK,
qA,
not_qA
);
out_A <= qA; -- Added
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity foo_tb is
end entity;
architecture fum of foo_tb is
signal CLK: std_logic := '0';
signal out_A: std_logic;
begin
DUT:
entity work.foo
port map (
CLK => CLK,
out_A => out_A
);
CLOCK:
process
begin
wait for 10 ns;
CLK <= not CLK;
if Now > 200 ns then
wait;
end if;
end process;
end architecture;
The not_Q output of the D_Flipflop has been initialized to '0' (it could have as easily been initialized to '1'). This represents the equivalent of a collector set for the Flip Flop on power up.
Now the Flip Flop can toggle - it has a known non-meta value on the D input.
This gives:
(clickable)
Related
I have this very simple 16-bit and gate written in structural form in VHDL:
The files are uploaded here.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity and_16bit is
Port (
A : in std_logic_vector(15 downto 0);
B : in std_logic_vector(15 downto 0);
Clk : in STD_LOGIC;
--Rst : in STD_LOGIC;
C : out std_logic_vector(15 downto 0) );
end and_16bit;
architecture Behavioral of and_16bit is
component and_1bit is
Port (
A : in std_logic;
B : in std_logic;
C : out std_logic );
end component;
signal s : std_logic_vector(15 downto 0);
begin
ands: for i in 15 downto 0 generate
and_1bit_x: and_1bit port map (A => A(i), B => B(i), C => s(i));
end generate;
process(Clk)
begin
if rising_edge(Clk) then
C <= s;
end if;
end process;
end Behavioral;
In order to update the output in the rising edge of the clock, I have defined this "s" signal. I wonder if this is the correct way to update the output in structural VHDL codes? what should I do to scape the unknown output for the first output?
Any comments will be a great help.
It's better to put the sequential process into a submodule and instantiate it in the top-level (and_16bit). Then your top-level will be more structural.
You can have one instance for each bit as you did for and_1bit.
For example, this module is a 1-bit register.
entity dff_1bit is
Port (
D : in std_logic;
Clk : in std_logic;
Q : out std_logic );
end dff_1bit;
architecture Behavioral of dff_1bit is
begin
process(Clk)
begin
if rising_edge(Clk) then
Q <= D;
end if;
end process;
end Behavioral;
Then you can instantiate it in and_16bit, inside the same generate block.
dff_1bit_x: dff_1bit port map (D => s(i), Clk => Clk, Q => C(i));
I'm currently learning about writing testbenchs for my VHDL components. I am trying to test a clock synchronizer, just made up of two cascaded D-type flip flops. I have written a testbench, supplying a clock and appropriate input signal stimuli but I see no output changing when I simulate, it just remains at "00".
I would be very grateful for any assistance!
EDIT: the dff component is a standard Quartus component, not quite sure how to get at the internal code.
Here is the component VHDL:
library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
--This device is to synchronize external signals that are asynchronous to the
--system by use of two cascaded D-Type flip flops, in order to avoid metastability issues.
--Set the generic term Nbits as required for the number of asynchronous inputs to
--be synchronized to the system clock OUTPUT(0) corresponds to INPUT(0), ect.
entity CLOCK_SYNCHRONIZER is
generic(Nbits : positive := 2);
port
(
--Define inputs
SYS_CLOCK : in std_logic;
RESET : in std_logic;
INPUT : in std_logic_vector(Nbits-1 downto 0);
--Define output
OUTPUT : out std_logic_vector(Nbits-1 downto 0) := (others=>'0')
);
end entity;
architecture v1 of CLOCK_SYNCHRONIZER is
--Declare signal for structural VHDL component wiring
signal A : std_logic_vector(Nbits-1 downto 0);
--Declare D-Type Flip-Flop
component dff
port(D : in std_logic; CLK : in std_logic; CLRN : in std_logic; Q : out std_logic);
end component;
begin
--Generate and wire number of synchronizers required
g1 : for n in Nbits-1 downto 0 generate
c1 : dff port map(D=>input(n), CLK=>sys_clock, Q=>A(n), CLRN=>reset);
c2 : dff port map(D=>A(n), CLK=>sys_clock, Q=>output(n), CLRN=>reset);
end generate;
end architecture v1;
And here is the testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity testbench is
end entity;
architecture v1 of testbench is
component CLOCK_SYNCHRONIZER
generic(Nbits : positive := 2);
port
(
--Define inputs
SYS_CLOCK : in std_logic;
RESET : in std_logic;
INPUT : in std_logic_vector(Nbits-1 downto 0);
--Define output
OUTPUT : out std_logic_vector(Nbits-1 downto 0)
);
end component;
constant Bus_width : integer := 2;
signal SYS_CLOCK : std_logic := '0';
signal RESET : std_logic := '1';
signal INPUT : std_logic_vector(Bus_width-1 downto 0) := (others=>'0');
signal OUTPUT : std_logic_vector(Bus_width-1 downto 0) := (others=>'0');
begin
C1 : CLOCK_SYNCHRONIZER
generic map(Nbits=>Bus_width)
port map(SYS_CLOCK=>SYS_CLOCK, RESET=>RESET, INPUT=>INPUT, OUTPUT=>OUTPUT);
always : process
begin
for i in 0 to 50 loop
INPUT <= "11";
wait for 24ns;
INPUT <= "00";
wait for 24ns;
end loop;
WAIT;
end process;
clk : process
begin
for i in 0 to 50 loop
SYS_CLOCK <= '1';
wait for 5ns;
SYS_CLOCK <= '0';
wait for 5ns;
end loop;
WAIT;
end process;
end architecture v1;
The problem is that you have not compiled an entity to bind to the dff component. See this example on EDA Playground, where you see the following warnings:
ELAB1 WARNING ELAB1_0026: "There is no default binding for component
"dff". (No entity named "dff" was found)." "design.vhd" 45 0 ...
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__1/c1 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__1/c2 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__0/c1 : dff not bound.
ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__0/c2 : dff not bound.
Given you have no configuration, this needs to have be called dff and must have exactly the same ports as the dff component, ie:
entity dff is
port(D : in std_logic; CLK : in std_logic; CLRN : in std_logic; Q : out std_logic);
end entity;
(Google "VHDL default binding rules")
This needs to model the functionality of the dff flip-flop. I have assumed the following functionality:
architecture v1 of dff is
begin
process (CLK, CLRN)
begin
if CLRN = '0' then
Q <= '0';
elsif rising_edge(CLK) then
Q <= D;
end if;
end process;
end architecture v1;
You can see this now does something more sensible on EDA Playground. (I haven't checked to see whether it is doing the right thing.)
BTW: why are you initialising this output? That seems a strange thing to do:
OUTPUT : out std_logic_vector(Nbits-1 downto 0) := (others=>'0')
I'm writing TDC based on Vernier method in Vivado. My board is VC707 with virtex 7 core. After I finished writing my vhdl code i started simulation . Unfortunately I'm still learning fpga and vhdl so I stuck with one problem.
At first i wanted to check my my input circuit so i write a simple testbench to simulate. I generate short time interval to check this part of TDC. After i start simulation two of my outputs are uninicialized and other outputs have no sense ( should be high edge but simulation show zeros on the output).
On outputs should be rising edges. This circuit is intended to shape signals for my ring oscillators.
My vhdl desing:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Uklad_WE is
Port ( Start : in STD_LOGIC;
Stop : in STD_LOGIC;
Reset : in STD_LOGIC;
Pulse_st : out STD_LOGIC;
Pulse_sp : out STD_LOGIC;
Encnt_st : out STD_LOGIC;
Encnt_sp : out STD_LOGIC);
end Uklad_WE;
architecture Behavioral of Uklad_WE is
signal dst1_out : std_logic;
signal dst2_out : std_logic;
signal dsp1_out : std_logic;
signal dsp2_out : std_logic;
signal INV_chain_13_o : std_logic;
signal INV_chain_15_o : std_logic;
signal gate_cnt1_o : std_logic;
signal gate_cnt2_o : std_logic;
signal dcnt1_out : std_logic;
signal dcnt2_out : std_logic;
component ffd
port(
D,CLK,R : in STD_LOGIC;
Q: out STD_LOGIC
);
end component;
component ffd_set
port(
D,S,CLK : in STD_LOGIC;
Q : out STD_LOGIC
);
end component;
component INV_chain_15
port(
input : in STD_LOGIC;
output : out STD_LOGIC;
cnt_sig : inout std_logic
);
end component;
component INV_chain_13
port(
input : in STD_LOGIC;
output : out STD_LOGIC;
cnt_sig : inout std_logic
);
end component;
begin
DST1: ffd port map(
D => '1',
CLK => Start,
R => Reset,
Q => dst1_out);
DST2 : ffd_set port map(
D => '0',
CLK => dst1_out,
S => INV_chain_13_o,
Q => dst2_out);
DSP1 : ffd port map(
D => dst1_out,
CLK => Stop,
R => Reset,
Q => dsp1_out);
DSP2 : ffd_set port map(
D => '0',
CLK => dsp1_out,
S => INV_chain_15_o,
Q => dsp2_out);
DCNT1 : ffd port map(
D => '1',
CLK => gate_cnt1_o,
R => Reset,
Q => dcnt1_out);
DCNT2 : ffd port map(
D => '1',
CLK => gate_cnt2_o,
R => Reset,
Q => dcnt2_out);
INV_chain_st : INV_chain_13 port map(
input => dst2_out,
output => INV_chain_13_o,
cnt_sig => gate_cnt1_o);
INV_chain_sp : INV_chain_15 port map(
input => dsp2_out,
output => INV_chain_15_o,
cnt_sig => gate_cnt2_o);
Pulse_st <= dst2_out;
Pulse_sp <= dsp2_out;
Encnt_st <= dcnt1_out;
Encnt_sp <= dcnt2_out;
end Behavioral;
My testbench :
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
entity symulacja_tdc_vo is
end symulacja_tdc_vo;
architecture Behavioral of symulacja_tdc_vo is
component Uklad_WE
Port(
Start : in STD_LOGIC;
Stop : in STD_LOGIC;
Reset : in STD_LOGIC;
Pulse_st : out STD_LOGIC;
Pulse_sp : out STD_LOGIC;
Encnt_st : out STD_LOGIC;
Encnt_sp : out STD_LOGIC);
end component;
--inputs
signal Start : STD_LOGIC := '0';
signal Stop : STD_LOGIC := '0';
signal Reset : STD_LOGIC := '0';
--outputs
signal Pulse_st : STD_LOGIC;
signal Pulse_sp : STD_LOGIC;
signal Encnt_st : STD_LOGIC;
signal Encnt_sp : STD_LOGIC;
begin
--uut
uut: Uklad_WE port map(
Start => Start,
Stop => Stop,
Reset => Reset,
Pulse_st => Pulse_st,
Pulse_sp => Pulse_sp,
Encnt_st => Encnt_st,
Encnt_sp => Encnt_sp);
-- stimuluis process
stim_proc1: process
begin
Start <= not Start after 5 ps;
wait for 500 ps;
end process;
stim_proc2: process
begin
Stop <= not Stop after 50 ps;
wait for 500 ps;
end process;
stim_proc3: process
begin
wait for 250 ps;
Reset <= not Reset;
wait for 500 ps;
end process;
end Behavioral;
Components code :
ffd - ffd with reset
library ieee;
use ieee.std_logic_1164.all;
entity ffd is
port (
D, CLK, R : in std_logic;
Q : out std_logic );
end ffd;
architecture Bech of ffd is
begin
process( CLK, R )
begin
if R = '0' then
Q <= '0';
elsif rising_edge(CLK) then
Q <= D;
end if;
end process;
end Bech;
ffd_set - ffd with set
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ffd_set is
port (
D, CLK, S : in std_logic;
Q : out std_logic );
end ffd_set;
architecture Bech of ffd_set is
begin
process( CLK, S )
begin
if S = '0' then
Q <= '1';
elsif rising_edge(CLK) then
Q <= D;
end if;
end process;
end Bech;
INV_chain_13 - inverters chain
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity INV_chain_13 is
Port ( input : in STD_LOGIC;
output : out STD_LOGIC;
cnt_sig : inout STD_LOGIC);
end INV_chain_13;
architecture Behavioral of INV_chain_13 is
signal gate_o : std_logic_vector(12 downto 0);
begin
gate_o(0) <= input;
inv_g_chain : for i in 1 to gate_o'high generate
gate_o(i) <= not gate_o(i-1);
end generate;
gate_o(1) <= cnt_sig;
output <= gate_o(12);
end Behavioral;
INV_chain_15 - also inverters chain, only number of inv is diffrent
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity INV_chain_15 is
Port ( input : in STD_LOGIC;
output : out STD_LOGIC;
cnt_sig : inout STD_LOGIC);
end INV_chain_15;
architecture Behavioral of INV_chain_15 is
signal gate_o : std_logic_vector(14 downto 0);
begin
gate_o(0) <= input;
inv_g_chain : for i in 1 to gate_o'high generate
gate_o(i) <= not gate_o(i-1);
end generate;
gate_o(1) <= cnt_sig;
output <= gate_o(14);
end Behavioral;
RTL Analysis
This is schematic of my design
RTL form Vivado screenshot
Simulation
And major problem :
Simulation screenshot
Maybe it's vhdl code issue, I don't know every rule of vhdl programming yet, I hope someone with better experience can help me.
I think there is some problem with set and reset in ffd . I try many options but nothing helped.
First of all: you're learning VHDL, and you have a Virtex-7??? I'm programming VHDL for 15 years now, but often only work with spartans... Virtex is just too expensive. Restectp.
But anyhow
inv_g_chain : for i in 1 to gate_o'high generate
gate_o(i) <= not gate_o(i-1);
end generate;
What are you trying to do here? I expect you want to use inverters to get some delay? Only, in VHDL concurrent assignment is instantaneous, so it does not work. You should add the delay manually. E.g.:
gate_o(i) <= not gate_o(i-1) after 10 ns;
by the way, do you know that you could use generics, more links to have a variable inverter delay chain length? Then you could combine INV_chain_13 and INV_chain_15 into one entity.
Then you have multiple drivers for the same signal:
gate_o(1) <= not gate_o(0);
and
gate_o(1) <= cnt_sig;
Multiple drivers does not work properly. And what's up with cnt_sig being of the inout type? <= is not a bidirectional assignment. VHDL is not good at bidirectional assignments, so try a different approach.
You are trying to build an asynchronous system. It is possible, but quite difficult. Please consider making something synchronous first, to get some experience.... Now you're trying to do F1 at your first driving lesson.
I'm a newbie in VHDL and hardware world.
I'm trying to make a Count&Compare example using Top Level Hierarchy and test it with testbench and see the results on ISIM.
Here is my block diagram sketch:
So I end up these 3 vhd source files:
Counter.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Count_src is
Port ( CLK : in STD_LOGIC;
Reset : in STD_LOGIC;
S : out STD_LOGIC_VECTOR (3 downto 0));
end Count_src;
architecture Behavioral of Count_src is
signal count : STD_LOGIC_VECTOR (3 downto 0);
begin
process (Reset, CLK)
begin
if Reset = '1' then -- Active high reset
count <= "0000"; -- Clear count to 0
elsif (rising_edge(CLK)) then -- Positive edge
count <= count + "0001"; -- increment count
end if;
end process;
S <= count; -- Export count
end Behavioral;
Compare
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Compare_src is
Port ( A : in STD_LOGIC_VECTOR (3 downto 0);
B : in STD_LOGIC_VECTOR (3 downto 0);
S : out STD_LOGIC);
end Compare_src;
architecture Behavioral of Compare_src is
begin
S <= '1' when (A = B) else -- Test if A and B are same
'0'; -- Set when S is different
end Behavioral;
CountCompare (Top Level)
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 CountCompare_src is
Port ( Clock : in STD_LOGIC;
Reset : in STD_LOGIC;
Value : in STD_LOGIC_VECTOR (3 downto 0);
Flag : out STD_LOGIC);
end CountCompare_src;
architecture Behavioral of CountCompare_src is
-- COMPONENT DECLERATIONS
component counter is
port ( CLK : in std_logic;
Reset : in std_logic;
S : out std_logic_vector(3 downto 0)
);
end component;
component compare is
port (A : in std_logic_vector(3 downto 0);
B : in std_logic_vector(3 downto 0);
S : out std_logic
);
end component;
-- Component Spesification and Binding
for all : counter use entity work.Count_src(behavioral);
for all : compare use entity work.Compare_src(behavioral);
-- Internal Wires
signal count_out : std_logic_vector(3 downto 0);
begin
-- Component instantiation
C1: counter PORT MAP ( Reset => Reset,
CLK => Clock,
S => count_out
);
C2: compare PORT MAP ( A => count_out,
B => Value,
S => Flag
);
end Behavioral;
To test the design I wrote a testbench as follows:
TestBench
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY TopLevelTester_tb IS
END TopLevelTester_tb;
ARCHITECTURE behavior OF TopLevelTester_tb IS
--Input and Output definitions.
signal Clock : std_logic := '0';
signal Reset : std_logic := '0';
signal Value : std_logic_vector(3 downto 0) := "1000";
signal Flag : std_logic;
-- Clock period definitions
constant clk_period : time := 1 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: entity work.CountCompare_src PORT MAP
(
Clock => Clock,
Reset => Reset,
Value => Value
);
proc: process
begin
Clock <= '0';
wait for clk_period/2;
Clock <= '1';
wait for clk_period/2;
end process;
END;
When I simulate behavioral model, the ISIM pops up, but I see no changes on the Compare Flag. Here is the ss of the ISIM:
What am I missing here? Why does'nt the Flag change?
My best regards.
You have two problems, both in your testbench.
The first is that you never reset count in the counter, it will always be 'U's or 'X's (after you increment it).
The second is that the directly entity instantiation in the testbench is missing an association for the formal flag output to the actual flag signal:
begin
uut:
entity work.countcompare_src
port map (
clock => clock,
reset => reset,
value => value,
flag => flag
);
proc:
process
begin
clock <= '0';
wait for clk_period/2;
clock <= '1';
wait for clk_period/2;
if now > 20 ns then
wait;
end if;
end process;
stimulus:
process
begin
wait for 1 ns;
reset <= '1';
wait for 1 ns;
reset <= '0';
wait;
end process;
Fix those two things and you get:
How can I make a testbench for this full adder code. I'm a newbie and would appreciate any help.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Full_Adder is
PORT(a , b , C_In : IN STD_LOGIC; S,C_Out : OUT STD_LOGIC);
end Full_Adder;
architecture Behavioral of Full_Adder is
begin
S <= a XOR b XOR C_In;
C_Out <= (a AND b) OR (a AND C_In) OR (b AND C_In);
end Behavioral;
Here's a good reference, one of the first that came up when I googled how to write a testbench.
You should google first, give it an honest shot, then come back here with more specific questions.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Full_Adder_tb is
end Full_Adder_tb;
architecture Behavioral of Full_Adder_tb is
component Full_Adder is -- component declaration
port(
a : in std_logic;
b : in std_logic;
C_in : in std_logic;
S : out std_logic;
C_out : out std_logic
);
end component;
signal a: std_logic := '0'; -- signal declarations
signal b: std_logic := '0';
signal C_in: std_logic := '0';
signal S: std_logic;
signal C_out : std_logic;
begin
uut : Full_Adder -- component instantiation
port map(
a => a, -- signal mappings
b => b,
C_in => C_in,
S => S,
C_out => C_out);
process
begin
wait 10 ns; -- wait time
a <= '0'; b <= '0'; C_in <= '1'; -- example test vector
wait 10 ns;
-- Other test vectors and waits here
end process;
end Behavioral;