|
chisel3.2中默认的时钟和复位都是上拉有效,且复位是同步复位,有时候需要用异步复位,要想用异步复位,一般做法是extends MultiIOModule或RawModule,然后再用withReset(reset.asAsyncReset){具体逻辑块},当然,如果是想用下降沿复位,则withReset((~reset.asUInt()).asBool().asAsyncReset){...},实验代码如下:
/**
* @Author Joe_Liang
* @Date 2021/10/8 15:55
* @Version 1.0
*/
import chisel3._
import chisel3.util._
class AsyncResetOddFreq(val N:Int) extends MultiIOModule {
val io = IO(new Bundle{
val clk_div = Output(Bool())
})
require(N>1 && (N % 2 == 1),"N必须大于1且N是奇数")
withReset((~reset.asUInt()).asBool().asAsyncReset()) { //查看verilog发现全部是异步复位
val cnt = RegInit(0.U(log2Ceil(N).W)) //计数范围0~N-1
val cnt1 = RegInit(0.U(log2Ceil(N).W)) //计数器cnt1在时钟上升沿加1,cnt1计数值为0到N/2时clk_div_pos为0,cnt1计数值为N/2+1到N-1时clk_div_pos为1
val clk_div_pos = RegInit(false.B)
val cnt2wire = Wire(UInt(log2Ceil(N).W)) //用wire连接withClock块中的信号,纯粹满足语法作用, 要不然不能在块外引用块内信号
val clk_div_neg_wire = Wire(UInt(1.W))//同上
withClock((~clock.asUInt()).asBool().asClock()){ //默认用时钟上升沿和高有效复位,此处用时钟下降沿,复位还是高有效
val cnt2 = RegInit(0.U(log2Ceil(N).W)) //cnt2计数器也在时钟下降沿加1,cnt2计数值为0到N/2时clk_div_neg为0,cnt2计数值为N/2+1到N-1时clk_div_neg为1
val clk_div_neg = RegInit(false.B)
when(cnt2 === (N-1).U) {
cnt2 := 0.U
}.otherwise{
cnt2 := cnt2 + 1.U
}
cnt2wire := cnt2
clk_div_neg_wire := clk_div_neg
when(cnt2 < (N/2).U) {
clk_div_neg := false.B
}.otherwise {
clk_div_neg := true.B
}
}
when(cnt === (N-1).U) {
cnt := 0.U
}.otherwise{
cnt := cnt + 1.U
}
when(cnt1 === (N-1).U) {
cnt1 := 0.U
}.otherwise{
cnt1 := cnt1 + 1.U
}
when(cnt1 < (N/2).U) {
clk_div_pos := false.B
}.otherwise {
clk_div_pos := true.B
}
io.clk_div := clk_div_pos | clk_div_neg_wire
}
}
|
|