如何正确使用来自 Chisel3.util 的内置 shiftRegister?
How to use this built-in shiftRegister from Chisel3.util properly?
我试图将这个内置的 shiftRegister 与 chisel-tutorial 中的一些常见移位寄存器进行比较。但是这个似乎实际上并没有移动位? 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()))
我得到了以下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
所以我的问题是,如何正确使用 Chisel3.util 中的这个内置 shiftRegister?
来自您的 link 和 ScalaDoc 评论:
/** 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 = { ...
ShiftRegister
延迟输入数据in
、n
个周期。对于被移入和移出的类型,它是通用的。我怀疑您指的是定型移位寄存器,它每个周期移入和移出 1 位数据。您可以通过输入类型 Bool
:
轻松地使用此构造来做到这一点
class Foo extends Module {
val io = IO(new Bundle {
val in = Input(Bool())
val out = Output(Bool())
})
io.out := ShiftRegister(io.in, 4)
}
给予
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
请注意,该构造向您隐藏了底层的触发器,它 returns 最终触发器的输出,即每个周期的 "shifted out value"。
我试图将这个内置的 shiftRegister 与 chisel-tutorial 中的一些常见移位寄存器进行比较。但是这个似乎实际上并没有移动位? 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()))
我得到了以下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
所以我的问题是,如何正确使用 Chisel3.util 中的这个内置 shiftRegister?
来自您的 link 和 ScalaDoc 评论:
/** 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 = { ...
ShiftRegister
延迟输入数据in
、n
个周期。对于被移入和移出的类型,它是通用的。我怀疑您指的是定型移位寄存器,它每个周期移入和移出 1 位数据。您可以通过输入类型 Bool
:
class Foo extends Module {
val io = IO(new Bundle {
val in = Input(Bool())
val out = Output(Bool())
})
io.out := ShiftRegister(io.in, 4)
}
给予
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
请注意,该构造向您隐藏了底层的触发器,它 returns 最终触发器的输出,即每个周期的 "shifted out value"。