digital circuit scheme to vhdl ring counter multiplexer - vhdl

I have this circuit that I want to implement in vhdl. There is a clock input and which clock event changes the 1 pin output sequentially. 0001 -> 0010 -> 0100 -> 1000 ...
I wondering what is the correct approach to do that. I could do that with multiple ifs and elsifs and an integer counter signal. Sorry for the noob question, is there a name for this kind of circuit?

It appears from your description this intended to be a ring counter. Your gates seem superfluous:
library ieee;
use ieee.std_logic_1164.all;
entity ring_counter is
port (
clk: in std_logic;
q: out std_logic_vector (0 to 3)
);
end entity;
architecture your_representation of ring_counter is
signal qint: std_logic_vector (0 to 3) := "0000";
signal all_zero: std_logic;
begin
YOURS:
process(clk)
begin
if rising_edge(clk) then
qint(0) <= qint(3);
qint(1) <= all_zero or qint(0);
qint (2 to 3) <= qint(1 to 2);
end if;
end process;
all_zero <= '1' when qint = "0000" else
'0';
q <= (qint(0) or all_zero) & qint(1 to 3);
end architecture;
With a test bench:
library ieee;
use ieee.std_logic_1164.all;
entity ring_counter_tb is
end entity;
architecture foo of ring_counter_tb is
signal clk: std_logic := '0';
signal q: std_logic_vector(0 to 3);
begin
DUT:
entity work.ring_counter(your_representation)
port map (
clk => clk,
q => q
);
CLOCK:
process
begin
wait for 10 ns;
clk <= not clk;
if Now > 200 ns then
wait;
end if;
end process;
end architecture;
Gives:
(clickable)
While a classic ring counter:
architecture classic of ring_counter is
signal qint: std_logic_vector (0 to 3) := "1000";
begin
RING_CTR:
process(clk)
begin
if rising_edge(clk) then
qint <= qint(3) & qint(0 to 2);
end if;
end process;
q <= qint;
end architecture;
(and modified test bench):
entity work.ring_counter(classic)
gives:
(clickable)
And the starting phase is all in the initial condition.

Related

I’m new to coding in VHDL and don’t understand why my code will not show an output when simulating on a VWF file

My code will not simulate an output when running the VWF file.
I have tried changing the code several different time and don't really understand what I'm doing wrong.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter_JM is
Port (
up_down : in std_logic;
LED : out std_logic;
Q : Buffer integer Range 0 to 7);
end Counter_JM;
architecture archi of Counter_JM is
Begin
-- up/down counter
process (up_down)
begin
if (Q=7) then
Q<=0;
end if;
if (up_down = '1') then
Q <= Q + 1;
else
Q<=0;
end if;
if (Q=0 or Q=1) then
LED <= '0';
else
LED <= '1';
end if;
end process;
end archi;
The LED output should show high for 4 cycles and low for 2 on the VWF file
I don't know why you use up_down. But as Oldfart said, you don't have a clock. I have simplified and modified your code (it works for me (in modelsim):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter_JM is
Port (
clk: in std_logic;
up_down : in std_logic;
LED : out std_logic
);
end Counter_JM;
architecture archi of Counter_JM is
Begin
process (clk)
variable Q: integer range 0 to 7;
begin
if rising_edge(clk) then
-- up/down counter
Q := Q + 1;
if Q=1 or Q=2 then
LED <= '0';
else
LED <= '1';
end if;
if Q = 7 then
Q := 0;
end if;
end if;
end process;
end archi;
and also created/generated a simple testbench here :
`-- Testbench automatically generated online
-- at http://vhdl.lapinoo.net
-- Generation date : 7.6.2019 11:22:53 GMT
library ieee;
use ieee.std_logic_1164.all;
entity tb_Counter_JM is
end tb_Counter_JM;
architecture tb of tb_Counter_JM is
component Counter_JM
port (clk : in std_logic;
up_down : in std_logic;
LED : out std_logic);
end component;
signal clk : std_logic;
signal up_down : std_logic;
signal LED : std_logic;
constant TbPeriod : time := 1000 ns; -- EDIT Put right period here
signal TbClock : std_logic := '0';
signal TbSimEnded : std_logic := '0';
begin
dut : Counter_JM
port map (clk => clk,
up_down => up_down,
LED => LED);
-- Clock generation
TbClock <= not TbClock after TbPeriod/2 when TbSimEnded /= '1' else '0';
-- EDIT: Check that clk is really your main clock signal
clk <= TbClock;
stimuli : process
begin
-- EDIT Adapt initialization as needed
up_down <= '0';
-- EDIT Add stimuli here
wait for 100 * TbPeriod;
-- Stop the clock and hence terminate the simulation
TbSimEnded <= '1';
wait;
end process;
end tb;
-- Configuration block below is required by some simulators. Usually no need to edit.
configuration cfg_tb_Counter_JM of tb_Counter_JM is
for tb
end for;
end cfg_tb_Counter_JM;`

How to create a pseudo-random sequence with a 16 bit LFSR

I am trying to generate a random sequence of 16 bit.
The problem is that the output is getting undefined state. I feel that this is due to parallel processing in those xor statements. So I have put in delays but it still doesn't work.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity random_data_generator is
port (
por : in STD_LOGIC;
sys_clk : in STD_LOGIC;
random_flag : in STD_LOGIC;
random_data : out STD_LOGIC_vector (15 downto 0)
);
end random_data_generator;
architecture Behavioral of random_data_generator is
signal q : std_logic_vector(15 downto 0);
signal n1,n2,n3 : std_logic;
begin
process(sys_clk)
begin
if(por='0') then
q<= "1001101001101010";
elsif(falling_edge(sys_clk)) then
if(random_flag='1') then
n1<= q(15) xor q(13);
n2<= n1 xor q(11) after 10 ns;
n3<= n2 xor q(10) after 10 ns;
q<= q(14 downto 0) & n3 after 10 ns;
end if;
end if;
end process;
random_data <= q;
end Behavioral;
Making some small structural changes to your LFSR:
library ieee;
use ieee.std_logic_1164.all;
entity random_data_generator is
port (
por: in std_logic;
sys_clk: in std_logic;
random_flag: in std_logic;
random_data: out std_logic_vector (15 downto 0)
);
end entity random_data_generator;
architecture behavioral of random_data_generator is
signal q: std_logic_vector(15 downto 0);
signal n1, n2, n3: std_logic;
begin
process (por, sys_clk) -- ADDED por to sensitivity list
begin
if por = '0' then
q <= "1001101001101010";
elsif falling_edge(sys_clk) then
if random_flag = '1' then
-- REMOVED intermediary products as flip flops
q <= q(14 downto 0) & n3; -- REMOVED after 10 ns;
end if;
end if;
end process;
-- MOVED intermediary products to concurrent signal assignments:
n1 <= q(15) xor q(13);
n2 <= n1 xor q(11); -- REMOVED after 10 ns;
n3 <= n2 xor q(10); -- REMOVED after 10 ns;
random_data <= q;
end architecture behavioral;
These changes remove the n1, n2, and n3 flip flops by promoting those assignments to concurrent signal assignment statements. The fundamental issue generating 'U's is that these flip flops were not initialized. They were flip flops because their assignment was inside the if statement with an elsif condition on the falling edge of sys_clk.
Adding a testbench:
library ieee;
use ieee.std_logic_1164.all;
entity rng_tb is
end entity;
architecture foo of rng_tb is
signal por: std_logic;
signal sys_clk: std_logic := '0';
signal random_flag: std_logic;
signal random_data: std_logic_vector (15 downto 0);
begin
DUT:
entity work.random_data_generator
port map (
por => por,
sys_clk => sys_clk,
random_flag => random_flag,
random_data => random_data
);
CLOCK:
process
begin
wait for 5 ns;
sys_clk <= not sys_clk;
if now > 2800 ns then
wait;
end if;
end process;
STIMULI:
process
begin
por <= '1';
random_flag <= '0';
wait until falling_edge(sys_clk);
por <= '0';
wait until falling_edge(sys_clk);
wait for 1 ns;
por <= '1';
wait until falling_edge(sys_clk);
random_flag <= '1';
wait;
end process;
end architecture;
Analyzing both, elaborating and simulating the testbench gives:
Showing a pseudo-random sequence with a length longer than 16 using a 16 bit Linear Feedback Shift Register (LFSR).

VHDL up/down counter error counting

Im trying to make a counter which counts up to 3 then counts down to 0 etc..
example: 0 1 2 3 2 1 0 1 2 3 2 1 0...
What I did:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Counter is
port(
Clock: in std_logic;
Reset: in std_logic;
Output: out std_logic_vector(0 to 1 ));
end Counter;
architecture Behavioral of Counter is
signal temp: std_logic_vector(0 to 1);
signal down: std_logic := '0';
begin process(Clock,Reset)
begin
if Reset='0' then
temp <= "00";
down<= '0';
elsif(rising_edge(Clock)) then
if temp="11" then
down<= '1';
elsif temp="00" then
down<='0';
end if;
if down='0' then
temp <= temp +1;
else
temp <= temp-1;
end if;
end if;
end process;
Output <= temp;
end Behavioral;
Somehow the output is going from 3 to 0 without showing the middle numbers..
What is wrong?
You are not looking at all the signals: look at down to see what happens. Because you are using clocked/synchronous logic, down is changed in the clock cycle where temp is detected 3, so it will have effect one clock cycle later. I.e. when temp is 3, down will still be 0, thus (3+1) mod 4 = 0.
One possible solution is to be one step ahead of this: Change down one clock cycle earlier... when temp=2.
One other problem is that you are combining the non-standardized packages STD_LOGIC_ARITH and STD_LOGIC_UNSIGNED with logic arrays in reverse direction. That can give unpredictable results. Please use standardized packages. Example:
library ieee;
use ieee.STD_LOGIC_1164.ALL;
entity counter is
port(
clk : in std_logic;
rst_n : in std_logic;
output : out std_logic_vector(1 downto 0)
);
end entity;
architecture behavioral of counter is
use ieee.numeric_std.ALL;
signal temp : unsigned(output'range) := (others => '0');
signal down : std_logic := '0';
begin
process(clk, rst_n)
begin
if rst_n = '0' then -- why asynchronous reset??
temp <= (others => '0');
down <= '0';
elsif(rising_edge(clk)) then
if temp = 2 then
down <= '1';
elsif temp = 1 then
down <= '0';
end if;
if down = '0' then
temp <= temp + 1;
else
temp <= temp - 1;
end if;
end if;
end process;
output <= std_logic_vector(temp);
end architecture;
-
entity counter_tb is end entity;
library ieee;
use IEEE.STD_LOGIC_1164.ALL;
architecture behavioral of counter_tb is
signal clk : std_logic;
signal rst_n : std_logic;
signal output : std_logic_vector(1 downto 0);
begin
DUT: entity work.Counter
port map(
clk => clk,
rst_n => rst_n,
output => output
);
rst_n <= '1';
process
begin
clk <= '0', '1' after 1 ns;
wait for 2 ns;
end process;
end architecture;
Next time please add your test bench to form a complete set...
and please don't use 3-space indentation :( use 4, like everybody does)

No Output From Entity in ModelSim Simulator - VHDL

I have written a simple entity in VHDL to blink an LED and am trying to simulate it in ModelSim but am getting no transitions on the output.
Here is my HDL file for the LED_Blink entity:
Library IEEE;
use IEEE.Std_logic_1164.all;
entity LED_Blink is
generic (
g_SYSTEM_CLOCK_PERIOD : in time := 10 ns; -- 100 MHz clock period
g_LED_ON_TIME : in time := 1 sec
);
port(
system_clock : in Std_logic;
reset_fpga_L : in Std_logic;
led_out : out Std_logic
);
end entity LED_Blink;
architecture RTL of LED_Blink is
signal led_state : Std_logic;
constant COUNTER_RELOAD_VAL : natural := g_LED_ON_TIME/g_SYSTEM_CLOCK_PERIOD;
begin
process(reset_fpga_L, system_clock)
variable counter : natural range 0 to COUNTER_RELOAD_VAL := COUNTER_RELOAD_VAL;
begin
if reset_fpga_L = '0' then
counter := COUNTER_RELOAD_VAL;
led_state <= '0';
elsif rising_edge(system_clock) then
if counter = 0 then
led_state <= not led_state;
counter := COUNTER_RELOAD_VAL;
else
counter := counter - 1;
end if;
end if;
led_out <= led_state;
end process;
end architecture RTL;
And here is my test-bench:
Library IEEE;
use IEEE.Std_logic_1164.all;
entity LED_Blink_TB is
end entity LED_Blink_TB;
architecture RTL of LED_Blink_TB is
signal reset_fpga_L : Std_logic := '0';
signal system_clock : Std_logic := '0';
signal led_out : Std_logic := '0';
begin
G1: entity work.LED_Blink(RTL) port map(reset_fpga_L, system_clock, led_out);
CLK: process
begin
while now <= 5 sec loop
system_clock <= not system_clock;
wait for 5 ns;
end loop;
wait;
end process CLK;
STIM: process
begin
reset_fpga_L <= '0';
wait for 100 ns;
reset_fpga_L <= '1';
wait for 4 sec;
reset_fpga_L <= '0';
wait for 50 ns;
reset_fpga_L <= '1';
wait;
end process STIM;
end architecture RTL;
I can't figure out why I'm not seeing any transitions on led_out when I run my test-bench in the simulator. I've taken care to add the waves for system_clock, reset_fpga_L, and led_out to the trace view. Do you see anything in my code that might be an issue? Thanks for your help.
A second form of the testbench can be used make generation of inputs to LED_Blink depend on the values supplied as generics:
library ieee;
use ieee.std_logic_1164.all;
entity led_blink_tb is
end entity;
architecture foo of led_blink_tb is
constant CLK_PERIOD: time := 100 ms;
constant LED_ON: time := 500 ms;
signal clk: std_logic := '0';
signal reset_n: std_logic;
signal led: std_logic;
begin
DUT:
entity work.led_blink
generic map ( CLK_PERIOD, LED_ON)
port map (
system_clock => clk,
reset_fpga_l => reset_n,
led_out => led
);
CLOCK:
process
begin
wait for CLK_PERIOD/2;
clk <= not clk;
if now > 2.5 sec then
wait;
end if;
end process;
STIMULI:
process
begin
reset_n <= '0';
wait for CLK_PERIOD * 2;
reset_n <= '1';
wait;
end process;
end architecture;
The idea, both the testbench and the model depend on constants supplied as generics making changing the parameters require less work.
Also note the association list in the port map uses named association.
If we take a look at the original testbench port map:
G1: entity work.LED_Blink(RTL) port map(reset_fpga_L, system_clock, led_out);
We see that the first positional association to the formal system_clock is associated with the actual reset_fpga_L while the second positional association representing formal reset_fpga_L is associated with the actual system_clock.
The two actual associations are in reversed order.

Applying 7-segment display using counter VHDL

I am beginner and it's my first VHDL code
It's a code to apply 7_segment display using counter
When compiling the 2 codes the main code had no errors while the test bench code gave 6 errors
any help ?
Main code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY counter IS
port (clk,rst: IN std_logic;
count: OUT std_logic_vector(6 downto 0) );
END counter;
ARCHITECTURE rtl OF counter IS
signalcount_sig: integer range 0 to 7;
BEGIN
PROCESS(clk,rst)
begin
if(rst='1')then
count_sig<=0;
elsif(rising_edge (clk))then
count_sig<= count_sig+1;
end if;
if (count_sig=0) then count <= "1000000";
elsif (count_sig=1) then count <= "1111001";
elsif (count_sig=2) then count <= "0100100";
elsif (count_sig=3) then count <= "0110000";
elsif (count_sig=4) then count <= "0011001";
elsif (count_sig=5) then count <= "0010010";
elsif (count_sig=6) then count <= "0000010";
elsif (count_sig=7) then count <= "1111000";
end if;
end PROCESS;
END rtl;
Test bench code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY test_counter IS
END test_counter;
ARCHITECTURE beh OF test_counter IS
COMPONENT counter IS
port (clk, rst: in std_logic;
count: out std_logic_vector(6 downto 0));
END counter;
SIGNAL clk, rst: std_logic;
SIGNAL count: std_logic_vector(6 downto 0);
BEGIN
V1: counter PORT MAP
(clk<=clk ,
rst<=rst ,
count<=count);
clock : PROCESS
begin
wait for 5 ns; clk<= not clk;
end PROCESS clock;
reset : PROCESS
begin
rst<= '1';
wait for 10 ns; rst<= '0';
wait for 80 ns;
end PROCESS reset;
END beh;
In the test bench code, the component declaration end is not to be END counter; but:
END component counter;
or just:
END component;
For the component instantiation, then mapping from port name (formal) to signal (actual) does not use <= but =>, so the code instantiation should be:
V1: counter PORT MAP
(clk => clk,
rst => rst,
count => count);

Resources