Bits

一、描述(Description)

Bits类型对应于没有算数意义的bits向量

二、声明(Declaration)

声明bit向量的语法如下所示:([]中为可填项)

语法 描述 返回类型
Bits[()] 创建一个BitVector, bits个数由编译器推断得到 Bits
Bits(x bits) 创建一个x bits的BitVector Bits
B(value: Int[,x bits])
B(value: BigInt[,x bits])
创建一个赋初值的x bits的BitVector Bits
B"[[size']base]value" 创建一个基h/d/o/b的赋初值的BitVector Bits
B([x bits,] element, ...) 创建一个由给定元素赋值的BitVector Bits
//Declaration
val myBits = Bits()
val myBits1 = Bits(32 bits)
val myBits2 = B(25, 8 bits)
val myBits3 = B"8'xFF"  //基可以是x/h(16), d(10), o(8), b(2)
val myBits4 = B"1001_0011"  //_增加可读性

//Element
val myBits5 = B(8 bits, default -> True) //"11111111"
val myBits6 = B(8 bits, (7 downto 5) -> B"101", 4 -> true, 3 -> True, default -> false) //"10111000"
val myBits7 = Bits(8 bits)
myBits7 := (7 -> true, default -> false)    //"10000000",在赋值的时候可以省去B

Verilog

  wire       [7:0]    myBits;
  wire       [31:0]   myBits1;
  wire       [7:0]    myBits2;
  wire       [7:0]    myBits3;
  wire       [7:0]    myBits4;
  wire       [7:0]    myBits5;
  reg        [7:0]    myBits6;
  reg        [7:0]    myBits7;

  assign myBits = 8'h19;
  assign myBits2 = 8'h19;
  assign myBits3 = 8'hff;
  assign myBits4 = 8'h93;
  assign myBits5 = 8'hff;

  function [7:0] zz_myBits6(input dummy);
    begin
      zz_myBits6 = 8'h0;
      zz_myBits6[7 : 5] = 3'b101;
      zz_myBits6[4] = 1'b1;
      zz_myBits6[3] = 1'b1;
    end
  endfunction

  assign _zz_1 = zz_myBits6(1'b0);
  always @(*) myBits6 = _zz_1;


  wire [7:0] _zz_1;
  function [7:0] zz_myBits7(input dummy);
    begin
      zz_myBits7 = 8'h0;
      zz_myBits7[7] = 1'b1;
    end
  endfunction
  wire [7:0] _zz_2;

  assign _zz_2 = zz_myBits7(1'b0);
  always @(*) myBits7 = _zz_2;

三、操作符(Operators)

  1. 逻辑运算(Logic) 以下是Bits类型的可用操作符

操作符 描述 返回类型
~x 按位取非 Bits(w(x) bits)
x & y 按位与 Bits(w(xy) bits)
x | y 按位或 Bits(w(xy) bits)
x ^ y 按位异或 Bits(w(xy) bits)
x.xorR x的所有bits取异或 Bool
x.orR x的所有bits取或 Bool
x.andR x的所有bits取与 Bool
x >> y 逻辑右移, y: Int Bits(w(x)-y bits)
x >> y 逻辑右移, y: UInt Bits(w(x) bits)
x << y 逻辑左移, y: Int Bits(w(x)+y bits)
x << y 逻辑左移, y: UInt Bits(w(x)+max(y) bits)
x |>> y 逻辑右移, y: Int/UInt Bits(w(x) bits)
x |<< y 逻辑左移, y: Int/UInt Bits(w(x) bits)
x.rotateLeft(y) 逻辑循环左移, y: UInt/Int Bits(w(x) bits)
x.rotateRight(y) 逻辑循环右移, y: UInt/Int Bits(w(x) bits)
x.clearAll[()] 清除所有bits
x.setAll[()] 置位所有bits
x.setAllTo(value: Boolean) 根据给定Boolean值置位
x.setAllTo(value: Bool) 根据给定Bool值置位

以上移位虽说是逻辑移位, 但生成的Verilog中是算术移位, 用>>><<<

//Bit级操作符
val a, b, c = Bits(32 bits)
c := ~(a & b)

val all_1 = a.andR  //检查a是不是全1

//逻辑移位
val bits_10bits = bits_8bits << 2   //结果是10bits
val shift_8bits = bits_8bits |<< 2  //结果所8bits

//循环移位
val myBits = bits_8bits.rotateLeft(3)

//置位/清零
val a = B"8'x42"
when(cond) {
    a.setAll()
}

Verilog:

wire                cond;
wire       [7:0]    bits_8bits;
wire       [31:0]   a;
wire       [31:0]   b;
wire       [31:0]   c;
wire                all_1;
wire       [9:0]    bits_10bits;
wire       [7:0]    shift_8bits;
wire       [7:0]    myBits;
reg        [7:0]    aa;

assign bits_8bits = 8'h0a;
assign c = (~ (a & b));
assign all_1 = (&a);
assign bits_10bits = ({2'd0,bits_8bits} <<< 2);
assign shift_8bits = (bits_8bits <<< 2);
assign myBits = {bits_8bits[4 : 0],bits_8bits[7 : 5]};
always @(*) begin
  aa = 8'h42;
  if(cond) begin
    aa = 8'hff;
  end
end
  1. 比较运算(Comparison)

操作符 描述 返回类型
x === y 相等 Bool
x =/= y 不相等 Bool
when(myBits === 3) {
    ...
}

when(myBits_32 =/= B"32'x44332211") {
    ...
}
  1. 类型转换(Type cast)

操作符 描述 返回类型
x.asBits 二进制转换为Bits Bits(w(x) bits)
x.asUInt 二进制转换为UInt UInt(w(x) bits)
x.asSInt 二进制转换为SInt SInt(w(x) bits)
x.asBools 转换成Bools数组 Vec(Bool, w(x))
B(x: T) 数据转换为Bits Bits(w(x) bits)

为了把Bool, UIntSInt转换成Bits, 也可以用B(something)

//把Bits转换成SInt
val mySInt = myBits.asSInt

//创建Bool向量
val myVec = myBits.asBools

//把SInt转换成Bits
val myBits = B(mySInt)

Verilog:

reg        [7:0]    myBits;
wire       [7:0]    mySInt;
wire                myVec_0;
wire                myVec_1;
wire                myVec_2;
wire                myVec_3;
wire                myVec_4;
wire                myVec_5;
wire                myVec_6;
wire                myVec_7;

assign mySInt = myBits;

assign myVec_0 = myBits[0];
assign myVec_1 = myBits[1];
assign myVec_2 = myBits[2];
assign myVec_3 = myBits[3];
assign myVec_4 = myBits[4];
assign myVec_5 = myBits[5];
assign myVec_6 = myBits[6];
assign myVec_7 = myBits[7];
  1. Bit位提取(Bit extraction)

操作符 描述 返回类型
x(y) 读对应bit位, y: Int/UInt Bool
x(offset, width bits) 读一块bits, offset: UInt, width: Int Bit(width bits)
x(range) 读范围内的bit, 例如myBits(4 down to 2) Bits(range bits)
x(y) := z 赋值对应bits, y: Int/UInt Bits(width bits)
x(offset, width bits) := z 赋值一块bits, offset: UInt, width: Int Bits(width bits)
x(range) := z 赋值范围内的bit, 例如myBits(4 down to 2) := B"010" Bits(range bits)
//取第4bit元素
val myBool = myBits(4)

//赋值
myBits(1) := True

//范围内操作
val myBits_8bits = myBits_16bits(7 downto 0)
val myBits_7bits = myBits_16bits(0 to 6)
val myBits_6bits = myBits_16bits(0 until 6)

myBits_8bits(3 downto 0) := myBits_4bits

Verilog:

reg        [7:0]    myBits;
wire                myBool;
reg        [15:0]   myBits_16bits;
wire       [3:0]    myBits_4bits;
wire       [7:0]    myBits_8bits;
wire       [6:0]    myBits_7bits;
wire       [5:0]    myBits_6bits;

assign myBool = myBits[4];
always @(*) begin
    myBits_16bits = {8'd0, myBits};
    myBits_16bits[3 : 0] = myBits_4bits;
end

assign myBits_4bits = myBits[3:0];
assign myBits_8bits = myBits_16bits[7 : 0];
assign myBits_7bits = myBits_16bits[6 : 0];
assign myBits_6bits = myBits_16bits[5 : 0];

always @(posedge clk or posedge reset) begin
    if(reset) begin
    myBits <= 8'h0;
    end else begin
    myBits[1] <= 1'b1;
    end
end
  1. Misc

操作符 描述 返回类型
x.getWidth 返回bit位数 Int
x.range 返回一个范围, 从大到小(x.high : 0) Range
x.high 返回x的最高边界 Int
x.msb 返回最高有效位的值 Bool
x.lsb 返回最低有效位的值 Bool
x ## y 拼接操作, x->高位, y->低位 Bits(w(x)+w(y) bits)
x.subdivideIn(y slices) 把x分成y个切片, y: Int Vec(Bits, y)
x.subdivideIn(y bits) 把x按y bits切片, y: Int Vec(Bits, w(x)/y)
x,resize(y) 返回x的变换大小后的复制, 如果变长则补零, y: Int Bits(y bits)
x.resized 返回一个根据需要自动变换长度的x Bits(w(x) bits)
x.resizeLeft(x) 保持MSB在同一位置进行放缩, x: Int Bits(x bits)
println(myBits_32bits.getWidth) //32

myBool := myBits.lsb    //相当于myBits(0)

//拼接
myBits_24bits := bits_8bits_1 ## bits_8bits_2 ## bits_8bits_3

//拆分
val sel = UInt(2 bits)
val myBitsWord = myBits_128bits.subdivideIn(32 bits)(sel)
//sel = 0 => myBitsWord = myBits_128bits(127 downto 96)
//sel = 1 => myBitsWord = myBits_128bits(95 downto 64)
//sel = 2 => myBitsWord = myBits_128bits(63 downto 32)
//sel = 3 => myBitsWord = myBits_128bits(31 downto 0)

//如果你想反向访问数据
val myVector = myBits_128bits.subdivideIn(32 bits).reverse
val myBitsWord = myVector(sel) 

//长度变换
myBits_32bits := B"32'x11223344"
myBits_8bits := myBits_32bits.resized  //自动确定长度(myBits_8bits=0x44)
myBits_8bits := myBits_32bits.resize(8) //长度变换为(myBits_8bits=0x44)
myBits_8bits := myBits_32bits.resizeLeft(8) //从高位变换(myBits_8bits=0x11)

Verilog:

reg        [31:0]   _zz_myBitsWord;
reg        [31:0]   myBits_32bits;
wire                myBool;
reg        [7:0]    bits_8bits_1;
reg        [7:0]    bits_8bits_2;
reg        [7:0]    bits_8bits_3;
wire       [7:0]    myBits_8bits;
wire       [7:0]    myBits;
wire       [23:0]   myBits_24bits;
wire       [127:0]  myBits_128bits;
wire       [31:0]   myBitsWord;
wire       [1:0]    sel;

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

//反向访问结果, myVector变量被优化掉了, 综合结果并不体现

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

assign myBool = myBits[0];
assign myBits_24bits = {{bits_8bits_1,bits_8bits_2},bits_8bits_3};
assign myBitsWord = _zz_myBitsWord;

always @(posedge clk or posedge reset) begin
    if(reset) begin
        myBits_32bits <= 32'h0;
    end else begin
        myBits_32bits <= 32'h11223344;
    end
end

assign myBits_8bits = myBits_32bits[7:0];
//高位变换
assign myBits_8bits = myBits_32bits[31 : 24];
  1. bit位遮罩(MaskedLiteral)

    不关心的值用-遮罩

    val myBits = B"1101"
    val test1 = myBits === M"1-01"  //True
    val test2 = myBits === M"0---"  //False
    val test3 = myBits === M"1--1"  //True
    

    Verilog:

    wire       [3:0]    myBits;
    wire                test1;
    wire                test2;
    wire                test3;
    
    assign myBits = 4'b1101;
    assign test1 = ((myBits & 4'b1011) == 4'b1001);
    assign test2 = ((myBits & 4'b1000) == 4'b0000);
    assign test3 = ((myBits & 4'b1001) == 4'b1001);