chisel计数器
计数器是最基本的时序电路之一,计数器一般就是寄存器的输出连接到加法器,而加法器的输出连到寄存器输入。比如4位寄存器能计数从
0到15,再加1就绕回到0:
val cntReg = RegInit(0.U(4.W))
cntReg := cntReg + 1.U
如果需要启动条件则:
val cntReg = RegInit(0.U(4.W))
when(event) {
cntReg := cntReg + 1.U
}
class CntRegTest(n:Int) extends MultiIOModule {
val io = IO(new Bundle {//用IO定义的信号是verilgo模块的输入输出信号,没用IO定义的比如下面val FAs,val sum则是verilog的wire,verilog的reg信号需要用Reg来定义
val A = Input(UInt(n.W))
val B = Input(UInt(n.W))
val out = Output(UInt(n.W))
})
val cntreg = RegInit(io.A,0.U(n.W))
cntreg := cntreg + 1.U
io.out := cntreg
}
结果发现:
al cntreg = RegInit(io.A,0.U(n.W))这句编译没问题但RUN时出现:
chisel3.package$ExpectedChiselTypeException: reg type 'UInt<4>(IO in unelaborated CntRegTest)' must be a Chisel type, not hardware
修改为:
//chiselTypeOf(硬件类型)的返回值是chisel类型
val cntreg = RegInit(chiselTypeOf(io.A),0.U)//其实RegInit(chiselTypeOf(io.A),0.U(n.W))也是运行OK 可以自动推断宽度
cntreg := cntreg + 1.U
io.out := cntreg
则运行成功。
查看verilog文件内容如下:
module CntRegTest(
input clock,
input reset,
input io_A,
input io_B,
output io_out
);
reg cntreg; // @
reg _RAND_0;
wire _T_1 = cntreg + 4'h1; // @
assign io_out = cntreg; // @
always @(posedge clock) begin
if (reset) begin
cntreg <= 4'h0;
end else begin
cntreg <= _T_1;
end
end
endmodule
还有一种计数器代码如下:
import chisel3._
class Counter(size:Int) extends Module { //size表示计数器可达到的最大计数值
val io = IO(new Bundle {
val ticker = Output(UInt(log2Ceil(size).W))//log2Ceil(size):表示size-1值需要的位宽,如果要求数值size所需要的位宽则log2Ceil(size+1)
}
val r = RegInit(0.U(log2Ceil(size).W))
r := r +1.U
io.ticker := r
}
页:
[1]