电力电子转战数字IC20220520day4——偶数分频

//偶数分频的两种方法
//1.寄存器法实现2^n分频,有clk上升沿则翻转
//2.计数器法可以实现任意偶数分频

1.首先按照自己的想法写,写出来是一个计数器二分频,实现了基本的波形。

module twofd (clk,rst,clk1);
//偶数分频的两种方法
//1.寄存器法实现2^n分频,有clk上升沿则翻转
//2.计数器法可以实现任意偶数分频
input clk,rst;
output clk1;
reg [1:0] clk1r;
reg [1:0] count;
assign clk1=clk1r;
//这里还是用寄存器给输出赋值
initial begin clk1r<=2'd0; count<=2'd0; end

always @(posedge clk or negedge rst)
	if(!rst)
		begin clk1r<=2'd0; count<=2'd0; end
	else if(count==2'd0)
		begin clk1r=!clk1r; count<=count+2'd1; end
			else if(count==2'd1)
				begin clk1r=!clk1r; count<=2'd0; end
endmodule 
`timescale 1ps/1ps

module twofdtest;
reg clk,rst;
wire clk1;

twofd t1(.clk(clk), .rst(rst), .clk1(clk1));//这里也要分号。

always #5 clk=~clk;

always
	begin
	clk=0;rst=1;
	#10 rst=0;
	#15 rst=1;
	#100 $stop;
	end

endmodule

 2.接下来按照寄存器的思想做一个二分频。测试模块的输出clk1不能被定义为reg型。

module twofd (clk,rst,clk1);

input clk,rst;
output reg [1:0] clk1;

initial clk1<=2'd0; 

always @(posedge clk or negedge rst)
	if(!rst)
		clk1<=2'd0;
	else clk1=!clk1; 
endmodule 
`timescale 1ps/1ps

module twofdtest;
reg clk,rst;
wire clk1;

twofd t1(.clk(clk), .rst(rst), .clk1(clk1));//这里也要分号。

always #5 clk=~clk;

always
	begin
	clk=0;rst=1;
	#10 rst=0;
	#15 rst=1;
	#100 $stop;
	end

endmodule

3.扩展到2^n分频的寄存器偶数分频,n每多1就要把前面的n-1次分频都做出来,然后取n-1分频的上升沿重复操作 

module twofd (clk,rst,clkn);
//想要做一个2^n分频的怎么做呢?
//先做一个2^(n-1)分频的,然后对这个进行重复的操作
input clk,rst;
output reg [1:0] clkn;
reg [1:0] clk1;
parameter n=2'd2;

initial begin clk1<=2'd0; clkn<=2'd0; end

always @(posedge clk or negedge rst)
	if(!rst)
		clk1<=2'd0;
	else clk1=!clk1; 

always @(posedge clk1 or negedge rst)
	if(!rst)
		clkn<=2'd0;
	else clkn=!clkn; 

endmodule 
`timescale 1ps/1ps

module twofdtest;
reg clk,rst;
wire clkn;

twofd t1(.clk(clk), .rst(rst), .clkn(clkn));//这里也要分号。

always #5 clk=~clk;

always
	begin
	clk=0;rst=1;
	#10 rst=0;
	#15 rst=1;
	#100 $stop;
	end

endmodule

4.最后是用计数器实现任意偶数分频的做法 ,不给定初始值的话则输出x

module twofd (clk,rst,clk1);

input clk,rst;
output [2:0] clk1;
reg [2:0] clk1r;
reg [2:0] count;
assign clk1=clk1r;
parameter N=6;
//不给初始值试试
always @(posedge clk or negedge rst)
	if(!rst)//rst为0,全部清0
		begin clk1r<=3'd0; count<=2'd0; end
		else if(count==2'd0)
			begin clk1r<=!clk1r; count<=count+2'd1; end
			else if(count==N/2)
				begin clk1r<=!clk1r; count<=count+2'd1; end
				else if(count==N-2'd1)
					count<=2'd0;
					else count<=count+2'd1;
			
	
endmodule 
//第一次做出来是一个3/4的四分频,检查后发现是count的位数只有2位,不够计数到5

 5.看看大佬的代码反思,定义N的时候也要直接给出位数,可以试试用逻辑或把两个翻转点合在一起写else if(count==3'd0||count==N/2)。

6.最后是用状态机实现不考虑占空比为50%的任意偶数分频。奇怪的是不给输出一个初始值就没有输出,不是给状态,也不是给count。

module twofd (clk,rst,clk1);

input clk,rst;
output clk1;
reg clk1r;
reg [2:0] count;
reg [2:0] state;
assign clk1=clk1r;
parameter stop=3'b000,one=3'b001,two=3'b010,three=3'b011,four=3'b100,five=3'b101;

initial begin state<=stop; count<=3'd3; clk1r<=0; end 

always @(posedge clk or negedge rst)
	if(!rst)
		begin
			state<=stop;
			count<=3'd0;
		end
	else 
			case(state)
			stop: if(count==3'd0)
						begin state<=one;count<=count+3'd1;clk1r<=!clk1r; end 
					else state<=stop;
			one: if(count==3'd1)
						begin state<=two;count<=count+3'd1;clk1r<=!clk1r; end 
					else state<=one;
			two: if(count==3'd2)
						begin state<=three;count<=count+3'd1; end
					else state<=two;
			three: if(count==3'd3)
						begin state<=four;count<=count+3'd1; end
					else state<=three;
			four: if(count==3'd4)
						begin state<=five;count<=count+3'd1; end
					else state<=four;
			five: if(count==3'd5)
						begin state<=stop;count<=3'd0; end
					else state<=five;
			default state<=3'bxxx;
			endcase
endmodule
`timescale 1ps/1ps

module twofdtest;
reg clk,rst;
wire clk1;

twofd t1(.clk(clk), .rst(rst), .clk1(clk1));

always #5 clk=~clk;

always
	begin
	clk=0;rst=1;
	#10 rst=0;
	#15 rst=1;
	#90 rst=0;
	#110 rst=1;
	#200 $stop;
	end

endmodule

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值