Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use this built-in shiftRegister from Chisel3.util properly?

Tags:

scala

chisel

I tried to compare this built-in shiftRegister with some common shift registers in the chisel-tutorial. But this one seems not actually shifting the bits? https://github.com/freechipsproject/chisel3/blob/9f620e06bacc2882068adfd4972ec2e9a87ea723/src/main/scala/chisel3/util/Reg.scala#L33

class MyShiftRegister_chisel[T <: Data](val init: Int = 1) extends Module {
  val io = IO(new Bundle {
    val in  = Input(Bool())
    val out = Output(UInt(4.W))
  })

  val state = ShiftRegister(io.in, 1, true.B)
//     val next_state = RegNext(UInt(4.W), state)
//      val nextState = Cat(state(2,0), io.in)
//   state := nextState
  io.out := state
}
println(getVerilog(new MyShiftRegister_chisel()))

And I got the following verilog:

[info] [0.000] Elaborating design...
[info] [0.070] Done elaborating.
Total FIRRTL Compile Time: 28.7 ms
module MyShiftRegister_chisel(
  input        clock,
  input        reset,
  input        io_in,
  output [3:0] io_out
);
  reg  state; // @[Reg.scala 15:16]
  reg [31:0] _RAND_0;
  assign io_out = {{3'd0}, state}; // @[cmd94.sc 11:10]
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
  integer initvar;
`endif
initial begin
  `ifdef RANDOMIZE
    `ifdef INIT_RANDOM
      `INIT_RANDOM
    `endif
    `ifndef VERILATOR
      `ifdef RANDOMIZE_DELAY
        #`RANDOMIZE_DELAY begin end
      `else
        #0.002 begin end
      `endif
    `endif
  `ifdef RANDOMIZE_REG_INIT
  _RAND_0 = {1{`RANDOM}};
  state = _RAND_0[0:0];
  `endif // RANDOMIZE_REG_INIT
  `endif // RANDOMIZE
end
  always @(posedge clock) begin
    state <= io_in;
  end
endmodule

So my question is, how to properly use this built-in ShiftRegister from Chisel3.util?

like image 915
Frederick Hong Avatar asked Dec 01 '25 03:12

Frederick Hong


1 Answers

From your link with the ScalaDoc comment:

  /** Returns the n-cycle delayed version of the input signal.
    *
    * @param in input to delay
    * @param n number of cycles to delay
    * @param en enable the shift
    *
    * @example {{{
    * val regDelayTwo = ShiftRegister(nextVal, 2, ena)
    * }}}
    */
  def apply[T <: Data](in: T, n: Int, en: Bool = true.B): T = { ...

The ShiftRegister delays the input data in, n cycles. It is generic as to the type being shifted in and out. I suspect you're referring to the stereotypical shift register which shifts in and out 1 bit of data per-cycle. You can easily do that with this construct by making the input type Bool:

class Foo extends Module {
  val io = IO(new Bundle {
    val in = Input(Bool())
    val out = Output(Bool())
  })

  io.out := ShiftRegister(io.in, 4)
}

Gives

module Foo(
  input   clock,
  input   reset,
  input   io_in,
  output  io_out
);
  reg  _T; // @[Reg.scala 15:16]
  reg [31:0] _RAND_0;
  reg  _T_1; // @[Reg.scala 15:16]
  reg [31:0] _RAND_1;
  reg  _T_2; // @[Reg.scala 15:16]
  reg [31:0] _RAND_2;
  reg  _T_3; // @[Reg.scala 15:16]
  reg [31:0] _RAND_3;
  assign io_out = _T_3; // @[main.scala 13:10]
// ...
  always @(posedge clock) begin
    _T <= io_in;
    _T_1 <= _T;
    _T_2 <= _T_1;
    _T_3 <= _T_2;
  end
endmodule

Note that the construct hides the underlying flops from you, it returns the output of the final flop which is the "shifted out value" each cycle.

like image 181
Jack Koenig Avatar answered Dec 02 '25 18:12

Jack Koenig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!