actually I want to make a local controller which will enable the latch.
As you can seen on my code below, the signal en will take the output from w AND x to enable the latch. After that, w and x will fetch the en. For example, initially, let say the w and x values start at 1, the en will become 1 and cause the latch to fetch data from data_in to data_out. After that, en will become the input of w and x and cause the latch to disable. However, the circuit didn't work when I tested it using university waveform program. The data_out didnt take the value of data_in. I can't figure out what is the problem still I'm new in VHDL. Hope you can assist/advice me on this :) Sorry for my bad english.
library ieee;
use ieee.std_logic_1164.all;
entity gasp_ctrl is
port(
w,x : inout std_logic; --! bidirectional wire
data_in : in std_logic; --! Data In when latch is enable
data_out: out std_logic --
);
end gasp_ctrl;
architecture ctrl of gasp_ctrl is
signal en, ww, xx : std_logic;
begin
en <= w and x; ------
ww <= en;
xx <= not en;
w <= ww;
x <= xx;
-------- Latch ------
process(en)
begin
if(en = '1') then
data_out <= data_in;
end if;
end process;
end gasp_ctrl;
Your code lines form a combinatorial loop:
en <= w and x;
ww <= en;
xx <= not en;
w <= ww;
x <= xx;
If you wan't to describe asynchronous gates and delays, then you must instantiate the primitives by hand, otherwise the synthesis compiler will optimize your lines and complain about signal loops.
Related
I've learned that SR-Latch does oscillate when S and R are both '0' after they were just '1' in following circuit VHDL Code.
here is VHDL of SRLATCH
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity SRLATCH_VHDL is
port(
S : in STD_LOGIC;
R : in STD_LOGIC;
Q : inout STD_LOGIC;
NOTQ: inout STD_LOGIC);
end SRLATCH_VHDL;
architecture Behavioral of SRLATCH_VHDL is
begin
process(S,R,Q,NOTQ)
begin
Q <= R NOR NOTQ;
NOTQ<= S NOR Q;
end process;
end Behavioral;
and followings are process in Testbench code and its simulation results
-- Stimulus process
stim_proc: process
begin
S <= '1'; R <= '0'; WAIT FOR 100NS;
S <= '0'; R <= '0'; WAIT FOR 100NS;
S <= '0'; R <= '1'; WAIT FOR 100NS;
S <= '0'; R <= '0'; WAIT FOR 100NS;
S <= '1'; R <= '1'; WAIT FOR 500NS;
end process;
and totally I don't have any idea why simulation doesn't reflect...
(click to enlarge)
Someone is teaching you wrong knowledge!
SR and RS basic flip-flops (also called latches) don't oscillate. The problem on S = R = 1 (forbidden) is that you don't know the state after you leave S = R = 1 because you can never go to S = R = 0 (save) simultaneously. You will transition for S = R = 1 to S = R = 0 through S = 1; R = 0 (set) or S = 0; R = 1 (reset). This will trigger either a set or reset operation before you arrive in state save.
Be aware that VHDL simulates with discrete time and is reproducing the same simulation results on every run. You can not (easily) simulate physical effects that cause different signal delays per simulation run.
Btw. you VHDL description is also wrong. Q and NOTQ are of mode out, not inout. Use either a proper simulator supporting VHDL-2008 (that allows read back of out-ports) or use an intermediate signal.
Nice question, and your instructor is right - this circuit will oscillate if both S and R are released at the "same" time. Your issue is that your TB isn't doing this, but this one does:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TOP is
end entity TOP;
architecture A of TOP is
signal S,R,Q,NOTQ: std_logic;
component SRLATCH_VHDL is
port(
S : in std_logic;
R : in std_logic;
Q : inout std_logic;
NOTQ : inout std_logic);
end component SRLATCH_VHDL;
begin
U1 : SRLATCH_VHDL port map(S, R, Q, NOTQ);
process is
begin
S <= '1';
R <= '1';
wait for 10 ns;
S <= '0';
R <= '0';
wait;
end process;
end architecture A;
This will produce infinite delta-delay oscillation:
This isn't a great way to demonstrate asynchronous behaviour, because you are effectively simplifying the physical nature of the circuit, and using the VHDL scheduler to show that there's a problem (with the use of 'delta delays'). A better way to do this is to model real circuit behaviour by adding signal delays (this is exactly what your tools are doing when they back-annotate for timing simulations). Look up signal assignments with after, and the difference between transport and inertial delays. If you draw a circuit diagram, you'll see that the issue arises if both S and R are released in a 'small' time window that doesn't allow the signal propagation around your circuit to complete before the second control signal changes. You now need to write a testbench that changes S and R inside this time window.
Pretty much everything you ever design will be asynchronous, in exactly the same way as your SR circuit. We make circuits 'synchronous' only by ensuring that input signals don't change at the same time. The job of the timing tools is to tell us what 'same' actually means: when you get a report or a datasheet value giving you a setup or a hold time, then that number is simply the numerical version of 'not the same'.
I am trying to detect changes in the input signals of my Selector. When I find the first input that changed (either rising or falling edge), I give an index as output. When I try to synthesize my source code, I get an error "unsupported Clock statement". A also tried to use "rising_edge" and "falling_edge", but I got the same error.
Here is my code
library ieee;
use ieee.std_logic_1164.all;
entity Selector is
port (
X1: in std_logic;
X2: in std_logic;
X3: in std_logic;
X4: in std_logic;
X5: in std_logic;
X6: in std_logic;
O: out std_logic_vector(2 downto 0)
);
end Selector;
architecture behave of Selector is
begin
process(X1,X2,X3,X4,X5,X6)
begin
if (X1'event) then
O <= "000";
elsif (X2'event) then
O <= "001";
elsif (X3'event) then
O <= "010";
elsif (X4'event) then
O <= "011";
elsif (X5'event) then
O <= "100";
elsif (X6'event) then
O <= "101";
else
O <= "000";
end if;
end process;
end behave;
Is there an alternative solution for that?
You would need an additional clock input to make a comparison between the value of X1, X2, ... in the current clock cycle and the value in the last clock cycle. If the Xes are asynchronous to the clock you have to synchronize them first.
Input synchronisation
To synchronize the inputs to the clock, you have to sample each input with two D flip-flops in serial. The output of the first flip-flop may be harmed by metastability problems which is described in more detail in these papers:
Ran Ginosar: Metastability and Synchronizers: A Tutorial
Sunburst Design: Synthesis and Scripting Techniques for Designing Multi-
Asynchronous Clock Designs
The connection between both flip-flops (for each input) must be constrained so that the rounting path between them is as short as possible. The implementation below will just show the two flip-flops. A more advanced implementation can be found in the sync_Bits component of the PoC Library where I am one of the authors.
Comparison
Once the input is synchronous to the clock, just delay it another clock cylce. This will make up the last value, so that, you can compare the current values to the last values to detect a signal change. The frequency of the input clock must be much faster than the frequency of change on one of the X inputs:
to get a fast repsonse of the edge-detection, and
to catch all signal changes.
Here is a possible implementation:
library ieee;
use ieee.std_logic_1164.all;
entity Selector is
port (
clk : in std_logic;
X1: in std_logic;
X2: in std_logic;
X3: in std_logic;
X4: in std_logic;
X5: in std_logic;
X6: in std_logic;
O: out std_logic_vector(2 downto 0)
);
end Selector;
architecture behave of Selector is
signal X : std_logic_vector(6 downto 1); -- all inputs in one vector
signal X_meta : std_logic_vector(6 downto 1); -- first sampling stage
signal X_curr : std_logic_vector(6 downto 1); -- second sampling stage =
-- current value
signal X_last : std_logic_vector(6 downto 1); -- last value of X_curr
begin
-- Concatenate all inputs to one vector for shorter code below.
X <= X6 & X5 & X4 & X3 & X2 & X1;
-- Synchronize external inputs to clock. If the X* inputs are already
-- synchronous to 'clk' then replace this process with:
-- X_curr <= X;
sync: process(clk)
begin
if rising_edge(clk) then
-- The path betweeen these two flip-flops must be constrained for a
-- short delay, so that, the wire in between is as ahort as
-- possible.
X_meta <= X;
X_curr <= X_meta;
end if;
end process;
-- This statement delays the current value X_curr by one clock cycle.
X_last <= X_curr when rising_edge(clk);
-- Comparison and selector output.
process(X_curr, X_last)
begin
if (X_curr(1) xor X_last(1)) = '1' then
O <= "000";
elsif (X_curr(2) xor X_last(2)) = '1' then
O <= "001";
elsif (X_curr(3) xor X_last(3)) = '1' then
O <= "010";
elsif (X_curr(4) xor X_last(4)) = '1' then
O <= "011";
elsif (X_curr(5) xor X_last(5)) = '1' then
O <= "100";
elsif (X_curr(6) xor X_last(6)) = '1' then
O <= "101";
else
O <= "000";
end if;
end process;
end behave;
In VHDL I can write this in my testbench:
signal clk : std_logic := '0';
signal count_in : std_logic_vector(3 downto 0) := "0000";
signal load : std_logic := '0';
signal reset : std_logic := '0';
signal count_out : std_logic_vector(3 downto 0) := "0000";
...
clk <= not clk after 50 ns;
reset <= '1' after 1400 ns, '0' after 1900 ns;
count_in <= "1010" after 2500 ns;
load <= '1' after 2700 ns, '0' after 3000 ns;
The signal declarations are before the "begin" of the testbench architecture while the portion after the elipse is in the body of the testbench architecture. A much better way is to use a process which ends with "wait" statement when writing testbenches. I understand how to do this in verilog as well as VHDL.
In verilog we can have an initial block that assigns value once. It is also possible to have multiple initial blocks. I have not tried this, but I don't think that it is wise to drive the same signal from multiple initial blocks.
Now my question is, how do I translate the above code for the DUT stimulus into Verilog? I expect that I shall use an assign statement with multiple #delay values. Is that correct? How do I do it?
In Verilog 2001 and above, you can initialize variables upon declaration, like VHDL. Another interesting, but perhaps less common way to do this is to use use a fork-join block with blocking assignments. In the following code, each line in the fork-join block is executed independently and concurrently.
module test;
reg clk, load, reset;
reg [3:0] count_in, count_out;
initial
begin
fork
begin clk = 0; while (1) #50 clk = ~clk; end
begin count_in = 0; #2500 ; count_in = 4'b1010; end
begin load = 0; #2700 ; load = 1 ; #3000; load = 0; end
begin reset = 0; #1400 ; reset = 1; #1900; reset = 1; end
count_out = 0;
join
end
endmodule
Working example on edaplayground.
Also, notice that the clk signal in your code only toggles once. I slightly modified it so that the clock is running endlessly.
I'm not too familiar with VHDL, but this looks like a test bench stimulus. I generated the runnable testcase for comparison here.
The Verilog equivalent would look something like:
reg clk = 1'b0;
reg [3:0] count_in = 4'b0000;
reg load = 1'b0;
reg reset = 1'b0;
wire [3:0] count_out; // test bench is not driving this
...
initial begin
clk <= #50 !clk;
reset <= #1400 1'b1;
reset <= #1900 1'b0;
count_in <= #2500 4'b1010;
load <= #2700 1'b1;
load <= #3000 1'b0;
end
This will generate the same waveform, except count_out is floating instead of all zeros. By the naming convention I consider count_out should be driven by the device-under-test, which needs to be a wire type.
A SystemVerilog may look something like:
/* Note: bit cannot be X or Z
* initializes equivalent to 'logic clk = 1'b0;' or 'reg clk = 1'b0;'
*/
bit clk;
bit [3:0] count_in;
bit load;
bit reset;
wire [3:0] count_out; // logic type is also okay
...
initial begin
clk <= #50ns !clk;
reset <= #1400ns 1'b1;
reset <= #1900ns 1'b0;
count_in <= #2500ns 4'b1010;
load <= #2700ns 1'b1;
load <= #3000ns 1'b0;
end
Working example of Verilog and System Verilog here
I'm writing vhdl code for a jk-flip-flop on modelsim and i get an error when i try to simulate it: Error: Iteration limit reached at time 0 ns.
I'm not sure what it means, but I've looked through much of my source code for errors to no success. Can anyone guess what the problem might be?
library ieee;
use ieee.std_logic_1164.all;
entity SRlatch is
port(S,R:in bit; Q : inout bit ; QN : inout bit := '1');
end SRlatch;
architecture structural of SRlatch is
begin
Q <= S nand QN;
QN <= R nand Q;
end;
entity JKFlipFlopStruct is
port(J,K,clk : in bit ; Q : inout bit ; QN : inout bit);
end JKFlipFlopStruct;
architecture structural of JKFlipFlopStruct is
component SRlatch is
port(S,R:in bit; Q : inout bit ; QN : inout bit := '1');
end component;
signal J0,K0,J1,K1,J2,K2 : bit;
begin
J0 <= not ( J and QN and clk) );
K0 <= not ( K and Q and clk) );
f1 : SRlatch port map ( J0,K0,J1,K1 );
J2 <= not ( J1 and (not clk) );
K2 <= not ( K1 and (not clk) );
f2 : SRlatch port map ( J2,K2,Q,QN );
end structural;
[JK Flop Flop negative edge triggered]
see image :http://i.stack.imgur.com/J3m1J.gif
As Russell say, this error usually indicates that ModelSim is stuck in an infinite loop. In VHDL, this can happen when a signal is placed in the sensitivity list and this signal is changed in the process.
A simple example:
process (sig)
begin
sig <= not sig;
end;
Your problem is also in this case. But there are some differences.
1. For any concurrent signal assignment statement, there is an equivalent process statement with the same meaning. (See VHDL LRM 93 $9.5 for more details)
So, in your code,
J0 <= not ( J and QN and clk) );
is short hand notation for
process
begin
J0 <= not ( J and QN and clk) );
wait on J, QN, clk;
end process;
or
process (J, QN, clk)
begin
J0 <= not ( J and QN and clk) );
end process;
Others concurrent statements are the same.
2. About simulation cycle (See VHDL LRM 93 $12.6.4 and Delta Delays)
In eacy cycle, the values of all signals in the description are computed. If as a result of this computation an event occurs on a given signal, process statements that are sentitive to that signal will resume and will be executed as part of the simulation cycle.
In your code:
f2 : SRlatch port map ( J2,K2,Q,QN );
it's equivalent process:
process (J2, K2)
begin
Q <= J2 nand QN;
QN <= K2 nand Q;
end process;
along with other processes make an infinite loop.
For example,
the J-K Flip-Flop is stable # 100 ns + 0 delta time
J or K or clk changes # 100 ns + 0 delta time
J0 or K0 \ ---
J1 or K1 |__ cost several delta times
J2 or K2 | Suppose that Q changes # 100 ns + 3 delta time
Q or QN changes / ---
Then the value of K0 will change again!!
This result in a infinite loop becase 100 ns + n delta time = 100 ns. Time never advanceds.
Solutions:
1.Make your design a sequential one (ie. use a synchronic clock).
process (clk)
begin
if (rising_edge(clk)) then
-- signal assignment
end if;
end process;
2.Use delay assignment. So, in the SRlatch.vhd, you should write
Q <= S nand QN after 1 ns;
QN <= R nand Q after 2 ns;
Unsymmetrical delay is used to ensure that either Q or QN sets up first and then feedbacks to set the other one.
Also refer to a similar question: Debugging Iteration Limit error in VHDL Modelsim.
Iteration limit means that you have created a feedback loop in your design and you made the simulator very angry! It cannot resolve the loop.
Use a clocked process to set J0 and K0.
jk_flippy_floppy : process (clk)
begin
if rising_edge(clk) then
J0 <= not ( J and QN );
K0 <= not ( K and Q );
end if;
end process jk_flippy_floppy;
library ieee;
use ieee.std_logic_1164.all;
entity SRlatch is
port(S,R:in bit; Q : inout bit := '0' ; QN : inout bit := '1');
end SRlatch;
architecture structural of SRlatch is
begin
Q <= S nand QN;
QN <= R nand Q;
end structural;
entity JKFlipFlopStruct is
port(J,K,clk : in bit ; Q : inout bit ; QN : inout bit:= '1');
end JKFlipFlopStruct;
architecture structural of JKFlipFlopStruct is
component SRlatch is
port(S,R:in bit; Q : inout bit ; QN : inout bit := '1');
end component;
signal J1 : bit;
signal J0,K0,K1,J2,K2 : bit:= '1';
begin
J0 <= not ( J and QN and (not clk) );
K0 <= not ( K and Q and (not clk) );
f1 : SRlatch port map ( J0,K0,J1,K1 );
J2 <= not ( J1 and clk );
K2 <= not ( K1 and clk );
f2 : SRlatch port map ( J2,K2,Q,QN );
end structural;
this is the correct code
I have a problem designing memory circuits in VHDL. I am trying to figure out a soultion to the following prompt:
Create a NAND basic cell in the Xilinx tools using structural VHDL methods. Add a 1ns gate delay to both NAND gates (for both rising and falling transitions). Label inputs S and R and the outputs Q and QN as appropriate. Create a VHDL test bench to simulate the circuit, driving the inputs as specified below.
De-assert both inputs at the start of the simulation. At 100ns, asset S. At 200ns, de-assert S. At 300ns, assert R. At 400ns, de-assert R. At 500ns, assert both inputs. At 600ns, de-assert both inputs. At 700ns, assert both inputs.
An undefined output
A set operation
A reset operation
A ‘0’ being stored in memory
A ‘1’ being stored in memory
A state where the Q and QN outputs are both driven to the same value
A metastable state
If i could get just a basic example of what the code will look like i can design a NOR circuit also (That is the actual problem i wish to solve) but a NAND example will be sufficient.
I have tried using this model for the structural code
import std_logic from the IEEE library
library ieee;
use ieee.std_logic_1164.all;
--ENTITY DECLARATION: name, inputs, outputs
entity nandGate is
port( A, B : in std_logic;
F : out std_logic);
end nandGate;
--FUNCTIONAL DESCRIPTION: how the NAND Gate works
architecture func of nandGate is
begin
F <= A nand B;
end func;
and this model for the test bench
architecture tb of nandGate_tb is
--pass nandGate entity to the testbench as component
component nandGate is
port( A, B : in std_logic;
F : out std_logic);
end component;
signal inA, inB, outF : std_logic;
begin
--map the testbench signals to the ports of the nandGate
mapping: nandGate port map(inA, inB, outF);
process
--variable to track errors
variable errCnt : integer := 0;
begin
--TEST 1
inA <= '0';
inB <= '0';
wait for 15 ns;
assert(outF = '1') report "Error 1" severity error;
if(outF /= '1') then
errCnt := errCnt + 1;
end if;
--TEST 2
inA <= '0';
inB <= '1';
wait for 15 ns;
assert(outF = '1') report "Error 2" severity error;
if(outF /= '1') then
errCnt := errCnt + 1;
end if;
--TEST 3
inA <= '1';
inB <= '1';
wait for 15 ns;
assert(outF = '0') report "Error 3" severity error;
if(outF /= '0') then
errCnt := errCnt + 1;
end if;
-------------- SUMMARY -------------
if(errCnt = 0) then
assert false report "Good!" severity note;
else
assert true report "Error!" severity error;
end if;
end process;
end tb;
The question is asking you to create an SR latch (called NAND basic cell in the instructions) from a cross-coupled pair of NAND gates.
The delay mentioned would be in the logic equation for the functional description of the NAND gate.
The following is a structural VHDL model of an SR latch made of two NAND gates:
entity nandCell is
port( S, R : in std_logic; --S and R are active low
Q, QN : out std_logic);
end nandCell;
architecture structural of nandCell is
--NAND gate component declaration
signal Qint, QNint : std_logic; --these internal signals are required to be able to read the "outputs"
begin
n1 : nandGate port map(S, QNint, Qint);
n2 : nandGate port map(R, Qint, QNint);
Q <= Qint;
QN <= QNint;
end structural;