Поддерживать порядок подключения на FIRRTL с помощью оператора Cat

Я хочу попросить любую идею для следующей проблемы: я хочу подключить входной порт блока с именем dut, ширина которого составляет 787:0 бит, к байтовому интерфейсу. Я делаю следующее:

val io = this.IO(new VerilatorHarnessIO(input_byte_count, output_byte_count*2))
val dut = Module(new DUT(dut_conf))

// inputs
val input_bytes = Cat(io.input_bytes)
val input_width = input_byte_count * 8
dut.io.inputs := input_bytes(input_width-1, input_width - dut_conf.inputBits)

Я хочу, чтобы порядок соединения сохранялся, т.е.:

Byte_0[7:0] ->input[7:0]

Байт_1[7:0] ->вход[15:8]

Но что я получаю:

Byte_0[7:0] ->input[787:780]

Байт_1[7:0] ->вход[779:772]

Будет намного проще отлаживать, если порты совпадают.

Есть ли способ сделать это соединение в правильном порядке? Спасибо


person maku lulaj    schedule 15.11.2019    source источник


Ответы (2)


Использование метода reverse перед Cat должно делать то, что вы хотите.

Рассмотрим следующее долото:

import chisel3._
import chisel3.stage.{ChiselStage, ChiselGeneratorAnnotation}
import chisel3.util.Cat

class Foo extends RawModule {
  val in = IO(Input(Vec(4, UInt(8.W))))
  val out = IO(Output(UInt(32.W)))

  out := Cat(in.reverse)
}

(new ChiselStage)
  .execute(Array.empty, Seq(ChiselGeneratorAnnotation(() => new Foo)))

Это создает следующий Verilog с байтами в том порядке, в котором вы ищете:

module Foo(
  input  [7:0]  in_0,
  input  [7:0]  in_1,
  input  [7:0]  in_2,
  input  [7:0]  in_3,
  output [31:0] out
);
  wire [15:0] _T; // @[Cat.scala 29:58]
  wire [15:0] _T_1; // @[Cat.scala 29:58]
  assign _T = {in_1,in_0}; // @[Cat.scala 29:58]
  assign _T_1 = {in_3,in_2}; // @[Cat.scala 29:58]
  assign out = {_T_1,_T}; // @[<pastie> 25:7]
endmodule
person seldridge    schedule 15.11.2019

Cat отображается задом наперед, потому что соответствует семантике Verilog и, таким образом, является обратным с точки зрения семантики Scala.

Рассмотреть возможность:

val xs = List(8, 9, 10)
println(xs(0)) // 8

Крайний левый элемент — это индекс самого низкого порядка в Scala. Однако в Verilog вы получаете обратное:

assign x = {4'hde, 4'had};

Самая левая часть этой конкатенации на самом деле является откуской старшего порядка в результате. Chisel Cat был создан, чтобы соответствовать семантике Verilog, что делает его несколько нелогичным в Scala.

Как упомянула Шайлер, вы всегда можете reverse Vec или Seq аргументировать Cat. В качестве альтернативы вы можете привести к UInt, который будет использовать более интуитивно понятный порядок Scala:

import chisel3._

class Foo extends RawModule {
  val in = IO(Input(Vec(4, UInt(8.W))))
  val out = IO(Output(UInt(32.W)))

  out := in.asUInt
}

.asUInt определен для всех Chisel Data, поэтому вы можете использовать его для приведения Bundles и других типов к UInt. Единственная загвоздка в том, что многие методы, определенные для Vec, возвращают Seq, супертип Scala для Vec, который не является долотом Data. Это означает, что вы не можете сделать что-то вроде myVec.map(_ === 0.U).asUInt. Вы всегда можете преобразовать Seq[T <: Data] (то есть Seq, содержащий элементы Chisel Data) в Vec через VecInit(mySeq), так что вы можете сделать VecInit(myVec.map(_ === 0.U)).asUInt

person Jack Koenig    schedule 15.11.2019