Scala 向具有下一个字段的寄存器添加enable
我有一个浮点添加凿模块,我想使用它有几个阶段的管道。我想让它可以暂停,这样我就可以将它安装到一个管道中,这个管道在任何给定时间都可能无法使用输出数据,因此我希望将部分计算的加法存储在模块中 我最初希望我可以添加一个启用信号,然后添加它作为更新各种寄存器的另一个条件,但不幸的是,该模块包含了大量Reg(next=xxx)形式的语句。我很好奇,如果我只是将寄存器分配给它自己,会发生什么,即使它的输入已经通过next=xxx分配,所以我做了一个测试模块,得到了一些(我认为)奇怪的结果 这是scala:Scala 向具有下一个字段的寄存器添加enable,scala,verilog,chisel,Scala,Verilog,Chisel,我有一个浮点添加凿模块,我想使用它有几个阶段的管道。我想让它可以暂停,这样我就可以将它安装到一个管道中,这个管道在任何给定时间都可能无法使用输出数据,因此我希望将部分计算的加法存储在模块中 我最初希望我可以添加一个启用信号,然后添加它作为更新各种寄存器的另一个条件,但不幸的是,该模块包含了大量Reg(next=xxx)形式的语句。我很好奇,如果我只是将寄存器分配给它自己,会发生什么,即使它的输入已经通过next=xxx分配,所以我做了一个测试模块,得到了一些(我认为)奇怪的结果 这是scala:
package Hello
import Chisel._
class Hello extends Module {
val io = new Bundle {
val in = UInt(INPUT, 8)
val en = Bool(INPUT)
val out = UInt(OUTPUT, 8)
}
val test_reg = Reg(next = io.in)
io.out := test_reg
when (!io.en) {
test_reg := test_reg
}
}
object Hello {
def main(args: Array[String]): Unit = {
}
}
下面是最终的verilog:
module Hello(input clk,
input [7:0] io_in,
input io_en,
output[7:0] io_out
);
reg [7:0] test_reg;
wire[7:0] T0;
wire T1;
`ifndef SYNTHESIS
// synthesis translate_off
integer initvar;
initial begin
#0.002;
test_reg = {1{$random}};
end
// synthesis translate_on
`endif
assign io_out = test_reg;
assign T0 = T1 ? test_reg : io_in;
assign T1 = io_en ^ 1'h1;
always @(posedge clk) begin
if(T1) begin
test_reg <= test_reg;
end else begin
test_reg <= io_in;
end
end
endmodule
模块你好(输入时钟,
将[7:0]io_输入,
输入io_en,
输出[7:0]输入输出
);
reg[7:0]测试\u reg;
导线[7:0]T0;
导线T1;
`ifndef合成
//综合翻译
整数初始化变量;
初始开始
#0.002;
test_reg={1{$random}};
结束
//综合翻译
`恩迪夫
分配io_out=test_reg;
分配T0=T1?测试注册:输入输出输入;
分配T1=io_en^1'h1;
始终@(posedge clk)开始
如果(T1)开始
test_reg我从未使用过凿子,但我猜这是:
when (io.en) {
test_reg := io.in
}
会产生这样的结果:
always @(posedge clk) begin
if(io_en) begin
test_reg <= io_in;
end
end
始终@(posedge clk)开始
如果(io_en)开始
测试注册
我认为这是一种糟糕的编码实践——要么使用Reg(next=…)
要么通过test\u Reg:=…
指定下一个值,但不要两者混合使用!首先,对于读者来说,哪位作者应该优先(尽管答案是“最后一位作者获胜”)是不明确的。其次,当读者看到Reg(next=…)
时,他可能不希望看到编写器在代码的其他地方被覆盖
写为:
val test_reg = Reg(io.in.clone())
when (io.en) {
test_reg := io.in
}
它仍然会生成一些未使用的信号,但代码的意图要清楚得多
always @(posedge clk) begin
if(io_en) begin
test_reg <= io_in;
end
end
始终@(posedge clk)开始
如果(io_en)开始
test_reg问题在于,我的示例试图模拟修改浮点加法器(我没有编写的代码)时会遇到的情况。如果我是从头开始写的,我会完全这样做——根据断言的enable更新状态元素。但是,我试图修改代码,同时尽量减少出错的机会,因此我希望尽可能少地重写已经存在的逻辑。原始作者(无意启用)编写了val reg_manta=reg(next=a_wrap.尾数)之类的东西,这意味着我实际上必须测试io.en何时不松弛。好的,我知道你在做什么,但是,如果试图通过只添加几行代码来解决这个问题,你只会让下一个查看代码的人感到困惑。那个人将来可能就是你,你看着这个,不知道它应该做什么。最好注释掉旧代码并用新代码替换它。使用凿子.RegEnable(updateData,resetData,enable)代替Reg也是一种选择。
always @(posedge clk) begin
if(io_en) begin
test_reg <= io_in;
end
end