FPGA期末考试复习总结
下学年可编程逻辑器件(FPGA)期末复习总结,仅供参考
判断题
关于端口定义:一般有输入(input)、输出(output)、双向端口(inout)。Verilog HDL是一种硬件描述语言一般用于设计数字电路核数字逻辑系统,可对算法级、门级、开关级等多种抽象设计层次进行建模。阻塞赋值与非阻塞赋值:1)阻塞赋值(=)–组合电路
变量=赋值表达式 ;// c = a&b ;
赋值语句结束后块才结束;a或者b的值改变,c会随之立即改变;在时序逻辑中用阻塞赋值会造成意向不到的后果。
2)非阻塞赋值(<=)–时序电路
变量 <=赋值表达式 ;// c <= a&b ;
块结束后才能完成赋值操作, a或者b的值改变,C不会随之立即变化。
3)阻塞赋值与非阻塞赋值的差别
always@(posedge clk) always@(posedge clk)
begin begin
b <= a ; b = a ;
c <= b ; c = b ;
end end
关于assign语句:不支持对reg 数据类型的assign或deassign进行综合,支持对wire数据类型的assign或deassign进行综合。分支语句:case 语句是一种多路条件分支的形式,可以解决 if 语句中有多个条件选项时使用不方便的问题
case 语句支持嵌套使用、case 语句中的条件选项表单式不必都是常量,也可以是 x 值或 z 值
case 语句执行时,如果 condition1 为真,则执行 true_statement1 ; 如果 condition1 为假,condition2 为真,则执行 true_statement2;依次类推。如果各个 condition 都不为真,则执行 default_statement 语句。
default 语句是可选的,且在一个 case 语句中不能有多个 default 语句。IP核种类:软核、硬核、固核。模块调用:在一个模块中引用另一个模块,对其端口进行相关连接,叫做模块例化。模块例化建立了描述的层次。信号端口可以通过位置或名称关联,端口连接也必须遵循一些规则。
命名端口连接、顺序端口连接、端口连接规则、位宽匹配、端口连续信号类型。可综合电路与不可综合电路
一般可综合电路用于设计;不可综合电路用于仿真和测试。
填空题
1.有关移位操作
移位操作符是把操作数向左或向右移若干位。移位操作符有两种:<<(左移)、>>(右移)。
移位操作符有两个操作数,右侧操作数表示的是左侧操作数所移动的位数。它是一个逻辑移位,空闲位添0补位。如果右侧操作数的值为x或z,则移位操作的结果为x。
4’b10x0 >> 1 = 4’b010x
4’b1010 <<2 = 4’b1000
2.字符拼接与复制
连接操作是将多组信号用大括号括起来,拼接成一组新信号。其表示形式如下:
{expr1, expr2, …, exprN}
例:a=3’b101 b=4’b1010 {a,b}=7’b1011010
{a,a}= {2{a}}=6’b101101
3. 端口
模块的端口定义声明了模块的所有输入\输出端口,格式如下:
module 模块名 (端口1,端口2,端口3,·······);
模块的端口包含模块与外部联系的全部输入输出信号,端口之间用“,”隔开;
4.always
always 块的综合可以分为至少两类电路:1、组合逻辑电路 2、时序逻辑电路
5.循环语句
forever、while、repeat、for (其中前三类只能用于仿真)
6.数据类型
Verilog共有19种数据类型,reg、wire、parameter、integer是最常用的四种数据类型。
7.FPGA开发流程
FPGA开发流程是自上而下(Top-Down)的设计方法。优化后的FPGA开发流程如图所示。
需求分析、模块划分、代码设计、综合优化、实现、板级调试
程序设计题
1.数码管动态扫描
下面展示一些内联代码片
。
// 数码管动态扫描//6个数码管显示123456,动态扫描
// An highlighted blockmodule smg(inputclk,inputrst_n,output reg[5:0]sel,//数码管选择输出引脚output reg[7:0] seg//数码管段输出引脚);reg[3:0] data;//定义显示数据寄存器reg[24:0]count; //定义计数寄存器//秒信号产生部分always @(posedge clk or negedge rst_n) //定义clk上升沿触发beginif(!rst_n)count<=0;else if(count == 25'd250000)//0.5S到了吗?count = 25'd0;//计数器清零elsecount = count + 1'b1;end//数码管动态扫描显示部分always @(posedge clk or negedge rst_n) //count[17:15]大约1ms改变一次beginif(!rst_n)data<=0;elsecase(count[15:13])//选择扫描显示数据3'd0:data<= 1;//个位3'd1:data<= 2;//十位3'd2:data<= 3;//百位3'd3:data<= 4;//千位3'd4:data <= 5;//万位3'd5:data<= 6;//十万位endcaseendalways @(posedge clk) //count[17:15]大约1ms改变一次begincase(count[15:13])//选择扫描显示数据3'd0:sel<= 6'b111110;//选择第一个数码管显示3'd1:sel<= 6'b111101;//选择第二个数码管显示3'd2:sel<= 6'b111011;//选择第三个数码管显示3'd3:sel<= 6'b110111;//选择第四个数码管显示3'd4:sel<= 6'b101111;//选择第五个数码管显示3'd5:sel<= 6'b011111;//选择第六个数码管显示endcaseendalways @(posedge clk)begincase(data)4'h0:seg<= 8'hc0;//显示04'h1:seg<= 8'hf9;//显示14'h2:seg <= 8'ha4;//显示24'h3:seg <= 8'hb0;//显示34'h4:seg <= 8'h99;//显示44'h5:seg <= 8'h92;//显示54'h6:seg <= 8'h82;//显示64'h7:seg <= 8'hf8;//显示74'h8:seg <= 8'h80;//显示84'h9:seg <= 8'h90;//显示94'ha:seg <= 8'hbf;//显示-default:sm_seg <= 8'hff;//不显示endcaseendendmodule
2.分频
下面展示一些内联代码片
。
// 分频//根据修改m的值实现任意分频//此处产生1Hz的clk
// An highlighted blockmodule demo_1(clk,rst_n,clk_div);input clk,rst_n;output clk_div;reg clk_div;//---------------------分频开始-----------------------parameter m=49999999;integer div_cnt=0;always@(posedge clk or negedge rst_n)if(!rst_n)div_cnt<=1’b0;elsebeginif(div_cnt==m)beginclk_div<=1'b1;div_cnt<=0;endelsebeginclk_div<=1'b0;div_cnt<=div_cnt+1;endend//---------------------分频结束-----------------------endmodule
3.按键消抖(盲猜会考)
下面展示一些内联代码片
。
// 按键消抖
// An highlighted blockmodule key_scan(clk ,rst_n ,key);input clk ;input rst_n ;input [3:0] key ;reg[19:0]count;reg[3:0]key_scan;//扫描按键值//---------------------------------------------//采样按键值,20ms扫描一次,采样频率小于按键毛刺频率,相当于滤除掉了高频毛刺信号。//---------------------------------------------always @(posedge clk or negedge rst_n)//检测时钟的上升沿和复位的下降沿beginif(rst_n==1'b0)count<=20'd0;//先将计数清零elsebeginif(count==20'd999_999)//20ms 扫描一次按键,20ms 计数(50M/50-1=999_999)begincount<=20'd0; //计数器计到 20ms,计数器清零key_scan<=key;//采样按键输入电pingendelsecount<=count+20'b1;//计数器加1endend//----------------------------------------------------// 按键信号锁存一个时钟节拍//----------------------------------------------------reg [3:0] key_scan_r;always @(posedge clk)key_scan_r <= key_scan; wire [3:0] flag_key = key_scan_r[3:0] & (~key_scan[3:0]); //当检测到按键有下降沿变化时,代表该按键被按下,按键有效endmodule
4.组合逻辑电路
此处仅放两个作为参考
下面展示一些内联代码片
。
// 四位全加器
module adder4(cout,sum,ina,inb,cin);output[3:0] sum;output cout;input[3:0] ina,inb;input cin;assign sum=ina^inb^cin;assign cout=(ina^inb)&cin|ina&inb;endmodule
下面展示一些内联代码片
。
// 四选一数据选择器
module mux4_1(out,in0,in1,in2,in3,sel);output out;input in0,in1,in2,in3;input[1:0] sel;reg out;always @(in0 or in1 or in2 or in3 or sel) //敏感信号列表case(sel)2'b00: out=in0;2'b01: out=in1;2'b10: out=in2;2'b11: out=in3;default: out=2'bx;endcaseendmodule
程序填空
有关状态机——以三段式为例
下面通过实例来说明状态机的原理与设计方法。如设计一个110报警检测器,当检测到报警电话110时则输出报警信号。
下面展示一些内联代码片
。
//状态机
module state_detec(clk,rst_n,num,result); input clk , rst_n ;//输入信号input num ;//output result ;//输出信号reg result ;//reg [3:0] cstate ;//中间信号reg [3:0] nstate ;//中间信号parameter idle = 4’b0001 ; //状态机参数定义parameter S1 = 4’b0010 ;parameter S2 = 4’b0100 ;parameter S3 = 4’b1000 ;always@(posedge clk)if(!rst_n)cstate <= idle ;elsecstate <= nstate ;always@(*)case(cstate)idle:if(num)nstate = S1 ;else nstate = idle ;S1:if(num)nstate = S2 ;elsenstate = idle ;S2:if(num)nstate = S2 ;elsenstate = S3 ;S3:if(num)nstate = S1 ;elsenstate = idle ;default: nstate = idle ;endcasealways@(posedge clk)if(!rst_n)result <= 1’b0 ;else if(nstate == S3)result <= 1’b1 ;elseresult <= 1’b0 ;endmodule
内容很长,感谢阅读,希望对你有帮助!