joe 发表于 2021-8-19 16:49:58

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

joe 发表于 2021-9-8 13:33:00

还有一种计数器代码如下:
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]
查看完整版本: chisel计数器