FPGA面试笔试题
1、什么是同步逻辑和异步逻辑?
同步逻辑是时钟之间有固定的因果关系。异步逻辑是各时钟之间没有固定的因果关系。
〔补充〕:
同步时序逻辑电路的特点:各触发器的时钟端全部连接在一起,并接在系统时钟端,只有当时钟脉冲到来时,电路的状态才能改变。改变后的状态将一直保持到下一个时钟脉冲的到来,此时无论外部输入有无变化,状态表中的每个状态都是稳定的。
异步时序逻辑电路的特点:电路中除可以使用带时钟的触发器外,还可以使用不带时钟的触发器和延迟元件作为存储元件,电路中没有统一的时钟,电路状态的改变由外部输入的变化直接引起。
2、同步电路和异步电路的区别是什么?
同步电路:存储电路中所有触发器的时钟输入端都接同一个时钟脉冲源,因而所有触发器的状态的变化都与所加的时钟脉冲信号同步。
异步电路:电路没有统一的时钟,有些触发器的时钟输入端与时钟脉冲源相连,这有这些触发器的状态变化与时钟脉冲同步,而其他的触发器的状态变化不与时钟脉冲同步。
3、时序设计的实质:
电路设计的难点在时序设计,时序设计的实质就是满足每一个触发器的建立/保持时间的而要求。
4、建立时间与保持时间的概念?
建立时间:触发器在时钟上升沿到来之前,其数据输入端的数据必须保持不变的时间。
保持时间:触发器在时钟上升沿到来之后,其数据输入端的数据必须保持不变的时间。
5、什么是亚稳态?为什么两级触发器可以防止亚稳态传播?
亚稳态是指触发器无法在某个规定的时间段内到达一个可以确认的状态。 使用两级触发器来使异步电路同步化的电路其实叫做“一步同位器”,他只能用来对一位异步信号进行同步。 两级触发器可防止亚稳态传播的原理:假设第一级触发器的输入不满足其建立保持时间,它在第一个脉冲沿到来后输出的数据就为亚稳态,那么在下一个脉冲沿到来之前,其输出的亚稳态数据在一段恢复时间后必须稳定下来,而且稳定的数据必须满足第二级触发器的建立时间,如果都满足了,在下一个脉冲沿到来时,第二级触发器将不会出现亚稳态,因为其输入端的数据满足其建立保持时间。同步器有效的条件:同步器有效的条件:第一级触发器进入亚稳态后的恢复时间+第二级触发器的建立时间 <= 时钟周期。 更确切地说,输入脉冲宽度必须大于同步时钟周期与第一级触发器所需的保持时间之和。最保险的脉冲宽度是两倍同步时钟周期。所以,这样的同步电路对于从较慢的时钟域来的异步信号进入较快的时钟域比较有效,对于进入一个较慢的时钟域,则没有作用。
6、对竞争冒险的理解,以及如何消除?
在组合逻辑中,由于门的输入信号通路中经过了不同的延时,导致到达该门的时间不一致叫竞争。产生毛刺叫冒险。
如果布尔式中有相反的信号则可能产生竞争和冒险现象。
解决方法:一是添加布尔式的消去项,二是在芯片外部加电容。
7、FPGA结构一般分为三部分:
可编程逻辑块(CLB)、可编程I/O模块和可编程内部连线。
8、用VHDL/Veilog HDL语言开发可编程逻辑电路的完整流程:
文本编辑享有→功能仿真→逻辑综合→布局布线→时序仿真。
综合其目的是将多个模块化设计文件合并为一个网表文件,供布局布线使用,网表中包含了目标器件中的逻辑单元和互连的信息。
布局布线就是根据设计者指定的约束条件(如面积、延时、时钟等)、目标器件的结构资源和工艺特性,以最优的方式对逻辑元件布局,并准确地实现元件间的互连,完成实现方案(网表)到使实际目标器件(FPGA或CPLD)的变换。
9、FPGA过程中的仿真有三种:
行为仿真、逻辑仿真、时序仿真。
10、锁存器(latch)和触发器(flip-flop)区别?
电平敏感的存储期间称为锁存器。可分为高电平锁存器和低电平锁存器,用于不同时钟之间的信号同步。
有交叉耦合的门构成的双稳态的存储原件称为触发器。分为上升沿触发和下降沿触发。可以认为是两个不同电平敏感的锁存器串连而成。前一个锁存器决定了触发器的建立时间,后一个锁存器则决定了保持时间。
11、系统最高速度计算(最快时钟频率)和流水线设计思想:
同步电路的速度是指同步系统时钟的速度,同步时钟愈快,电路处理数据的时间间隔越短,电路在单位时间内处理的数据量就愈大。假设Tco是触发器的输入数据被时钟打入到触发器到数据到达触发器输出端的延时时间;Tdelay是组合逻辑的延时;Tsetup是D触发器的建立时间。假设数据已被时钟打入D触发器,那么数据到达第一个触发器的Q输出端需要的延时时间是Tco,经过组合逻辑的延时时间为Tdelay,然后到达第二个触发器的D端,要希望时钟能在第二个触发器再次被稳定地打入触发器,则时钟的延迟必须大于Tco+Tdelay+Tsetup,也就是说最小的时钟周期Tmin=Tco+Tdelay+Tsetup,即最快的时钟频率Fmax=1/Tmin。FPGA开发软件也是通过这种方法来计算系统最高运行速度Fmax。因为Tco和Tsetup是由具体的器件工艺决定的,故设计电路时只能改变组合逻辑的延迟时间Tdelay,所以说缩短触发器间组合逻辑的延时时间是提高同步电路速度的关键所在。由于一般同步电路都大于一级锁存,而要使电路稳定工作,时钟周期必须满足最大延时要求。故只有缩短最长延时路径,才能提高电路的工作频率。可以将较大的组合逻辑分解为较小的N块,通过适当的方法平均分配组合逻辑,然后在中间插入触发器,并和原触发器使用相同的时钟,就可以避免在两个触发器之间出现过大的延时,消除速度瓶颈,这样可以提高电路的工作频率。这就是所谓"流水线"技术的基本设计思想,即原设计速度受限部分用一个时钟周期实现,采用流水线技术插入触发器后,可用N个时钟周期实现,因此系统的工作速度可以加快,吞吐量加大。注意,流水线设计会在原数据通路上加入延时,另外硬件面积也会稍有增加。
12、用D触发器实现2倍分频的Verilog描述?
module divide2( clk , clk_o, reset); input clk , reset; output clk_o; wire in; reg out ; always @ ( posedge clk or posedge reset) begin if ( reset) out <= 0; else out <= in; end assign in = ~out; assign clk_o = out; endmodule
13、用Verilog或VHDL写一段代码,实现10进制计数器。
`timescale 1ns/10ps module counter10(clk,rst,count); input clk,rst; output [3:0] count; reg [3:0] q; assign count = q; always@(posedge clk or negedge rst) begin if(!rst) q <= 0; else if(q >= 4'd9) q <= 0; else q <= q + 1; end endmodule
14、请用Verilog描述四位的全加法器。
module add_4( input [3:0] a,b, output [3:0] sum, output cout, input cin ); assign{cout,sum} = a+b+cin; endmodule
15、画出可以检测10010串的状态图,并用verilog实现。
module seq_dect( input wire clk, input wire rst_n, input wire num_in, output wire res ); parameter Idle = 3'b000, // s1 = 3'b001, //1 s2 = 3'b010, //10 s3 = 3'b011, //100 s4 = 3'b100, //1001 s5 = 3'b101, //10010 s6 = 3'b110, //10001 s7 = 3'b111; //1000 reg[2:0] current_state; reg[2:0] next_state; always@(posedge clk or posedge rst_n) begin if(rst_n == 1'b0) begin current_state = Idle; next_state = Idle; end else begin current_state = next_state; end end assign res = (current_state==s4 && num_in==0)? 1 : 0; always@(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) begin current_state <= Idle; end else begin case(current_state) Idle:begin if(num_in == 1'b0) next_state <= Idle; else next_state <= s1; end s1:begin if(num_in == 1'b0) next_state <= s2; else next_state <= s1; end s2:begin if(num_in == 1'b0) next_state <= s3; else next_state <= s1; end s3:begin if(num_in == 1'b0) next_state <= s7; else next_state <= s4; end s4:begin if(num_in == 1'b0) next_state <= s5; else next_state <= s1; end s5:begin if(num_in == 1'b0) next_state <= s3; else next_state <= s1; end s6:begin if(num_in == 1'b0) next_state <= s2; else next_state <= s1; end s7:begin if(num_in == 1'b0) next_state <= s7; else next_state <= s1; end default:begin current_state <= Idle; end endcase end end endmodule
16、用Verilog设计一个5分频器。
方法一:5分频,奇数分频都可以类似这么做,只需要改div1和div2的参数。div1为奇数分频除2的余数。采用上升延和下降延分别触发不同波形,最后叠加的方式产生奇数分频。
module divfreq(clk, clk1x, rst, clk1xpose, clk1xnege, coutpose, coutnege); input clk; input rst; output clk1x; output clk1xpose; output clk1xnege; output [2:0] coutpose; output [2:0] coutnege; reg clk1xpose; reg clk1xnege; reg [2:0] coutpose; reg [2:0] coutnege; parameter div1 = 2 , div2 = 4; // div1 = ( 5 - 1 ) / 2, div2 = 5 - 1 assign clk1x = clk1xpose | clk1xnege; always@(posedge clk or negedge rst) begin if(!rst) clk1xpose = 0; else if(coutpose == div1) clk1xpose = ~clk1xpose; else if(coutpose == div2) clk1xpose = ~clk1xpose; else clk1xpose = clk1xpose; end always@(negedge clk or negedge rst) begin if(!rst) clk1xnege = 0; else if(coutnege == div1) clk1xnege = ~clk1xnege; else if(coutnege == div2) clk1xnege = ~clk1xnege; else clk1xnege = clk1xnege; end always@(posedge clk or negedge rst) begin if(!rst) coutpose = 0; else if(coutpose == div2) outpose = 0; else coutpose = coutpose + 1; end always@(negedge clk or negedge rst) begin if(!rst) coutnege = 0; else if(coutnege == div2) coutnege = 0; else coutnege = coutnege + 1; end endmodule