Chisel3: Verilog "default" case equivalent

Viewed 1378

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 Answers
Related