FPGA初探(四)仿顺序操作及控制模块的发令协调作用

仿顺序操作

我们知道在FPGA中,所有功能都是以并行工作的,而很多时候,我们需要实现顺序操作,即执行完一部分功能,在进行下一步,这里就用到了仿顺序操作,仿顺序操作以i的数值为步骤,在对应i数值不同的情况下执行不同的步骤或者功能

控制模块的作用

协调工作
管理运作

以按键触发SOS信号实验为例

这里写图片描述
sos_module //sos声音信号输出功能模块

module sos_module
(
     CLK, RSTn, Pin_Out, SOS_En_Sig
);

     input CLK;
     input RSTn;
     input SOS_En_Sig;//使能信号
     output Pin_Out;

     /****************************************/

     parameter T1MS = 16'd49_999;//DB4CE15开发板使用的晶振为50MHz,50M*0.001-1=49_999

     /***************************************/

     reg [15:0]Count1;

     always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              Count1 <= 16'd0;
          else if( isCount && Count1 == T1MS )
              Count1 <= 16'd0;
          else if( isCount )
              Count1 <= Count1 + 1'b1;
          else if( !isCount )
              Count1 <= 16'd0;

    /****************************************/  

    reg [9:0]Count_MS;

     always @ ( posedge CLK or negedge RSTn )
        if( !RSTn )
              Count_MS <= 10'd0;
          else if( isCount && Count1 == T1MS )
              Count_MS <= Count_MS + 1'b1;
          else if( !isCount )
              Count_MS <= 10'd0;

    /******************************************/

    reg isCount;
    reg rPin_Out;
    reg [4:0]i;

    always @ ( posedge CLK or negedge RSTn )
        if( !RSTn )
             begin
                 isCount <= 1'b0;
                    rPin_Out <= 1'b0;
                    i <= 5'd0;
              end
         else 
            case( i )
              //通过不同的i数值,完成不同的步骤,仿顺序操作的用法
                5'd0 : 
                    if( SOS_En_Sig ) i <= 5'd1;

                    5'd1, 5'd3, 5'd5, 
                    5'd13, 5'd15, 5'd17 :  
                    if( Count_MS == 10'd100 ) begin isCount <= 1'b0; rPin_Out <= 1'b0; i <= i + 1'b1; end // short
                    else begin isCount <= 1'b1; rPin_Out <= 1'b1; end

                    5'd7, 5'd9, 5'd11 :
                    if( Count_MS == 10'd300 ) begin isCount <= 1'b0; rPin_Out <= 1'b0; i <= i + 1'b1; end // long
                    else begin isCount <= 1'b1; rPin_Out <= 1'b1; end

                    5'd2, 5'd4, 5'd6,  
                    5'd8, 5'd10, 5'd12,
                    5'd14, 5'd16, 5'd18 :
                    if( Count_MS == 10'd50 ) begin isCount <= 1'b0; i <= i + 1'b1; end// interval
                    else isCount <= 1'b1;

                    5'd19 :
                    begin rPin_Out <= 1'b0; i <= 5'd0; end  // end

              endcase

    /***************************************************/

     assign Pin_Out = !rPin_Out;//此处取反,是因为蜂鸣器低电平有效,低电平时蜂鸣器响,高电平时不响

     /***************************************************/


endmodule

inter_control_module //Trig-Sig 控制Sos_En_Sig

module inter_control_module
(
    CLK, RSTn, Trig_Sig, SOS_En_Sig
);

    input CLK;
     input RSTn;
     input Trig_Sig;
     output SOS_En_Sig;

     /***********************************/

     reg i;
     reg isEn;

     always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              begin
                  i <= 1'd0;
                     isEn <= 1'b0;
                end
          else
              case( i )

                    2'd0 :
                     if( Trig_Sig ) begin isEn <= 1'b1; i <= 1'd1; end

                     2'd1 :
                     begin isEn <= 1'b0; i <= 1'd0; end

                endcase

    /***********************************************/

     assign SOS_En_Sig = isEn;

     /***********************************************/

endmodule

detect_module //电平检测

module detect_module 
(
    CLK, RSTn, Pin_In, H2L_Sig, L2H_Sig
);

    input CLK;
     input RSTn;
     input Pin_In;
     output H2L_Sig;
     output L2H_Sig;

     /**********************************/

     parameter T100US = 13'd4_999;//DB4CE15开发板使用的晶振为50MHz,50M*0.0001-1=4999

     /**********************************/

     reg [12:0]Count1;
     reg isEn;

     always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              begin
                  Count1 <= 13'd0;
                  isEn <= 1'b0;
                end
         else if( Count1 == T100US )
                isEn <= 1'b1;
          else
              Count1 <= Count1 + 1'b1;

    /********************************************/

     reg H2L_F1;
     reg H2L_F2;
     reg L2H_F1;
     reg L2H_F2;

     always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              begin
                    H2L_F1 <= 1'b1;
                     H2L_F2 <= 1'b1;
                     L2H_F1 <= 1'b0;
                     L2H_F2 <= 1'b0;
               end
          else
              begin
                     H2L_F1 <= Pin_In; 
                     H2L_F2 <= H2L_F1;
                     L2H_F1 <= Pin_In;
                     L2H_F2 <= L2H_F1;
                end

    /***********************************/


     assign H2L_Sig = isEn ? ( H2L_F2 & !H2L_F1 ) : 1'b0;
     assign L2H_Sig = isEn ? ( !L2H_F2 & L2H_F1 ) : 1'b0;


     /***********************************/

endmodule


delay_module //延时消抖

module delay_module 
(
    CLK, RSTn, H2L_Sig, L2H_Sig, Pin_Out
);

    input CLK;
     input RSTn;
     input H2L_Sig;
     input L2H_Sig;
     output Pin_Out;

     /****************************************/

     parameter T1MS = 16'd49_999;//DB4CE15开发板使用的晶振为50MHz,50M*0.001-1=49_999

     /***************************************/

     reg [15:0]Count1;

     always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              Count1 <= 16'd0;
          else if( isCount && Count1 == T1MS )
              Count1 <= 16'd0;
          else if( isCount )
              Count1 <= Count1 + 1'b1;
          else if( !isCount )
              Count1 <= 16'd0;

    /****************************************/  

    reg [3:0]Count_MS;

     always @ ( posedge CLK or negedge RSTn )
        if( !RSTn )
              Count_MS <= 4'd0;
          else if( isCount && Count1 == T1MS )
              Count_MS <= Count_MS + 1'b1;
          else if( !isCount )
              Count_MS <= 4'd0;

    /******************************************/

     reg isCount;
     reg rPin_Out;
     reg [1:0]i;

     always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              begin
                  isCount <= 1'b0;
                     rPin_Out <= 1'b0;
                     i <= 2'd0;
               end
          else
               case ( i )

                     3'd0 : 
                      if( H2L_Sig ) i <= 2'd1;
                      else if( L2H_Sig ) i <= 2'd3;

                     3'd1 : 
                      if( Count_MS == 4'd10 ) begin isCount <= 1'b0; rPin_Out <= 1'b1; i <= 2'd2; end
                     else   isCount <= 1'b1;

                      3'd2 : 
                      begin rPin_Out <= 1'b0; i <= 2'd0; end

                      3'd3 :
                      if( Count_MS == 4'd10 ) begin isCount <= 1'b0; i <= 2'd0; end
                     else   isCount <= 1'b1;


                 endcase


    /********************************************/

     assign Pin_Out = rPin_Out;

     /********************************************/



endmodule

debounce_module2 // 将按键信号输出

module debounce_module2
(
    CLK, RSTn, Pin_In, Pin_Out
);

     input CLK;
     input RSTn;
     input Pin_In;
     output Pin_Out;

     /**************************/

     wire H2L_Sig;
     wire L2H_Sig;

     detect_module U1
     (
         .CLK( CLK ),
          .RSTn( RSTn ),
          .Pin_In( Pin_In ),   // input - from top
          .H2L_Sig( H2L_Sig ), // output - to U2
          .L2H_Sig( L2H_Sig )  // output - to U2
     );

     /**************************/

     delay_module U2
     (
         .CLK( CLK ),
          .RSTn( RSTn ),
          .H2L_Sig( H2L_Sig ), // input - from U1
          .L2H_Sig( L2H_Sig ), // input - from U1
          .Pin_Out( Pin_Out )  // output - to top
     );

     /*******************************/

endmodule

exp06_top //组合模块

module exp06_top 
(
    CLK, RSTn,
     Pin_In, Pin_Out
);

    input CLK;
     input RSTn;
     input Pin_In;
     output Pin_Out;

     /***************************************/

     wire Trig_Sig;

     debounce_module2 U1
     (
         .CLK( CLK ),
          .RSTn( RSTn ),
          .Pin_In( aPin_In ),   // input - from top
          .Pin_Out( Trig_Sig ) // output - to U2
     );

     /***************************************/

     wire SOS_En_Sig;

     inter_control_module U2
     (
          .CLK( CLK ),
            .RSTn( RSTn ),
            .Trig_Sig( Trig_Sig ),    // input - from U1
            .SOS_En_Sig( SOS_En_Sig ) // output - to U2
     );

     /***************************************/

     sos_module U3
     (
         .CLK( CLK ),
          .RSTn( RSTn ),
          .SOS_En_Sig( SOS_En_Sig ), // input - from U2
          .Pin_Out( Pin_Out )        // ouput - to top
     );

     /***************************************/

endmodule

这里写图片描述

清晰的思路,独立的模块,感谢VerilogHDL那些事儿_建模篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值