|
前面帖子中介绍了偶数50%占空比分频(核心思想就是计数到N/2 -1时翻转),这个帖子中也介绍了奇数50%占空比分频(核心思想就是二个计数器,各自
的输出在小于N/2和N-1时翻转,最后将二个输出进行相“或”,则能得到50%占空比的奇分频。根据这二种50%占空比的分频做法,可以实现任意分频占空比为50%,代码如下:
/**
* @Author Joe_Liang
* @Date 2021/10/9 14:06
* @Version 1.0
*/
import chisel3._
import chisel3.util._
class ArbitraryScaleFreq (val N:Int) extends Module { //任意比例分频
val io = IO(new Bundle{
val clk_div = Output(Bool())
})
require(N>0,"分频数N必须要大于0")
if(N == 1) {
io.clk_div := clock.asUInt().asBool()
}
else {
//偶分频 50%占空比 采用最高bit位输出法
val cntReg = RegInit(0.U(log2Ceil(N).W))
when(cntReg === (N-1).U) {
cntReg := 0.U
}.otherwise {
cntReg := cntReg + 1.U
}
//上面偶分频输出时:cntReg(log2Ceil(N))表示取N个计数器的bit位中的最高位的值作为输出值,从而达到50%占空比
//奇分频 50%占空比 采用两计数器时钟上下沿采样再相“或”法
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)
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
}
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
}
//最终输出50%占空比的分频
io.clk_div := Mux((N%2 == 0).asBool(),cntReg(log2Ceil(N)-1),clk_div_pos | clk_div_neg)
}
}
}
|
|