Digital Design 2 Lab: An-Najah University
Digital Design 2 Lab: An-Najah University
Digital Design 2 Lab: An-Najah University
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
10
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
2.1
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.
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
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.
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.
code 4: direction
1
direction:process(clk)
begin
3
4
5
6
7
8
9
10
11
12
13
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;
2.4
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.
----------------------------------------------------------------------------------- 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
26
27
28
29
30
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
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
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
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.
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
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
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
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
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
26
27
28
29
30
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
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