case class Movie(name: String, year: Int, genre: String) {
def decade(): String = (year - year%10) + "s"
}
val m1 = Movie("Gattaca", 1997, "drama")
m1.genre
val m2 = Movie("The Avengers", 1998, "action")
m2.copy(year=2012)
m2.decade
출력
defined class Movie
m1: Movie = Movie("Gattaca", 1997, "drama")
res2_2: String = "drama"
m2: Movie = Movie("The Avengers", 1998, "action")
res2_4: Movie = Movie("The Avengers", 2012, "action")
res2_5: String = "1990s"
class LoopyCounter(w: Int) extends Module {
val io = IO(new Bundle {
val count = Output(UInt(w.W))
})
io.count := io.count + 1.U
// io.count := RegNext(io.count + 1.U)
}
println(getVerilog(new LoopyCounter(4)))
class MakeValid(w: Int) extends Module {
val io = IO(new Bundle {
val en = Input(Bool())
val in = Input(UInt(w.W))
val out = Valid(UInt(w.W))
})
io.out.valid := io.en
io.out.bits := io.in
}
println(getVerilog(new MakeValid(4)))
실제로, Chisel은 Combinational Loop가 존재한다며 오류를 뱉는다.
이런 꼴의 루프가 있다면,
가능한 한 최대한의 속도로 무한히 1이 더해질 것이다.
전력낭비에 불과하고, 의미가 없다.
그래서, Chisel Compiler가 거절한다.
class MakeValid(w: Int) extends Module {
val io = IO(new Bundle {
val en = Input(Bool())
val in = Input(UInt(w.W))
val out = Valid(UInt(w.W))
})
io.out.valid := io.en
io.out.bits := io.in
}
println(getVerilog(new MakeValid(4)))
class ValidReceiver(w: Int) extends Module {
val io = IO(new Bundle {
val in = Flipped(Valid(UInt(w.W)))
})
when (io.in.valid) {
printf(" received %d\n", io.in.bits)
}
}
// println(getVerilog(new ValidReceiver(4)))
test(new ValidReceiver(4)) { c =>
for (cycle <- 0 until 8) {
c.io.in.bits.poke(cycle.U)
println(s"cycle: $cycle")
c.io.in.valid.poke((cycle%2 == 0).B)
c.clock.step()
}
}
class CountWhenReady(maxVal: Int) extends Module {
val io = IO(new Bundle {
val en = Input(Bool())
val out = Decoupled(UInt())
})
val (count, wrap) = Counter(io.out.fire, maxVal)
when (io.en) {
io.out.enq(count)
// io.out.bits := count
// io.out.valid := true.B
} .otherwise {
io.out.noenq()
// io.out.bits := DontCare
// io.out.valid := false.B
}
}
// println(getVerilog(new CountWhenReady(3)))
test(new CountWhenReady(3)) { c =>
c.io.en.poke(true.B)
for (cycle <- 0 until 7) {
c.io.out.ready.poke((cycle%2 == 1).B)
println(s"cycle: $cycle, count: ${c.io.out.bits.peek()}")
c.clock.step()
}
}
class CountIntoQueue(maxVal: Int, numEntries: Int, pipe: Boolean, flow: Boolean) extends Module {
val io = IO(new Bundle {
val en = Input(Bool())
val out = Decoupled(UInt())
val count = Output(UInt())
})
val q = Module(new Queue(UInt(), numEntries, pipe=pipe, flow=flow))
val (count, wrap) = Counter(q.io.enq.fire, maxVal)
q.io.enq.valid := io.en
q.io.enq.bits := count
io.out <> q.io.deq
io.count := count // for visibility
}
// println(getVerilog(new CountIntoQueue(3,1,false,false)))
test(new CountIntoQueue(4,3,pipe=false,flow=false)) { c =>
c.io.en.poke(true.B)
c.io.out.ready.poke(false.B)
for (cycle <- 0 until 4) { // Fill up queue
println(s"f count:${c.io.count.peek()} out:${c.io.out.bits.peek()} v:${c.io.out.valid.peek()}")
c.clock.step()
}
println()
c.io.en.poke(false.B)
c.io.out.ready.poke(true.B)
for (cycle <- 0 until 4) { // Drain queue
println(s"d count:${c.io.count.peek()} out:${c.io.out.bits.peek()} v:${c.io.out.valid.peek()}")
c.clock.step()
}
println()
c.io.en.poke(true.B)
for (cycle <- 0 until 4) { // Simultaneous
println(s"s count:${c.io.count.peek()} out:${c.io.out.bits.peek()} v:${c.io.out.valid.peek()}")
c.clock.step()
}
}
f count:UInt<1>(0) out:UInt<1>(0) v:Bool(false)
f count:UInt<1>(1) out:UInt<1>(0) v:Bool(true)
f count:UInt<2>(2) out:UInt<1>(0) v:Bool(true)
f count:UInt<2>(3) out:UInt<1>(0) v:Bool(true)
d count:UInt<2>(3) out:UInt<1>(0) v:Bool(true)
d count:UInt<2>(3) out:UInt<1>(1) v:Bool(true)
d count:UInt<2>(3) out:UInt<2>(2) v:Bool(true)
d count:UInt<2>(3) out:UInt<1>(0) v:Bool(false)
s count:UInt<2>(3) out:UInt<1>(0) v:Bool(false)
s count:UInt<1>(0) out:UInt<2>(3) v:Bool(true)
s count:UInt<1>(1) out:UInt<1>(0) v:Bool(true)
s count:UInt<2>(2) out:UInt<1>(1) v:Bool(true)
test CountIntoQueue Success: 0 tests passed in 14 cycles in 0.017046 seconds 821.30 Hz
fill과 drain이 제대로 동작하는 것을 출력을 통해 확인할 수 있다.