-
Notifications
You must be signed in to change notification settings - Fork 0
/
FinalProject.scala
189 lines (159 loc) · 7.54 KB
/
FinalProject.scala
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
import spatial._
import org.virtualized._
import spatial.targets.DE1
object FinalProject extends SpatialApp {
import IR._
override val target = DE1
val Cmax = 320
val Rmax = 240
val cirRad = 10
val cirCount = 10
val maxCircles = 10 // maximum number of circles you can instantiate
type Int64 = FixPt[TRUE,_64,_0]
type Int16 = FixPt[TRUE,_16,_0]
type UInt8 = FixPt[FALSE,_8,_0]
type UInt16 = FixPt[FALSE,_16,_0]
type UInt5 = FixPt[FALSE,_5,_0]
type UInt6 = FixPt[FALSE,_6,_0]
@struct case class Pixel16(b: UInt5, g: UInt6, r: UInt5)
@virtualize
def convolveVideoStream(): Unit = {
val imgOut = BufferedOut[Pixel16](target.VGA)
val dwell = ArgIn[Int]
val d = args(0).to[Int]
setArg(dwell, d)
Accel{
// ball values
val cirX = SRAM[Int](maxCircles) // x position
val cirY = SRAM[Int](maxCircles) // y position
val cirVelX = SRAM[Int](maxCircles) // velocity vector x comp
val cirVelY = SRAM[Int](maxCircles) // velocity vector y comp
// collision variables
val collisionType = SRAM[Int](maxCircles) // 1 = ball to ball collision , 2 = border collision , 0 = no collision
val ballCollide = SRAM[Int](maxCircles) // i = no ball colliding, j = ball collided with
val ballCollideVelX = SRAM[Int](maxCircles)
val ballCollideVelY = SRAM[Int](maxCircles)
Sequential{ // instantiate values
// Fill array with circle values
Foreach(0 until cirCount){ i =>
Pipe{
val X = random[UInt16](Cmax).to[Int]
val Y = random[UInt16](Rmax).to[Int]
cirX(i) = mux(X < 0, 0.to[Int], X)
cirY(i) = mux(Y < 0, 0.to[Int], Y)
cirVelX(i) = random[UInt8](3).to[Int] - 6.to[Int] // range of -3 to 3
cirVelY(i) = random[UInt8](3).to[Int] - 6.to[Int] // range of -3 to 3
}
}
// Get rid of any overlaps among circles
Foreach(0 until cirCount){_=> // arbitrary number of loops, TODO: ideal would be a do while loop
Sequential.Foreach(0 until cirCount, 0 until cirCount){ (i,j) =>
Pipe{
val sqrRad = 4*cirRad*cirRad
val distSqr = (cirX(i) - cirX(j)) * (cirX(i) - cirX(j)) + (cirY(i) - cirY(j))*(cirY(i) - cirY(j))
if(distSqr <= sqrRad && (i != j)){ // if overlap found, instantiate new x and y params
cirX(i) = random[UInt16](Cmax).to[Int]
cirY(i) = random[UInt16](Rmax).to[Int]
}
}
}
}
}
// Update frames
Stream(*) { _ =>
FSM[Int]{state => state < 4}{state =>
if(state == 0.to[Int]){ // Determine collision type
Sequential{
val borderCollision = SRAM[Int](maxCircles)
val ballCollision = SRAM[Int](maxCircles)
Sequential.Foreach(0 until cirCount){ i => // detect border collision
Pipe{
borderCollision(i) = mux(cirX(i) + cirRad >= Cmax || cirX(i) - cirRad <= 0.to[Int] || cirY(i) + cirRad >= Rmax || cirY(i) - cirRad <= 0.to[Int], 1.to[Int], 0.to[Int])
ballCollide(i) = i.to[Int]
ballCollision(i) = 0.to[Int]
ballCollideVelX(i) = 0.to[Int]
ballCollideVelY(i) = 0.to[Int]
}
}
Sequential.Foreach(0 until cirCount, 0 until cirCount){ (i,j) => // detect ball to ball collision
Pipe{
val sqrRad = 4*cirRad*cirRad
val distSqr = (cirX(i) - cirX(j)) * (cirX(i) - cirX(j)) + (cirY(i) - cirY(j))*(cirY(i) - cirY(j))
ballCollision(i) = mux(distSqr <= sqrRad && (i != j), 1.to[Int], ballCollision(i))
ballCollide(i) = mux(distSqr <= sqrRad && (i != j), j.to[Int], ballCollide(i))
ballCollideVelX(i) = mux(distSqr <= sqrRad && (i != j), cirVelX(j), ballCollideVelX(i))
ballCollideVelY(i) = mux(distSqr <= sqrRad && (i != j), cirVelY(j), ballCollideVelY(i))
}
}
Sequential.Foreach(0 until cirCount){ i => // determine collision type
Pipe{
collisionType(i) = mux(borderCollision(i) == 1, 1.to[Int],
mux(ballCollision(i) == 1, 2.to[Int],
0.to[Int]))
}
}
}
}else if(state == 1.to[Int]){ // Update velocities
// 1 = border collision , 2 = ball to ball collision , 0 = no collision
Sequential{
Sequential.Foreach(0 until cirCount){ i =>
Pipe{
val ball2 = ballCollide(i)
val x2 = cirX(ball2)
val y2 = cirY(ball2)
val x1 = cirX(i)
val y1 = cirY(i)
cirVelX(i) = mux(collisionType(i) == 1 &&(cirX(i) + cirRad >= Cmax || cirX(i) - cirRad <= 0.to[Int]),0 - cirVelX(i),
mux(collisionType(i) == 2 &&((x1 < x2 && cirVelX(i) > 0) || (x1 > x2 && cirVelX(i) < 0)),0 - cirVelX(i),
//mux(collisionType(i) == 2 && cirVelX(i) == 0, ballCollideVelX(i),
cirVelX(i)))
cirVelY(i) = mux(collisionType(i) == 1 && (cirY(i) + cirRad >= Rmax || cirY(i) - cirRad <= 0.to[Int]), 0 - cirVelY(i),
mux(collisionType(i) == 2 && ((y1 < y2 && cirVelY(i) > 0) || (y1 > y2 && cirVelY(i) < 0)), 0 - cirVelY(i),
//mux(collisionType(i) == 2 && cirVelY(i) == 0, ballCollideVelY(i),
cirVelY(i)))
}
}
}
}else if(state == 2.to[Int]){ // Calculate new positions
Sequential{
Sequential.Foreach(0 until cirCount){ i =>
Pipe{
cirX(i) = mux( cirX(i) + cirVelX(i) > Cmax -cirRad, Cmax - cirRad,
mux( cirX(i) + cirVelX(i) <= cirRad, cirRad,
cirX(i) + cirVelX(i)))
cirY(i) = mux( cirY(i) + cirVelY(i) > Rmax -cirRad, Rmax - cirRad,
mux( cirY(i) + cirVelY(i) <= cirRad, cirRad,
cirY(i) + cirVelY(i)))
}
}
}
}else if(state == 3.to[Int]){ // Draw circle
Sequential{
Foreach(0 until dwell){_=>
Foreach(0 until Rmax, 0 until Cmax){ (r, c) =>
val acc = SRAM[UInt6](1)
Pipe{
acc(0) = 0.to[UInt6]
Sequential.Foreach(0 until cirCount){ i=>
Pipe{
val pixel = mux((r.to[Int64] - cirY(i).to[Int64])*(r.to[Int64] -cirY(i).to[Int64]) + (c.to[Int64] - cirX(i).to[Int64])*(c.to[Int64] -cirX(i).to[Int64]) < cirRad.to[Int64] * cirRad.to[Int64], 63.to[UInt6], 0.to[UInt6])
acc(0) = mux(acc(0) == 0.to[UInt6], pixel, acc(0))
}
}
}
imgOut(r, c) = Pixel16(0.to[UInt5], acc(0), 0.to[UInt5])
}
}
}
}
}{state => mux(state == 3.to[Int], 0.to[Int], state + 1)}
}// end of stream(*)
}// end of accel
}
@virtualize
def main() {
val R = Rmax
val C = Cmax
convolveVideoStream()
}
}