Долото: условие «когда-иначе» не работает в определении функции - PullRequest
2 голосов
/ 26 сентября 2019

Я пытаюсь разработать простую схему с использованием долота 3 для генерации факториала для числа n .Вот моя реализация:

class Factorial extends Module{
    val io = IO(new Bundle{
        val input = Input(UInt(8.W))
        val output = Output(UInt(16.W))
    })

    def factorial(n: UInt): UInt = { 
        when (n === 0.U) {1.U}
        .otherwise {n*factorial(n-1.U)}
    }

    io.out := factorial(io.in)
}

Однако, когда я пытаюсь запустить его, я получаю следующую ошибку:

cmd26.sc:9: type mismatch;
found   : Unit
required: chisel3.UInt
       .otherwise {n*factorial(n-1.U)}
                  ^Compilation Failed

Есть ли какая-то конкретная причина для этого?Как мне решить эту проблему?

Кроме того, я понимаю, что простое решение состоит в том, чтобы просто иметь номер n типа Int и вместо него иметь предложение if-else,Есть ли способ набрать приведение параметра, передаваемого во время вызова функции (т.е. от chisel3.UInt до Int)?

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

Операторы Chisel when, elsewhen и otherwise не возвращают значение.Ваш дизайн, кажется, является попыткой вычислить факториальное значение для входа в одном цикле.Это будет практично только для небольших входных значений и, вероятно, будет проще реализовать это через справочную таблицу.

Я думаю, что вы ищете (что было бы хорошим обучающим упражнением), чтобы построить схему, котораяданный вход вернет факториальное значение после некоторого количества циклов.Это очень похоже на то, как работает пример GCD, GCD включен в качестве примера в репо с шаблоном долота в качестве примера.Для этого вам понадобятся регистры, а также готовые и действительные порты.

Я предлагаю вам выяснить, как это работает, и вам будет гораздо проще создать факториал.Удачи.И, как предлагает @FabienM, вам понадобится очень большой выходной порт для ответа даже для скромных входных значений.

2 голосов
/ 26 сентября 2019

Я думаю, ты не можешь этого сделать.when () {}. в противном случае {} - это аппаратная конструкция, которая не возвращает никакого значения (единицы), как мы можем видеть в коде .

С помощью этой конструкции вы хотите сгенерировать оборудование«На лету», что невозможно.

Я думаю, что вы сгенерировали все решения, подобные этому:

class Factorial extends Module{
    val io = IO(new Bundle{
        val input = Input(UInt(8.W))
        val output = Output(UInt(1676.W))
    })

    def factorial(n: BigInt): BigInt = {
      if(n == 0){
        1
      }else{
        n*factorial(n-1)
      }
    }

    io.output := 0.U
    for(i <- 0 to 0xFF) {
      when(io.input === i.U){
        io.output := factorial(i).U
      }
    }
}

Вы можете сохранить рекурсивную функцию scala, но только на этапе генерации оборудования.Обратите внимание, что 255!действительно большое число, вам потребуется более 16 бит UInt для вывода значения;)

...