Назначение Chisel3 REPL Ve c в модуль работает только после eval - PullRequest
1 голос
/ 06 августа 2020

Если мы запустим следующий код Chisel3

class Controller extends Module {

  val io = IO(new Bundle {
  })
  val sff = Module(new SFF)

  val frame: Vec[UInt] = Reg(Vec(ProcedureSpaceSize, Integer32Bit))
  for(i <- 0 until ProcedureSpaceSize)
    frame(i) := 99.U

  sff.io.inputDataVector := frame
}

class SFF extends Module {

  val io = IO(new Bundle {
    val inputDataVector: Vec[UInt] = Input(Vec(ProcedureSpaceSize, Integer32Bit))
  })

}

в режиме отладки REPL. Сначала выполните

reset;step

peek sff.io_inputDataVector_0;peek sff.io_inputDataVector_1;peek sff.io_inputDataVector_2

REPL возвращает

Error: exception Error: getValue(sff.io_inputDataVector_0) returns value not found
Error: exception Error: getValue(sff.io_inputDataVector_1) returns value not found
Error: exception Error: getValue(sff.io_inputDataVector_2) returns value not found

Затем выполните

eval sff.io_inputDataVector_0

, который будет успешным, что даст

...
resolve dependencies
  evaluate     sff.io_inputDataVector_0 <= frame_0
  evaluated    sff.io_inputDataVector_0 <= 99.U<32>

Затем снова выполните описанный выше просмотр.

peek sff.io_inputDataVector_0;peek sff.io_inputDataVector_1;peek sff.io_inputDataVector_2;

На этот раз он возвращает

peek sff.io_inputDataVector_0  99
peek sff.io_inputDataVector_1  99
peek sff.io_inputDataVector_2  99

, что более ожидаемо.

Почему REPL действует таким образом? Или я что-то упустил? Спасибо!

*chisel-iotesters в версии 1.4.2, а chiseltest в версии 0.2.2. Оба должны быть последней версии.

Ответы [ 2 ]

1 голос
/ 11 августа 2020

Фирменный интерпретатор REPL не обязательно вычисляет или сохраняет значения, которые в ветви mux не используются. Это может привести к проблемам, указанным выше, например,

Error: exception Error: getValue(sff.io_inputDataVector_0) returns value not found.

eval можно использовать для принудительной оценки неиспользуемых ветвей в любом случае. REPL - это экспериментальная функция, которая не нашла широкого применения.

treadle - это более современный симулятор на основе долота scala. Он лучше поддерживается и быстрее интерпретатора. Он имеет собственный REPL, но не имеет эквивалента executeFirrtlRepl.

Его необходимо запускать из командной строки через сценарий ./treadle.sh в каталоге root. Также можно запустить sbt assembly, чтобы создать намного более быстрый запуск jar, который помещается в utils / bin. Этот REPL также использовался нечасто, но меня интересуют отзывы, которые сделают его лучше и проще в использовании.

1 голос
/ 09 августа 2020

Я думаю, что проблема, которую вы видите, заключается в том, что все ваши провода удаляются из-за устранения мертвого кода. Есть несколько вещей, которые вы должны попытаться исправить.

  • Убедитесь, что у вас есть надежные соединения ваших проводов. Оборудование, которое в конечном итоге не влияет на результат, скорее всего, будет удалено. В вашем примере у вас нет ничего, управляющего выходом верхнего уровня
  • . Вероятно, вам понадобится ваша схема, чтобы что-то вычислить с этими регистрами. Если регистры инициализированы до 99, то распространение констант, вероятно, их устранит. Я не уверен, что вы пытаетесь заставить схему делать, поэтому трудно дать конкретную рекомендацию c.

Если вы сделаете это, я думаю, что ответ будет работать как ожидается. У меня есть вопрос о том, какой ответ вы используете (их два: firrtl-интерпретатор и педаль), я рекомендую использовать последний. Он более современный и лучше поддерживается. В нем также есть две команды, которые могут быть полезны:

  • show lofirrtl покажет вам опущенную фирму, вот как вы можете видеть, что многие вещи из высокого пальца, испускаемого chisel3, были изменены.
  • symbol . показывает все символы в схеме (. - это регулярное выражение, которое соответствует всему.

Вот несколько случайное редактирование вашей схемы, которая управляет и выводит на основе вашего frame Vec. Эта схема сгенерирует первый, который не устранит провода, которые вы пытаетесь увидеть.

class Controller extends Module {
  val io = IO(new Bundle {
    val out = Output(UInt(32.W))
  })
  val sff = Module(new SFF)

  val frame: Vec[UInt] = Reg(Vec(ProcedureSpaceSize, Integer32Bit))
  when(reset.asBool()) {
    for (i <- 0 until ProcedureSpaceSize) {
      frame(i) := 99.U
    }
  }
  frame.zipWithIndex.foreach { case (element, index) => element := element + index.U }
  sff.io.inputDataVector := frame
  io.out := sff.io.outputDataVector.reduce(_ + _)

}

class SFF extends Module {

  val io = IO(new Bundle {
    val inputDataVector: Vec[UInt] = Input(Vec(ProcedureSpaceSize, Integer32Bit))
    val outputDataVector: Vec[UInt] = Output(Vec(ProcedureSpaceSize, Integer32Bit))
  })

  io.outputDataVector <> io.inputDataVector
}
...