玩命加载中 . . .

传参

class adder(width: Int = 8) extends Module {
  val io = new Bundle {
    val a = in UInt(width bits)
    val b = in UInt(width bits)
    val sum = out UInt(width bits)
  }
  io.sum := io.a + io.b
}

class top extends Module {
  val adder0 = new adder(16)
  val adder1 = new adder(32)
}
module top (
);

  wire       [15:0]   adder0_io_a;
  wire       [15:0]   adder0_io_b;
  wire       [31:0]   adder1_io_a;
  wire       [31:0]   adder1_io_b;
  wire       [15:0]   adder0_io_sum;
  wire       [31:0]   adder1_io_sum;

  adder adder0 (
    .io_a      (adder0_io_a[15:0]    ), //i
    .io_b      (adder0_io_b[15:0]    ), //i
    .io_sum    (adder0_io_sum[15:0]  )  //o
  );
  adder_1 adder1 (
    .io_a      (adder1_io_a[31:0]    ), //i
    .io_b      (adder1_io_b[31:0]    ), //i
    .io_sum    (adder1_io_sum[31:0]  )  //o
  );

endmodule

module adder_1 (
  input      [31:0]   io_a,
  input      [31:0]   io_b,
  output     [31:0]   io_sum
);


  assign io_sum = (io_a + io_b);

endmodule

module adder (
  input      [15:0]   io_a,
  input      [15:0]   io_b,
  output     [15:0]   io_sum
);


  assign io_sum = (io_a + io_b);

endmodule

二位数组

class top extends Module {
    val para_buf = Vec(UInt(8 bits),4)
    para_buf(0) := 1
    para_buf(1) := 2
    para_buf(2) := 3
    para_buf(3) := 4    
}
module top (
);

  wire       [7:0]    para_buf_0;
  wire       [7:0]    para_buf_1;
  wire       [7:0]    para_buf_2;
  wire       [7:0]    para_buf_3;

  assign para_buf_0 = 8'h01;
  assign para_buf_1 = 8'h02;
  assign para_buf_2 = 8'h03;
  assign para_buf_3 = 8'h04;

endmodule

外联RTL

class adder(width: Int) extends BlackBox {
  addGeneric("WIDTH", width)

  val io = new Bundle {
    val ain = in UInt(width bits)
    val bin = in UInt(width bits)
    val add_out = out UInt(width bits)
  }
  noIoPrefix()

  addRTLPath("rtl/adder.v")
}

class top extends Module {
  val io = new Bundle {
    val ain = in UInt(16 bits)
    val bin = in UInt(16 bits)
    val add_out = out UInt(16 bits)
  }
  noIoPrefix()
  var adder0 = new adder(16)
  io.ain <> adder0.io.ain
  io.bin <> adder0.io.bin
  io.add_out <> adder0.io.add_out
}
module top (
  input      [15:0]   ain,
  input      [15:0]   bin,
  output     [15:0]   add_out
);

  wire       [15:0]   adder0_add_out;

  adder #(
    .WIDTH(16) 
  ) adder0 (
    .ain        (ain[15:0]             ), //i
    .bin        (bin[15:0]             ), //i
    .add_out    (adder0_add_out[15:0]  )  //o
  );
  assign add_out = adder0_add_out;

endmodule

自定义时钟域

class top extends Module{
    val io = new Bundle {
    val clk_a = in Bool()
    val rst_a_n = in Bool()
    val clk_b = in Bool()
    val rst_b_n = in Bool()
    }
    noIoPrefix()

    //1、创建clockDomain
    val cd_a = ClockDomain(io.clk_a, io.rst_a_n, config = ClockDomainConfig(resetActiveLevel = LOW))
    val cd_b = ClockDomain(io.clk_b, io.rst_b_n, config = ClockDomainConfig(resetActiveLevel = LOW))

    //2、clockDomain a logic
    val cnt_a = cd_a on UInt(8 bits) setAsReg() init 0
    val wr_en_a = cd_a on Bool()
    when(wr_en_a) {
        cnt_a := cnt_a + 1
    }
    val cnt_a_gray = toGray(cnt_a)

    //3、clockDomain b logic
    val cnt_b = cd_b on UInt(8 bits) setAsReg() init 0
    val wr_en_b = cd_b on Bool()
    when(wr_en_b) {
        cnt_b := cnt_b + 1
    }

    //4、clockDomain cross logic
    val cnt_a2b = cd_b on RegNext(cnt_a_gray) init 0 addTag(crossClockDomain)
    val cnt_a2b_sync1 = cd_b on RegNext(cnt_a2b) init 0
    val cnt_a2b_sync2 = cd_b on RegNext(cnt_a2b_sync1) init 0
}
module top (
  input               clk_a,
  input               rst_a_n,
  input               clk_b,
  input               rst_b_n
);

  wire       [7:0]    cnt_a_gray_bits;
  reg        [7:0]    cnt_a;
  wire                wr_en_a;
  wire       [7:0]    cnt_a_gray;
  reg        [7:0]    cnt_b;
  wire                wr_en_b;
  (* async_reg = "true" *) reg        [7:0]    cnt_a2b;
  reg        [7:0]    cnt_a2b_sync1;
  reg        [7:0]    cnt_a2b_sync2;

  assign cnt_a_gray_bits = (cnt_a >>> 1'b1);
  assign cnt_a_gray = (cnt_a_gray_bits ^ cnt_a);
  always @(posedge clk_a or negedge rst_a_n) begin
    if(!rst_a_n) begin
      cnt_a <= 8'h0;
    end else begin
      if(wr_en_a) begin
        cnt_a <= (cnt_a + 8'h01);
      end
    end
  end

  always @(posedge clk_b or negedge rst_b_n) begin
    if(!rst_b_n) begin
      cnt_b <= 8'h0;
      cnt_a2b <= 8'h0;
      cnt_a2b_sync1 <= 8'h0;
      cnt_a2b_sync2 <= 8'h0;
    end else begin
      if(wr_en_b) begin
        cnt_b <= (cnt_b + 8'h01);
      end
      cnt_a2b <= cnt_a_gray;
      cnt_a2b_sync1 <= cnt_a2b;
      cnt_a2b_sync2 <= cnt_a2b_sync1;
    end
  end


endmodule

Enum

class top extends Module{
    val io = new Bundle {
        val start = in Bool()
    }
    
    object mainState extends SpinalEnum {
        val IDLE,TX_DATA,DONE = newElement()
        rawElementName()  //状态机名去掉object名字前缀
    }
    val cstate = mainState() setAsReg() init(mainState.IDLE)
    val nstate = mainState()
    
    val cnt = Reg(UInt(5 bits)) init(0)
    when(io.start) {
        cnt := 0
    } elsewhen(cstate === mainState.TX_DATA) {
        cnt := cnt + 1
    }
    
    cstate := nstate
    switch(cstate) {
        is(mainState.IDLE) {
            when(io.start) {
                nstate := mainState.TX_DATA
            } otherwise {
                nstate := cstate
            }
        }
        is(mainState.TX_DATA) {
            when(cnt === U"5'd31") {
                nstate := mainState.DONE
            } otherwise {
                nstate := cstate
            }
        }
        is(mainState.DONE) {
            nstate := mainState.IDLE
        }
    }
        
}
module top (
  input               io_start,
  input               clk,
  input               rstn
);
  localparam IDLE = 2'd0;
  localparam TX_DATA = 2'd1;
  localparam DONE = 2'd2;

  reg        [1:0]    cstate;
  reg        [1:0]    nstate;
  reg        [4:0]    cnt;

  always @(*) begin
    case(cstate)
      IDLE : begin
        if(io_start) begin
          nstate = TX_DATA;
        end else begin
          nstate = cstate;
        end
      end
      TX_DATA : begin
        if((cnt == 5'h1f)) begin
          nstate = DONE;
        end else begin
          nstate = cstate;
        end
      end
      default : begin
        nstate = IDLE;
      end
    endcase
  end

  always @(posedge clk or negedge rstn) begin
    if(!rstn) begin
      cstate <= IDLE;
      cnt <= 5'h0;
    end else begin
      if(io_start) begin
        cnt <= 5'h0;
      end else begin
        if((cstate == TX_DATA)) begin
          cnt <= (cnt + 5'h01);
        end
      end
      cstate <= nstate;
    end
  end


endmodule

无符号数——运算

class top extends Module{
    val a = UInt(5 bits)
    val b = UInt(8 bits)
    
    val res1 = a + b + 1
    val res2 = a - b - 1
    val res3 = a * b
}
module top (
);

  wire       [4:0]    a;
  wire       [7:0]    b;
  wire       [7:0]    res1;
  wire       [7:0]    res2;
  wire       [12:0]   res3;

  assign res1 = (({3'd0, a} + b) + 8'h01);
  assign res2 = (({3'd0, a} - b) - 8'h01);
  assign res3 = (a * b);

endmodule

条件语句

由于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