|
奇分频还有二种情况,一种是占空比为50%,另一种情况是占空比接近50%,本例介绍占空比为50%:
计数器cnt1上升沿计数,对应定义一个寄存器clk_div_pos,在小于N/2时翻转,N-1时再次翻转,计数器cnt2下降沿计数,对应定义一个寄存器clk_div_neg,也是在N/2时翻转,N-1时再次翻转。
关键是输出clk_div需要将clk_div_pos | clk_div_neg 这样就能获得占空比为50%的分步。
/**
* @Author Joe_Liang
* @Date 2021/10/9 10:06
* @Version 1.0
*/
import chisel3._
import chisel3.util._
class OddFreq(val N:Int) extends Module { //奇分频
val io = IO(new Bundle{
val clk_div = Output(Bool())
})
require(N>1 && (N % 2 == 1),"N必须大于1且N是奇数")
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))//同上
//万一,复位信号是在clock上升沿之后下降沿之前上拉的话????,所以,必须要注意到这种情况
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) { //计数范围0~N-1
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(cnt1 === (N-1).U) { //计数范围0~N-1
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
}
因为withClock语句块中定义的cnt2变量,在语句块外无法使用,有二种使用方法,一种是上面例子中的做法,在语句块外面定义中间变量,通过中间变量中转;另一种做法就是将语句块外后面的逻辑代码放在语句块内(以后再做实验)。
|
|