玩命加载中 . . .

SpinalHDL基础-组合逻辑


数据类型

SpinalHDL提供了5个基本类型,以及2个可以使用的复合类型。

基本类型:Bool , Bits , UInt用于无符号整数,SInt用于有符号整数、Enum枚举。
复合类型:Bundle和Vec。

逻辑操作

SpinalHDL支持verilog所有的逻辑操作,大部分跟verilog用法一致,只有少量是有差别的

class top extends Module{
    val a,b = UInt(8 bits)
    val en = Bool()
    
    val rst_and = a & b
    val rst_or = a | b
    val rst_xor = a ^ b
    val rst_self_not = ~a
    val rst_self_and = a.andR  //自与
    val rst_self_or  = a.orR   //自或
    val rst_self_xor = a.xorR  //自异或
    val rst_not = !en
    val rst_equal = (a===b)
    val rst_inequal = (a=/=b)
    val rst_bigger = (a>=b)   //注意Bits()没有比较大小方法 
}

object main extend App {
    SpinalVerilog(new top())
}
module top (
);

  wire       [7:0]    a;
  wire       [7:0]    b;
  wire                en;
  wire       [7:0]    rst_and;
  wire       [7:0]    rst_or;
  wire       [7:0]    rst_xor;
  wire       [7:0]    rst_self_not;
  wire                rst_self_and;
  wire                rst_self_or;
  wire                rst_self_xor;
  wire                rst_not;
  wire                rst_equal;
  wire                rst_inequal;
  wire                rst_bigger;

  assign rst_and = (a & b);
  assign rst_or = (a | b);
  assign rst_xor = (a ^ b);
  assign rst_self_not = (~ a);
  assign rst_self_and = (&a);
  assign rst_self_or = (|a);
  assign rst_self_xor = (^a);
  assign rst_not = (! en);
  assign rst_equal = (a == b);
  assign rst_inequal = (a != b);
  assign rst_bigger = (b <= a);

endmodule

赋值(基础)

SpinalHDL除了能像verilog一样赋值外,还提供了其他非常丰富的赋值方式

定义时赋值用=
非定义时赋值用:=

class top extends Module{
    //方法一:先定义后赋值
    val rst0 = Bits(8 bits)
    rst0 := 32   //注意用:=
    
    //方法二:定义时赋值,verilog形式的赋值
    val rst1 = B(25, 8 bits)
    val rst2 = B"8'hFF"   //与verilog一样,d(base10),b(base2),o(base8)
    val rst3 = B"1001_0011"  //与verilog一样,_增加可读性
    
    //扩展VHDL赋值方法到verilog,只关注某些bit
    val rst4 = B(8 bits, default -> True) // "11111111"
    val rst5 = B(8 bits, (7 downto 5) -> B"101", 4 -> true, 3 -> True, default -> false) // "10111000"

    //全置0,全置1,不需指定位宽
    val a,b = Bits(8 bits)
    a.clearAll()
    b.setAll()
}
module top (
);

  wire       [7:0]    rst0;
  wire       [7:0]    rst1;
  wire       [7:0]    rst2;
  wire       [7:0]    rst3;
  wire       [7:0]    rst4;
  reg        [7:0]    rst5;
  wire       [7:0]    a;
  wire       [7:0]    b;
  wire       [7:0]    rst5_const;

  assign rst0 = 8'h20;
  assign rst1 = 8'h19;
  assign rst2 = 8'hff;
  assign rst3 = 8'h93;
  assign rst4 = 8'hff;
  assign rst5_const = 8'h0;
  always @(*) begin
      rst5 = rst5_const;
      rst5[7 : 5] = 3'b101;
      rst5[4] = 1'b1;
      rst5[3] = 1'b1;
  end

  assign a = 8'h0;
  assign b = 8'hff;

endmodule

bit操作

不同点:

verilog采用的是[]取bit,SpinalHDL采用的是()取bit
范围采用VHDL的downto和scala的to,until

class top extends Module{
    val a = Bits(8 bits)
    a(0) := True
    a(7 downto 1) := B"7'h7f"
    val res1 = a(0)
    val res2 = a(7 downto 1)  //[7:1]
    val res4 = a(1 to 7)      //[7:1]
    val res3 = a(1 until 7)   //[6:1],注意不包含7
}
module top (
);

  reg        [7:0]    a;
  wire                res1;
  wire       [6:0]    res2;
  wire       [6:0]    res4;
  wire       [5:0]    res3;
  wire                a_const;

  assign a_const = 1'b1;
  always @(*) begin
      a[0] = a_const;
      a[7 : 1] = 7'h7f;
  end

  assign res1 = a[0];
  assign res2 = a[7 : 1];
  assign res4 = a[7 : 1];
  assign res3 = a[6 : 1];

endmodule

拼位

class top extends Module{
    val a = Bits(8 bits)
    val b = Bits(3 bits)
    val c = Bool()
    
    val rst1 = a ## b ## c
    val rst2 = Cat(a,b,c)  //与上面是等价的
    val rst3 = a.cat(4)    //复制4次自拼接
}
module top (
);

  wire       [7:0]    a;
  wire       [2:0]    b;
  wire                c;
  wire       [11:0]   rst1;
  wire       [11:0]   rst2;
  wire       [31:0]   rst3;

  assign rst1 = {a,b,c};
  assign rst2 = {a,b,c};
  assign rst3 = {4{a}};

endmodule

X态与Z态

class top extends Module{
    val a = Bits(8 bits)
    val b = Bits(8 bits)
    val c = Bool()
    
    a.assignDontCare
    c := b===M"1---1---"
}
showRtl(new top())
module top (
);

  wire       [7:0]    a;
  wire       [7:0]    b;
  wire                c;

  assign a = 8'bxxxxxxxx;
  assign c = ((b & 8'h88) == 8'h88);

endmodule

本文作者: 董续胜

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

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


 评论