I'm an amateur when it comes to VHDL and hardware in general but I've been working on a project for school and I came across something that I can't understand.
I have a register (type D FF) that's processing a clock signal to store the input value and, in simulation, it works fine if I use a "Force clock" in it's clk input but if I try to "simulate" a clock by manually changing it with "Force Constant" from zero to one and so forth it doesn't "pick up" on the rising edge.
Is this normal behavior? I assumed it would still detect the rising edge when going from 0 to 1.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity register_D is
generic (
WIDTH : POSITIVE := 1
);
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC;
EN : in STD_LOGIC;
D : in STD_LOGIC_VECTOR(WIDTH-1 downto 0);
Q : out STD_LOGIC_VECTOR(WIDTH-1 downto 0));
end register_D;
architecture Behavioral of register_D is
begin
process (CLK, RST, EN)
begin
if (RST='1') then
Q <= (others=>'0');
elsif (rising_edge(CLK) and EN = '1') then
Q <= D;
end if;
end process;
end Behavioral;
Screenshot of me trying to trigger the FF by manually setting the clock (and not working):
Here you can see it working when I switch clk from "Force constant" to "Force clock":
Related
I was hoping you could help me with a problem I encountered while trying to design synchronous circuits.
I have a simple D flip-flop in my design, such as the one shown in the figure below. But when I initialize my inputs and set the reset to 1 in the test bench, the output of the D flip-flop is always undefined (as can be seen in the "Objects" view), even though I explicitly define it to be 0 when reset is high (the code for the D flip-flop is shown below).
This causes errors in larger circuits when I use the flip-flops and the outputs as signals to other components that require a defined input. How can I achieve an output of zero when my reset is high during initialization?
library ieee;
use ieee.std_logic_1164.all;
entity Dff_en is
port (
d : in std_logic;
en : in std_logic;
clk : in std_logic;
reset : in std_logic;
q : out std_logic
) ;
end entity;
architecture rtl of Dff_en is
signal q_next, q_reg : std_logic;
begin
--dff logic
process(clk, reset) is
begin
if(reset = '1') then
q_reg <= '0';
elsif(rising_edge(clk)) then
q_reg <= q_next;
end if;
end process;
-- next-state logic
q_next <= d when (en = '1') else q_reg;
--output
q <= q_reg;
end architecture; -- arch
Your code will only update the q_reg output when there are events on the signals in the sensitivity list (clk, reset). VHDL (and Verilog) require events to trigger changes. With signal initialization, then at time 0 the values are set, but there are no further events to simulate.
Even if you did a run 100 ns, there would be no change in outputs since you have not had any events. Change either clk or reset some time after time 0 and try again.
It should output value of Qpl when all inputs are x and clk = 1 but it does not. What is the problem with the following code;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--This is a D Flip-Flop with Synchronous Reset,Set and Clock Enable(posedge clk).
--Note that the reset input has the highest priority,Set being the next highest
--priority and clock enable having the lowest priority.
ENTITY syn IS
PORT (
Q : OUT std_logic; -- Data output
CLK : IN std_logic; -- Clock input
Qpl : IN std_logic;
RESET : IN std_logic; -- Synchronous reset input
D : IN std_logic; -- Data input
SET : IN std_logic -- Synchronous set input
);
END syn;
ARCHITECTURE Behavioral OF syn IS --architecture of the circuit.
BEGIN
--"begin" statement for architecture.
PROCESS (CLK) --process with sensitivity list.
BEGIN
--"begin" statment for the process.
IF (CLK'EVENT AND CLK = '1') THEN --This makes the process synchronous(with clock)
IF (RESET = '1') THEN
Q <= '0';
ELSE
IF (SET = '1') THEN
Q <= D;
ELSE
Q <= Qpl;
END IF;
END IF;
END IF;
END PROCESS; --end of process statement.
END Behavioral;
Following diagram is showing the waveform of the above design, and desired operation requirements;
From the waveform diagram, it seems that everything works alright, when the input signal SET becomes U, the if condition cannot be evaluated, thus the output Q also becomes as such, namely U. You can see while SET was 0, the output Q was getting the value of Qpl correctly.
Sorry for the crude drawing, but you can see at the circled clock rising while SET is 0, Q gets the value of Qpl as expected. Only after SET signal becomes U, the output Q also loses its value in the next clock rising event, and also becomes U
You code and comments differ. As does the table/diagram. A D-flipflop/register is a very simple component. Example:
entity dff is
port (
clk : in std_logic;
rst : in std_logic;
set : in std_logic;
load : in std_logic;
d : in std_logic;
q : out std_logic
);
architecture rtl of dff is
begin
dff_proc : process(clk)
begin
if rising_edge(clk) then
if rst='1' then
q <= '0';
elsif set='1' then
q <= '1';
elsif load='1' then
q <= d;
end if;
end if;
end process;
end architecture;
I'm having an issue with this code. Theoretically it should turn my 50MHz sign into 36KHz but as i run the simulation it turns out that the ir_38khz doesn't get any value it is unassigned.
Can you help me where i slip?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.all;
entity orajelKonverter is
Port ( clk50 : in STD_LOGIC;
rst : in STD_LOGIC;
ir_38khz : out STD_LOGIC);
end orajelKonverter;
architecture Behavioral of orajelKonverter is
signal hz38_ctr : STD_LOGIC_VECTOR(9 downto 0);
signal s38 : std_logic;
begin
clk_generator : process (clk50, rst)
begin
if rst = '1' then
s38 <= '0';
hz38_ctr <= (others => '0');
elsif clk50='1' then
if hz38_ctr = "1010010010" then
hz38_ctr <= (others => '0');
s38 <= not s38;
else
hz38_ctr <= hz38_ctr + "1";
end if;
end if;
end process clk_generator;
ir_38khz <= s38;
end Behavioral;
Here is the picture from the simulation:
You need to initialize your signals to some value OR assert your reset to initialize them in simulation. I personally prefer #1, since signal initial conditions are synthesizable, despite the relatively common misconception that they are not. As a matter of fact, I avoid resets in my designs unless I absolutely need to use them. This is actually recommended by Xilinx. So for example you can do:
signal s38 : std_logic := '0';
This will guarantee that when your simulation starts it knows what to do with the line:
s38 <= not s38;
Previously the simulator was trying to do not U which is U.
I'm presently trying to use VHDL to design a traffic light controller, which I'm programming on an Altera EPM240T100C5 with a custom expansion board for displaying the traffic lights. As the slowest clock setting on the board is still faster than I would like, I've needed to write a clock divider which I did as so:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity clockdivider is
port
(
clkin : in std_logic;
dividedclk : out std_logic
);
end clockdivider;
architecture divider of clockdivider is
signal J : std_logic;
signal K : std_logic;
begin
J <= '1';
K <= '1';
process(clkin)
variable tempdividedclk : std_logic;
begin
if (rising_edge(clkin)) then
tempdividedclk := (NOT(tempdividedclk) AND J) OR (tempdividedclk AND (NOT(K)));
end if;
dividedclk <= '0';
dividedclk <= tempdividedclk;
end process;
END divider;
This runs fine on the board but in the simulator (ModelSim) the "dividedclk" output fails to ever initialise to anything. I was wondering if anyone had any idea why?
At the beginning of the simulation, "tempdividedclk" is initialized to "unitialized".
When a clock edge occurs, tempdividedclk will be assigned to (not(U) and 1) or (U and 0), which is "undefined". To simulate correctly, tempdividedclk must be initialized either by a reset or just at simulation level. It works find on silicon because the "U" state will be either a 1 or a 0.
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.