麻烦理解凿子中的陈述顺序

发布于 2025-02-12 10:59:21 字数 1507 浏览 2 评论 0原文

这是一个简单的模块,其中包含一个倒数计数器:

import chisel3.util.{Valid, DeqIO}
class Input(WIDTH : Int) extends Bundle {
  val x = UInt(WIDTH.W)
}
class Output(WIDTH : Int) extends Bundle {
  val y = UInt(WIDTH.W)
}
class DownCount(WIDTH : Int) extends Module {
  val io  = IO(new Bundle {
    val in  = DeqIO(new Input(WIDTH))
    val out = Output(Valid(new Output(WIDTH)))
  })
  val i = Reg(UInt(WIDTH.W))
  val p = RegInit(false.B)

  printf("i = %d, p = %b, out.valid = %b\n",
    i, p, io.out.valid)
  io.in.ready := !p
  io.out.valid := false.B
  io.out.bits.y := 10.U
  when (p) {
    i := i - 1.U
    when (i === 0.U) {
      printf("Before setting out.valid = %b\n", io.out.valid)
      p := false.B
      // Here the register is set to 1.
      io.out.valid := true.B
    }
  }.otherwise {
    when (io.in.valid) {
      printf("Initializing\n")
      i := WIDTH.U - 1.U
      p := true.B
    }
  }
}

这是在模块上应用clock.step()函数后几次输出的输出:

i =    0, p = 0, out.valid = 0
Initializing
i =    7, p = 1, out.valid = 0
i =    6, p = 1, out.valid = 0
i =    5, p = 1, out.valid = 0
i =    4, p = 1, out.valid = 0
i =    3, p = 1, out.valid = 0
i =    2, p = 1, out.valid = 0
i =    1, p = 1, out.valid = 0
i =    0, p = 1, out.valid = 1
Before setting out.valid = 1     <-- why is it 1 here??
i =  255, p = 0, out.valid = 0

到底如何io.out.ut.valid < /代码>为1(true) 它被分配true.b值?凿子是否以某种怪异的方式重新排序printf语句?

Here is a simple module containing a down counter:

import chisel3.util.{Valid, DeqIO}
class Input(WIDTH : Int) extends Bundle {
  val x = UInt(WIDTH.W)
}
class Output(WIDTH : Int) extends Bundle {
  val y = UInt(WIDTH.W)
}
class DownCount(WIDTH : Int) extends Module {
  val io  = IO(new Bundle {
    val in  = DeqIO(new Input(WIDTH))
    val out = Output(Valid(new Output(WIDTH)))
  })
  val i = Reg(UInt(WIDTH.W))
  val p = RegInit(false.B)

  printf("i = %d, p = %b, out.valid = %b\n",
    i, p, io.out.valid)
  io.in.ready := !p
  io.out.valid := false.B
  io.out.bits.y := 10.U
  when (p) {
    i := i - 1.U
    when (i === 0.U) {
      printf("Before setting out.valid = %b\n", io.out.valid)
      p := false.B
      // Here the register is set to 1.
      io.out.valid := true.B
    }
  }.otherwise {
    when (io.in.valid) {
      printf("Initializing\n")
      i := WIDTH.U - 1.U
      p := true.B
    }
  }
}

Here is the output after applying the clock.step() function on the module a few times:

i =    0, p = 0, out.valid = 0
Initializing
i =    7, p = 1, out.valid = 0
i =    6, p = 1, out.valid = 0
i =    5, p = 1, out.valid = 0
i =    4, p = 1, out.valid = 0
i =    3, p = 1, out.valid = 0
i =    2, p = 1, out.valid = 0
i =    1, p = 1, out.valid = 0
i =    0, p = 1, out.valid = 1
Before setting out.valid = 1     <-- why is it 1 here??
i =  255, p = 0, out.valid = 0

How on earth can io.out.valid be 1 (true) before it is assigned the true.B value? Is Chisel reordering printf statement in some weird way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

汹涌人海 2025-02-19 10:59:21

似乎是正常的行为。使用:=运算符,左值将在时钟周期结束时以正确的值编写。
out.valid仍然是true.bfalse.b分配。

// i =    0, p = 1, out.valid = 1
  printf("i = %d, p = %b, out.valid = %b\n",i, p, io.out.valid) 
  io.in.ready := !p
  io.out.valid := false.B
// Here, io.out.valid is still true.B if printf was true.B
// false.B will be written at the end of cycle,
//  except if another connection write true.B
  io.out.bits.y := 10.U
  when (p) {
    i := i - 1.U
    when (i === 0.U) {
      printf("Before setting out.valid = %b\n", io.out.valid)
      p := false.B
      // Here the register is set to 1.
      io.out.valid := true.B  // Will be set to true.B (but was already true.B)
    }
  }.otherwise {
    when (io.in.valid) {
      printf("Initializing\n")
      i := WIDTH.U - 1.U
      p := true.B
    }
  }
}

It seems to be normal behavior. With the := operator, the left-value will be written with right value at the end of clock cycle.
out.valid is still true.B just after false.B assignation.

// i =    0, p = 1, out.valid = 1
  printf("i = %d, p = %b, out.valid = %b\n",i, p, io.out.valid) 
  io.in.ready := !p
  io.out.valid := false.B
// Here, io.out.valid is still true.B if printf was true.B
// false.B will be written at the end of cycle,
//  except if another connection write true.B
  io.out.bits.y := 10.U
  when (p) {
    i := i - 1.U
    when (i === 0.U) {
      printf("Before setting out.valid = %b\n", io.out.valid)
      p := false.B
      // Here the register is set to 1.
      io.out.valid := true.B  // Will be set to true.B (but was already true.B)
    }
  }.otherwise {
    when (io.in.valid) {
      printf("Initializing\n")
      i := WIDTH.U - 1.U
      p := true.B
    }
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文