Behavioral into FlipFlop Structural - process

In this code, when reset equals 1 the s becomes 1000 and when reset equals 0 the s becomes 0100 then 0010 then 0001 and it starts all over again with 1000 as the start value, only if the clock is up.
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clock_behav is
port (clock : in std_logic;
reset : in std_logic;
s : out std_logic_vector (3 downto 0));
end clock_behav;
architecture behav of clock_behav is
begin
process(clock,reset)
variable shift_counter: integer := 0;
begin
if (reset='1') then
s<="1000";
shift_counter := 1;
else
if(clock'event and clock='1') then
if(shift_counter =1) then
s<="0100";
shift_counter := 2;
elsif(shift_counter =2) then
s<="0010";
shift_counter := 3;
elsif(shift_counter =3) then
s<="0001";
shift_counter := 0;
else
s<="1000";
shift_counter := 1;
end if;
end if;
end if;
end process;
end behav;
I want to create this
With FlipFlops as you can see, one Set and 3 Reset. But, I struggle to move from behavioral into structural, because in VHDL we can't have in process port maps. Of course I tried many things, as you can see below, but it's impossible to recreate it with flipflops if the port maps are not inside the process. As you can clearly understand , my knowledge about VHDL it's not that great. Also, I want you to tell me if I did right when I changed the flipflop D and Q types, it was std_logic and I changed it to std_logic_vector . I did this for the purpose of this exercise.
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity clock_structural is
port (clock : in std_logic;
reset : in std_logic;
s : out std_logic_vector (3 downto 0));
end clock_structural;
architecture behavior of clock_structural is
signal t,t1,t2,t3 : std_logic_vector (3 downto 0);
component flipflop_new
port
(D : in std_logic_vector (3 downto 0);
CLK : in std_logic;
CLR : in std_logic;
Q : out std_logic_vector (3 downto 0));
end component;
component flipflop_set
port
(D_s : in std_logic_vector (3 downto 0);
CLK_s : in std_logic;
CLR_s : in std_logic;
Q_s : out std_logic_vector (3 downto 0));
end component;
begin
process(clock,reset)
variable shift_counter: integer := 0;
begin
if (reset='1') then
t<="1000";
shift_counter := 1;
else
if(clock'event and clock='1') then
if(shift_counter =1) then
shift_counter := 2;
elsif(shift_counter =2) then
shift_counter := 3;
elsif(shift_counter =3) then
shift_counter := 0;
else
shift_counter := 1;
end if;
end if;
end if;
end process;
FFS1: flipflop_set port map(t,clock,reset,t1);
s<=t1;
FFR1: flipflop_new port map(t1,clock, reset,t2);
s<=t2;
FFR2: flipflop_new port map(t2,clock, reset,t3);
s<=t3;
FFR3: flipflop_new port map(t3,clock, reset,s);
end behavior ;
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity flipflop_new is
port ( D : in std_logic_vector (3 downto 0);
CLK : in std_logic;
CLR : in std_logic;
Q : out std_logic_vector (3 downto 0)
);
end flipflop_new;
architecture behavior of flipflop_new is
begin
process(CLK)
begin
if CLR='0' then null;
elsif RISING_EDGE(CLK) then
Q <= D;
end if;
end process ;
end behavior ;
library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity flipflop_set is
port ( D_s : in std_logic_vector (3 downto 0);
CLK_s : in std_logic;
CLR_s : in std_logic;
Q_s : out std_logic_vector (3 downto 0)
);
end flipflop_set;
architecture behavior of flipflop_set is
begin
process(CLK_s)
begin
if CLR_s='1' then null;
elsif RISING_EDGE(CLK_s) then
Q_s <= D_s;
end if;
end process ;
end behavior ;

There are several things to change or improve. A structural VHDL model should describe your schematic, which you don't really do.
First, why do you have shift_counter in your structural? You don't need that process.
Second, you instantiate 4 of your flip-flop entity which are each 4 bits wide, while your schematic's has 4 flip-flops. Basically, you instantiate a total of 16 registers when you need 4. Why is your flip-flop model 4 bits wide? It should be a single bit.
Third, look at your flip-flop description:
process(CLK)
begin
if CLR='0' then
null;
elsif RISING_EDGE(CLK) then
Q <= D;
end if;
end process ;
Does it seems what a flip-flop do? The Q <= D when the clock rises is fine, but does nothing happens when the clr of the flip-flop is active? Your output should reset/set in that case, which is not what your VHDL describe.
Another error is that you assign your output s 3 times. s must be assigned once, but you can assign bit individually like s(0) <= t1.
Finally, you don't describe the feedback. The output of your last flip-flop is s, while the input of the first flip-flop is t. From your schematic, they should be connected together.

Related

Rising Edge Led Counter Problems in VHDL

I'm new to fpga and VHDL in general (I'm using a fpga aprox. 2 weeks now). I am trying to create a project that lights up LEDs in order. First of all I made a falling edge detector for the button. And then I created a std_logic_vector for LEDs. But I can't detect a signal change in fallen edge detection. Because of that I can't change LED state. There is my testbench for simulation. I don't have any idea what's going on. Thanks for your answers and sorry for my bad English.
Code:
library ieee;
use ieee.std_logic_1164.all;
entity sequential_led is
end sequential_led;
architecture seq_led of sequential_led is
signal clk : std_logic := '0';
--signal rst : std_logic := '1';
--signal rstb : std_logic := '1';
signal i : natural := 0;
signal dus_next : std_logic := '0';
signal dusen : std_logic := '0';
signal button : std_logic := '0';
signal led : std_logic_vector(7 downto 0);
begin
clk <= not clk after 1 ns;
button <= not button after 2 ns;
falling:
process begin
if rising_edge(clk) then
dus_next <= button;
end if;
wait for 100 ns;
end process falling;
dusen <= (not button) and dus_next;
led_changes:
process begin
if dusen = '1' then
i <= i + 1;
if i = 7 then
i <= 0;
end if;
end if;
led(7-i) <= '0';
led(i) <= '1';
wait for 100 ns;
end process led_changes;
end architecture;
UPDATE: First of all very big thanks to DomasAquinas and Martin Thompson! After 3 days of work, I finally finished my little LED project.
Change: I've made sure all of processes has a sensivity trigger.
For falling process I've included 'clk' signal for sensivity.
For led_change process I've included 'dusen' signal for sensivity.
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sequential_led is
port(
clk : in std_logic;
button : in std_logic;
led : out std_logic_vector(7 downto 0) := (others => '0')
);
signal dus_next : std_logic;
signal i : natural range 0 to 7;
signal dusen : std_logic := '0';
end sequential_led;
architecture seq_led of sequential_led is
begin
falling:
process(clk) begin
if rising_edge(clk) then
dus_next <= button;
end if;
end process falling;
dusen <= (not button) and dus_next;
led_changes:
process(dusen) begin
if dusen = '1' then
i <= i + 1;
if i = 7 then
i <= 0;
end if;
led(i) <= '1';
led(i+7) <= '0';
end if;
end process led_changes;
end architecture;

VHDL password program with DE2-board

Summary:
I'm trying to make a password system in VHDL with the DE2 Altera board. SW 0 to 7 is the combination lock, LEDR 0 to 7 shows the current code and signal 'code' stores the combination. When the switches match the code you have the option to change the code by holding down KEY(1).
Problem:
The code works as it should, only the starter code is not what's expected. It should be: "01010101" as shown in the signal; but it comes out as "01111111". I suspect the program enters the if-statement on startup, but I don't see how that's possible, seeing as 'code' and SW should't be equal.
What am I missing?
Here is the code:
library IEEE;
use IEEE.std_logic_1164.all;
entity pass_sys is
port(
SW : in std_logic_vector(7 downto 0);
KEY : in std_logic_vector(3 downto 0);
LEDR : out std_logic_vector(17 downto 0);
LEDG : out std_logic_vector(17 downto 0)
);
end pass_sys;
architecture func of pass_sys is
signal code : std_logic_vector(7 downto 0) := "01010101"; --start code
begin
process(SW)
begin
LEDR(7 downto 0)<=code;
if (SW = code) then
LEDG(0)<='1';
LEDG(1)<=not KEY(1);
if (KEY(1) = '0') then
code<=SW;
end if;
else
LEDG(0)<='0';
end if;
end process;
end func;
I assume your problem happens on your board, not in simulation. If I'm wrong, my answer is not the one you expect.
This initialization way is usefull only in simulation :
signal code : std_logic_vector(7 downto 0) := "01010101"; --start code
Synthesis will not consider your initialization value (That's why I discourage you to use this, except in test bench). If you want to initialize a signal, I advice to use a reset.
Notes :
You should put KEY in sensitivity list and put this line out of your process :
LEDR(7 downto 0)<=code;
Your process infers latches, it's not forbidden but you must be careful with this
EDIT : How to add a reset
library IEEE;
use IEEE.std_logic_1164.all;
entity pass_sys is
port(
RST : in std_logic;
SW : in std_logic_vector(7 downto 0);
KEY : in std_logic_vector(3 downto 0);
LEDR : out std_logic_vector(17 downto 0);
LEDG : out std_logic_vector(17 downto 0)
);
end pass_sys;
architecture func of pass_sys is
signal code : std_logic_vector(7 downto 0);
begin
LEDR(7 downto 0)<=code;
process(SW, code, KEY)
begin
if RST = '1' then
LEDG <= (others => '0');
code <= "01010101";
elsif (SW = code) then
LEDG(0)<='1';
LEDG(1)<=not KEY(1);
if (KEY(1) = '0') then
code<=SW;
end if;
else
LEDG(0)<='0';
end if;
end process;
end func;
The pin RST of your component could be connected to an analogic signal of you card (POWER_GOOD, ALIM_ON, DONE, ...) or to a pll_locked signal of a PLL if you use it.

trigger with arbitrary width

Well, I'm trying to make a module in VHDL language, so far I have the internal clock (100MHz) and a control signal called IN (std_logic), and I need an output signal OUT (std_logic) of arbitrary width, said wide I want to control counting the clock rising_edge, I don't have a good programming base, that's why I'm stuck with this, if anyone can help me I thank you
  I enclose an illustrative image of how I wish to have the output, where delta / \ is an arbitrary interval that does not depend on the IN input, when IN goes low, the OUT signal must remain on until the counter finishes its purpose..
https://imgur.com/a/NoPZZjP
So you basically what to create an off delay?
Note: VHDL 2008 migth apply (my usual language)
entity off_delay is
generic(
n : natural : 2 -- off delay
);
port(
clk : in std_logic;
a : in std_logic;
b : out std_logic
);
end entity;
clk _/¯\__/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\
a _____/¯¯¯\________________________________
b _________/¯¯¯¯¯¯¯¯¯¯¯¯\___________________
architecture synkron of off_delay is
signal delay: std_logic_vector(n downto 0); -- 1+n cycles out signal
begin
b <= delay(0);
process(clk)
begin
if rising_edge(clk) then
delay <= (others => '1') when a else ('0' & delay(delay'left downto 1));
end if;
end process;
end architecture;
clk _/¯\__/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\_/¯\
a _____/¯¯¯\_____________________________
b _____/¯\¯\¯¯¯¯¯¯¯¯¯¯\___________________
architecture asynkron of off_delay is
signal delay: std_logic_vector(n-1 downto 0); -- n cycles off delay
begin
b <= delay(0) or a;
process(clk)
begin
if rising_edge(clk) then
delay <= (others => '1') when a else ('0' & delay(delay'left downto 1));
end if;
end process;
end architecture;
Note: The asynkron solution will be dependent on stable a as it will be susceptible to glitches.
Note: The asynkron solution will introduce a delta delay that might be hard to debug
Note: Those are the simplest soulutions. To get technical a SR latch could be implemented to set by a in an asynkron fassion and reset by the synkron delay line. OBS Latches are strongly adviced against in fpga design!
Here is another solution which use more ressources with a low width but less with a high width and with width as an input instead of generic :
entity top is
port
(
i_rst : in std_logic;
i_clk : in std_logic;
i_din : in std_logic;
i_width : in std_logic_vector(7 downto 0);
o_dout : out std_logic
);
end top;
architecture Behavioral of top is
signal counter : unsigned(7 downto 0);
signal oe : std_logic;
begin
process(i_clk)
begin
if i_rst = '1' then
counter <= (others => '0');
oe <= '0';
elsif rising_edge(i_clk) then
if oe = '1' then
counter <= counter + 1;
if counter = unsigned(i_width) - 1 then
counter <= (others => '0');
oe <= '0';
end if;
elsif i_din = '1' then
if unsigned(i_width) > x"01" then
counter <= counter + 1;
oe <= '1';
end if;
end if;
end if;
end process;
o_dout <= oe or i_din;
end Behavioral;
But as Halfow told you, use combinational just before the output makes your module very sensitive to glitches.

Entity does not match component port

I have a vhdl code written for a shifter made with d-flip flops and multiplexers which runs and checks with successful syntax. However, now that i'm working on the testbench i'm running into some errors.
The VHDL Code is:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY MUX41 IS
PORT (i3, i2, i1, i0 : IN BIT;
s: IN BIT_VECTOR(1 DOWNTO 0);
o: OUT BIT);
END MUX41;
ARCHITECTURE arch_mux41 OF MUX41 IS
BEGIN
PROCESS(i3, i2, i1, i0, s)
BEGIN
CASE s IS
WHEN "00" => o <= i0;
WHEN "01" => o <= i1;
WHEN "10" => o <= i2;
WHEN "11" => o <= i3;
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
END arch_mux41;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY DFF IS
PORT(d, clk : IN BIT;
q, qb : OUT BIT);
END DFF;
ARCHITECTURE arch_dff OF DFF IS
BEGIN
PROCESS(clk)
VARIABLE q_temp : BIT;
BEGIN
IF(clk'EVENT AND clk='1')THEN
q_temp := d;
END IF;
q <= q_temp;
qb <= NOT q_temp;
END PROCESS;
END arch_dff;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY UShift IS
PORT(clk, il, ir : IN BIT;
s: IN BIT_VECTOR(1 DOWNTO 0);
i : IN BIT_VECTOR(3 DOWNTO 0);
q : OUT BIT_VECTOR(3 DOWNTO 0));
END UShift;
ARCHITECTURE struct OF UShift IS
COMPONENT MUX41
PORT (i3, i2, i1, i0 : IN BIT;
s: IN BIT_VECTOR(1 DOWNTO 0);
o: OUT BIT);
END COMPONENT;
COMPONENT DFF
PORT(d, clk : IN BIT;
q, qb : OUT BIT);
END COMPONENT;
FOR U1, U2, U3, U4: MUX41 USE ENTITY WORK.MUX41(arch_mux41);
FOR U5, U6, U7, U8: DFF USE ENTITY WORK.DFF(arch_dff);
SIGNAL o: BIT_VECTOR(3 DOWNTO 0);
SIGNAL qb: BIT_VECTOR(3 DOWNTO 0);
SIGNAL qt:BIT_VECTOR(3 DOWNTO 0);
BEGIN
U1:MUX41 PORT MAP(il,qt(2), i(3), qt(3), s, o(3));
U2:MUX41 PORT MAP(qt(3), qt(1), i(2), qt(2), s, o(2));
U3:MUX41 PORT MAP(qt(2), qt(0), i(1), qt(1), s, o(1));
U4:MUX41 PORT MAP(qt(1), ir, i(0), qt(0), s, o(0));
U5:DFF PORT MAP(o(3), clk, qt(3), qb(3));
U6:DFF PORT MAP(o(2), clk, qt(2), qb(2));
U7:DFF PORT MAP(o(1), clk, qt(1), qb(1));
U8:DFF PORT MAP(o(0), clk, qt(0), qb(0));
q <= qt;
END struct;
The error messages that come up only appear when checking for the syntax in the testbench. They state that the entity does not match component port for "clk", "il", "ir", "i", "s", and "q". Does anyone have any ideas on what I may have wrong? I have read some suggestions online for similar issue but none have applied actually applied to this particular code.
The testbench is:
LIBRARY ieee;
USE IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY UShift_test IS
END UShift_test;
ARCHITECTURE behavior OF UShift_test IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT UShift
PORT(clk : IN std_logic; il : IN std_logic; ir : IN std_logic; i : IN std_logic_vector(3 downto 0); s:IN std_logic_vector(1 downto 0);
q : OUT std_logic_vector(3 downto 0));
END COMPONENT;
--Inputs
signal clk : std_logic := '0';
signal il : std_logic := '0';
signal ir : std_logic := '0';
signal s : std_logic_vector(1 downto 0) := (others => '0');
signal i : std_logic_vector(3 downto 0) := (others => '0');
--Outputs
signal q : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 20 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: UShift PORT MAP (
clk => clk,
il => il,
ir => ir,
s => s,
i => i,
q => q);
-- 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_proc: process
begin
---- test clr
ir<= '0';
wait for 40ns;
---- test parallel loading
ir<= '1';
s<= "11";
i<= "0010";
wait for 40ns;
---- test shift right
s<= "01";
il<='1';
wait;
end process;
END;
Yes. Here is the entity for UShift:
ENTITY UShift IS
PORT(clk, il, ir : IN BIT;
s: IN BIT_VECTOR(1 DOWNTO 0);
i : IN BIT_VECTOR(3 DOWNTO 0);
q : OUT BIT_VECTOR(3 DOWNTO 0));
END UShift;
Here is the corresponding component in UShift_test:
COMPONENT UShift
PORT(clk : IN std_logic; il : IN std_logic; ir : IN std_logic; i : IN std_logic_vector(3 downto 0); s:IN std_logic_vector(1 downto 0);
q : OUT std_logic_vector(3 downto 0));
END COMPONENT;`:
As you can see, they are different. Unless you use a configuration with a port map which includes type conversion functions, the component and entity should be identical. I highly recommend you don't try to fix this using a configuration, instead I recommend you change the types to match. You have used type BIT in your designs, which is unusual. Unless there is a good reason for that, I'd change type BIT to type STD_LOGIC (and the corresponding vectors, obviously).
And, why are you using component instantiation? Direct instantiation is easier and is less typing and the extra flexibility offered by component instantiation is usually not required. Here is an example that compares the two methods: https://www.edaplayground.com/x/2QrS.

VHDL small error when using a conditional signal assignment (when...else)

I'm currently working on a component that will perform addition or subtraction, depending on the user input. Right now, I am working on a process that handles the assignment of values to the internal signals which will be used by the internal components I am using. One problem that comes up is in the line when I'm assigning b_in with either the input b or the 2's complement of the input b. Two errors show up:
Error: COMP96_0015: addsub_16.vhd : (85, 17): ';' expected.
Error: COMP96_0046: addsub_16.vhd : (85, 41): Sequential statement expected.
The errors all reference to the line
b_in <= (b) when add_sub = '0' else (b_2scomp);
However when I placed this outside the process, no error occurred; only when it's inside the process. Can someone please help me why this is and what I can do to solve it?
In addition, I know that normally port mapping is done between the architecture declaration and the begin statement of the architecture. The reason I placed them after the process is because I needed to make sure that b_in has the right signal before the other components can use it. I don't know if this is the right way to do it, but I hope it is. This is just in case you guys are wondering why I'm dong it like this. Thanks
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
entity addsub_16 is
port(
c_in : in STD_LOGIC;
enable : in std_logic;
reset : in std_logic;
clk : in std_logic;
add_sub : in STD_LOGIC;
a : in STD_LOGIC_VECTOR(15 downto 0);
b : in STD_LOGIC_VECTOR(15 downto 0);
c_out : out STD_LOGIC;
result : out STD_LOGIC_VECTOR(15 downto 0)
);
end addsub_16;
architecture addsub_16 of addsub_16 is
--Signal declarations to hold internal vectors a, b g, p, and carry
signal a_in : std_logic_vector(15 downto 0); --Holds input a
signal b_in : std_logic_vector(15 downto 0); --Holds input b if add_sub = 0. Otherwise, holds b_2scomp
signal b_2scomp : std_logic_vector(15 downto 0); --Holds the 2s complement of b
signal prop_in : std_logic_vector(15 downto 0); --Holds the propagate signals from CLAs
signal gen_in : std_logic_vector(15 downto 0); --Holds the generate signals from CLAs
signal carry_in : std_logic_vector(15 downto 0); --Holds the carry signal from carry_logic
signal temp_result : std_logic_vector(15 downto 0); --Holds the temporary result to be driven out
--Component declarations
component cla_4bit
port (
a, b : in std_logic_vector(3 downto 0);
gen, prop : out std_logic_vector(3 downto 0)
);
end component;
component carry_logic
port (
g, p : in std_logic_vector(15 downto 0);
c_in : in std_logic;
carry : out std_logic_vector(15 downto 0);
c_out : out std_logic
);
end component;
--Actual behavior of module
begin
--b_in <= (b) when add_sub = '0' else (b_2scomp);
process (clk, reset)
begin
if reset = '0' then --At reset, everything is 0
a_in <= (others => '0');
b_in <= (others => '0');
b_2scomp <= (others => '0');
temp_result <= (others => '0');
elsif (rising_edge(clk)) then --Read in data to components on rising edge
if enable = '1' then --Only if enable is on
a_in <= a;
b_2scomp <= ((not b) + '1');
b_in <= (b) when add_sub = '0' else (b_2scomp);
end if;
elsif (falling_edge(clk)) then --Drive out values on falling edge
for i in 0 to 15 loop
temp_result(i) <= a_in(i) xor b_in(i) xor carry_in(i);
end loop;
result <= temp_result;
end if;
end process;
--portmapping of the components here. I don't think it'd be necessary to include them, but let me know if they are needed.
The ternary operator .. when .. else .. is not allowed inside a process block prior to VHDL-2008.
Solution 1: Write an ordinary if .. then .. else .. end if statement
Solution 2: Enable VHDL-2008 support in your tool chain
Solution 3: Write a function, lets say ite (if-then-else), which performs the ternary operation.