对于时钟的分频,Verilog而言如果是偶数分频那就可以直接用计数的方式进行分频。

如对频率进行二分频:

	[email protected](posedge Clk or negedge Rst)
	begin
		if(!Rst)
			div_2_r<=0;
		else
			div_2_r<=~div_2_r;
	end

对于四分频如下:

        reg [1:0]count;
	[email protected](posedge Clk or negedge Rst)
	begin
		if(!Rst)
			count<=0;
		else
			count<=count+1'b1; 
	end
        [email protected](posedge Clk or negedge Rst)
	begin 
		if(!Rst)
			div_4_r<=0;
		else if (count==0||count==2'b10)
			div_4_r<=~div_4_r;
		else
			div_4_r<=div_4_r;
	end

而对于三分频,五分频的话用以上计数的方式就似乎行不通了。这里用了一种很巧妙的方式来处理:

    reg [1:0]s;
    reg [1:0]n;
    parameter s0=2'b00;
    parameter s1=2'b01;
    parameter s2=2'b10;
    parameter n0=2'b00;
    parameter n1=2'b01;
    parameter n2=2'b10;
    [email protected](posedge Clk or negedge Rst)
    begin
        if(!Rst)
            s<=s0;
        else
        begin
            case(s)
                s0:s<=s1;
                s1:s<=s2;
                s2:s<=s0;
                default:s<=s0;
            endcase
        end
            
    end
    
    [email protected](negedge Clk or negedge Rst)
    begin 
        if(!Rst)
            n<=n0;
        else
        begin
            case(n)
                n0:n<=n1;
                n1:n<=n2;
                n2:n<=n0;
                default:n<=n0;
            endcase
        end
    end
    assign div_3=~(s[1]|n[1]);

这里用了两个状态机去实现三分频,注意这里的是s与n状态的触发条件是不一样的,一个是上升沿敏感,一个是下降沿敏感。要特别注意。

以下是完整代码

module div(
	input Clk,
	input Rst,
	output div_2,
	output div_3,
	output div_4,
	output div_6,
	output div_8,
	output div_50Hz
);
	reg div_2_r;
	reg div_6_r;
	reg div_4_r;
	reg div_8_r;
	reg [1:0]count;
	reg [1:0]count_1;
	reg [1:0]count_3;
	[email protected](posedge Clk or negedge Rst)
	begin
		if(!Rst)
			count<=0;
		else
			count<=count+1'b1; 
	end
	[email protected](posedge Clk or negedge Rst)
	begin
		if(!Rst)
			count_1<=0;
		else if(count_1>2'b01)
			count_1<=0;
		else
			count_1<=count_1+1'b1; 
	end
	[email protected](negedge Clk or negedge Rst)
	begin
	   if(!Rst)
	       count_3<=0;
	   else if(count_3>2'b01)
	       count_3<=0;
	   else
	       count_3<=count_3+1'b1;
	end
	//二分频
	[email protected](posedge Clk or negedge Rst)
	begin
		if(!Rst)
			div_2_r<=0;
		else
			div_2_r<=~div_2_r;
	end
	//四分频
	[email protected](posedge Clk or negedge Rst)
	begin 
		if(!Rst)
			div_4_r<=0;
		else if (count==0||count==2'b10)
			div_4_r<=~div_4_r;
		else
			div_4_r<=div_4_r;
	end
	//八分频
	[email protected](posedge Clk or negedge Rst)
	begin
		if(!Rst)
			div_8_r<=0;
		else if(count==0)
			div_8_r<=~div_8_r;
		else
			div_8_r<=div_8_r;
	end
	//六分频
	[email protected](negedge Clk or negedge Rst)
	begin
		if(!Rst)
			div_6_r<=0;
		else if(count_1==2'b01&&count_3==2'b01)
			div_6_r<=~div_6_r;
		else
			div_6_r<=div_6_r;
	end
	//频率为50HZ的信号
	reg [19:0]count_2;
	reg div_50Hz_r;
	[email protected](posedge Clk or negedge Rst)
	begin 
		if(!Rst)
			count_2<=0;
		else if(count_2<1_000_000)
			count_2<=count_2+1'b1;
		else 
			count_2<=0;
	end
	[email protected](posedge Clk or negedge Rst)
	begin
		if(!Rst)
			div_50Hz_r<=0;
		else if(count_2==999_999)
			div_50Hz_r<=~div_50Hz_r;
		else
			div_50Hz_r<=div_50Hz_r;
	end
	//三分频,这里用到了状态机
	reg [1:0]s;
    reg [1:0]n;
    parameter s0=2'b00;
    parameter s1=2'b01;
    parameter s2=2'b10;
    parameter n0=2'b00;
    parameter n1=2'b01;
    parameter n2=2'b10;
    [email protected](posedge Clk or negedge Rst)
    begin
        if(!Rst)
            s<=s0;
        else
        begin
            case(s)
                s0:s<=s1;
                s1:s<=s2;
                s2:s<=s0;
                default:s<=s0;
            endcase
        end
            
    end
    
    [email protected](negedge Clk or negedge Rst)
    begin 
        if(!Rst)
            n<=n0;
        else
        begin
            case(n)
                n0:n<=n1;
                n1:n<=n2;
                n2:n<=n0;
                default:n<=n0;
            endcase
        end
    end
    assign div_3=~(s[1]|n[1]);
	assign div_2=div_2_r;
	assign div_6=div_6_r;
	assign div_4=div_4_r;
	assign div_8=div_8_r;
	assign div_50Hz=div_50Hz_r;
endmodule

测试代码如下

module div_tb;
	reg clk_50m;
	reg rst_n;
	
	
	wire div_2;
	wire div_3;
	wire div_4;
	wire div_6;
	wire div_8;
	wire div_50hz;
	
	div div_inst
	(
		.Clk(clk_50m),
		.Rst(rst_n),
		.div_2(div_2),
		.div_3(div_3),
		.div_4(div_4),
		.div_6(div_6),
		.div_8(div_8),
		.div_50Hz(div_50hz)
	);
	
	initial begin 
	rst_n=0;
	clk_50m=0;
	#200 ;
	rst_n=1;
	end
		
	always begin 
		#10;
		clk_50m=~clk_50m;
	end
	
endmodule

用modelsim仿真时序如下:Verilog 奇偶数分频

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-10-31
  • 2020-11-18
  • 2021-12-12
  • 2021-05-18
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-10-27
  • 2022-12-23
  • 2022-12-23
  • 2021-10-17
  • 2021-09-01
相关资源
相似解决方案