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 实现一个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
出现问题如下:
注意 连接操作不是chisel内核代码,因此使用时需要进行import
import chisel3.util.Cat import chisel3.util._
修改之后重新运行:
生成的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 <= 16h1; end else begin if (io_inc) begin res <= _T_14; end end end endmodule