这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » 新人求助,请问如何完成下面的时序

共5条 1/1 1 跳转至

新人求助,请问如何完成下面的时序

菜鸟
2014-05-23 19:04:20     打赏
时序是这样的

系统时钟为50M 两个脉冲之间的时间为200us 既周期为200us   每当检测到Start_sig     EN1拉高12us

A1以4us为周期进行翻转 。


EN1 和A1 这两个信号和start_sig不同步也可以。


下面是我写的程序:

module jifa  (
               clk,                     //50m
reset,                   //低电频有效
start_sig,               //触发信号 使模块开始工作

EN1,                     //第一路ADG1436使能        激发换能器
A1                       //第一路ADG1436控制信号


              ) ;


 input clk ;
 input reset ;
 input start_sig ;
       
 output EN1;
 output A1;
 
 reg EN1;
 reg A1;
              
 reg [13:0] cnt;
 
 //检测 start_sig 并开始计数
 always @(posedge clk or negedge reset)
    //if(!reset || start_sig)
  if(!reset)
    cnt <= 14'd0;
  else if(start_sig)
    cnt <= 14'd0;
else  
 cnt <= cnt+1'd1;  


//产生ADG1436使能信号EN1
always @(posedge clk or negedge reset)
     //if(!reset || start_sig)
 if(!reset)
      EN1 <= 1'b0;
 
     else if(start_sig)                        //----->修改对cnt的判断时间以改变EN持续的时间
  EN1 <= 1'b0;
 else if (cnt == 99 || cnt == 699)         //>0<cnt<99时EN为0 cnt计到100使EN翻转为高 700再翻转为低  
 EN1 <= ~EN1;                              //600*20ns 使EN持续12us
                              

//产生ADG1436的控制信号
always @(posedge clk or negedge reset)         //同上
   //if (!reset || start_sig)
 if(!reset)
      A1 <= 1'b0;

   else if(start_sig)
 A1 <= 1'b0;
else if (cnt==99 || cnt==199 || cnt==299 || cnt==399 || cnt==499 || cnt==599 || cnt==699)
A1 <= ~A1;


endmodule


有两个问题 

第一个问题:感觉我这个程序里面的计数并不是被start_sig控制的 start_sig只不过用来复位

怎么写才能让每当检测到start_sig 就开始不停计数。

第二个问题:   //if (!reset || start_sig) 为什么我用这个就不能通过编译,应该怎么修改


新手求教,望指导  谢谢

[丨]




关键词: 新人求助    

菜鸟
2014-05-24 09:52:19     打赏
2楼

 //检测 start_sig 并开始计数  

always @(posedge clk or negedge reset)    

     //if(!reset || start_sig)   if(!reset)    

                cnt <= 14'd0;   

       else if(start_sig)     cnt <= 14'd0; else    cnt <= cnt+1'd1;   

 这个进程可以改成 

 reg cstate; 

  always @(posedge clk or negedge reset)  

 if(!reset)     

    begin     

    cnt <= 14'd0;     

    cstate <= 1'b0;     

    end   

else    case(cstate)             

        1'b0:  if(start_sig)                             

                        begin                             

                        cnt <= 14'd0;                             

                        cstate <= 1'b1;                           

                         end                    

                 else cstate <= 1'b0;              

        1'b1: begin                    

                  if(start_sig)                        

                         begin                         

                        cnt <= 1'b0;                        

                         cstate <= 1'b1;                         

                        end                     

                else begin                            

                        cnt <= cnt + 1'b1;                             

                        cstate <= 1'b1;                           

                        end                      

                 end             

             default:;        

             endcase

 这种做法的前提是你的start_sig的搞电平宽度持续一个时钟周期,如果是持续很多个周期,可以考虑在前面加一个边沿检测,检测上升沿


菜鸟
2014-05-24 17:02:04     打赏
3楼

非常感谢

这个里面 cstate=1’b0的时候用不用加点东西 例如cnt=0什么的。


在就是上面那段程序里面当一个start_sig来了以后 castate一直就是1‘b1了把 用不用加上例如 cnt == 多少的时候让他跳回 1'b0


还有一个问题 请问下为什么我用 

always @(posedge clk or negedge reset)
    //if(!reset || start_sig) 

 这样一条语句编译无法通过 怎么样才能让他通过


谢谢


菜鸟
2014-05-26 11:33:38     打赏
4楼

那个不用加,至于你那个复位,很奇怪,我没见过这种写法,大概是应为FPGA里的全局复位资源问题吧,我建议可以这样写:

            if(!reset)                         

                    begin                         

                    end                 

                else if(start_sig)                         

                        begin                         

                        end


菜鸟
2014-05-27 19:01:43     打赏
5楼
谢谢

共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]