Chisel 语言学习 1 基本数据类型和操作

Chisel 语言学习 1 基本数据类型和操作

系列文章主要用来记录学习Chisel和scala过程中遇到的难点或知识点:

目录

[TOC]来生成目录:

变量的声明与赋值

= ,  可立即得出数值
:=, 具体值需要依赖前边变量的值。
在写Scala时要特别注意变量计算需要用“=”还是用“:=”

数据位操作

截取

class ByteSelector extends Module {
  val io = IO(new Bundle {
    val in     = Input(UInt(32.W))
    val offset = Input(UInt(2.W))
    val out    = Output(UInt(8.W))
  })
  io.out := 0.U(8.W)
  when (io.offset === 0.U(2.W)) {
    io.out := io.in(7,0)
  } .elsewhen (io.offset === 1.U) {
    io.out := io.in(15,8)
  } .elsewhen (io.offset === 2.U) {
    io.out := io.in(23,16)
  } .otherwise {
    io.out := io.in(31,24)
  }
}

合并

val A = UInt(32.W)
val B = UInt(32.W)
val bus = Cat(A, B) // concatenate A and B

练习

LFSR16
LSFR16 chisel
实现一个16位线性反馈移位寄存器

class LFSR16 extends Module {
  val io = IO(new Bundle {
    val inc = Input(Bool())
    val out = Output(UInt(16.W))
  })
  // ...
  io.out := 0.U
}

将代码补充完整:

class LFSR16 extends Module {
  val io = IO(new Bundle {
    val inc = Input(Bool())
    val out = Output(UInt(16.W))
  })

  val res = RegInit(1.U(16.W))
  when (io.inc) { 
    val nxt_res = Cat(res(0)^res(2)^res(3)^res(5), res(15,1)) 
    res := nxt_res
  }
  io.out := res
}

用C++实现如下:

uint16_t reg = 0xACE1;
       uint16_t bit;
       while(1)
       {
               bit =((reg >> 0) ^
                     (reg >> 2) ^
                     (reg >> 3) ^
                     (reg >> 5) ) & 0x0001;
               reg = (reg >> 1) | (bit << 15);
               printf("%04X/n",reg);
       }

进行测试

./run-problem.sh LFSR16

出现问题如下:

cat出现问题
注意 连接操作不是chisel内核代码,因此使用时需要进行import

import chisel3.util.Cat

import chisel3.util._ 

修改之后重新运行:
Cat成果运行

生成的verilog内容如下 

`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif

module LFSR16(
  input         clock,
  input         reset,
  input         io_inc,
  output [15:0] io_out
);
  reg [15:0] res; // @[LFSR16.scala 19:20]
  reg [31:0] _RAND_0;
  wire  _T_6; // @[LFSR16.scala 21:26]
  wire  _T_7; // @[LFSR16.scala 21:33]
  wire  _T_8; // @[LFSR16.scala 21:29]
  wire  _T_9; // @[LFSR16.scala 21:40]
  wire  _T_10; // @[LFSR16.scala 21:36]
  wire  _T_11; // @[LFSR16.scala 21:47]
  wire  _T_12; // @[LFSR16.scala 21:43]
  wire [14:0] _T_13; // @[LFSR16.scala 21:55]
  wire [15:0] _T_14; // @[Cat.scala 30:58]
  wire [15:0] _GEN_0; // @[LFSR16.scala 20:17]
  assign _T_6 = res[0]; // @[LFSR16.scala 21:26]
  assign _T_7 = res[2]; // @[LFSR16.scala 21:33]
  assign _T_8 = _T_6 ^ _T_7; // @[LFSR16.scala 21:29]
  assign _T_9 = res[3]; // @[LFSR16.scala 21:40]
  assign _T_10 = _T_8 ^ _T_9; // @[LFSR16.scala 21:36]
  assign _T_11 = res[5]; // @[LFSR16.scala 21:47]
  assign _T_12 = _T_10 ^ _T_11; // @[LFSR16.scala 21:43]
  assign _T_13 = res[15:1]; // @[LFSR16.scala 21:55]
  assign _T_14 = {_T_12,_T_13}; // @[Cat.scala 30:58]
  assign _GEN_0 = io_inc ? _T_14 : res; // @[LFSR16.scala 20:17]
  assign io_out = res;
`ifdef RANDOMIZE
  integer initvar;
  initial begin
    `ifndef verilator
      #0.002 begin end
    `endif
  `ifdef RANDOMIZE_REG_INIT
  _RAND_0 = {1{$random}};
  res = _RAND_0[15:0];
  `endif // RANDOMIZE_REG_INIT
  end
`endif // RANDOMIZE
  always @(posedge clock) begin
    if (reset) begin
      res <= 16'h1;
    end else begin
      if (io_inc) begin
        res <= _T_14;
      end
    end
  end
endmodule
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值