forked from 412910609/galvoMC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
XY2_100.v
239 lines (219 loc) · 5.12 KB
/
XY2_100.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
module XY2_100
(
input sys_clk,
input rst_n,
input xy_clk,
input xy_sync,
input xy_x_data,
input xy_y_data,
output reg finish_flag,
output reg [15:0] out_x_data,
output reg [15:0] out_y_data
);
parameter IDLE = 2'b00;
parameter READ = 2'b01;
parameter END = 2'b11;
reg [ 1:0] state_current;
reg [ 1:0] state_next;
reg [ 1:0] det_sync_edge;
wire [ 1:0] det_sync_edge_n;
reg sync_posedge_reg;
wire sync_posedge_reg_n;
reg [ 1:0] det_clk_edge;
wire [ 1:0] det_clk_edge_n;
reg clk_negedge_reg;
wire clk_negedge_reg_n;
reg [ 4:0] bit_cnt;
reg [ 4:0] bit_cnt_n;
reg [19:0] shift_x_data;
reg [19:0] shift_x_data_n;
//reg [15:0] out_x_data;
reg [15:0] out_x_data_n;
reg [19:0] shift_y_data;
reg [19:0] shift_y_data_n;
//reg [15:0] out_y_data;
reg [15:0] out_y_data_n;
//reg finish_flag;
reg finish_flag_n;
/******************* 检测 XY_SYNC 信号的上升沿 *******************/
//时序电路,det_sync_edge
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
det_sync_edge <= 2'b00;
else
det_sync_edge <= det_sync_edge_n;
end
//组合电路
assign det_sync_edge_n = {det_sync_edge[0], xy_sync};
//时序电路,sync_posedge_reg
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
sync_posedge_reg <= 1'b0;
else
sync_posedge_reg <= sync_posedge_reg_n;
end
//组合电路
assign sync_posedge_reg_n = (det_sync_edge == 2'b01) ? 1'b1 : 1'b0;
/******************* 检测 XY_SYNC 信号的上升沿 *******************/
/******************* 检测 XY_CLK 信号的下降沿 *******************/
//时序电路,det_clk_edge
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
det_clk_edge <= 2'b00;
else
det_clk_edge <= det_clk_edge_n;
end
//组合电路
assign det_clk_edge_n = {det_clk_edge[0], xy_clk};
//时序电路,clk_negedge_reg
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
clk_negedge_reg <= 1'b0;
else
clk_negedge_reg <= clk_negedge_reg_n;
end
//组合电路
assign clk_negedge_reg_n = (det_clk_edge == 2'b10) ? 1'b1 : 1'b0;
/******************* 检测 XY_CLK 信号的下降沿 *******************/
/******************* 实现XY2-100协议解析的状态机 *******************/
//时序电路,用来给 state_current 寄存器赋值
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
state_current <= IDLE;
else
state_current <= state_next;
end
//组合电路,用来实现状态机
always @ (*)
begin
case(state_current)
IDLE:
if(sync_posedge_reg)
state_next = READ;
else
state_next = state_current;
READ:
if(bit_cnt == 5'd20)
state_next = END;
else
state_next = state_current;
END:
if(finish_flag)
state_next = IDLE;
else
state_next = state_current;
default:
state_next = IDLE;
endcase
end
/******************* 实现XY2-100协议解析的状态机 *******************/
//时序电路,bit_cnt
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
bit_cnt <= 5'b0;
else
bit_cnt <= bit_cnt_n;
end
//组合电路,bit_cnt_n
always @ (*)
begin
if(bit_cnt >= 5'd20 || state_current != READ)
bit_cnt_n = 5'd0;
else if(state_current == READ && clk_negedge_reg)
bit_cnt_n = bit_cnt + 5'b1;
else
bit_cnt_n = bit_cnt;
end
/****************** 获取 X 轴位置数据 **************/
//时序电路,shift_x_data
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
shift_x_data <= 20'b0;
else
shift_x_data <= shift_x_data_n;
end
//组合电路,shift_x_data_n
always @ (*)
begin
if(state_current == READ && clk_negedge_reg)
shift_x_data_n = {shift_x_data[18:0], xy_x_data};
else
shift_x_data_n = shift_x_data;
end
//时序电路,out_x_data
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
out_x_data <= 16'h8000;
else
out_x_data <= out_x_data_n;
end
//组合电路,out_x_data_n
always @ (*)
begin
if(bit_cnt == 5'd20)
out_x_data_n = shift_x_data[16:1];
else
out_x_data_n = out_x_data;
end
/****************** 获取 X 轴位置数据 **************/
/****************** 获取 Y 轴位置数据 **************/
//时序电路,shift_y_data
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
shift_y_data <= 20'b0;
else
shift_y_data <= shift_y_data_n;
end
//组合电路,shift_y_data_n
always @ (*)
begin
if(state_current == READ && clk_negedge_reg)
shift_y_data_n = {shift_y_data[18:0], xy_y_data};
else
shift_y_data_n = shift_y_data;
end
//时序电路,out_y_data
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
out_y_data <= 16'h8000;
else
out_y_data <= out_y_data_n;
end
//组合电路,out_y_data_n
always @ (*)
begin
if(bit_cnt == 5'd20)
out_y_data_n = shift_y_data[16:1];
else
out_y_data_n = out_y_data;
end
/****************** 获取 Y 轴位置数据 **************/
/****************** XY2-100一帧数据传输完成标志 **************/
//时序电路,finish_flag
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
finish_flag <= 1'b0;
else
finish_flag <= finish_flag_n;
end
//组合电路,finish_flag_n
always @ (*)
begin
if(bit_cnt == 5'd20)
finish_flag_n = 1'b1;
else
finish_flag_n = 1'b0;
end
/****************** XY2-100一帧数据传输完成标志 **************/
endmodule