3

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 1

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Switching completely to using a when, elsewhen, otherwise construct works even better as the otherwise behaves like the default state in Verilog. This removes the need for the extra bracket and the need for the default assignments.Thanks Wei. It's not clear from the Chisel documentation that anything other than an is() construct is supported within switch() construct

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.