初探FPGA(三)之建模思想

来源:互联网 发布:淘宝买港版note7怎么退 编辑:程序博客网 时间:2024/06/05 19:47

建模思想

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 那些事儿_建模篇

0 0
原创粉丝点击