VHDL 3-bit sequence counter with T-Flip Flops - vhdl

I am new to VHDL and I can't see a solution to my problem. I want to find a VHDL code for my 3-bit sequence counter with T Flip Flop's which goes: ..,0,4,5,7,6,2,3,1,0,... I made a truth table and minimized equations for T_FF like so:
T0=Q2 xor Q1 xor Q0;
T1=(Q2 xor Q1) and Q0;
T2= not(Q2 xor Q1) and Q0;
Then I draw the circuit:
Last VHDL:
T-FLIP FLOP
library ieee;
use ieee.std_logic_1164.all;
entity tff is
port(
clk: in std_logic;
reset: in std_logic;
t: in std_logic;
q: out std_logic
);
end tff;
architecture behave of tff is
-- signal q_reg: std_logic; --v registru
-- signal q_next: std_logic; --naslednje stanje
begin
process
variable x: std_logic:='0';
begin
wait on clk;
if (clk' event and clk = '1') then
if reset='1' then
x:='0';
else x:=t;
end if;
end if;
if (t = '1') then
q<=not x;
else
q<=x;
end if;
end process;
end behave;
-----------------------------------------------------------
Gray counter
library ieee;
use ieee.std_logic_1164.all;
entity tff_gray is
port(
clk: in std_logic;
reset: in std_logic;
q: inout std_logic_vector (2 downto 0)
--q: out std_logic
);
end tff_gray;
architecture behave of tff_gray is
component tff is
port(
clk: in std_logic;
reset: in std_logic;
t: in std_logic;
q: out std_logic
);
end component;
signal i0,i1,i2: std_logic; --v registru
--signal q_next: std_logic; --naslednje stanje
begin
i0<=q(0) xor q(1) xor q(2);
i1<=q(0) and (q(1) xor q(2));
i2<=q(0) and not(q(1) xor q(2));
Tff0: tff port map(clk, reset, i0, Q(0));
Tff1: tff port map(clk, reset, i1, Q(1));
Tff2: tff port map(clk, reset, i2, Q(2));
end behave;
I wrote this bunch of code of what I found over the internet. When I compiled my code it all went through without a problem but the simulation is wrong. I went through this code a lot of times and I don't know what is wrong. If anyone has any idea please share.
I have mostly watched this altera site and LBEbooks on YouTube.

A number of things. Firstly:
T-FF aka toggle flip flop
You've got your toggle flip-flop description incorrect.
A toggle flip flop flips the output if T='1'. so:
signal q_int : std_logic := '0';
begin
tff_proc: process(clk) begin
if rising_edge(clk) then
if t='1' then
q_int <= not q_int;
end if;
-- reset statement
if reset='1' then
q_int <= '0';
end if;
end if;
end process;
q <= q_int;
redundant code
Don't combine wait on clk and if (clk'event and clk='1') as they do the same thing. Combining will cause issues. Refer to my example above for correct instantiations.
component instantiation
You don't need to include the component tff code in your tff_gray entity. Just simply instantiate the entity directly from the library. e.g.
Tff0: entity work.tff port map(clk, reset, i0, q(0));
bidirectional ports (inout type)
Using the inout type, which you use for the q of tff_gray can give problems in simulation and implementation. It should be out.
However, you must have encountered the cannot read outputs error. This is no longer an issue in VHDL-2008, so you should compile using VHDL-2008 mode.
Alternatively, you need to use intermediate signals, like I did in the example above. E.g.
signal q_int : std_logic_vector(2 downto 0) := (others => '0');
[...]
q <= q_int;

Related

VHDL Filter not getting output for first values

I tried implementing a fir filter in VHDL but during the first three clocks I get no output and the error at 0 ps, Instance /filter_tb/uut/ : Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es)..
Source file (I also have 2 other files for D Flip-Flops):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
entity filter is
port ( x: in STD_LOGIC_VECTOR(3 downto 0);
clk: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(9 downto 0));
end filter;
architecture struct of filter is
type array1 is array (0 to 3) of STD_LOGIC_VECTOR(3 downto 0);
signal coef : array1 :=( "0001", "0011", "0010", "0001");
signal c0, c1, c2, c3: STD_LOGIC_VECTOR(7 downto 0):="00000000";
signal s0, s1, s2, s3: STD_LOGIC_VECTOR(3 downto 0) :="0000";
signal sum: STD_LOGIC_VECTOR(9 downto 0):="0000000000";
component DFF is
Port ( d : in STD_LOGIC_VECTOR(3 downto 0);
clk : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(3 downto 0));
end component;
component lDFF is
Port ( d : in STD_LOGIC_VECTOR(9 downto 0);
clk : in STD_LOGIC;
q : out STD_LOGIC_VECTOR(9 downto 0));
end component;
begin
s0<=x;
c0<=x*coef(0);
DFF1: DFF port map(s0,clk,s1);
c1<=s1*coef(1);
DFF2: DFF port map(s1,clk,s2);
c2<=s2*coef(2);
DFF3: DFF port map(s2,clk,s3);
c3<=s3*coef(3);
sum<=("00" & c0+c1+c2+c3);
lDFF1: lDFF port map(sum,clk,y);
end struct;
Testbench:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use ieee.std_logic_unsigned.all;
ENTITY filter_tb IS
END filter_tb;
ARCHITECTURE behavior OF filter_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT filter
PORT(
x : IN STD_LOGIC_VECTOR(3 downto 0);
clk : IN std_logic;
y : OUT STD_LOGIC_VECTOR(9 downto 0)
);
END COMPONENT;
--Inputs
signal x : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
signal clk : std_logic := '0';
--Outputs
signal y : STD_LOGIC_VECTOR(9 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: filter PORT MAP (
x => x,
clk => clk,
y => y
);
-- 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_proc1: process
begin
x<="0001";
wait for 10ns;
x<="0011";
wait for 10ns;
x<="0010";
wait for 10ns;
--x<="0011";
end process;
END;
Output:
If anyonce could help, I'd appreciate it. I think it has something to do with the inital values of the signals c_i and s_i but I'm not too sure.
Your FIR filter contains flip-flops. These flip-flops have no reset input and so power up in an unknown state. You simulator models this by initialising the flip-flops' outputs to "UUUU" (as the are four bits wide). A 'U' std_logic value represents and uninitialised value.
So, your code behaves as you ought to expect. If you're not happy with that behaviour, you need to add a reset input and connect it to your flip-flops.
You have build a series of three register making up a cascade of registers.
You have not provided a reset so the register contents will be Unknown. You use the registers for calculations without any condition. Thus you arithmetic calculations will see the Unknown values and fail as you have seen.
The first (simplest) solution would be to add a reset. But that is not the best solution. You will no longer get warnings but the first three cycles of your output will be based on the register reset value not of your input signal.
If you have a big stream and don't care about some incorrect values in the first clock cycle you can live with that.
The really correct way would be to have a 'valid' signal transported along side your data. You only present the output data when there is a 'valid'. This is the standard method to process data through any pipeline hardware structure.
By the way: you normally do not build D-ffs yourself. The synthesizer will do that for you. You just use a clocked process and process the data vectors in it.
I have some questions. If I add a reset pin, when will I toggle it from 1 to 0? How can I create this circuit without explicitly using D-ffs?
You make a reset signal in the same way as you make your clock.
As to D-registers: they come out if you use the standard register VHDL code:
reg : process (clk,reset_n)
begin
// a-synchronous active low reset
if (reset_n='0') then
s0 <= "0000";
s1 <= "0000";
s2 <= "0000";
elsif (rising_edge(clk)) then
s0 <= x;
s1 <= s0;
s2 <= s1;
....
(Code entered as-is, not checked for syntax or typing errors)

VHDL Testbench : Output not changing

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')

D flip-flop synthesizable

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;

Pseudo Random Number Generator using LFSR in VHDL

I'm having a bit of trouble creating a prng using the lfsr method. Here is my code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pseudorng is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;
architecture Behavioral of pseudorng is
signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0);
begin
PROCESS(clock)
BEGIN
IF rising_edge(clock) THEN
IF (reset='1') THEN Qt <= "00000000";
ELSE Qt <= seed;
END IF;
temp <= Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
--Qt <= temp & Qt(7 downto 1);
END IF;
END PROCESS;
check <= temp;
Q <= Qt;
end Behavioral;
Here is the simulation I have ran:
prng sim
Firstly, the check output is just there so I can monitor the output of the temp signal. Secondly, the line that is commented out is what is causing the problem.
As can be seen from the simulation, on the first rising edge of the clock, the Qt signal reads the seed. However, and this is my question, for some reason the temp signal only XORs the bits of the Qt signal on the second rising edge of the clock. It remains undefined on the first clock pulse. Why is that? If it operated on the first rising edge right after the Qt signal reads the seed, then I could uncomment the line that shifts the bits and it would solve my problem. Any help would be much appreciated!
Here is the test bench if anyone cares:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_pseudorng is
end tb_pseudorng;
architecture bench of tb_pseudorng is
COMPONENT pseudorng
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
END COMPONENT;
signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;
begin
mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
Q => Q1,
check => check1);
clock: PROCESS
BEGIN
clock1<='0'; wait for 50ns;
clock1<='1'; wait for 50ns;
END PROCESS;
reset: PROCESS
BEGIN
reset1<='0'; wait for 900ns;
END PROCESS;
end bench;
I made some slight modifications to what you had (you are pretty much there though); I don't think the LFSR would step properly otherwise. I added an enable signal to the LFSR so you can effectively control when you want it to step. Resulting sim is here.
Just as a sidenote, you could also include a load and seed inputs if you wanted to seed the LFSR with a different value (instead of making it const).
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity pseudorng is
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
-- constant seed: STD_LOGIC_VECTOR(7 downto 0) := "00000001";
end pseudorng;
architecture Behavioral of pseudorng is
--signal temp: STD_LOGIC;
signal Qt: STD_LOGIC_VECTOR(7 downto 0) := x"01";
begin
PROCESS(clock)
variable tmp : STD_LOGIC := '0';
BEGIN
IF rising_edge(clock) THEN
IF (reset='1') THEN
-- credit to QuantumRipple for pointing out that this should not
-- be reset to all 0's, as you will enter an invalid state
Qt <= x"01";
--ELSE Qt <= seed;
ELSIF en = '1' THEN
tmp := Qt(4) XOR Qt(3) XOR Qt(2) XOR Qt(0);
Qt <= tmp & Qt(7 downto 1);
END IF;
END IF;
END PROCESS;
-- check <= temp;
check <= Qt(7);
Q <= Qt;
end Behavioral;
And tb:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_pseudorng is
end tb_pseudorng;
architecture bench of tb_pseudorng is
COMPONENT pseudorng
Port ( clock : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (7 downto 0);
check: out STD_LOGIC);
END COMPONENT;
signal clock1: STD_LOGIC;
signal reset1: STD_LOGIC;
signal Q1: STD_LOGIC_VECTOR(7 downto 0);
signal check1: STD_LOGIC;
signal en : STD_LOGIC;
begin
mapping: pseudorng PORT MAP(
clock => clock1,
reset => reset1,
en => en,
Q => Q1,
check => check1);
clock: PROCESS
BEGIN
clock1 <= '0'; wait for 50 ns;
clock1 <= '1'; wait for 50 ns;
END PROCESS;
reset: PROCESS
BEGIN
reset1 <= '0';
en <= '1';
wait for 900 ns;
END PROCESS;
end bench;

pseudorandom pattern generator, output is not changing

I am using modelsim for simulating a pseudo-random pattern generator using the below code. The problem is when i force the data_reg signal to a seed value (ex: 0001010101101111) the data_out shows the same value instead of a random value. i will really appreciate any help i cud get on this one.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dff is
Port ( CLK : in std_logic;
RSTn : in std_logic;
D : in std_logic;
Q : out std_logic);
end dff;
architecture Behavioral of dff is
begin
process(CLK)
begin
if CLK'event and CLK='1' then
if RSTn='1' then
Q <= '1';
else
Q <= D;
end if;
end if;
end process;
end Behavioral;
VHDL CODE FOR PRBS Generator using LFSR:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity lfsr is
Port ( CLK : in STD_LOGIC;
RSTn : in STD_LOGIC;
data_out : out STD_LOGIC_VECTOR (15 downto 0));
end lfsr;
architecture Behavioral of lfsr is
component dff
Port ( CLK : in std_logic;
RSTn : in std_logic;
D : in std_logic;
Q : out std_logic);
end component;
signal data_reg : std_logic_vector(15 downto 0);
signal tap_data : std_logic;
begin
process(CLK)
begin
tap_data <= (data_reg(1) xor data_reg(2)) xor (data_reg(4) xor
data_reg(15));
end process;
stage0: dff
port map(CLK, RSTn, tap_data, data_reg(0));
g0:for i in 0 to 14 generate
stageN: dff
port map(CLK, RSTn, data_reg(i), data_reg(i+1));
end generate;
data_out <= data_reg after 3 ns;
end Behavioral;
First off. In your LFSR you have a process sensitive to CLK which should only be combinational:
process(CLK) -- Not correct
-- Change to the following (or "all" in VHDL-2008)
process(data_reg)
You could also just implement it as a continuous assignment outside of a formal process which is functionally the same in this case.
When you force data_reg to a value you are overriding the normal signal drivers instantiated in the design. In the GUI the force command defaults to "Freeze". Once that is in place, the drivers can't update data_reg because the freeze force is dominant until you cancel it. In the force dialog select the "Deposit" kind to change the state without overriding the drivers on subsequent clocks.
The Modelsim documentation has this to say about the different force kinds:
freeze -- Freezes the item at the specified value until it is forced again or until it is unforced with a noforce command.
drive -- Attaches a driver to the item and drives the specified value until the item is forced again or until it is unforced with a noforce command. This option is illegal for unresolved signals.
deposit -- Sets the item to the specified value. The value remains until there is a subsequent driver transaction, or until the item is forced again, or until it is unforced with a noforce command
Note: While a lot of instructional materials (unfortunately) demonstrate the use of the std_logic_arith and std_logic_unsigned libraries, these are not actual IEEE standards and shouldn't be used in standard conformant VHDL. Use numeric_std instead or, in your case, just eliminate them since you aren't using any arithmetic from those libraries.

Resources