[chisel-tutorial] Memo.scala

YumeIroVillain·2023년 8월 7일
0

Chisel 독학

목록 보기
13/44
post-custom-banner

예제 출처

아주 간단한 R/W 레지스터 파일을 구현하는 문제이다.

오답노트

오답 1

Errors: 1: in the following tutorials
Tutorial Memo: exception  : [module Memo]  Reference io is not fully initialized.
   @[Memo.scala 31:16] : io.rdData <= mux(io.wen, VOID, mux(io.ren, mem._T_1.data, VOID)) @[Memo.scala 31:16]
  • 원인은, io.rdData가 실제로 elaborate될 때, Mux로 elaborate 되는데,
  • 기본값이 도대체 무엇이냐를 scala상에서 명시하지 않아서
  • verilog로 elaborate하는데는 성공했지만,
  • Tutorial을 수행하던 중 Exception이 발생했다는 것으로 추정된다.
  • io.rdData가 io.wen 조건일 때 초기화되지 않는걸 발견하고, 고쳤다.
  io.ren := 0.U
  val memVal = mem(io.rdAddr)
  when(io.wen){
    mem(io.wrAddr) := io.wrData
    io.rdData := 0.U
  }.elsewhen(io.ren){
    mem(io.wrAddr) := mem(io.wrAddr)
    io.rdData  :=  memVal
  }.otherwise{
    mem(io.wrAddr) := mem(io.wrAddr)
    io.rdData  :=  0.U
  }
  • 보다시피, io.rdData가 기본값을 모든 경우에 대해 설정했는데....
  • 왜 안되는지 잘 와닿지 않는다.

오답 2

  io.ren := 0.U
  val memVal = mem(io.rdAddr)
  when(io.wen){
    mem(io.wrAddr) := io.wrData
  }.elsewhen(io.ren){
    io.rdData  :=  memVal
  }.otherwise{
    io.rdData  :=  0.U
  }
  • 래치를 없애고자 초기화를 해주었다.
  • 그럼에도 에러가 발생하였다.
[info] running problems.Launcher Memo
Starting tutorial Memo
[info] [0.001] Elaborating design...
chisel3.internal.ChiselException: Connection between sink (Bool(IO in unelaborated Memo)) and source (UInt<1>(0)) failed @: Sink is unwriteable by current module.
	at chisel3.internal.throwException$.apply(Error.scala:85)
	at chisel3.Data.connect(Data.scala:406)
	at chisel3.Data.$colon$eq(Data.scala:494)
	at problems.Memo.<init>(Memo.scala:29)
	at problems.Launcher$.$anonfun$tests$41(Launcher.scala:76)
	at chisel3.Module$.do_apply(Module.scala:52)
	at chisel3.stage.ChiselGeneratorAnnotation.$anonfun$elaborate$1(ChiselAnnotations.scala:50)
	at chisel3.internal.Builder$.$anonfun$build$1(Builder.scala:408)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:62)
	at chisel3.internal.Builder$.build(Builder.scala:406)
	at chisel3.stage.ChiselGeneratorAnnotation.elaborate(ChiselAnnotations.scala:50)
	at chisel3.stage.phases.Elaborate.$anonfun$transform$1(Elaborate.scala:19)
	at scala.collection.TraversableLike.$anonfun$flatMap$1(TraversableLike.scala:245)
	at scala.collection.immutable.List.foreach(List.scala:392)
	at scala.collection.TraversableLike.flatMap(TraversableLike.scala:245)
	at scala.collection.TraversableLike.flatMap$(TraversableLike.scala:242)
	at scala.collection.immutable.List.flatMap(List.scala:355)
	at chisel3.stage.phases.Elaborate.transform(Elaborate.scala:18)
	at chisel3.iotesters.setupTreadleBackend$.apply(TreadleBackend.scala:143)
	at chisel3.iotesters.Driver$.$anonfun$execute$2(Driver.scala:53)
	at scala.runtime.java8.JFunction0$mcZ$sp.apply(JFunction0$mcZ$sp.java:23)
	at logger.Logger$.$anonfun$makeScope$2(Logger.scala:168)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:62)
	at logger.Logger$.makeScope(Logger.scala:166)
	at logger.Logger$.makeScope(Logger.scala:127)
	at chisel3.iotesters.Driver$.$anonfun$execute$1(Driver.scala:38)
	at scala.runtime.java8.JFunction0$mcZ$sp.apply(JFunction0$mcZ$sp.java:23)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:62)
	at chisel3.iotesters.Driver$.execute(Driver.scala:38)
	at problems.Launcher$.$anonfun$tests$40(Launcher.scala:77)
	at problems.Launcher$.$anonfun$tests$40$adapted(Launcher.scala:75)
	at utils.TutorialRunner$.$anonfun$apply$3(TutorialRunner.scala:56)
	at scala.collection.immutable.List.foreach(List.scala:392)
	at utils.TutorialRunner$.apply(TutorialRunner.scala:47)
	at problems.Launcher$.main(Launcher.scala:104)
	at problems.Launcher.main(Launcher.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at sbt.Run.invokeMain(Run.scala:115)
	at sbt.Run.execute$1(Run.scala:79)
	at sbt.Run.$anonfun$runWithLoader$3(Run.scala:84)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
	at scala.util.Try$.apply(Try.scala:213)
	at sbt.Run.directExecute$1(Run.scala:84)
	at sbt.Run.runWithLoader(Run.scala:93)
	at sbt.Defaults$.$anonfun$bgRunMainTask$7(Defaults.scala:1458)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
	at scala.util.Try$.apply(Try.scala:213)
	at sbt.internal.BackgroundThreadPool$BackgroundRunnable.run(DefaultBackgroundJobService.scala:360)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:750)
================================================================================
Errors: 1: in the following tutorials
Tutorial Memo: exception Connection between sink (Bool(IO in unelaborated Memo)) and source (UInt<1>(0)) failed @: Sink is unwriteable by current module.
================================================================================
2023-08-07 21:14:27,667 shutdown-hooks-run-all ERROR No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2
  • 엄청난 에러가 발생한다.
  • 대충 Connection Between sink 가 발생했다는 뜻인데,
  • Elaborate 중 에러가 발생했다는 사실 외에는 감이 오지 않았다.
  • .v파일도 만들어지지 않고, fir파일만 만들어진 상태라 구체적 원인확인도 힘들었다.

오답 3

  when(io.wen){
    mem(io.wrAddr) := io.wrData
  }

  when(io.ren){
    io.rdData := mem(io.rdAddr)
  }
[info] running problems.Launcher Memo
Starting tutorial Memo
[info] [0.001] Elaborating design...
[info] [0.557] Done elaborating.
Computed transform order in: 220.7 ms
firrtl.passes.CheckInitialization$RefNotInitializedException:  : [module Memo]  Reference io is not fully initialized.
   @[Memo.scala 49:15] : io.rdData <= mux(io.ren, mem._T_1.data, VOID) @[Memo.scala 49:15]
================================================================================
Errors: 1: in the following tutorials
Tutorial Memo: exception  : [module Memo]  Reference io is not fully initialized.
   @[Memo.scala 49:15] : io.rdData <= mux(io.ren, mem._T_1.data, VOID) @[Memo.scala 49:15]
================================================================================
2023-08-07 21:19:48,546 shutdown-hooks-run-all ERROR No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2
  • 두 개의 when문으로 아예 따로 구현하였다.
  • 당연히 훨씬 깔끔하고 이게 맞다(...)
  • 그러나 이번엔 초기화를 다시 빼먹었다.

정답

// See LICENSE.txt for license details.
package problems

import chisel3._

// Problem:
//
// Implement a dual port memory of 256 8-bit words.
// When 'wen' is asserted, write 'wrData' to memory at 'wrAddr'
// When 'ren' is asserted, 'rdData' holds the output
// of reading the memory at 'rdAddr'
//
class Memo extends Module {
  val io = IO(new Bundle {
    val wen     = Input(Bool())
    val wrAddr  = Input(UInt(8.W))
    val wrData  = Input(UInt(8.W))
    val ren     = Input(Bool())
    val rdAddr  = Input(UInt(8.W))
    val rdData  = Output(UInt(8.W))
  })

  val mem = Mem(256, UInt(8.W))
  
  // Implement below ----------

  when(io.wen){
    mem(io.wrAddr) := io.wrData
  }

  io.rdData := 0.U
  when(io.ren){
    io.rdData := mem(io.rdAddr)
  }

  // Implement above ----------

}

합성된 verilog 코드는 아래와 같다.

reset이 있긴 한데, 따로 쓰이지는 않고
그냥 출력 마지막단에 mux가 있어서 0으로 hard wire 여부만 달라질 뿐이다.


What I learned

  • when으로 memory의 read/write path를 구분하여 구현하는게 훨씬 깔끔하다(verilog에서도 그랬지만).
  • 초기화, 까먹지말자. when 바깥에서 하면 된다.
  • 8비트짜리의 256개 row 메모리를 선언하려면,
    val mem = Mem(256, UInt(8.W))
    하면 된다.
profile
HW SW 둘다 공부하는 혼종의 넋두리 블로그 / SKKU SSE 17 / SWM 11th
post-custom-banner

0개의 댓글