赞
踩
大家好,最近写了一下半整数分频的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
-
三、上仿真结果
由图可知,本代码通过上升沿和下降沿产生的两个时钟分频信号clk_P和clk_N,并进行“或”运算得到了3.5倍的分频效果。其中半整数分频中无法实现50%占空比效果。
下面对上述仿真结果进行解释:
①sys_clk是系统时钟,本代码中作为被分频时钟。
②clk_div是分频后时钟。
③cnt是计数器,作为分频计数使用。
④sys_rst是复位信号,高有效。
⑤clk_P是上升沿有效的时钟,clk_N是下降沿有效的时钟信号。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。