求大虾指点,用Verilog编了一个脉冲发生器,出现了一个怪异的问题。。。

2019-03-25 10:38发布

做了一个脉冲发生器,脉冲间隔是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      此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
eeleader
1楼-- · 2019-03-25 18:02
< /

看了上面的程序,给我感觉就是没有理解同步设计的概念!!!!!!!!!!

全数字同步设计,要求所有触发器的时钟都是系统时钟,比如在本例中的设计时钟要求在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

 

qqichang
2楼-- · 2019-03-25 18:28
 精彩回答 2  元偷偷看……

一周热门 更多>