Digital Design 2 Lab: An-Najah University

Download as pdf or txt
Download as pdf or txt
You are on page 1of 17

Digital Design 2 Lab

An-Najah University
Computer Engineering Department

Sudqi Jawabreh
Laith Abu Khader

summry
this is the sum of every thing.

Contents
Summery

1 Introduction

2 Procedure
2.1 Auto up-down counter . . . . . . .
2.2 push button counter . . . . . . . .
2.3 rotary counter . . . . . . . . . . . .
2.4 output on seven Segments display .
2.5 Conclusion . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

1
1
2
3
4
9

A auto up-down counter

10

B push button counter

11

C rotary counter

12

Introduction

inputs and outputs devices provid an interaction with the user which is essintial in most of embeded systems.in
this experiment we will build a counter and control it using different inputs like push buttons ,swichtes and
rotery and in the same time we will use leds and seven segment displays to show the result.

Procedure

in this lab we will use :


ISE Design Suite by Xilnix.
Spartan 3E Board.
the experiment consists of 4 parts :

2.1

Auto up-down counter

auto up-down counter is a 4 bit counter that counts every one second either up or down according to the
input signal up-down and it goes back to zero when the reset signal is activated as shown in Figure 1.

Figure 1: auto updown counter abstract


first we will create the counter it self without worrying about the speed of the clk as showon in code 1.
code 1: 4 bit counter with reset and updown
1
2
3
4
5
6
7
8
9
10
11
12
13
14

process(clk1,reset,updown)
variable count:std_logic_vector(3 downto 0):="0000";
begin
if(reset=1 )then
count:="0000";
elsif( clk1event and clk1=1 )then
if( updown=1)then
count:=count+1;
elsif(updown=0)then
count:=count-1;
end if;
end if;
cnt<=count;
end process;

for clk we create a process to divide the clk that comes from the spartan board which is 50mHz to 1H so
every second the counter counts as shown in code 2.
code 2: clock divider process
1
2
3
4
5
6
7
8
9
10
11
12

process(clk)
variable temp: integer range 0 to 25000000 :=0;
begin
if(clkevent and clk=1)then
temp:=temp+1;
if(temp=24999999)then
clk1<=1;
else
clk1<=0;
end if;
end if;
end process;

then we will take the clock generated by clock divider process and connect it to the counter process so the
overall code will be as shown in the appendix A.
in the synthesizing process we will map the counter output to 4 leds and each of reset and updown input
to a switch.

2.2

push button counter

instead of making the counter counts every second we want user control the count number by using a push
button but the push doesnt produce a very clean signal because when the user push the button it will make
a bouncing so it will appear as multiple pushes rather than one as shown in the figure 2.

Figure 2: signal produced by push button


to solve the debouncing problem we have multiple choices which are :
connect the signal to schmmit trigger buffer.
connect the signal to 555 timer on one shoot mode.
debounce the signal using the software.
since it is hard to add an addittional component to the sparatn 3e board we used to solve it in software.the
software solution depends on wait enough time for the signal unitl it settels down so we can have a clear
signal.to do it in vhdl we will we should count make counter that counts for specific amount of time so we
used the the clk divider process we used in auto up-down counter in section 1 with some changes.
2

code 3: delay process


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

process(clk1,reset,updown)
process(clk,pb_in)
variable temp: integer range 0 to rc :=0;
variable pb_old : std_logic:=0;
variable t_on:std_logic:=0;
begin
if(clkevent and clk=1)then
if(t_on=1)then
temp:=temp+1;
if(temp=749999)then
t_on:=0;
end if;
elsif(t_on=0)then
if(pb_old /= pb_in)then
t_on:=1;
clk1<=not(clk1);
end if;
end if;
pb_old:=pb_in;
end if;
end process;

as shown in code 3 we count for 3ms so the bouncing will end and the value will be stable,but the time
depends on how quick the user pushes the button.the output signal will be the input clk to the counter
process which is the same process in 1. the final code will be as shown in appendix B.

2.3

rotary counter

rotary input consist of two buttons . Because rotary shape doesnt look as a regular shape it will close on
of the buttons before the other so the rotation direction is determined by the values of the button signals
however the signals are not clean the have some bouncing so we have to eliminate the bouncing before using
the signals to control the counter.we can use the same process in section 2.2 but in this part we used different
approach.

Figure 3: signal generated by rotary with bouncing

code 4: direction
1

direction:process(clk)

begin

3
4
5
6
7
8
9
10
11
12
13

if(clkevent and clk=1)then


old<=q1;
if(q1 =1 and old=0) then
r_event<=1;
rotate_left<=q2;
else
r_event<=0;
rotate_left<=rotate_left;
end if;
end if;

14
15

end process;

so to control the counter it should take more two inputs which are rotate direction and rotate event to
indicate there is a rotation as shown in code 5.
code 5: counter triggered with rotate signal
1
2
3
4
5
6
7
8
9
10
11
12
13
14

counter:process(r_event,reset,rotate_left)
variable count:std_logic_vector(3 downto 0):="0000";
begin
if(reset=1 )then
count:="0000";
elsif( r_eventevent and r_event=1 )then
if( rotate_left=1)then
count:=count-1;
elsif(rotate_left=0)then
count:=count+1;
end if;
end if;
cnt<=count;
end process;

the overall code will be as shown in appendix C.

2.4

output on seven Segments display

seven segment display consists of multiple leds. the number displayed on it by turning some of leds on and
others off.table in figure 4 shows the the truth table of seven segment decoder.

Figure 4: seven segment decoder truth table


we implemented the table in vhdl as shown in code 6 in a component
code 6: 7 segment decoder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

----------------------------------------------------------------------------------- Company:
-- Engineer:
--- Create Date: 14:42:49 02/23/2016
-- Design Name:
-- Module Name: decoder - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--- Dependencies:
--- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
----------------------------------------------------------------------------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

22
23
24
25

-- Uncomment the following library declaration if using


-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

26
27
28
29
30

-- Uncomment the following library declaration if instantiating


-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

31
32
33
34
35
36

entity decoder is
Port ( counter : in STD_LOGIC_VECTOR (3 downto 0);
segmantout: out std_logic_vector(6 downto 0)
);
end decoder;

37

38
39
40
41

architecture Behavioral of decoder is


signal decoded :std_logic_vector(6 downto 0);
begin
process(counter)

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

begin
case counter is
when "0000" => decoded<="1111110";
when "0001" => decoded<="0110000";
when "0010" => decoded<="1101101";
when "0011" => decoded<="1111001";
when "0100" => decoded<="0110011";
when "0101" => decoded<="1011011";
when "0110" => decoded<="1011111";
when "0111" => decoded<="1110000";
when "1000" => decoded<="1111111";
when "1001" => decoded<="1111011";
when others => decoded<=decoded;
end case;
end process;
segmantout<=decoded;
end Behavioral;

because seven segment display one digit we modified our counter to be as bcd counter .to make a 2 digit
bcd counter we made 2 counter of the same process but we made the first process drives the second one so
when it reaches it limits it triggers the second counter. as shown code 7.
code 7: 2 digit counter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

----------------------------------------------------------------------------------- Company:
-- Engineer:
--- Create Date: 14:49:04 02/23/2016
-- Design Name:
-- Module Name: updowncounter - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--- Dependencies:
--- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
----------------------------------------------------------------------------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

22
23
24

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

25
26
27
28

-- Uncomment the following library declaration if using


-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

29
30
31
32
33

use ieee.std_logic_unsigned.all;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

34
35
36
37
38
39
40
41
42

entity updowncounter is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
updown : in STD_LOGIC;
segmant : out STD_LOGIC_VECTOR (6 downto 0);
led:out std_logic_vector(3 downto 0);
c : out std_logic);
end updowncounter;

43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

architecture Behavioral of updowncounter is


signal clk1 : std_logic;
signal cnt : std_logic_vector ( 3 downto 0);
signal trigger : std_logic;
signal cnt2:std_logic_vector(3 downto 0);
signal dec_in: std_logic_vector (3 downto 0);
signal oldc: std_logic:=0;
component decoder
Port ( counter : in STD_LOGIC_VECTOR (3 downto 0);
segmantout: out std_logic_vector(6 downto 0)
);
end component;

58
59

begin

60
61
62

process(clk)
variable temp: integer range 0 to 25000000 :=0;

63
64
65
66

begin
if(clkevent and clk=1)then

67
68
69
70
71
72
73
74

temp:=temp+1;
if(temp=24999999)then
clk1<=1;
else
clk1<=0;
end if;
end if;

75
76

end process;

77
78
79
80
81
82
83
84

digit1:process(clk1,reset,updown)
variable count:std_logic_vector(3 downto 0):="0000";
begin
if(reset=1 )then
count:="0000";
elsif( clk1event and clk1=1 )then

85

trigger<=0;

86
87
88
89

if( updown=1)then
count:=count+1;
if(count="1010")then

90
91
92

count:="0000";
trigger<=1;

93
94
95
96
97
98
99

end if;
elsif(updown=0)then
count:=count-1;
if(count="1111")then
count:="1001";
trigger<=1;

100
101
102
103
104
105

end if;
end if;
end if;
cnt<=count;
end process;

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

digit2: process(trigger,reset,updown)
variable count:std_logic_vector(3 downto 0):="0000";
begin
if(reset=1 )then
count:="0000";
elsif( triggerevent and trigger=1 )then
if( updown=1)then
count:=count+1;
if(count="1010")then
count:="0000";
end if;
elsif(updown=0)then
count:=count-1;
if(count="1111")then
count:="1001";
end if;
end if;
end if;
cnt2<=count;
end process;

131
132
133
134
135
136
137
138
139
140

mult:process(clk)
variable count:integer range 0 to 250000:=0;
begin
if(clkevent and clk=1) then
count:= count +1;
if (count = 249999)then
if(oldc = 0 )then

141
142
143
144
145
146
147

dec_in<=cnt2;
elsif(oldc=1)then
dec_in<=cnt;
end if;
oldc<=not(oldc);
count:=0;
end if;

148
149

end if;

150
151

end process;

152
153
154
155
156
157

led<=cnt;
c<=oldc;
d1:decoder
port map(dec_in,segmant);

158
159
160

end Behavioral;

2.5

Conclusion

input devices are essential to most of embedded systems but we have to make it works probably by study
how they work and insure to debounce them before using them in the system.

auto up-down counter


code 8: auto up-down counter module

1
2
3
4
5

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

6
7
8
9
10
11
12

entity autocounter is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
updown : in STD_LOGIC;
cnt : out STD_LOGIC_VECTOR (3 downto 0));
end counter;

13
14
15
16

architecture Behavioral of autocounter is


signal clk1 : std_logic;
begin

17
18
19
20
21
22
23
24
25
26
27
28
29

process(clk)
variable temp: integer range 0 to 25000000 :=0;
begin
if(clkevent and clk=1)then
temp:=temp+1;
if(temp=24999999)then
clk1<=1;
else
clk1<=0;
end if;
end if;
end process;

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

process(clk1,reset,updown)
variable count:std_logic_vector(3 downto 0):="0000";
begin
if(reset=1 )then
count:="0000";
elsif( clk1event and clk1=1 )then
if( updown=1)then
count:=count+1;
elsif(updown=0)then
count:=count-1;
end if;
end if;
cnt<=count;
end process;
end Behavioral;

10

push button counter


code 9: push button counter module

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

----------------------------------------------------------------------------------- Company:
-- Engineer:
--- Create Date: 15:04:09 02/16/2016
-- Design Name:
-- Module Name: counter - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--- Dependencies:
--- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
----------------------------------------------------------------------------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

22
23
24
25
26
27
28
29
30

-- Uncomment the following library declaration if using


-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
use ieee.std_logic_unsigned.all;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

31
32
33
34
35
36
37
38

entity counter is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
updown : in STD_LOGIC;
pb_in:in std_logic;
cnt : out STD_LOGIC_VECTOR (3 downto 0));
end counter;

39
40
41
42

architecture Behavioral of counter is


signal clk1 : std_logic;
begin

43
44
45
46
47
48
49
50
51
52

process(clk,pb_in)
variable temp: integer range 0 to 750000 :=0;
variable pb_old : std_logic:=0;
variable t_on:std_logic:=0;
begin
if(clkevent and clk=1)then
if(t_on=1)then
temp:=temp+1;
if(temp=749999)then

11

53
54
55
56
57
58
59
60
61
62
63

t_on:=0;
end if;
elsif(t_on=0)then
if(pb_old /= pb_in)then
t_on:=1;
clk1<=not(clk1);
end if;
end if;
pb_old:=pb_in;
end if;
end process;

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

process(clk1,reset,updown)
variable count:std_logic_vector(3 downto 0):="0000";
begin
if(reset=1 )then
count:="0000";
elsif( clk1event and clk1=1 )then
if( updown=1)then
count:=count+1;
elsif(updown=0)then
count:=count-1;
end if;
end if;
cnt<=count;
end process;
end Behavioral;

rotary counter
code 10: rotary counter module

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

----------------------------------------------------------------------------------- Company:
-- Engineer:
--- Create Date: 14:46:00 02/21/2016
-- Design Name:
-- Module Name: roterycounter - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--- Dependencies:
--- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
----------------------------------------------------------------------------------library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

12

23
24
25

-- Uncomment the following library declaration if using


-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

26
27
28
29
30

-- Uncomment the following library declaration if instantiating


-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

31
32
33
34
35
36
37
38

entity roterycounter is
Port ( a_in : in STD_LOGIC;
b_in : in STD_LOGIC;
reset : in STD_LOGIC;
clk : in STD_LOGIC;
cnt : out STD_LOGIC_VECTOR (3 downto 0));
end roterycounter;

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

architecture Behavioral of roterycounter is


signal r_in: std_logic_vector(1 downto 0);
signal q1,q2:std_logic;
signal old:std_logic;
signal r_event,rotate_left:std_logic;
begin
rotery_filter: process (clk)
begin
if clkevent and clk=1 then
r_in<=a_in & b_in;
case r_in is
when "00"=> q1<=0;
q2<=q2;
when "01"=> q1<=q1;
q2<=1;
when "10"=>q1<=q1;
q2<=0;
when "11" => q1<=1;
q2<=q2;
when others => q1<=q1;
q2<=q2;
end case;
end if;
end process;

64
65
66
67
68
69
70
71
72
73
74
75
76
77

direction:process(clk)
begin
old<=q1;
if(clkevent and clk=1)then
if(q1 =1 and old=0) then
r_event<=1;
rotate_left<=q2;
else
r_event<=0;
rotate_left<=rotate_left;
end if;
end if;

78

13

79

end process;

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

counter:process(r_event,reset,rotate_left)
variable count:std_logic_vector(3 downto 0):="0000";
begin
if(reset=1 )then
count:="0000";
elsif( r_eventevent and r_event=1 )then
if( rotate_left=1)then
count:=count-1;
elsif(rotate_left=0)then
count:=count+1;
end if;
end if;
cnt<=count;
end process;
end Behavioral;

14

You might also like