7 segment up counter for DE0-Nano

In my previous post I have mentioned about the 7-segment display that I soldered for my DE0-Nano board. Now it’s time to get a simple program going in it. Here I will be implementing a up counter in the FPGA fabric. Conventional truth tables and karnaugh maps have been used to derive the logic for this simple task. Also in this demo you will understand how to develop a design module by module and how to combine them together using VHDL.

LED-7-Segment-Display

Following are the VHDL entries:

dflipflip.vhd

library IEEE;
use IEEE.std_logic_1164.all;

--Implemented here is a D-Flip Flop with synchronous reset.

entity dflipflop is
port (D, Clk, Reset: in std_logic;
		Q, Qbar: out std_logic);
end entity dflipflop;

architecture behaviour of dflipflop is
begin
p0: process (Clk) is
variable state: std_logic;
begin
	if (Reset = '0') then
		state := '0';
	elsif rising_edge(Clk) then
		state := D;
	end if;
	Q <= state;
	Qbar <= not (state);
end process p0;
end architecture behaviour;

counter.vhd

library IEEE;
use IEEE.std_logic_1164.all;

--Implemented below is a BCD up counter using simple logic.
--Pre implemted D-flip flop with a reset is also used for the task.

entity counter is
port (Clock, Rst: in std_logic;
		Q0, Q1, Q2, Q3: out std_logic);			
end entity counter;

architecture behaviour of counter is

component dflipflop is
port (D, Clk, Reset: in std_logic;
		Q, Qbar: out std_logic);
end component dflipflop;

signal D0s, D1s, D2s, D3s, Q0s, Q1s, Q2s, Q3s, Q0bars, Q1bars, Q2bars, Q3bars: std_logic;

begin
Q0 <= Q0s;
Q1 <= Q1s;
Q2 <= Q2s;
Q3 <= Q3s;

df0: dflipflop port map (D0s, Clock, Rst, Q0s, Q0bars);
df1: dflipflop port map (D1s, Clock, Rst, Q1s, Q1bars);
df2: dflipflop port map (D2s, Clock, Rst, Q2s, Q2bars);
df3: dflipflop port map (D3s, Clock, Rst, Q3s, Q3bars);

D0s <= Q0bars;
D1s <= (Q1bars and Q0s and Q3bars) or (Q1s and Q0bars);
D2s <= (Q1bars and Q2s) or (Q0bars and Q2s) or (Q1s and Q0s and Q2bars);
D3s <= (Q1s and Q0s and Q2s) or (Q3s and Q0bars);

end architecture behaviour;

drive_all.vhd

library IEEE;
use IEEE.std_logic_1164.all;

-- Implemented here is the BCD to 7 segment converter. 

entity drive_all is
	port (Q0, Q1, Q2, Q3: in std_logic; -- Q0 >> LSB
			a, b, c, d, e, f, g: out std_logic);
end entity drive_all;

architecture behaviour of drive_all is
begin
	a <= Q1 or Q3 or (Q2 and Q0) or ((not (Q0)) and (not (Q2)));
	b <= (not (Q2)) or (Q1 and Q0) or ((not (Q1)) and (not (Q0)));
	c <= (not (Q1)) or Q0 or Q2;
	d <= ((not (Q0)) and Q1) or ((not (Q0)) and (not (Q2))) or ((not (Q1)) and Q0 and Q2) or ((not (Q3)) and (not(Q2)) and Q1);
	e <= ((not (Q0)) and (not(Q2))) or ((not (Q0)) and Q1);
	f <= Q3 or ((not (Q1)) and (not (Q0))) or (Q2 and (not (Q1))) or (Q2 and (not(Q0)));
	g <= Q3 or (Q1 and (not (Q0))) or (Q2 and (not (Q1))) or ((not (Q3)) and (not(Q2)) and Q1);

end architecture behaviour;

svnsegment.vhd

	library IEEE;
	use IEEE.std_logic_1164.all;

	-- Implemented below is the combination of required modules for
	-- a 7 segment up counter

	entity svnsegment is
	port (Clk, Rst: in std_logic;
			a, b, c, d, e, f, g: out std_logic);
	end entity svnsegment;

	architecture behavior of svnsegment is

	component drive_all is
	port (Q0, Q1, Q2, Q3: in std_logic;
				a, b, c, d, e, f, g: out std_logic);
	end component drive_all;

	component counter is
	port (Clock, Rst: in std_logic;
			Q0, Q1, Q2, Q3: out std_logic);
	end component counter;

	signal C0, C1, C2, C3: std_logic;

	begin

	cntr0: counter port map (Clk, Rst, C0, C1, C2, C3);
	m0: drive_all port map (C0, C1, C2, C3, a, b, c, d, e, f, g);

	end architecture behavior;

Following pin assignments have been made,

pin

The clock is supplied through a Push Button.

Following is a demo.

Note: Here I am using a Common Cathode seven segment display. If you want to use a Common Anode one simple put not gates to the whole logic blocks driving a ~ g outputs in drive_all.vhd.

Thank you.

6 comments

  1. hey there,
    in your dflipflip.vhd, there is a little “mistake”
    in your process sensivity list, the reset is missing so
    p0: process (Clk) is
    should be
    p0: process (Clk, reset) is

    however in this example it does not matter, because the synthesis would be the same, but if you make more complicated processes, you could encounter problems if you dont specify all signals, which should be react on!

    And my another thought, why do you need an asynchronous reset in a d flip-flop. It doesn’t make much sense to me.

    1. Thank you for the comment. I have not included the ‘reset’ in the process’s sensitivity list to make sure that I only go into the process when there is a clock pulse. Even the reset should be clocked in. I’m still new to vhdl, I post as I learn, I’ll consult some veteran and come back to you.

      For your 2nd question, sometimes in applications you need to change the initial state of the d-ff independent to the clock. It is just another implementation. May not be standard. That is why there is sometimes a asynchronous reset. But here it is not asynchronous.

      1. I am not a vhdl Veteran for sure 🙂 . But your Code would (is) very strange. Your Reset is not Synchronous for sure, because it CAN react on reset anytime.
        So the correct reset-synchronous d-flip-flop should look like this. But as i said before, your implementation is asynchronous for sure, it is just not specified correctly, yet the synthesis process will manage it without mistake.

        p0: process (Clk) is
        variable state: std_logic;
        begin
        if rising_edge(Clk) then
        if (Reset = ‘0’) then
        state := ‘0’;
        else
        state := D;
        end if;
        end if;
        Q <= state;
        Qbar <= not (state);
        end process p0;

      2. Thank you man. So even-though I do not include the reset in the sensitivity list it would still trigger the process. I will look into this later. Could not work much on VHDL recently. Thank you again for finding a issue and providing the solution.

  2. hey there,

    can u describe how to interface seven segment display with De0 nano board. I think u had interfaced this display using GPIOs of De0 nano. So my doubt is can we directly interface seven segment display with Deo nano board. Since GPIOs provides arround 3.3v output so what are selected values of registers. one more thing what is max current provided by GPIOs of DEO nano board and how that current is used for seven segment display.

    1. Hello,

      You can use 330 Ohm resistors to limit currents. Even 1k would work. However, the best way would be to drive the 7 segment through some current drives.

      Please check the chip datasheet for pin max current. I think that is configurable.

      Hope I helped.

      Thanx!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s