Chisel3:Verilog“默认”情况等效

时间:2017-07-17 12:57:10

标签: chisel

是否可能有一个Chisel“is”条件,其行为类似于Chisel“switch”语句中的Verilog“默认”情况?这是为了防止锁存器被推断为来自FSM的组合输出。

Verilog示例:

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允许这种行为,因为默认值可以在“is”条件之外的switch语句中分配给out1和out2。

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不支持像Chisel2这样的默认赋值语法。构建错误被标记:

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

Chisel3似乎没有任何方法可以防止在out1和out2输出上推断出锁存器。我知道out1和out2赋值可以移到switch语句之外,并使用条件赋值进行处理。但是,从代码可见性的角度来看,处理具有数十个状态和组合输出的大型FSM的case语句中的赋值更为清晰。

1 个答案:

答案 0 :(得分:3)

您可以故意添加括号以识别应该一起阅读的一些代码。 类似的东西:

{ // 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
        }
    }
}

我相信Chisel永远不会生成锁存器。如果未启用后续分配更改,则第一个分配将生效。