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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With