初探FPGA(三)之建模思想

建模思想

C语言和FPGA&FPGA

单片机是一种完成的硬件,它的功能已经相对固定化,串口,定时器等等,我们使用它,只需要通过C语言调用即可,可以说C语言是单片机的灵魂,这导致了单片机的局限性,只能做到能够做到的事情。VHDL是一种富有形状的语言,它可以描述单片机的任何部分。

编程VS建模

建模是指使用硬件描述语言去建立某个资源模块。VHDL语言更加适合建模思想,相对C语言更加适合编程思想。建模更加实体化,形象化,而编程更加抽象化

低级建模思想

讲求资源的分类,以图形的方式来提高建模的可读性。
功能模块,控制模块,组合模块
一个工程和项目,首先要把它分解一个个的功能,按照功能一个个的去实现,再把功能组合控制。
一个功能模块/控制模块必须仅有一个功能。

举例说明低级建模的思想

按键消抖实验
按键消抖实验
把工程分解,如图示,为了实现功能,按照一个模块一个功能的原则,分解为电平检查和10MS的延时模块,直观,形象,从整体到部分,然后去编写对应的模块,思路清晰,这便是低级建模的精髓所在。
detect_module

module detect_module ///检测电平变化输入Pin_In,输出H2L_Sig,L2H_Sig
(
    CLK,RSTn,Pin_In,H2L_Sig,L2H_Sig
);
    input CLK;
    input RSTn;
    input Pin_In;//按键输入
    output H2L_Sig;//高to低
    output L2H_Sig;//低to/********/
    //50MHZ 10ms延时 避免出现因为复位导致的电平不稳 50_000_000*0.01-1 =500_000-1 = 499_999;
    parameter T10MS = 19'd499_999;

    reg[18:0]Count ; 
    reg isEn;               //判断信号
    always@(posedge CLK or negedge RSTn)
    if(!RSTn)
        begin
            Count <= 19'd0;
            isEn <= 1'b0;
        end
        else if(Count == T10MS)
            isEn <= 1'b1;
        else
            Count <= Count +1'd1;
    /*************************************/
    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;
        //复位10ms之后,电平由高变低的信号H2L_Sig出现的时刻仅在由高变低的一瞬间
        assign L2H_Sig = isEn?(!L2H_F2&L2H_F1):1'b0;
        //复位10ms之后,电平由低变高的信号L2H_Sig出现的时刻仅在由低变高的一瞬间
        /***************************************/
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;

    reg [15:0]Count;
    reg isCount;

    always@(posedge CLK or negedge RSTn)//1ms延时
    if(!RSTn)
            Count <= 1'd0;
            else if(isCount && Count == T1MS)
                Count <= 1'd0;
                else if(isCount)
                    Count <= Count +1'd1;
                    else if(!isCount)
                        Count <= 16'd0;
    reg [3:0]Count_MS;

    always@(posedge CLK or negedge RSTn)//定时10ms
    if(!RSTn)
        Count_MS <= 4'd0;
        else if(isCount && Count == T1MS)
            Count_MS <= Count_MS + 1'b0;
            else if(isCount)
                Count_MS <= 4'd0;
    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)
            2'd0:
            if(H2L_Sig) //高变低 i=1
                i <= 2'd1;
            else if(L2H_Sig) //低变高 i=2
                i <= 2'd2;
            2'd1:
            if(Count_MS == 4'd10)//默认情况isCount 为1仅当10ms延时完成时为0
                begin 
                    isCount <= 1'd0;
                    rPin_Out <=1'b1;//输出高
                    i <= 2'd0;
                end
            else 
                isCount <= 1'b1;
            2'd2:
                if(Count_MS == 4'd10)
                    begin
                        isCount <=1'b0;
                        rPin_Out <=1'b0;//输出低
                        i<=2'd0;
                    end
                else 
                isCount <= 1'b1;
        endcase

        assign Pin_Out = rPin_Out;
endmodule

debounce_module

module debounce_module
(
    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),
        .H2L_Sig(H2L_Sig),
        .L2H_Sig(L2H_Sig)
    );
    delay_module U2
    (
        .CLK(CLK),
        .RSTn(RSTn),
        .L2H_Sig(L2H_Sig),
        .H2L_Sig(H2L_Sig),
        .Pin_Out(Pin_Out)
    );
endmodule

关于按键消抖的说明

该实验仅仅判断了按键按下的动作,延时实现忽略抖动的中间过程,无法判断按键最终的状态,抬起,或者按下,不过这不是这个实验的重点。

致谢

Verilog HDL 那些事儿_建模篇

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值