|
楼主 |
发表于 2003-11-20 17:06:24
|
显示全部楼层
最近小作:Verilog版的dpll
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
//计数器的下一个数值(加1或减1)
wire [8:0] INC_cnt,DEC_cnt;
assign INC_cnt=CounterINC+1;
assign DEC_cnt=CounterDEC-1;
//形成置位和清零脉冲(带有毛刺)
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;
//形成置位和清零标志(没有毛刺)
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个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
//以下是加脉冲和减脉冲的形成,它们保持4个clk(必须是4个)
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
///以下是两个计数器(其实不可逆)
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 |
|