学习FPGA的心得.docx
《学习FPGA的心得.docx》由会员分享,可在线阅读,更多相关《学习FPGA的心得.docx(21页珍藏版)》请在冰豆网上搜索。
![学习FPGA的心得.docx](https://file1.bdocx.com/fileroot1/2023-5/22/e756293b-6373-4df6-bf15-3850e95b558f/e756293b-6373-4df6-bf15-3850e95b558f1.gif)
学习FPGA的心得
学习FPGA的心得
一:
设计规范:
1,文件名必须体现模块的功能
2,时钟信号clk和低电平有效的信号(低电平有效*_n)
3,parameter和`define进行宏定义和定义参数是,名字要大写
4,信号,端口,模块,例话(代码最好小写)
5,一般字符的命名长度不应超过32个
6模块调用实体名的设定mux4u_mux4_1(....)
7,位宽【x:
0】
8,begin和end,case和endcase。
。
。
的对齐问题
9,原理图输入时,当有文本输入和原理图输入时,原理图作为顶层文件,最好采用页面水平分层结构
10,阻塞(=)和非阻塞(>=)的问题
阻塞计算完立刻赋值,而非阻塞计算后不立刻赋值,而是一起赋值,组合逻辑(阻塞赋值),时序逻辑(非阻塞),既有时序又有组合是使用(非阻塞)
11,敏感信号列表(影响模块的输出和状态)
12,复位和初始化
13,输出设为reg
14.verilog中reg与integer的区别首先,integer和reg与wire最大的差別是,integer本身是个32位元的有号数,含正负。
其次,integer消耗的资源也比多。
二:
分频器(]frequencydivider)
Modulediv_10(clk_50,f_10,rst_n);
Inputclk_50;
Inputrst_n;
Outputf_10;
Reg[2:
0]cnt;
Regf_10;
Always@(posedgeclkornegedgerst_n)
If(!
rstn)
Cnt<=3’b0;
F_10<=0;
Else
Begin
If(cnt==3’b100)
begin
Cnt<=0;
F_10<=~f_10;
end
Else
Begin
Cnt<=cnt+3’b1;
end
End
Endmodule
三:
计数器(counter)
Modulecounter(clk,rst_n,s,q,en,d,co);
Inputclk;
Inputrst_n;
Inputen;
Input[3:
0]d;
Output[3:
0]q;
Outputco;
Regco;
Reg[3:
0]q;
Always@(posedgeclkornegedgerstn)
If(!
rst_n)
begin
q=0;
end
Else
Begin
If(s)
Begin
q=d;
End
Else
If(en)
Begin
q=q+4’b1;
If(q==4’b1111)
Begin
Co=1;
End
Else
Begin
Co=0;
end
end
else
Begin
Q=q;
End
End
Endmodule
四:
D触发器(D_Trigger)
ModuleD_Trigger(clk,rst_n,q,qn,s,d);
Inputclk,rst_n,s,d;
Outputq,qn;
Regq,qn;
Always@(posedgeclk)_
If({rst_n,s}==2’b01)
begin
Q=1’b0;
Qn=1’b1;
end
Else
If({rst_n,s}==2’b10)
begin
Q=1’b1;
Qn=1’b0;
end
Else
If({rst_n,s}==2’b11)
begin
Q=d;
Qn=~d;
End
Endmodule
五:
三态门(triplegate)
Moduletri(din,dout,en);
Inputdin,en;
Outputdout;
Assigndout=en?
din:
’bz;
Endmodule
六:
编码器(encoder)
Module8_3encoder(din,dout);
Input[7:
0]din;
Output[2:
0]dout;
Reg[2:
0]dout;
Always@(din)
Begin
Case(din)
8’b00000001:
dout=3’b000;
8’b00000010:
dout=3’b001;
8’b00000100:
dout=3’b010;
8’b00001000:
dout=3’b011;
8’b00010000:
dout=3’b100;
8’b00100000:
dout=3’b101;
8’b01000000:
dout=3’b110;
8’b10000001:
dout=3’b111;
Defult:
dout=3’dzzz;
Endcase
end
Endmodule
优先编码器(priorityencoder)
Modulecoder_42(in,out);
Input[3:
0]in;
Output[1;0]out;
Always@(in)
Begin
Case(in)
4’b1000:
out=2’b00;
4’bx100:
out=2’b01;
4’bxx10:
out=2’b10;
4’bxxx1:
out=2’b11;
Default:
out=2’bx;
Endcase
End
endmodule
七:
译码器(.decoder)
A1,A2,A3为三个输入信号,s1,s2‘,s3’为3个使能输入,
Y1’Y1‘,Y2’,Y3’,Y4’,Y5’,Y6’,Y7’为8个输出信号;
Module8_3decoder(a,gs1,gs2,gs3,y);
Input[2:
0]a;
Inputgs1,gs2,gs3;
Out[7:
0]y;
Reg[7:
0]y;
Always@(aorgs1orgs2orgs3)
Begin
If(gs1==1)
Y=8’b11111111;
Elseif(gs2===0)
Y=8’b11111111;
Elseif(gs3==0)
Y=8’b11111111;
Else
Case(a)
3’b000:
Y=8’b11111110;
3’b001:
Y=8’b11111101;
3’b010:
Y=8’b11111011;
3’b011:
Y=8’b11110111;
3’b100:
Y=8’b11101111;
3’b101:
Y=8’b11011111;
3’b110:
Y=8’b10111111;
3’b111:
Y=8’b01111111;
Default:
Y=8’b11111111;
Endcase
End
Endmmodule
八,移位寄存器(shiftregister)
4位异步清零的并入串出移位寄存器
Modulereg_bc(clk,clr,din,dout);
Inputclk,clr;
Input[7;0]din;
Outputdout;
Regdout;;
Reg[3:
0]q;
Reg[1:
0]cnt;
Always@(posedgeclk)
Begin
Cnt<=cnt+1;
If(clr)
Begin
Q<=4’b0000;
End
Else
Begin
if(cnt>0)
Begin
Q[3:
1]<=q[2:
0];
End
Elseif(cnt==2’b00)
begin
Q<=din;
end
Dout<=q[3];
End
End
Endmmodule
九:
数据选择器(multiplexer)
Modulemux4_1(d1,d2,d3,d4,g,a,y);
Inputg;
Inputd0,d1,d2,d3;
Input[1:
0]a;
Outputy;
Regy;
Always@(aord0ord1ord2ord3org)
Begin
If(g==0)
Y=1’b0;;
Else
Case(a)
2’b00:
y=d0;
2’b01:
y=d1;
2’b10:
y=d2;
2’b11:
y=d3;
Default:
y=1’b0;
Endcase
End
Endmodule
10.串行加法器(serialadder)
Moduleadd_4(a,b,c,ci,co);
Input[3:
0]a,b;
Inputci;
Output[3:
0]c;
Outputco;
Assign{co,c}=a+b+ci;
Endmodule
11.简单运算单元(ALU)
11种简单运算逻辑单元,通过选择端来选择运算功能的ALU。
ModuleALU(in1,in2,op,out);
Input[7:
0]in1,in2;
Inputop;
Output[15:
0]out;
Wire[7:
0]in1,in2;
Wireop;
Reg[15:
0]out;
Parameter
Transfer=4’b0001,
Increase=4’b0010,
Decrease=4’b0011,Addition=4’b0100,Subtraction=4’b0101,
And=4’b0110,
Or=4’b0111,
Xor=4’b1000,
Not=4’b1001,
Shift_left=4’b1010,
Shift_right=4’b1011;
Always@(in1orin2orop)
Begin
Case(op)
Transfer:
out=in1;
Increase:
out=in1+1’b1;
Decrease:
out=in1-1’b1;Addition:
out=in1+in2;Subtraction:
out=in1-in2;
And:
out=in1&in2;
Or:
out=in1|in2;Xor:
out=in1^in2;
Not:
out=~in1;
Shift_left:
out=in1<<1;
Shift_right:
out=in1>>1;
Default:
out=16’bz;
Endcase
End
Endmodule
十二:
LED灯
一般绿,蓝,白,暖白色的led导通电压为3.0~3.5V,红,黄为
2.5~2.8v,导通电流为15ma,一般高亮的led灯,限流电阻为400~500欧姆,普通的1K就可以了,但不要超过2k,反相击穿约为5V;
流水灯的控制方式有循环和移位;
移位的控制方式:
Always@(posedgeclkornegedgerst_n)
Begin
If(!
Rst_n)
begin
Count<=41’h0;
Led_temp<=8’h80;
End
Else
Count<=count+41’h1;
If(count==41’hff_ff_ff)
begin
Led_temp<=led_temp>>1;
Led_temp<=~led_temp;
Count<=41’h0;
If(led_temp==8’h01)
begin
Led_temp<=8’h80;
end
End
Endmodule
循环控制的方法:
Always@(posedgeclk)
Begin
If(count==24’h500000)
Begin
Clk_div<=~clk_div;
Count<=24’h000000;
End
Else
Count<=count+1’b1;
End
Always@(posedgeclk_divornegedgereset)
If(!
Reset)
begin
Led<=8’hff;
Led_state<=5’b00000;
End
Else
Begin
Case(led_state)
5’b00000:
led<=8’b1111_1110;
....
Default:
led<=8’b1111_1111;
Endcase
Led_state<=led_state+1’b1;
End
Endmodule
PWM控制(pulse_widthmodulation)
13.LED灯的亮暗(按键控制)
modulepwm(clk,reset,key,led);
inputclk,reset,key;
outputled;
regpwm_out;
regkey_out;
parameters0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;
reg[1:
0]state;
reg[31:
0]clk_counter;
reg[9:
0]pwm_counter;
regflag;
/******************按键消抖**************************/
always@(posedgeclk)
begin
case(state)
s0:
begin
key_out<=1'b1;
if(key==1'b0)
state<=s1;
else
state<=s0;
end
s1:
begin
if(key==1'b0)
state<=s2;
else
state<=s0;
end
s2:
begin
if(key==1'b0)
state<=s3;
else
state<=s0;
end
s3:
begin
if(key==1'b0)
begin
key_out<=1'b0;
state<=s3;
end
else
begin
key_out<=1'b1;
state<=s0;
end
end
default:
state<=s0;
endcase
end
always@(posedgeclk)
begin
clk_counter<=clk_counter+1'b1;
if(clk_counter[13:
4]pwm_out=1;
else
pwm_out=0;
if(clk_counter[15]==1'b1)
begin
if(flag==1'b1)
begin
flag<=1'b0;
if(key_out==1'b0)
pwm_counter<=(pwm_counter+10'b0000000011);
else
pwm_counter<=pwm_counter;
end
end
else
flag<=1'b1;
end
assignled=pwm_out;
Endmodule
14.数码管的动态显示
刷新的频率大于50Hz,及显示一轮的时间不超过20ms,显示的时间控制在1ms左右最佳
Moduleseg(clk,rst_n,wei,duan);
Inputclk,rst_n;
Output[7:
0]wei;
Output[7:
0]duan;
Reg[7:
0]wei;
Reg[7:
0]duan;
integercount;
Regclk_1KHz;
Reg[2:
0]wei_count;
Always@(posedgeclk)
begin
If(count==50000)
begin
Count<=0;
Clk_1KHz<=~clk_1KHz;
End
Else
Count<=count+1;
End
Always@(posedgeclk_1KHz)
Begin
Case(wei_count)
3'b000:
beginwei=8'b11111110;duan=8'b0000_0000;wei_count=wei_count+1'b1;end
3'b001:
beginwei=8'b11111101;duan=8'b0000_0000;wei_count=wei_count+1'b1;end
3'b010:
beginwei=8'b11111011;duan=8'b0000_0000;wei_count=wei_count+1'b1;end
3'b011:
beginwei=8'b11110111;duan=8'b0000_0000;wei_count=wei_count+1'b1;end
3'b100:
beginwei=8'b11101111;duan=8'b0000_0000;wei_count=wei_count+1'b1;end
3'b101:
beginwei=8'b11011111;duan=8'b0000_0000;wei_count=wei_count+1'b1;end
3'b110:
beginwei=8'b10111111;duan=8'b0000_0000;wei_count=wei_count+1'b1;end
3'b111:
beginwei=8'b01111111;duan=8'b0000_0000;wei_count=wei_count+1'b1;end
Endcase
Endmodule
十五:
秒表数码管显示
moduleseg(clk,duan,wei);
inputclk;
output[7:
0]duan;
output[1:
0]wei;
reg[7:
0]duan;
reg[1:
0]wei;
integercount;
integercount2;
reg[3:
0]ge;
reg[3:
0]shi;
regclk_1Hz;
regclk_scan;
regselect;
always@(posedgeclk)
begin
if(count==25000000)
begin
count<=0;
clk_1Hz<=~clk_1Hz;
end
else
count<=count+1'b1;
end
always@(posedgeclk_1Hz)
begin
if(ge==4'b1001)
begin
ge<=4'b0;
if(shi==4'b1001)
shi<=4'b0;
elseshi<=shi+1'b1;
end
else
ge<=ge+1'b1;
end
always@(posedgeclk)
begin
if(count2==50000)
begin
clk_scan<=~clk_scan;
count2<=0;
end
else
count2<=count2+1'b1;
end
always@(posedgeclk_scan)
begin
select<=select+1'b1;
end
always@(georshiorselect)
begin
if(select==1)
begin
wei<=2'b10;
case(ge)
4'b0000:
beginduan=8'b1100_0000;end
4'b0001:
beginduan=8'b1111_1001;end
4'b0010:
beginduan=8'b1010_0100;end
4'b0011:
beginduan=8'b1011_0000;end
4'b0100:
beginduan=8'b1001_1001;end
4'b0101:
beginduan=8'b1001_0010;end
4'b0110:
beginduan=8'b1000_0011;end
4'b0111:
beginduan=8'b1111_1000;end
4'b1000:
beginduan=8'b1000_0000;end
4'b1001:
beginduan=8'b1001_1000;end
defaultduan=8'bx;
endcase
end
else
begin
wei=2'b01;
case(shi)
3'b000:
duan=8'b1100_0000;
3'b001:
duan=8'b1111_1001;
3'b010:
duan=8'b1010_0100;
3'b011:
duan=8'b1011_0000;
3'b100:
duan=8'b1001_1001;
3'b101:
duan=8'b1001_0010;
3'b110:
duan=8'b1000_0011;
defaultduan=8'bx;
endcase
end
end
endmodule