我们正在实现一个处理器管道,并希望有效的方法来阻止它。如果我们控制了电路,那么我们将使用具有使能输入的锁存器。要停止,只需禁用锁存器,然后他们不会在下一个时钟边沿更新,它们将保持不变直到再次启用。
但是,如何在Chisel中做到这一点?目前还不清楚"什么时候"声明将转化为。有助于幕后的黑魔法,以及如何控制终端电路的提示将不胜感激。
答案 0 :(得分:0)
when
语句基本上只是帮助构建多路复用树的简写方法。例如:
class SimpleWhen extends Module {
val io = IO(new Bundle {
val cond = Input(Bool())
val a = Input(UInt(32.W))
val b = Input(UInt(32.W))
val z = Output(UInt(32.W))
})
when (io.cond) { io.z := io.a }
.otherwise { io.z := io.b }
}
如果我们从中生成Verilog,我们得到(在Chisel 3中):
module SimpleWhen(
input clock,
input reset,
input io_cond,
input [31:0] io_a,
input [31:0] io_b,
output [31:0] io_z
);
wire _T_11;
wire [31:0] _GEN_1;
assign io_z = _GEN_1;
assign _T_11 = io_cond == 1'h0;
assign _GEN_1 = _T_11 ? io_b : io_a;
endmodule
正如人们所料,此模块基本上只根据条件a
在b
和cond
之间进行多路复用。
对于更有趣的寄存器用例:
class RegEnableTest extends Module {
val io = IO(new Bundle {
val en = Input(Bool())
val a = Input(Valid(UInt(32.W)))
val b = Input(Valid(UInt(32.W)))
val out = Output(UInt(32.W))
})
val regNext = Wire(UInt(32.W))
val myReg = Reg(UInt(32.W))
when (io.en) { myReg := regNext }
regNext := myReg
when (io.a.valid) { regNext := io.a.bits }
when (io.b.valid) { regNext := io.b.bits }
io.out := myReg
}
此处我们有一个注册表myReg
,只有在输入en
为高时才会更新。生成的Verilog是:
module RegEnableTest(
input clock,
input reset,
input io_en,
input io_a_valid,
input [31:0] io_a_bits,
input io_b_valid,
input [31:0] io_b_bits,
output [31:0] io_out
);
wire [31:0] regNext;
reg [31:0] myReg;
reg [31:0] _GEN_1;
wire [31:0] _GEN_0;
wire [31:0] _GEN_2;
assign io_out = myReg;
assign regNext = _GEN_2;
assign _GEN_0 = io_en ? regNext : myReg;
assign _GEN_2 = io_b_valid ? io_b_bits : io_a_bits;
// ... Randomization removed for clarity ...
always @(posedge clock) begin
if (io_en) begin
myReg <= regNext;
end
end
endmodule
myReg仅在io.en
为高时更新。使用RegEnable(https://chisel.eecs.berkeley.edu/api/index.html#chisel3.util.RegEnable $)
答案 1 :(得分:0)
以下是如何使用RegEnable来实现它,这是一个帮助对象构造启用的寄存器: https://github.com/ucb-bar/chisel3/blob/master/src/main/scala/chisel3/util/Reg.scala
import chisel3._
import chisel3.util._
class RegEnableTest extends Module {
val io = IO(new Bundle {
val en = Input(Bool())
val a = Input(Valid(UInt(32.W)))
val b = Input(Valid(UInt(32.W)))
val out = Output(UInt(32.W))
})
val regNext = Wire(UInt(32.W))
val myReg = RegEnable(regNext,io.en)
when (io.a.valid) { regNext := io.a.bits }
when (io.b.valid) { regNext := io.b.bits }
io.out := myReg
}
这会产生以下verilog(编辑以删除不需要的宏)
module RegEnableTest(
input clock,
input reset,
input io_en,
input io_a_valid,
input [31:0] io_a_bits,
input io_b_valid,
input [31:0] io_b_bits,
output [31:0] io_out
);
wire [31:0] regNext;
reg [31:0] myReg;
reg [31:0] _GEN_1;
wire [31:0] _GEN_0;
wire [31:0] _GEN_2;
assign io_out = myReg;
assign regNext = _GEN_2;
assign _GEN_0 = io_en ? regNext : myReg;
assign _GEN_2 = io_b_valid ? io_b_bits : io_a_bits;
always @(posedge clock) begin
if (io_en) begin
myReg <= regNext;
end
end
endmodule
答案 2 :(得分:0)
或者你可以这样做:
val regNext = Wire(UInt(32.W))
when (io.a.valid) { regNext := io.a.bits }
when (io.b.valid) { regNext := io.b.bits }
io.out := RegEnable(regNext,io.en)
但是状态在verilog代码中没有好名字
assign io_out = _T_30;
assign regNext = _GEN_1;
assign _GEN_1 = io_b_valid ? io_b_bits : io_a_bits;
assign _GEN_2 = io_en ? regNext : _T_30;
always @(posedge clock) begin
if (io_en) begin
_T_30 <= regNext;
end
end
endmodule