-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathled_blink.v
119 lines (97 loc) · 3.04 KB
/
led_blink.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// LED blink verilog Code from Nandland
module tutorial_led_blink
(
i_clock,
i_enable,
i_switch_1,
i_switch_2,
o_led_drive
);
input i_clock;
input i_enable;
input i_switch_1;
input i_switch_2;
output o_led_drive;
// Constants (parameters) to create the frequencies needed:
// Input clock is 25 kHz, chosen arbitrarily.
// Formula is: (25 kHz / 100 Hz * 50% duty cycle)
// So for 100 Hz: 25,000 / 100 * 0.5 = 125
parameter c_CNT_100HZ = 125;
parameter c_CNT_50HZ = 250;
parameter c_CNT_10HZ = 1250;
parameter c_CNT_1HZ = 12500;
// These signals will be the counters:
reg [31:0] r_CNT_100HZ = 0;
reg [31:0] r_CNT_50HZ = 0;
reg [31:0] r_CNT_10HZ = 0;
reg [31:0] r_CNT_1HZ = 0;
// These signals will toggle at the frequencies needed:
reg r_TOGGLE_100HZ = 1'b0;
reg r_TOGGLE_50HZ = 1'b0;
reg r_TOGGLE_10HZ = 1'b0;
reg r_TOGGLE_1HZ = 1'b0;
// One bit select
reg r_LED_SELECT;
wire w_LED_SELECT;
begin
// All always blocks toggle a specific signal at a different frequency.
// They all run continuously even if the switches are
// not selecting their particular output.
always @ (posedge i_clock)
begin
if (r_CNT_100HZ == c_CNT_100HZ-1) // -1, since counter starts at 0
begin
r_TOGGLE_100HZ <= !r_TOGGLE_100HZ;
r_CNT_100HZ <= 0;
end
else
r_CNT_100HZ <= r_CNT_100HZ + 1;
end
always @ (posedge i_clock)
begin
if (r_CNT_50HZ == c_CNT_50HZ-1) // -1, since counter starts at 0
begin
r_TOGGLE_50HZ <= !r_TOGGLE_50HZ;
r_CNT_50HZ <= 0;
end
else
r_CNT_50HZ <= r_CNT_50HZ + 1;
end
always @ (posedge i_clock)
begin
if (r_CNT_10HZ == c_CNT_10HZ-1) // -1, since counter starts at 0
begin
r_TOGGLE_10HZ <= !r_TOGGLE_10HZ;
r_CNT_10HZ <= 0;
end
else
r_CNT_10HZ <= r_CNT_10HZ + 1;
end
always @ (posedge i_clock)
begin
if (r_CNT_1HZ == c_CNT_1HZ-1) // -1, since counter starts at 0
begin
r_TOGGLE_1HZ <= !r_TOGGLE_1HZ;
r_CNT_1HZ <= 0;
end
else
r_CNT_1HZ <= r_CNT_1HZ + 1;
end
// Create a multiplexer based on switch inputs
always @ (*)
begin
case ({i_switch_1, i_switch_2}) // Concatenation Operator { }
2'b11 : r_LED_SELECT <= r_TOGGLE_1HZ;
2'b10 : r_LED_SELECT <= r_TOGGLE_10HZ;
2'b01 : r_LED_SELECT <= r_TOGGLE_50HZ;
2'b00 : r_LED_SELECT <= r_TOGGLE_100HZ;
endcase
end
assign o_led_drive = r_LED_SELECT & i_enable;
// Alternative way to design multiplexer (same as above):
// More compact, but harder to read, especially to those new to Verilog
// assign w_LED_SELECT = i_switch_1 ? (i_switch_2 ? r_TOGGLE_1HZ : r_TOGGLE_10HZ) :
(i_switch_2 ? r_TOGGLE_50HZ : r_TOGGLE_100HZ);
// assign o_led_drive = w_LED_SELECT & i_enable;
end
endmodule