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