【问题标题】:Chisel3: Verilog "default" case equivalentChisel3:Verilog“默认”案例等效
【发布时间】:2017-07-17 12:57:10
【问题描述】:

是否有可能在 Chisel “switch” 语句中具有类似于 Verilog “default” 情况的 Chisel “is” 条件?这是防止从 FS​​M 的组合输出推断锁存器所必需的。

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 语句中的分配更加清晰。

【问题讨论】:

    标签: chisel


    【解决方案1】:

    你可以故意加括号来标识一些代码应该一起阅读。 比如:

    { // 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 永远不会产生闩锁。如果以后没有启用分配更改,则第一个分配生效。

    【讨论】:

    • 完全切换到使用 when、elsewhen 和 elsewhen 构造会更好,因为 else 的行为类似于 Verilog 中的默认状态。这消除了对额外括号和默认分配的需要。谢谢 Wei。从 Chisel 文档中不清楚 switch() 构造中是否支持 is() 构造以外的任何东西
    猜你喜欢
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 2016-04-04
    • 1970-01-01
    相关资源
    最近更新 更多