系列文章主要用来记录学习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 <= 16'h1;
end else begin
if (io_inc) begin
res <= _T_14;
end
end
end
endmodule