Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 向具有下一个字段的寄存器添加enable_Scala_Verilog_Chisel - Fatal编程技术网

Scala 向具有下一个字段的寄存器添加enable

Scala 向具有下一个字段的寄存器添加enable,scala,verilog,chisel,Scala,Verilog,Chisel,我有一个浮点添加凿模块,我想使用它有几个阶段的管道。我想让它可以暂停,这样我就可以将它安装到一个管道中,这个管道在任何给定时间都可能无法使用输出数据,因此我希望将部分计算的加法存储在模块中 我最初希望我可以添加一个启用信号,然后添加它作为更新各种寄存器的另一个条件,但不幸的是,该模块包含了大量Reg(next=xxx)形式的语句。我很好奇,如果我只是将寄存器分配给它自己,会发生什么,即使它的输入已经通过next=xxx分配,所以我做了一个测试模块,得到了一些(我认为)奇怪的结果 这是scala:

我有一个浮点添加凿模块,我想使用它有几个阶段的管道。我想让它可以暂停,这样我就可以将它安装到一个管道中,这个管道在任何给定时间都可能无法使用输出数据,因此我希望将部分计算的加法存储在模块中

我最初希望我可以添加一个启用信号,然后添加它作为更新各种寄存器的另一个条件,但不幸的是,该模块包含了大量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