玩命加载中 . . .

SpinalHDL基础-条件语句


条件语句

由于if被scala语言占用了,SpinalHDL使用when…elsewhen…otherwise来用作硬件的条件语句

class top extends Module{
    val a,b = UInt(8 bits)
    val mode = Bits(2 bits)
    
    when(a === b) {
        mode := 0
    } elsewhen(a>b) {
        mode := 1
    } otherwise {
        mode := 2
    }
}
module top (
);

  wire       [7:0]    a;
  wire       [7:0]    b;
  reg        [1:0]    mode;

  always @(*) begin
    if((a == b)) begin
      mode = 2'b00;
    end else begin
      if((b < a)) begin
        mode = 2'b01;
      end else begin
        mode = 2'b10;
      end
    end
  end


endmodule

三元操作符

SpinalHDL有2种方法实现verilog的en ? a : b,建议使用后2个方法,第一种方法的|容易与逻辑或混淆。复杂条件建议使用when,这样更加清晰。

  • en ? a | b
  • en ? a otherwise b,推荐
  • Mux(en,a,b),推荐
class top extends Module{
    val a,b = UInt(8 bits)   
    val mode1 = (a===b) ? B"2'd0" | B"2'd1"
    val mode2 = (a===b) ? B"2'd0" otherwise B"2'd1"
    val mode3 = Mux(a===b,B"2'd0",B"2'd1")
}
module top (
);

  wire       [7:0]    a;
  wire       [7:0]    b;
  wire       [1:0]    mode1;
  wire       [1:0]    mode2;
  wire       [1:0]    mode3;

  assign mode1 = ((a == b) ? 2'b00 : 2'b01);
  assign mode2 = ((a == b) ? 2'b00 : 2'b01);
  assign mode3 = ((a == b) ? 2'b00 : 2'b01);

endmodule

case语句

class top extends Module{
    val sel = Bits(2 bits)
    val mode = Bits(3 bits)
    switch(sel) {
        is(0,2) {
            mode := B"3'd0"
        }
        is(1) {
            mode := B"3'd1"
        }
        default {
            mode := B"3'd2"
        }
    }
}
module top (
);

  wire       [1:0]    sel;
  reg        [2:0]    mode;

  always @(*) begin
    case(sel)
      2'b00, 2'b10 : begin
        mode = 3'b000;
      end
      2'b01 : begin
        mode = 3'b001;
      end
      default : begin
        mode = 3'b010;
      end
    endcase
  end


endmodule

case简写方式

class top extends Module{
    val sel = Bits(2 bits)
    val mode = sel.mux(
        (0,1) -> B"3'd0",
        2 -> B"3'd1",
        default -> B"3'd2"
    )
    
    val mode_reg = Reg(UInt(3 bits))
    mode_reg.switchAssign(sel)(
        (0,1) -> U"3'd0",
        2 -> U"3'd1"
    )
}
module top (
  input               clk,
  input               rstn
);

  wire       [1:0]    sel;
  reg        [2:0]    mode;
  reg        [2:0]    mode_reg;

  always @(*) begin
    case(sel)
      2'b00, 2'b01 : begin
        mode = 3'b000;
      end
      2'b10 : begin
        mode = 3'b001;
      end
      default : begin
        mode = 3'b010;
      end
    endcase
  end

  always @(posedge clk) begin
    case(sel)
      2'b00, 2'b01 : begin
        mode_reg <= 3'b000;
      end
      2'b10 : begin
        mode_reg <= 3'b001;
      end
      default : begin
      end
    endcase
  end


endmodule

等分case

class top extends Module{
    val sel  = UInt(2 bits)
    val data = Bits(128 bits)

    // Dividing a wide Bits type into smaller chunks, using a mux:
    val dataWord1 = sel.muxList(for (index <- 0 until 4) yield (index, data(index*32+32-1 downto index*32)))
    val dataWord2 = sel.muxList(data.divideIn(4 slices))

    // A shorter way to do the same thing:
    val dataWord3 = data.subdivideIn(32 bits)(sel)
}
module top (
);

  reg        [31:0]   dataWord3_bits;
  wire       [1:0]    sel;
  wire       [127:0]  data;
  reg        [31:0]   dataWord1;
  reg        [31:0]   dataWord2;
  wire       [31:0]   dataWord3;

  always @(*) begin
    case(sel)
      2'b00 : begin
        dataWord3_bits = data[31 : 0];
      end
      2'b01 : begin
        dataWord3_bits = data[63 : 32];
      end
      2'b10 : begin
        dataWord3_bits = data[95 : 64];
      end
      default : begin
        dataWord3_bits = data[127 : 96];
      end
    endcase
  end

  always @(*) begin
    case(sel)
      2'b00 : begin
        dataWord1 = data[31 : 0];
      end
      2'b01 : begin
        dataWord1 = data[63 : 32];
      end
      2'b10 : begin
        dataWord1 = data[95 : 64];
      end
      default : begin
        dataWord1 = data[127 : 96];
      end
    endcase
  end

  always @(*) begin
    case(sel)
      2'b00 : begin
        dataWord2 = data[31 : 0];
      end
      2'b01 : begin
        dataWord2 = data[63 : 32];
      end
      2'b10 : begin
        dataWord2 = data[95 : 64];
      end
      default : begin
        dataWord2 = data[127 : 96];
      end
    endcase
  end

  assign dataWord3 = dataWord3_bits;

endmodule

casez

class top extends Module{
    val sel = Bits(4 bits)
    val mode = Bits(3 bits)
    switch(sel) {
        is(M"---1") {
            mode := B"3'd0"
        }
        is(M"--1-") {
            mode := B"3'd1"
        }
        is(M"-1--") {
            mode := B"3'd2"
        }
        default {
            mode := B"3'd3"
        }
    }
}
module top (
);

  wire       [3:0]    sel;
  reg        [2:0]    mode;

  always @(*) begin
    casez(sel)
      4'b???1 : begin
        mode = 3'b000;
      end
      4'b??1? : begin
        mode = 3'b001;
      end
      4'b?1?? : begin
        mode = 3'b010;
      end
      default : begin
        mode = 3'b011;
      end
    endcase
  end


endmodule

本文作者: 董续胜

本文链接: https://dxsm.github.io/p/spinalhdl-conditional.html

版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0许可协议。转载请注明出处!


 评论