Chisel3: Verilog "default" case equivalent

Is it possible to have a Chisel "is" condition which behaves similar to a Verilog "default" case in a Chisel "switch" statement? This is required to prevent latches being inferred for combinatorial outputs from an FSM.

Verilog Example:

module detector (clk, rstn, in1, in2, out1, out2); input clk, rstn, in1, in2; output reg out1, out2; localparam [1:0] IDLE = 2'b01; localparam [1:0] GOT_IN1 = 2'b10; reg [1:0] state, nxtState; always @ (posedge clk or negedge rstn) begin if (!rstn) begin state <= IDLE; end else begin state <= nxtState; end end always @ (*) begin case (state) IDLE: begin if (in1) begin out1 = 1'b1; out2 = 1'b0; nxtState = GOT_IN1; end else begin out1 = 1'b0; out2 = 1'b0; nxtState = IDLE; end end GOT_IN1: begin if (in2) begin out1 = 1'b0; out2 = 1'b1; nxtState = IDLE; end else begin out1 = 1'b0; out2 = 1'b0; nxtState = GOT_IN1; end end default: begin out1 = 1'b0; out2 = 1'b0; nxtState = IDLE; end endcase end endmodule 

Chisel2 allowed this type of behavior as a default value could be assigned to out1 and out2 in the switch statement outside of an "is" condition.

switch (state) { io.out1 := UInt(0) io.out2 := UInt(0) is (IDLE) { when (io.in1 === UInt(1)) { io.out1 := UInt(1) io.out2 := UInt(0) state := GOT_IN1 } .otherwise { io.out1 := UInt(0) io.out2 := UInt(0) state := IDLE } } is (GOT_IN1) { when (io.in2 === UInt(1)) { io.out1 := UInt(0) io.out2 := UInt(1) state := IDLE } .otherwise { io.out1 := UInt(0) io.out2 := UInt(0) state := GOT_IN1 } } } 

Chisel3 doesn't support this default assignment syntax like Chisel2. A build error gets flagged:

◾exception during macro expansion: java.lang.Exception: Cannot include blocks that do not begin with is() in switch. at chisel3.util.switch 

Chisel3 doesn't appear to have any method to prevent a latch from being inferred on the out1 and out2 outputs. I understand that out1 and out2 assignments can be moved outside of the switch statement and handled using a conditional assignment. However, from a code visibility standpoint it's clearer to handle the assignments within the case statement for large FSMs with dozens of states and combinatorial outputs.

1 Answer

You can add bracket deliberately to identify some code should be read together. Something like:

{ // state machine block io.out1 := UInt(0) io.out2 := UInt(0) when (state === IDLE) { when (io.in1 === UInt(1)) { io.out1 := UInt(1) io.out2 := UInt(0) state := GOT_IN1 } .otherwise { io.out1 := UInt(0) io.out2 := UInt(0) state := IDLE } } when (state === GOT_IN1) { when (io.in2 === UInt(1)) { io.out1 := UInt(0) io.out2 := UInt(1) state := IDLE } .otherwise { io.out1 := UInt(0) io.out2 := UInt(0) state := GOT_IN1 } } } 

I believe Chisel will never generate latches. The first assignment takes effect if no later assignment change is enabled.

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like