/
conv.v
152 lines (139 loc) · 3.08 KB
/
conv.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
`include "./define/define.v"
`timescale 1ns/100ps
module conv(
input Aclk,
input rst,
input [`pattern_bit:0] Xin,
input [`kernel_bit:0] Kin,
output reg [`result_bit:0] Rout,
output reg result_done
);
reg [`pattern_bit:0] pattern [`pattern_num-1:0];
reg [4:0] daddr;
wire pattern_done;
reg [`kernel_bit:0] kernel [`kernel_num-1:0];
reg [4:0] kaddr;
wire kernel_done;
reg [`result_bit:0] result [`result_num-1:0];
reg [4:0] out_cnt;
integer i;
/*loading pattern*/
assign pattern_done = (daddr-1>=9) ? 1'd1 : 1'd0;
always@(posedge Aclk)
begin
if(rst)
begin
for(i=0;i<`pattern_num;i=i+1)
begin
pattern[i] <= `pattern_bit'd0;
end
daddr <= 5'd1; //不能為0,pattern接不到資料
end
else
begin
if(pattern_done)
begin
pattern[daddr] <= pattern[daddr];
daddr <= daddr;
end
else
begin
pattern[daddr-1] <= Xin;
daddr <= daddr + 5'd1;
end
end
end
/*loading kernel*/
assign kernel_done = (kaddr-1>=4) ? 1'd1 : 1'd0;
always@(posedge Aclk)
begin
if(rst)
begin
for(i=0;i<`kernel_num;i=i+1)
begin
kernel[i] <= `kernel_bit'd0;
end
kaddr <= 5'd1;
end
else
begin
if(kernel_done)
begin
kernel[kaddr] <= kernel[kaddr];
kaddr <= kaddr;
end
else
begin
kernel[kaddr-1] <= Kin;
kaddr <= kaddr + 5'd1;
end
end
end
/*convolution computation*/
always@(*)
begin
if(rst)
begin
for(i=0;i<`result_num;i=i+1)
begin
result[i] = 7'd0;
end
end
else
begin
if(pattern_done & kernel_done)
begin
result[0] = pattern[0]*kernel[0] + pattern[1]*kernel[1] + pattern[3]*kernel[2] + pattern[4]*kernel[3];
result[1] = pattern[1]*kernel[0] + pattern[2]*kernel[1] + pattern[4]*kernel[2] + pattern[5]*kernel[3];
result[2] = pattern[3]*kernel[0] + pattern[4]*kernel[1] + pattern[6]*kernel[2] + pattern[7]*kernel[3];
result[3] = pattern[4]*kernel[0] + pattern[5]*kernel[1] + pattern[7]*kernel[2] + pattern[8]*kernel[3];
end
else
begin
for(i=0;i<`result_num;i=i+1)
begin
result[i] = 7'd0;
end
end
end
end
always@(posedge Aclk)
begin
if(rst)
begin
result_done <= 1'd0;
end
else
begin
if(pattern_done & kernel_done)
begin
result_done <= 1'd1;
end
else
begin
result_done <= result_done;
end
end
end
always@(posedge Aclk)
begin
if(rst)
begin
Rout <= 7'd0;
out_cnt <= 5'd1;
end
else
begin
if(pattern_done & kernel_done)
begin
out_cnt <= out_cnt + 5'd1;
Rout <= result[out_cnt-1];
end
else
begin
out_cnt <= 5'd1;
Rout <= 5'd0;
end
end
end
endmodule