列表

详情


VL76. 任意奇数倍时钟分频

描述

编写一个模块,对输入的时钟信号clk_in,实现任意奇数分频,要求分频之后的时钟信号占空比为50%。模块应包含一个参数,用于指定分频的倍数。

       模块的接口信号图如下:
    

       要求:使用Verilog HDL语言实现,并编写testbench验证模块的功能。

输入描述

clk_in:输入时钟信号
rst_n:复位信号,低电平有效

输出描述

clk_out:分频之后的时钟信号

原站题解

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module clk_divider
    #(parameter dividor = 5)
( 	input clk_in,
	input rst_n,
	output clk_out
);
    
    reg [$clog2(dividor) : 0] cnt;
    reg clk_p;
    reg clk_n;
    
    always@(posedge clk_in or negedge rst_n) begin
        if(rst_n == 1'b0)
            cnt <= 0;
        else if(cnt == dividor - 1)
            cnt <= 0;
        else
            cnt <= cnt + 1;
    end
    
    always@(posedge clk_in or negedge rst_n) begin
        if(rst_n == 1'b0)
            clk_p <= 0;
        else if(cnt == dividor >> 1 || cnt == dividor - 1)
            clk_p <= ~clk_p;
        else
            clk_p <= clk_p;
    end
    
    always@(negedge clk_in or negedge rst_n) begin
        if(rst_n == 1'b0)
            clk_n <= 0;
        else if(cnt == dividor >> 1 || cnt == dividor - 1)
            clk_n <= ~clk_n;
    end
    
    assign clk_out = clk_p || clk_n;
    
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module clk_divider
    #(parameter dividor = 5)
( 	input clk_in,
	input rst_n,
	output clk_out
);
    
    parameter n=$clog2(dividor);
    reg [n:0] cnt;
    reg clk,clk2;
    
    always@(posedge clk_in  or negedge rst_n)
        if(!rst_n)
            cnt<='d0;
    else cnt<=(cnt==dividor-1)?0:cnt+1;
    
    always@(posedge clk_in  or negedge rst_n)
        if(!rst_n)
            clk<='d0;
    else if(cnt==dividor-1||cnt==(dividor-1)>>1)
        clk<=~clk;
    else clk<=clk;
    
    always@(negedge clk_in  or negedge rst_n)
        if(!rst_n)
            clk2<='d0;
    else if(cnt==dividor-1||cnt==(dividor-1)>>1)
        clk2<=~clk2;
    else clk2<=clk2;
    assign clk_out=clk||clk2;
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-05

`timescale 1ns/1ns

module clk_divider
    #(parameter dividor = 5)
( 	input clk_in,
	input rst_n,
	output clk_out
);
    reg [dividor-1:0] cnt;
	
	reg rise,down;
	
	always@(posedge clk_in or negedge rst_n) begin
		if(!rst_n) begin
			cnt <= 'b0;
		end else begin
            cnt <= (cnt==dividor-1)?'b0:cnt+1'b1;
		end
	end
	
	always@(posedge clk_in or negedge rst_n) begin
		if(!rst_n) begin
			rise <= 'b0;
		end else begin
            rise <= (cnt==(dividor-1)>>1)|(cnt==(dividor-1))?(~rise):rise;
		end
	end
	always@(negedge clk_in or negedge rst_n) begin
		if(!rst_n) begin
			down <= 'b0;
		end else begin
            down <= (cnt==(dividor-1)>>1)|(cnt==(dividor-1))?(~down):down;
		end
	end	
	
	assign clk_out = rise |down;
	
    
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-05

`timescale 1ns/1ns

module clk_divider
    #(parameter dividor = 5)
( 	input clk_in,
	input rst_n,
	output clk_out
);
    reg [$clog2(dividor):0] cnt_p,cnt_n;
    
    reg clk_p,clk_n;
    always@(posedge clk_in or negedge rst_n)
        if(!rst_n)
            begin
                cnt_p<=0;
            end
        else
            cnt_p<=(cnt_p== dividor-1'b1)? 0:cnt_p+1'd1;
    
    always@(posedge clk_in or negedge rst_n)
        if(!rst_n)
            begin
                clk_p<=0;
            end
        else
            begin
                if(cnt_p ==dividor>>1'd1 |cnt_p == dividor-1'd1)
                    clk_p<= !clk_p;
                else
                    clk_p<=clk_p;
            end
    

    
    always@(negedge clk_in or negedge rst_n)
        if(!rst_n)
            begin
                cnt_n<=0;
            end
    else
        cnt_n<=(cnt_n== dividor-1'b1)? 0:cnt_n+1'd1;

    always@(negedge clk_in or negedge rst_n)
        if(!rst_n)
            begin
                clk_n<=0;
            end
    else
            begin
                if(cnt_p ==dividor>>1'd1 |cnt_p == dividor-1'd1)
                    clk_n<= !clk_n;
                else
                    clk_n<= clk_n;
            end
    
    assign clk_out = clk_n|clk_p;
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-05

`timescale 1ns/1ns

module clk_divider
    #(parameter dividor = 5)
( 	input clk_in,
	input rst_n,
	output clk_out
);
    
    reg [3:0] cnt1;
    reg clk_out1,clk_out2;
    
    always@(posedge clk_in or negedge rst_n)begin
        if(!rst_n)
            cnt1<=0;
        else
            cnt1<=(cnt1==dividor-1)?0:cnt1+1;
    end
    
    always@(posedge clk_in or negedge rst_n)begin
        if(!rst_n)
            clk_out1<=0;
        else if(cnt1==(dividor-1)/2)
            clk_out1<=~clk_out1;
        else if(cnt1==dividor-1)
            clk_out1<=~clk_out1;
        else
            clk_out1<=clk_out1;
    end
    
    always@(negedge clk_in or negedge rst_n)begin
        if(!rst_n)
            clk_out2<=0;
        else if(cnt1==(dividor-1)/2)
            clk_out2<=~clk_out2;
        else if(cnt1==dividor-1)
            clk_out2<=~clk_out2;
        else
            clk_out2<=clk_out2;
    end
    
    assign clk_out=clk_out1|clk_out2;
    
endmodule

上一题