ucb-bar / chisel2-deprecated

chisel.eecs.berkeley.edu
388 stars 90 forks source link

Wrong code interpretation? #618

Closed ghost closed 8 years ago

ghost commented 8 years ago

Hello! I got confused when this code:

val io = new Bundle {
  val a = Bool(OUTPUT)
}
val start = Reg(init = Bool(false))
start := Bool(true)
when (start) {
  io.a := Bool(true)
}
io.a := Bool(false)

gave me this:

module Top(
    output io_a
);
  assign io_a = 1'h0;
endmodule

Then I changed the code to this:

val io = new Bundle {
  val a = Bool(OUTPUT)
}
val start = Reg(init = Bool(false))
start := Bool(true)
when (start) {
  a := Bool(true)
} .otherwise {                       // <- just added .otherwise { ... }
  a := Bool(false)
}

and now the result is what I expected:

module Top(input clk, input reset,
    output io_a
);

  wire T0;
  reg  start;
  wire T1;

`ifndef SYNTHESIS
// synthesis translate_off
  integer initvar;
  initial begin
    #0.002;
    start = {1{$random}};
  end
// synthesis translate_on
`endif

  assign io_a = T0;
  assign T0 = start ? 1'h1 : 1'h0;
  assign T1 = reset == 1'h0;

  always @(posedge clk) begin
    start <= T1;
  end
endmodule

I always thought that I could place "default value" for wire wherever I want and just specify the values with 'when' blocks without explicitly saying 'otherwise' for this wire. Well, not just thought, I use this approach with slightly more complicated dependencies for 'when' expression and it works as expected.

Is Chisel right about these two examples?

seldridge commented 8 years ago

You would have to specify the default value before your when block to get the anticipated behavior (same thing with Verilog). That io.a := Bool(false) is overwriting any logic that you establish with your when block., but it should give you the correct behavior if you place it before the when block.

ghost commented 8 years ago

Right! Thanks!