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.
Related
I've got a situation like the following:
library ieee;
use ieee.std_logic_1164;
entity clkin_to_clkout is
port (
clk_in : in std_logic;
clk_out : out std_logic);
end entity clkin_to_clkout;
architecture arch of clkin_to_clkout is
begin
clk_out <= clk_in;
end architecture arch;
The assignment of clk_in to clk_out isn't a problem for synthesis, but in a simulator it will induce a delta delay from clk_in to clk_out, thereby creating a clock crossing boundary. Is there any way to assign an entity output to an entity input without introducing a delta delay? Thanks.
Edit: Responses to some comments. First, I want this exact question answered, please. For clarification, I want the output port to behave exactly as if it were an alias of the input port. If the answer is, "In VHDL there is no possible way to make an output port an exact behavioral match of an input port", then that is the correct answer and I'll accept it as a limitation of the language. Second, if you don't see what the problem is, please instantiate the clkin_to_clkout entity in the following testbench and observe the difference between mr_sig_del_dly vs mr_sig_clk_dly when you simulate for a few clk1 cycles:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity delta_delay is
end entity delta_delay;
architecture arch of delta_delay is
signal clk1: std_logic := '0';
signal clk2 : std_logic;
signal mr_sig : unsigned(7 downto 0) := (others => '0');
signal mr_sig_del_dly : unsigned(7 downto 0);
signal mr_sig_clk_dly : unsigned(7 downto 0);
component clkin_to_clkout is
port (
clk_in : in std_logic;
clk_out : out std_logic);
end component clkin_to_clkout;
begin
clk1 <= not clk1 after 10 ns;
clk_inst : clkin_to_clkout
port map (
clk_in => clk1,
clk_out => clk2);
mr_sig <= mr_sig + 1 when rising_edge(clk1);
mr_sig_del_dly <= mr_sig when rising_edge(clk2);
mr_sig_clk_dly <= mr_sig when rising_edge(clk1);
end architecture arch;
When you simulate, you will observe that mr_sig_clk_dly is delayed 1 clock cycle as expected because it is assigned on the same clock that mr_sig is on (clk1). mr_sig_del_dly is not delayed 1 clk1 cycle even though clk2 is just a passthrough of clk1 in the clkin_to_clkout module. This is because clk2 is a delta delayed version of clk1 because I used a signal assignment.
Again, thanks for all your responses.
In VHDL-2008 or before there is no possible way to make an output port an exact behavioral match of an input port.
Reference Jim Lewis's comment to the original question.
Thanks, Jim and to all who opined.
It seems you do not know what a delta delay is.
A delta delay is an infinity small delay. Every assignment has (at least) a delta delay in simulation. That's just how VHDL works.
edit:
After your comments, I see where you are coming from. The issue you are encountering is probably simulation only, as synthesis will simplify it. However, there is a electronic equivalent, being the multi-phase clocks. Consider you want a 2-phase clock, i.e. differential signal, where the second signal is the inverse of the first. If you would realize these clocks by just using one invertor, the second signal would have a phase offset. This is due to the latency of the invertor component. Thus, in clock generating logic (like PLL and DCM) the not-inverted signal is also delayed (using a variable latency buffer). I.e. all clock signals need to be processed, giving them the same (delta) delay.
The same solution can be applied in VHDL. Example:
library ieee;
use ieee.std_logic_1164.all;
entity clk_buffers is
port(
clk : in std_logic;
clk1 : out std_logic;
clk2_n : out std_logic
);
end entity;
architecture rtl of clk_buffers is begin
clk1 <= clk;
clk2_n <= not clk;
end architecture;
library ieee;
entity test_bench is end entity;
architecture behavioural of test_bench is
use ieee.std_logic_1164.all;
signal clk, clk1, clk2_n : std_logic := '1';
signal base, child1, child2 : integer := 0;
begin
clk <= not clk after 1 ns;
clk_buffers_inst : entity work.clk_buffers
port map(clk => clk, clk1 => clk1, clk2_n => clk2_n);
base <= base+1 when rising_edge(clk1);
child1 <= base when rising_edge(clk1);
child2 <= base when falling_edge(clk2_n);
end architecture;
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;
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 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 am trying to implement a signed accumulator using Core Gen in Xilinx. According to my understanding an accumulator performs the function of a normal register which is just routing the input to the output, but I wanted clarification on that.
I added the Accumulator IPcore (.xco) module to the project and I have a main file which basically contains the component declaration and the port map. I have a single step process too. Everything compiles and I can see the result on the board but don't quite understand what's going on...
When I input 1000 the 8 bit output on the LEDs is 11111000. Another input of 1111 gives me 11110111. I am attaching the code here for the main vhd file called Accm and the .vho file.
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
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 Accm is
port( b: in std_logic_vector(3 downto 0);
sclr, clk, b1, b2 : in std_logic;
q : out std_logic_vector(7 downto 0)
);
end Accm;
architecture Behavioral of Accm is
-- signal declaration
type tell is (rdy,pulse,not_rdy);
signal d_n_s: tell;
signal en: std_logic;
-- component declaration
COMPONENT my_accm
PORT (
b : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clk : IN STD_LOGIC;
sclr : IN STD_LOGIC;
q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- port map
begin
A1 : my_accm
PORT MAP (
b => b,
clk => en,
sclr => sclr,
q => q
);
process(clk)
begin
if clk'event and clk='1' then
case d_n_s is
when rdy => en <= '0';
if b1='1' then d_n_s <= pulse; end if;
when pulse => en <= '1';
d_n_s <= not_rdy;
when not_rdy => en <='0';
if b2='1' then d_n_s <= rdy; end if;
end case;
end if;
end process;
-- .VHO CODE
------------- Begin Cut here for COMPONENT Declaration ------ COMP_TAG
COMPONENT my_accm
PORT (
b : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clk : IN STD_LOGIC;
sclr : IN STD_LOGIC;
q : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- COMP_TAG_END ------ End COMPONENT Declaration ------------
-- The following code must appear in the VHDL architecture
-- body. Substitute your own instance name and net names.
------------- Begin Cut here for INSTANTIATION Template ----- INST_TAG
your_instance_name : my_accm
PORT MAP (
b => b,
clk => clk,
sclr => sclr,
q => q
);
end Behavioral;
I am also pasting an image of the accumualtor I generated in CoreGen.
I'D appreciate it if someone could explain me what is going on in this program. Thanks!
"Accumulator" can mean many things. In the hardware Xilinx library, the component you instantiated is an adder in front of a register. The adder is adding the current value of the accumulator register with the input term. The accumulator register is wider than the input so you can accumulate (add together) many input terms without overflowing the output.
When your circuit starts, the accumulator contains zero. You input 1000 (-8) which when added to zero becomes 11111000 (-8 sign extended) on the output. You then add 1111 (-1), and the output becomes 11110111 (-9 sign extended).
Once you are done "accumulating", assert SCLR to clear the accumulator register back to zero (or use SSET or SINIT, as appropriate for your logic).
This should all be covered by the documentation for the Xilinx library (try clicking the "datasheet" button in the corgen dialog).
Actually, I think I get it now. It's just acting like an Adder with signed inputs. I think I am correct on this but would appreciate any clarification!