Search code examples
chisel

Why is ready signal always 0 in arbiter?


I'm trying to follow chisel3 materials(jupyter) and i'm wondering why ready signals are always 0 in arbiter.

Here is the code below:

test(new Module {
    // Example circuit using a priority arbiter
    val io = IO(new Bundle {
      val in = Flipped(Vec(2, Decoupled(UInt(8.W))))
      val out = Decoupled(UInt(8.W))
    })
    // Arbiter doesn't have a convenience constructor, so it's built like any Module
    val arbiter = Module(new Arbiter(UInt(8.W), 2))  // 2 to 1 Priority Arbiter
    arbiter.io.in <> io.in
    io.out <> arbiter.io.out
  }) { c =>
    c.io.in(0).valid.poke(false.B)
    c.io.in(1).valid.poke(false.B)
    println(s"Start:")
    println(s"\tin(0).ready=${c.io.in(0).ready.peek().litValue}, in(1).ready=${c.io.in(1).ready.peek().litValue}")
    println(s"\tout.valid=${c.io.out.valid.peek().litValue}, out.bits=${c.io.out.bits.peek().litValue}")
    c.io.in(1).valid.poke(true.B)  // Valid input 1
    c.io.in(1).bits.poke(42.U)
    // What do you think the output will be?
    println(s"valid input 1:")
    println(s"\tin(0).ready=${c.io.in(0).ready.peek().litValue}, in(1).ready=${c.io.in(1).ready.peek().litValue}")
    println(s"\tout.valid=${c.io.out.valid.peek().litValue}, out.bits=${c.io.out.bits.peek().litValue}")
    c.io.in(0).valid.poke(true.B)  // Valid inputs 0 and 1
    c.io.in(0).bits.poke(43.U)
    // What do you think the output will be? Which inputs will be ready?
    println(s"valid inputs 0 and 1:")
    println(s"\tin(0).ready=${c.io.in(0).ready.peek().litValue}, in(1).ready=${c.io.in(1).ready.peek().litValue}")
    println(s"\tout.valid=${c.io.out.valid.peek().litValue}, out.bits=${c.io.out.bits.peek().litValue}")
    c.io.in(1).valid.poke(false.B)  // Valid input 0
    // What do you think the output will be?
    println(s"valid input 0:")
    println(s"\tin(0).ready=${c.io.in(0).ready.peek().litValue}, in(1).ready=${c.io.in(1).ready.peek().litValue}")
    println(s"\tout.valid=${c.io.out.valid.peek().litValue}, out.bits=${c.io.out.bits.peek().litValue}")
}

and the result is:

Start:
    in(0).ready=0, in(1).ready=0
    out.valid=0, out.bits=0
valid input 1:
    in(0).ready=0, in(1).ready=0
    out.valid=1, out.bits=42
valid inputs 0 and 1:
    in(0).ready=0, in(1).ready=0
    out.valid=1, out.bits=43
valid input 0:
    in(0).ready=0, in(1).ready=0
    out.valid=1, out.bits=43

The material is explaining about ready signal like this: Ready signal should only be dependent on whether the sink is able to receive data

So I thought that when valid signal comes to input, c.io.in.ready signal should be 1(or true) but ready signal is always 0 here, even when both in(0) and in(1) is valid

Thanks for answering and actually this is the first time for me to ask a question here, so if there is any problem(or something that i have to know when i write a question here), please let me know. Thank you!


Solution

  • Your code looks good, but you are just missing a couple of small things.

    The Arbiter will not say it is ready until it's output ready is high. Thus you need to add a

    c.io.out.ready.poke(true.B)
    

    and that will pass the ready along to the inputs.

    You also need to advance the clock after you add poke values into the arbiter. Add the following after each block of pokes:

    c.clock.step()