📄 1.txt
字号:
异或门鉴相器就是一个异或门。
K可变模计数器的源代码如下:
module KCounter(rst,clk,ud,Kmode,INC_plus,DEC_plus);
input rst,clk,ud;
input [2:0] Kmode;
output INC_plus,DEC_plus;
reg [8:0] CounterINC,CounterDEC;
reg [8:0] Kvalue;
//K±??£
always@(Kmode)
begin
case(Kmode)
3'b001:Kvalue<=9'b000000111;
3'b010:Kvalue<=9'b000001111;
3'b011:Kvalue<=9'b000011111;
3'b100:Kvalue<=9'b000111111;
3'b101:Kvalue<=9'b001111111;
3'b110:Kvalue<=9'b011111111;
3'b111:Kvalue<=9'b111111111;
default:Kvalue<=9'b000001111;
endcase
end
//?ÆêyÆ÷μ???ò???êy?죨?ó1?ò??1£?
wire [8:0] INC_cnt,DEC_cnt;
assign INC_cnt=CounterINC+1;
assign DEC_cnt=CounterDEC-1;
//Ð?3é????oí??á???3?£¨′?óÐ??′ì£?
wire E_Kvalue,E_zero;
assign E_Kvalue=(CounterINC==Kvalue)?1:0;
assign E_zero=(CounterDEC==0)?1:0;
wire C_set,C_clr;
assign C_clr=E_Kvalue&~ud;
assign C_set=E_zero&ud;
//Ð?3é????oí??á?±ê??£¨??óÐ??′ì£?
reg clr_flag;
reg set_flag;
always@(posedge rst or negedge clk)
begin
if(rst) clr_flag<=1'b0;
else clr_flag<=C_clr;
end
always@(posedge rst or negedge clk)
begin
if(rst) set_flag<=1'b0;
else set_flag<=C_set;
end
//ò???ê?Ð?3é?ó????3?μ??¨?úμ??·£?ê1Æ??éò?±£3?3??clk
reg [2:0] INCshift,DECshift;
always@(posedge rst or negedge clk)
begin
if(rst) INCshift[2:0]<=3'b000;
else begin
INCshift[2]<=clr_flag;
INCshift[1]<=INCshift[2];
INCshift[0]<=INCshift[1];
end
end
always@(posedge rst or negedge clk)
begin
if(rst) DECshift[2:0]<=3'b000;
else begin
DECshift[2]<=set_flag;
DECshift[1]<=DECshift[2];
DECshift[0]<=DECshift[1];
end
end
reg clrINC,clrDEC;
always@(posedge rst or negedge clk)
begin
if(rst) clrINC<=1'b0;
else clrINC<=INCshift[0];
end
always@(posedge rst or negedge clk)
begin
if(rst) clrDEC<=1'b0;
else clrDEC<=DECshift[0];
end
//ò???ê??ó??3?oí????3?μ?Ð?3é£??ü??±£3?4??clk
reg INC_plus,DEC_plus;
always@(posedge rst or posedge set_flag or posedge clrDEC)
begin
if(rst) DEC_plus<=1'b0;
else if(set_flag) DEC_plus<=1'b1;
else DEC_plus<=1'b0;
end
always@(posedge rst or posedge clr_flag or posedge clrINC)
begin
if(rst) INC_plus<=1'b0;
else if(clr_flag) INC_plus<=1'b1;
else INC_plus<=1'b0;
end
///ò???ê?á????ÆêyÆ÷(Æ?êμ2??é??)
wire INC,DEC;
assign INC=~ud&clk;
assign DEC=ud&clk;
always@(posedge rst or negedge DEC or posedge set_flag)
begin
if(rst) CounterDEC<=9'b000000000;
else if(set_flag) CounterDEC<=Kvalue;
else CounterDEC<=DEC_cnt;
end
always@(posedge rst or negedge INC or posedge clr_flag)
begin
if(rst) CounterINC<=9'b000000000;
else if(clr_flag) CounterINC<=9'b000000001;
else CounterINC<=INC_cnt;
end
endmodule
加减脉冲计数器源代码如下:
module IDCnt(clk,rst,INC,DEC,serout);
input clk,rst,INC,DEC;
output serout;
/////2·?Æμ?ÆêyÆ÷£?Æ?ê?3?ê??à2??api£?????±è?a50£¥μ?·?2¨
reg div2;
wire cdiv2;
always@(posedge rst or negedge clk)
begin
if(rst) div2<=0;
else div2<=~div2;
end
assign cdiv2=~div2;
////INCó?DECμ?±????ì2a
reg [1:0] INC_det,DEC_det;
wire INC_edge,DEC_edge;
wire ser1,ser2;
assign ser1=div2&clk;
assign ser2=cdiv2&clk;
always@(posedge rst or negedge ser1)
begin
if(rst) INC_det[1]<=0;
else INC_det[1]<=INC;
end
always@(posedge rst or negedge ser1)
begin
if(rst) INC_det[0]<=0;
else INC_det[0]<=INC_det[1];
end
assign INC_edge=~INC_det[1]&INC_det[0];
always@(posedge rst or posedge ser2)
begin
if(rst) DEC_det[1]<=0;
else DEC_det[1]<=DEC;
end
always@(posedge rst or posedge ser2)
begin
if(rst) DEC_det[0]<=0;
else DEC_det[0]<=DEC_det[1];
end
assign DEC_edge=~DEC_det[1]&DEC_det[0];
//////ê?3?μ?êy?Yà′?′ó?×′ì?
reg INC_flag;
reg DEC_flag;
always@(posedge rst or negedge INC)
begin
if(rst) INC_flag<=1'b0;
else INC_flag<=~INC_flag;
end
always@(posedge rst or negedge DEC)
begin
if(rst) DEC_flag<=1'b0;
else DEC_flag<=~DEC_flag;
end
wire iddet;
//assign iddet=INC_edge|DEC_edge;
reg ioed;
always@(posedge rst or posedge INC_edge or posedge DEC_edge)
begin
if(rst) ioed<=1'b0;
else if(INC_edge) ioed<=1'b1;
else ioed<=1'b0;
end
wire detenable;
wire select;
assign select=(ioed&INC_flag&~DEC_flag)|(~ioed&~INC_flag&~DEC_flag)|(~ioed&INC_flag&DEC_flag)|(ioed&~INC_flag&DEC_flag);
assign detenable=select?cdiv2:div2;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////
reg idedge1,idedge2;
always@(posedge rst or negedge clk)
begin
if(rst) idedge1<=1'b0;
else if(detenable) idedge1<=INC_edge;
end
always@(posedge rst or negedge clk)
begin
if(rst) idedge2<=1'b0;
else if(detenable) idedge2<=DEC_edge;
end
reg state;
always@(posedge rst or posedge idedge1 or posedge idedge2)
begin
if(rst) state<=1'b0;
else if(idedge1) state<=~state;
else state<=~state;
end
////ê?3?????
assign serout=state?ser1:ser2;
endmodule
8分频计数器很简单,采用异步即可,代码如下(图中标为4分频,该其为8分频):
module div4(rst,clk,out);
input rst,clk;
output out;
reg out;
reg a,b;
always@(posedge rst or negedge clk)
begin
if(rst) a<=1'b0;
else a<=~a;
end
always@(posedge rst or negedge a)
begin
if(rst) b<=1'b0;
else b<=~b;
end
always@(posedge rst or negedge b)
begin
if(rst) out<=1'b0;
else out<=~out;
end
endmodule
按照这个程序,clk的频率为datain的16倍不同步即可。
对了,还有顶层模块:
module dplltop(rst,clk,datain,Kmode,dataout);
input rst,clk,datain;
input [2:0] Kmode;
output dataout;
wire div4out,ud;
assign ud=datain^div4out;
wire incsin,decsin;
KCounter KCounter1(.rst(rst),.clk(clk),.ud(ud),.Kmode(Kmode),.INC_plus(incsin),.DEC_plus(decsin));
wire idout;
IDCnt IDCnt1(.clk(clk),.rst(rst),.INC(incsin),.DEC(decsin),.serout(idout));
div4 div41(.rst(rst),.clk(idout),.out(div4out));
assign dataout=div4out;
endmodule
整套软件我用的是FPGA Advantage5.4(正版的)综合仿真(前仿)都没有问题。
我希望有兴趣的朋友能做进一步的改进或完善,也希望大家把结果公布出来,共同提高。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -