大家好,最近写了一下半整数分频的verilog代码(半整数是指含有0.5的小数,如2.5, 3.5, 4.5, 6.5,等等),进行了仿真和验证,下面将代码附上,需要请自取。
一、上代码
`timescale 1ns / 1ps
///
module CLK_DIV_HALF
#(
parameter Multiple = 7//Multiple表示的是倍频*2。 7表示是3.5倍分频。
)
(
input sys_rst,
input sys_clk,
output clk_div ,
output [15:0] cnt,
output clk_P,
output clk_N
);
reg [15:0] cnt=16'b0;
always@(posedge sys_clk)
begin
if(sys_rst) //复位信号,高有效
begin
cnt <= 16'b0;
end
else
if(cnt == (Multiple -1))
begin
cnt <=16'b0;
end
else
begin
cnt <= cnt + 1'b1 ;
end
end
//----------------------------------//
reg clk_P=1'b0;
always@(posedge sys_clk)
begin
if(sys_rst) //复位信号,高有效
begin
clk_P <= 1'b0;
end
else
if(cnt == 16'd0 || cnt == Multiple/2+1)
begin
clk_P <= 1'b1 ;
end
else
begin
clk_P <= 1'b0 ;
end
end
//--------------------------------//
reg clk_N=1'b0;
always@(negedge sys_clk)
begin
if(sys_rst) //复位信号,高有效
begin
clk_N <= 1'b0 ;
end
else
if( cnt == Multiple/2+1)
begin
clk_N <=1'b1;
end
else
begin
clk_N <= 1'b0 ;
end
end
//--------------------------------//
assign clk_div = clk_P | clk_N ;
endmodule
二、上仿真代码
`timescale 1ns / 1ps
//
module CLK_DIV_HALF_TB;
// Inputs
reg sys_rst;
reg sys_clk;
// Outputs
wire clk_div;
wire [15:0] cnt;
wire clk_P;
wire clk_N;
// Instantiate the Unit Under Test (UUT)
CLK_DIV_HALF uut (
.sys_rst(sys_rst),
.sys_clk(sys_clk),
.clk_div(clk_div),
.cnt(cnt),
.clk_P(clk_P),
.clk_N(clk_N)
);
initial begin
// Initialize Inputs
sys_rst = 1;
sys_clk = 0;
// Wait 100 ns for global reset to finish
#100;sys_rst = 0;
forever #500 sys_clk=~sys_clk;
// Add stimulus here
end
endmodule
三、上仿真结果
![](https://img-blog.csdnimg.cn/0e98bac4b721403e95bcfef8fc4d0d66.png)
由图可知,本代码通过上升沿和下降沿产生的两个时钟分频信号clk_P和clk_N,并进行“或”运算得到了3.5倍的分频效果。其中半整数分频中无法实现50%占空比效果。
下面对上述仿真结果进行解释:
①sys_clk是系统时钟,本代码中作为被分频时钟。
②clk_div是分频后时钟。
③cnt是计数器,作为分频计数使用。
④sys_rst是复位信号,高有效。
⑤clk_P是上升沿有效的时钟,clk_N是下降沿有效的时钟信号。