-
Notifications
You must be signed in to change notification settings - Fork 0
/
HC595_driver.v
136 lines (118 loc) · 3.44 KB
/
HC595_driver.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
`timescale 1ns / 1ps
//74HC595 driver
//parallel to serial
module HC595_driver(
clk, rst_n, p_data, s_data, sclk, rclk
);
input wire clk;
input wire rst_n;
input wire [15:0] p_data;//p_data[15:8] = seg[7:0], p_data[7:0] = sel[7:0]
output wire sclk;//74HC595 read 1 bit from serial port (s_data) every posedge of sclk. Frequency should be 12.5MHz according to datasheet.
//for successful reading, 1bit data need to stay still until the next posedge of sclk come, the only time we can change it is while in the vicinity of negedge.
output reg s_data;//serial data output
output reg rclk;//save bits and output to the parallel port at rclk's posedge(impulse)
//clk_divider: 50MHz to 12.5MHz
reg [1:0] divider_cnt;
always @(posedge clk, negedge rst_n) begin
if(!rst_n)
divider_cnt <= 0;
else if(divider_cnt == 3)
divider_cnt <= 0;
else
divider_cnt <= divider_cnt + 1;
end
assign sclk = (divider_cnt == 1 | divider_cnt == 2)?1:0;
wire sclk_impulse;
assign sclk_impulse = (divider_cnt == 1);
reg [4:0] sclk_impulse_cnt;
always @(posedge clk, negedge rst_n) begin
if(!rst_n)
sclk_impulse_cnt <= 0;
else if(sclk_impulse_cnt == 17)
sclk_impulse_cnt <= 0;
else if(sclk_impulse == 1)
sclk_impulse_cnt <= sclk_impulse_cnt + 1;
else
sclk_impulse_cnt <= sclk_impulse_cnt;
end
always @(*) begin
case (sclk_impulse_cnt)
0: begin
rclk <= 1;
s_data <= 1;
end
1: begin
rclk <= 0;
s_data <= p_data[15];
end
2: begin
rclk <= 0;
s_data <= p_data[14];
end
3: begin
rclk <= 0;
s_data <= p_data[13];
end
4: begin
rclk <= 0;
s_data <= p_data[12];
end
5: begin
rclk <= 0;
s_data <= p_data[11];
end
6: begin
rclk <= 0;
s_data <= p_data[10];
end
7: begin
rclk <= 0;
s_data <= p_data[9];
end
8: begin
rclk <= 0;
s_data <= p_data[8];
end
9: begin
rclk <= 0;
s_data <= p_data[7];
end
10: begin
rclk <= 0;
s_data <= p_data[6];
end
11: begin
rclk <= 0;
s_data <= p_data[5];
end
12: begin
rclk <= 0;
s_data <= p_data[4];
end
13: begin
rclk <= 0;
s_data <= p_data[3];
end
14: begin
rclk <= 0;
s_data <= p_data[2];
end
15: begin
rclk <= 0;
s_data <= p_data[1];
end
16: begin
rclk <= 0;
s_data <= p_data[0];
end
17: begin
rclk <= 1;
s_data <= 1;
end
default: begin
rclk <= 0;
s_data <= 1;
end
endcase
end
endmodule