1

シフト レジスタを含むデータ パスを作成しようとしていますが、新しい入力を待っている間、すべてを停止できるようにしたいと考えています。標準ライブラリにイネーブル行のあるシフト レジスタがあることがわかりました (ただし、デフォルトは true です)。

問題は、私がそれを使用しようとすると、コンパイルされた Verilog が実際にイネーブルが低いときにシフト レジスタを停止しているように見えないことです。

次のチゼル コードを考えてみましょう。

package SR

import Chisel._

class SR extends Module {
  val io = new Bundle { 
    val in = UInt(INPUT, 8)
    val enable = Bool(INPUT)
    val out = UInt(OUTPUT, 8)
  }
  io.out:= ShiftRegister(io.in, 10, io.enable)
}

class SRTests(c: SR) extends Tester(c) {
}

object SR {
  def main(args: Array[String]): Unit = {
    val tutArgs = args.slice(1, args.length)
    chiselMainTest(tutArgs, () => Module(new SR())) {
      c => new SRTests(c) }
  }
}

次のベリログを取得します。

module SR(input clk,
    input [7:0] io_in,
    input  io_enable,
    output[7:0] io_out
);

  reg [7:0] R0;
  reg [7:0] R1;
  reg [7:0] R2;
  reg [7:0] R3;
  reg [7:0] R4;
  reg [7:0] R5;
  reg [7:0] R6;
  reg [7:0] R7;
  reg [7:0] R8;
  reg [7:0] R9;
  wire[7:0] T10;

`ifndef SYNTHESIS
  integer initvar;
  initial begin
    #0.002;
    R0 = {1{$random}};
    R1 = {1{$random}};
    R2 = {1{$random}};
    R3 = {1{$random}};
    R4 = {1{$random}};
    R5 = {1{$random}};
    R6 = {1{$random}};
    R7 = {1{$random}};
    R8 = {1{$random}};
    R9 = {1{$random}};
  end
`endif

  assign io_out = R0;
  assign T10 = io_enable ? io_in : R9;

  always @(posedge clk) begin
    R0 <= R1;
    R1 <= R2;
    R2 <= R3;
    R3 <= R4;
    R4 <= R5;
    R5 <= R6;
    R6 <= R7;
    R7 <= R8;
    R8 <= R9;
    if(io_enable) begin
      R9 <= io_in;
    end
  end
endmodule

シフトレジスタは、全体ではなく最初の値のみを固定しているようです。たとえば、連続するクロック サイクルで 1,2,3,4,5 を書き込んで、1,2,3 のイネーブル ハイのみを保持した場合、3 は正しく保持されますが、1 と 2 は最終的にシフト アウトし、全体がシフト レジスタは値 3 で満たされます。

のみのチュートリアルで見られるシフト レジスタの例のような動作を希望します。問題は、パラメータ化可能な長いシフト レジスタが必要なため、各レジスタを手書きすることはできません。チゼル チュートリアルに見られるような有効な動作を備えたシフト レジスタを実装するチゼル コードの例に非常に感謝しますが、標準ライブラリに見られるようにさまざまな長さにパラメータ化されます。

4

1 に答える 1