当前位置:首页 » 《随便一记》 » 正文

可编程逻辑器件期末复习总结_ZZZZZZZAX的博客

20 人参与  2022年03月20日 18:14  分类 : 《随便一记》  评论

点击全文阅读


FPGA期末考试复习总结

2021年下学年可编程逻辑器件(FPGA)期末复习总结,仅供参考

判断题

  1. 关于端口定义:一般有输入(input)、输出(output)、双向端口(inout)。
  2. Verilog HDL是一种硬件描述语言一般用于设计数字电路核数字逻辑系统,可对算法级、门级、开关级等多种抽象设计层次进行建模。
  3. 阻塞赋值与非阻塞赋值:
    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
    在这里插入图片描述
  4. 关于assign语句:不支持对reg 数据类型的assign或deassign进行综合,支持对wire数据类型的assign或deassign进行综合。
  5. 分支语句:case 语句是一种多路条件分支的形式,可以解决 if 语句中有多个条件选项时使用不方便的问题
    case 语句支持嵌套使用、case 语句中的条件选项表单式不必都是常量,也可以是 x 值或 z 值
    case 语句执行时,如果 condition1 为真,则执行 true_statement1 ; 如果 condition1 为假,condition2 为真,则执行 true_statement2;依次类推。如果各个 condition 都不为真,则执行 default_statement 语句。
    default 语句是可选的,且在一个 case 语句中不能有多个 default 语句。
  6. IP核种类:软核、硬核、固核。
  7. 模块调用:在一个模块中引用另一个模块,对其端口进行相关连接,叫做模块例化。模块例化建立了描述的层次。信号端口可以通过位置或名称关联,端口连接也必须遵循一些规则。
    命名端口连接、顺序端口连接、端口连接规则、位宽匹配、端口连续信号类型。
  8. 可综合电路与不可综合电路
    一般可综合电路用于设计;不可综合电路用于仿真和测试。

填空题

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 block
module smg(
	input				clk,
	input				rst_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上升沿触发
begin
	if(!rst_n)
		count<=0;
	else if(count == 25'd250000)		//0.5S到了吗?
		count = 25'd0;					//计数器清零
	else
		count = count + 1'b1;
end	
//数码管动态扫描显示部分
always @(posedge clk or negedge rst_n)   //count[17:15]大约1ms改变一次
begin
	if(!rst_n)
		data<=0;
	else
	case(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;			//十万位
	endcase
end
always @(posedge clk)   				//count[17:15]大约1ms改变一次
begin
	case(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;			//选择第六个数码管显示
	endcase	
end
always @(posedge clk)
begin
	case(data)
		4'h0:seg<= 8'hc0;					//显示0
		4'h1:seg<= 8'hf9;					//显示1
		4'h2:seg <= 8'ha4;					//显示2
		4'h3:seg <= 8'hb0;					//显示3
		4'h4:seg <= 8'h99;					//显示4
		4'h5:seg <= 8'h92;					//显示5
		4'h6:seg <= 8'h82;					//显示6
		4'h7:seg <= 8'hf8;					//显示7
		4'h8:seg <= 8'h80;					//显示8
		4'h9:seg <= 8'h90;					//显示9
		4'ha:seg <= 8'hbf;					//显示-
		default:sm_seg <= 8'hff;			//不显示
	endcase
end
endmodule

2.分频
下面展示一些 内联代码片

// 分频
//根据修改m的值实现任意分频
//此处产生1Hz的clk
// An highlighted block
module 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;
else
begin
	if(div_cnt==m)
   		begin
			clk_div<=1'b1;
			div_cnt<=0;
   		end
	else
   		begin
   			clk_div<=1'b0;
   			div_cnt<=div_cnt+1;
   	end
end
//---------------------分频结束-----------------------
endmodule

3.按键消抖(盲猜会考)
下面展示一些 内联代码片

// 按键消抖
// An highlighted block
module 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)//检测时钟的上升沿和复位的下降沿
begin
if(rst_n==1'b0)
count<=20'd0;//先将计数清零
else
begin
if(count==20'd999_999)//20ms 扫描一次按键,20ms 计数(50M/50-1=999_999)
begin
count<=20'd0; //计数器计到 20ms,计数器清零
key_scan<=key;//采样按键输入电ping
end
else
count<=count+20'b1;//计数器加1
end
end
//----------------------------------------------------
// 按键信号锁存一个时钟节拍
//----------------------------------------------------
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;
 endcase
endmodule

程序填空

有关状态机——以三段式为例
下面通过实例来说明状态机的原理与设计方法。如设计一个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       ;
      else
          cstate   <= nstate  ;

always@(*)
   case(cstate)
              idle:if(num)
                      nstate  = S1    ;
                      else 
                       nstate  = idle ;
              S1:if(num)
                       nstate   = S2 ;
                   else
                       nstate   = idle ;
			  S2:if(num)
    	       		   nstate   = S2 ;
    			   else
     				   nstate  = S3 ;
			  S3:if(num)
     				   nstate  = S1 ;
   	  			  else
    	  			   nstate  = idle ;
 			default: nstate = idle ;
	endcase
always@(posedge clk)
    if(!rst_n)
       result <= 1’b0  ;
    else if(nstate == S3)
       result <= 1’b1  ;
    else
       result <= 1’b0  ;
 endmodule

内容很长,感谢阅读,希望对你有帮助!


点击全文阅读


本文链接:http://zhangshiyu.com/post/36431.html

显示  端口  赋值  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1