做了一个脉冲发生器,脉冲间隔是45.5ms,脉宽是1us,可是示波器测试时,总在45.4~45.6ms之间波动。
但我把间隔改成45ms或45.6ms,45.8ms时,却很稳定;诡异的是像45.3ms,45.5ms,45.7ms。。等小数
点后面为奇数的都是不稳定
求高手指点,这是怎么回事啊,是编程的问题吗:(
PS:我用的是Cyclone II EP2C5T144C8的片子
下面是程序
module pulse_generating(
clk_50M,
sw3,sw2,sw1,sw0,
f_out,
reset,
out1,out2,out3,out4,out5,out6,out7,out8
);
input clk_50M;//时钟
input sw3,sw2,sw1,sw0;//拨码开关,选择间隔
input reset;//复位
output f_out;//输出
reg fref;
reg clk_1M;//0.5ms
reg [15:0] cnt0=0,cnt1=0,cnt2=0, cnt3=0, cnt4=0, cnt5=0, cnt6=0, cnt7=0,
cnt8=0,cnt9=0,cnt10=0,cnt11=0,cnt12=0,cnt13=0,cnt14=0,cnt15=0;//用于计数器计数
reg [8:0] clkcnt;
always @ (posedge clk_50M or negedge reset)//分频
begin
if(!reset)
clkcnt<=0;
else
begin
if(clkcnt==49)
clkcnt<=0;
else
clkcnt<=clkcnt+1'b1;
if(clkcnt<25)
clk_1M<=1'b0;
else
clk_1M<=1'b1;
end
end
always @(posedge clk_1M or negedge reset)
begin
if(!reset)
begin
fref<=0;
cnt0<=0;cnt1<=0;cnt2 <=0;cnt3 <=0;cnt4 <=0;cnt5 <=0;cnt6 <=0;cnt7 <=0;
cnt8<=0;cnt9<=0;cnt10<=0;cnt11<=0;cnt12<=0;cnt13<=0;cnt14<=0;cnt15<=0;
end
else
begin
case({sw3,sw2,sw1,sw0})
4'b0000: //50ms
begin
if(cnt0==49999)
cnt0<=0;
else
cnt0<=cnt0+1'b1;
if(cnt0==49999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0001: //49ms
begin
if(cnt1==48999)
cnt1<=16'b0;
else
cnt1<=cnt1+1'b1;
if(cnt1==48999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0010: //48ms
begin
if(cnt2==47999)
cnt2<=0;
else
cnt2<=cnt2+1'b1;
if(cnt2==47999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0011:
begin
if(cnt3==46999)
cnt3<=0;
else
cnt3<=cnt3+1'b1;
if(cnt3==46999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0100:
begin
if(cnt4==45999)
cnt4<=0;
else
cnt4<=cnt4+1'b1;
if(cnt4==45999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0101: //45.5ms
begin
if(cnt5==45499)
cnt5<=0;
else
cnt5<=cnt5+1'b1;
if(cnt5==45499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0110: //46.5ms
begin
if(cnt6==46499)
cnt6<=0;
else
cnt6<=cnt6+1'b1;
if(cnt6==46499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0111:
begin
if(cnt7==47499)
cnt7<=0;
else
cnt7<=cnt7+1'b1;
if(cnt7==47499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1000:
begin
if(cnt8==48499)
cnt8<=0;
else
cnt8<=cnt8+1'b1;
if(cnt8==48499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1001:
begin
if(cnt9==49499)
cnt9<=0;
else
cnt9<=cnt9+1'b1;
if(cnt9==49499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1010:
begin
if(cnt10==50499)
cnt10<=0;
else
cnt10<=cnt10+1'b1;
if(cnt10==50499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1011:
begin
if(cnt11==51499)
cnt11<=0;
else
cnt11<=cnt11+1'b1;
if(cnt11==51499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1100:
begin
if(cnt12==52499)
cnt12<=0;
else
cnt12<=cnt12+1'b1;
if(cnt12==52499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1101:
begin
if(cnt13==53499)
cnt13<=0;
else
cnt13<=cnt13+1'b1;
if(cnt13==53499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1110:
begin
if(cnt14==54499)
cnt14<=0;
else
cnt14<=cnt14+1'b1;
if(cnt14==54499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1111:
begin
if(cnt15==55499)
cnt15<=0;
else
cnt15<=cnt15+1'b1;
if(cnt15==55499)
fref<=1'b1;
else
fref<=1'b0;
end
endcase
end
end
assign f_out=fref;
endmodule
此帖出自
小平头技术问答
看了上面的程序,给我感觉就是没有理解同步设计的概念!!!!!!!!!!
全数字同步设计,要求所有触发器的时钟都是系统时钟,比如在本例中的设计时钟要求在5OMHZ。
下面分析上面的程序:
-------------------------------下面是模块定义----------------------------------------
module pulse_generating(
clk_50M,
sw3,sw2,sw1,sw0,
f_out,
reset,
out1,out2,out3,out4,out5,out6,out7,out8
);
input clk_50M;//时钟
input sw3,sw2,sw1,sw0;//拨码开关,选择间隔
input reset;//复位
output f_out;//输出
reg fref;
reg clk_1M;//0.5ms
reg [15:0] cnt0=0,cnt1=0,cnt2=0, cnt3=0, cnt4=0, cnt5=0, cnt6=0, cnt7=0,
cnt8=0,cnt9=0,cnt10=0,cnt11=0,cnt12=0,cnt13=0,cnt14=0,cnt15=0;//用于计数器计数
reg [8:0] clkcnt;
-------------------------------------------下面第一个ALWAYS 模块,分频 获取一个CLK_1M 1MHZ的时钟信号-----------------
always @ (posedge clk_50M or negedge reset)//分频
begin
if(!reset)
clkcnt<=0;
else
begin
if(clkcnt==49)
clkcnt<=0;
else
clkcnt<=clkcnt+1'b1;
if(clkcnt<25)
clk_1M<=1'b0;
else
clk_1M<=1'b1;
end
end
-----------------------CLK1_M 占空比为1--------------------------------------
always @(posedge clk_1M or negedge reset)
begin
if(!reset)
begin
fref<=0;
cnt0<=0;cnt1<=0;cnt2 <=0;cnt3 <=0;cnt4 <=0;cnt5 <=0;cnt6 <=0;cnt7 <=0;
cnt8<=0;cnt9<=0;cnt10<=0;cnt11<=0;cnt12<=0;cnt13<=0;cnt14<=0;cnt15<=0;
end
else
begin
case({sw3,sw2,sw1,sw0})
------------------上面模块表示,CLK_1M上升沿或RESET下降沿,模块执行----------------------
case({sw3,sw2,sw1,sw0})
4'b0000: //50ms
begin
if(cnt0==49999)
cnt0<=0;
else
cnt0<=cnt0+1'b1;
if(cnt0==49999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0001: //49ms
begin
if(cnt1==48999)
cnt1<=16'b0;
else
cnt1<=cnt1+1'b1;
if(cnt1==48999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0010: //48ms
begin
if(cnt2==47999)
cnt2<=0;
else
cnt2<=cnt2+1'b1;
if(cnt2==47999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0011:
begin
if(cnt3==46999)
cnt3<=0;
else
cnt3<=cnt3+1'b1;
if(cnt3==46999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0100:
begin
if(cnt4==45999)
cnt4<=0;
else
cnt4<=cnt4+1'b1;
if(cnt4==45999)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0101: //45.5ms
begin
if(cnt5==45499)
cnt5<=0;
else
cnt5<=cnt5+1'b1;
if(cnt5==45499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0110: //46.5ms
begin
if(cnt6==46499)
cnt6<=0;
else
cnt6<=cnt6+1'b1;
if(cnt6==46499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b0111:
begin
if(cnt7==47499)
cnt7<=0;
else
cnt7<=cnt7+1'b1;
if(cnt7==47499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1000:
begin
if(cnt8==48499)
cnt8<=0;
else
cnt8<=cnt8+1'b1;
if(cnt8==48499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1001:
begin
if(cnt9==49499)
cnt9<=0;
else
cnt9<=cnt9+1'b1;
if(cnt9==49499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1010:
begin
if(cnt10==50499)
cnt10<=0;
else
cnt10<=cnt10+1'b1;
if(cnt10==50499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1011:
begin
if(cnt11==51499)
cnt11<=0;
else
cnt11<=cnt11+1'b1;
if(cnt11==51499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1100:
begin
if(cnt12==52499)
cnt12<=0;
else
cnt12<=cnt12+1'b1;
if(cnt12==52499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1101:
begin
if(cnt13==53499)
cnt13<=0;
else
cnt13<=cnt13+1'b1;
if(cnt13==53499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1110:
begin
if(cnt14==54499)
cnt14<=0;
else
cnt14<=cnt14+1'b1;
if(cnt14==54499)
fref<=1'b1;
else
fref<=1'b0;
end
4'b1111:
begin
if(cnt15==55499)
cnt15<=0;
else
cnt15<=cnt15+1'b1;
if(cnt15==55499)
fref<=1'b1;
else
fref<=1'b0;
end
endcase
end
end
assign f_out=fref;
endmodule
上面的程序存在两个问题:
if(cnt15==55499)
cnt15<=0;
else
cnt15<=cnt15+1'b1;
if(cnt15==55499) -----这条语句永远无法执行!!!!!!!!!!!!!!
fref<=1'b1;
else
fref<=1'b0;
end
其二: 拨码开关改变时,其与CNT没有清0
一周热门 更多>