FPGA面试题目笔记(四)—— 序列检测器、跨时钟域中的格雷码、乒乓操作、降低静态和动态损耗、定点化无损误差

1、序列检测器

题目:

Moore型状态机实现序列“1101”从右到左的不重叠检测

1、请画出状态转移图,其中状态用S1,S2,…来标识。

2、针对这个具体设计,如何衡量验证的完备性?


Moore型:状态机的状态变化仅和当前状态有关。

1.1 状态机实现序列检测器

1.11不重叠检测和重叠检测

看下图即可:
在这里插入图片描述
题目分析:
从右到左不重叠检测1101,也就是从左到右不重叠检测1011,因此我们可画出状态图:
在这里插入图片描述

1.1.2 verilog实现

//序列检测器1011,不重叠检测

module test(
    
	 input clk,
	 input rst_n,
	 input d,         //序列输入
	 output reg done  //检测完成

);
parameter S1 = 3'd1,S2 = 3'd2,S3 = 3'd3,S4 = 3'd4,S5 = 3'd5;

reg [2:0] state,next_state;


//三段式状态机

//第一段,状态寄存器
always@(posedge clk)
    if(!rst_n)
	     state <= S1;
	 else
	     state <= next_state;
		  
//第二段,组合逻辑描述状态转移
always @ (*)begin
    case(state)
		  S1: next_state = d ? S2:S1;
		  S2: next_state = d ? S2:S3;
		  S3: next_state = d ? S4:S1;
		  S4: next_state = d ? S5:S3;
		  S5: next_state = d ? S2:S1;
		  default: next_state = S1;
	
    endcase
end	  
//第三段,状态输出
always@(*)
    done = (state == S5) ;

endmodule

1.1.3 tb文件

`timescale 1ns/1ns

module test_tb;

	 reg clk;
	 reg rst_n;
	 reg d;        //序列输入
	 
	 wire done ; //检测完成



 test u1 (
    
	 .clk(clk),
	 .rst_n(rst_n),
	 .d(d),         //序列输入
	 .done(done) //检测完成

);
//
initial clk = 0;
    always #1 clk = ~clk;
//
initial begin
    rst_n = 0;
    #1;
    rst_n = 1;
end
//
initial begin
    d = 0;
    #2;
    d = 1;
    #2;
    d = 0;	 
    #2;
    d = 1;
	 #2;
    d = 1;
	 
    #2;
	 d = 0;
	 #2;
    d = 1;
	 #2;
    d = 1;
	 #3;
	 d= 0;
	 #20;
	 $stop;
	 	 
end

endmodule

波形:
可看到当检测到1011的时候,done变成高电平。
在这里插入图片描述
由于是不重叠序列检测,因此可看到,如下1011时done没有变成高电平,因此设计正确。
在这里插入图片描述

1.1.4 如何衡量设备的完备性

设备完备性的衡量是用来验证的,对于状态机来说,会出现各种状态跳转错误等,因此我们要确保状态之间的正确跳转,同时本题中是不重叠检测,因此也要明确这点,确保当出现重叠序列的时候,不会误检。

1.2 用移位操作实现循环序列发生器

题目要求:
循环产生如下序列:0010_1101_11。


解题:可采用状态机实现,但为了简化操作,这里采用移位操作来实现序列的循环发生

verilog如下:

module test(
    
    input clk,
    input rst_n,
	 input [9:0] in,
	 
    output reg out
);

    reg [9:0] out_r;
	 
//移位
    always@(posedge clk or negedge rst_n) 
	     if(!rst_n)
		      out_r <= in;  //0010_1101_11

		  else 
		     
				out_r <= {
    
    out_r[8:0],out_r[9] };
 
//逐高位输出		  
    always@(posedge clk or negedge rst_n) 
	     if(!rst_n)
		      out <= 0;
	
		  else 
		      out <= out_r[9];

endmodule

tb测试:

`timescale 1ns/1ns

module test_tb;

	 reg clk;
	 reg rst_n;
	 reg [9:0] in;

	 wire out ; //检测完成



 test u1 (
    
	 .clk(clk),
	 .rst_n(rst_n),
	 .in(in),
	 .out(out)


);

initial clk = 0;
    always #1 clk = ~clk;

initial begin
    rst_n= 0;
	 in = 10'b0010_1101_11;
    #10;
    rst_n= 1;
	 #5;  

	 #50;

	 $stop;
end

endmodule

仿真波形:
在这里插入图片描述

2、最高工作频率与最小工作周期

在这里插入图片描述

找到电路的关键路径。
同时最小工作周期公式:Tmin = Tco + Tcmob + Tsu - Tskew。
组合逻辑电路则最小工作周期:Tmin = Tco + Tcmob + Tsu。

本题中,Tco为触发器输出的延时,为这里的逻辑延时6ns,组合逻辑的延时为反相器INV2的延时2ns,Tsu为建立时间2ns。这里没有考虑INV1的延迟,因为关键路径的延迟是从源触发器的Tco开始算
因此最小工作周期 Tmin = 6 + 2 +2 = 10ns。
最高工作频率 = 1 / 10ns = 0.1 GHZ = 100 MHZ

补充:1ns = 10^-9 s
在这里插入图片描述


3、跨时钟域处理——格雷码

在前面的笔记中,我们已经详细介绍了握手信号等,这里主要介绍跨时钟域处理中的格雷码。

格雷码:可以解决多bit跨时钟域信号传输。

题目参考
题目:
在这里插入图片描述
本题目中第四种方法不常见,自己也不太懂,可参考其他博文的解释,我这里主要来分析第三种格雷码的方式。


格雷码:相邻的两个编码之间只有一位是不一样的。
独热码:每个编码只有一位是1。

为什么格雷码能用于跨时钟域处理?

由于格雷码相邻数据只有一个bit不同,因此,在进行跨时钟域传输时,只有发生变化的那个bit有可能处于亚稳态,而其余bit保持不变,因此是稳定的,故多比特格雷码的跨时钟域传输就相当于单比特信号的跨时钟域传输,这样的话,我们即可采用两级同步来处理。

但本题中是0-6的计数,对应的二进制码和格雷码如下,可看到转换后不符合题目0-6的要求,因此不能用格雷码
在这里插入图片描述


4、乒乓操作

乒乓buffer可以提高系统的数据吞吐量,提高系统的处理并行度 。(判断题)——正确

5、时钟周期与建立和保持时间

在这里插入图片描述
本题是对静态时序分析的考察,最后一个正确

1、未考虑时钟偏移:

(T-Tco-Tsu) >   Tcomb > (Th-Tco) ,即对组合逻辑延迟的要求。

Tcmob为组合逻辑延迟,本题还包括走线延迟。

2、考虑时钟偏移:

根据上述公式我们可得到如下的推导:
在这里插入图片描述

6、降低峰值损耗和SRAM动态损耗

峰值功耗是属于动态功耗中的短路功耗,即NMOS和PMOS同时导通所引起的峰值电流,最终带来的功耗。这个功耗和电源电压,时钟翻转率,以及峰值电流有关。峰值损耗一般出现在时钟翻转的瞬间。
CMOS管功耗 = 动态功耗 + 静态功耗
静态功耗:是时钟不工作的状态下所需的功耗
动态损耗:器件工作时所增加的功耗,它由切换信号及容性负载的充放电引起
动态功耗 = 负载功耗 + 内部功耗
负载功耗:指CMOS管在翻转过程中对负载电容进行充放电消耗的功耗。
内部功耗:指CMOS管在翻转过程中,对内部结点电容进行充放电消耗的功耗及短路电流消耗的功耗。


题目1:下列功耗措施哪个可以降低峰值功耗? ——A

A 静态模块级Clock Gating
B Memory Shut Down
C Power Gating
D 大幅度提高HVT比例

A:由于峰值损耗一般出现在时钟翻转的瞬间,而A选项是加入时钟门控,当我们不需要时钟翻转时可将其关闭。
B:存储关闭,当不被访问的时候,关闭存储器,属于降低静态功耗。
C:电源门控,即模块不工作的时候,关闭电源,模块睡眠,工作时候再启动电源,也属于降低静态功耗。
D:采用高阈值电压的晶体管,阈值电压增加的效果在于降低亚阈值漏电电流,属于降低静态功耗。
该题有争议,从两个角度来看答案不同,我认为A正确,这里暂选择A。

题目2:以下哪些手段可以降低SRAM的动态功耗( )。(大疆FPGA逻辑岗B卷)(多选)
A 不访问SRAM时,关闭时钟
B 不访问SRAM时,地址线不翻转
C 不访问SRAM时,写数据线不翻转
D 不访问SRAM时,将其Power down

D:首先对于SRAM来说,它属于静态随机存取存储器,静态是指只要通电,数据即可保持,当断电的时候,数据丢失。因此D选项不能作为降低损耗的方法。

A:影响动态功耗的主要变量是电容充电、工作电压和时钟频率。因此在SRAM不工作时,关闭控制SRAM的时钟,SDRAM中的数据并不会丢失,而且可以降低动态损耗。
BC:不访问SRAM时,地址线和写数据线不翻转,相当于减少了CMOS管的翻转,因此能降低动态损耗。


7、阻塞和非阻塞

阻塞和非阻塞的细讲

答案0 2
在这里插入图片描述
这里可直接画出对应的电路更好理解:
左边:
在这里插入图片描述

右边:
在这里插入图片描述

8、编写满足特定要求的tb测试文件

(1)频率为100MHz的时钟
(2)对时钟敏感的4位宽信号,限制该信号在8到15的范围内随机化16次。

`timescale 1ns/1ps
module random1();
reg clk;
reg [3:0] out_rand; //定义成了reg型
 
initial begin
    clk  = 0;
always #5 clk = ~clk;

integer i;
 
initial begin
    for(i = 0;i < 16; i = i + 1) begin
        @(posedge clk) begin
            out_rand = 4'b1000+ {
    
    $random}%8;
        end
    end
end

endmodule

为什么out_rand定义成reg型?
因为该信号虽然是由随机函数产生,但其本身是输入信号,在tb测试文件中,输入信号定义成reg型,输出信号定义成wire型。——本题只是想通过随机函数来生成可随机化的输入信号,因此仍为reg型。

随机函数

对本题的随机函数进行小补充:

{$random}%8 :表示 0 ~ 8 范围内的数
$random %8 :表示 -8 ~ 8 范围内的数

9、计算存储器的地址线和数据总线

关于存储器

(大疆2020芯片工程师A卷,单选)1个16K x 8位的存储器,其地址线和数据线总和是

A、46

B、17

C、48

D、22

解析:

地址线:16K = 1K * 16 = 1024* 16 = (2 ^10 )*(2^4) = 2^14,即需要 14 根地址线;

数据线:8 位数据需要 8 根数据线;因此共需要 22 根线。——D


10、八分频电路

给出如下电路,画出波形,并分析电路功能。
在这里插入图片描述

该电路可看到是由四个二分频D触发器,以及一个D触发器构成。A端连接的是复位,触发器默认复位输出0,反之为高电平1。
波形如下:
在这里插入图片描述

可看到输出是八分频输出。
对于Y来说,相当于对A的检测,其中最后一个触发器的clk为Q4输出,因此当时钟上升沿的时候,即可检测到A的值,只要A为高电平的时间足够长,Y就能输出高电平,看图可知,A高电平的时间必须大于等于7个时钟周期,否则检测不到高电平,因此会当作毛刺过滤掉,从而该电路的功能为滤波电路。

代码如下:

module test(
    
    input clk,
    input A,
    output reg Y
);


    reg Q1_n, Q2_n ,Q3_n, Q4;

//四个二分频D触发器	 
    always@(posedge clk or negedge A) begin
        if(~A) begin 
            Q1_n <= 1'b1;
        end
        else begin 
            Q1_n <= ~Q1_n;
        end
    end
	 
	 
    always@(posedge Q1_n or negedge A) begin
        if(~A) 
		      Q2_n <= 1'b1; 
        else 
		      Q2_n <= ~Q2_n;
    end
    always@(posedge Q2_n or negedge A) begin
        if(~A) 
		      Q3_n <= 1'b1; 
        else 
		      Q3_n <= ~Q3_n;
    end
    always@(posedge Q3_n or negedge A) begin
        if(~A) 
		      Q4 <= 1'b0; 
        else 
		      Q4 <= ~Q4;
    end
//D触发器	 
    always@(posedge Q4 or negedge A) begin
        if(~A) 
		      Y <= 1'b0;
        else 
		      Y <= A;
    end
    
endmodule

RTL如下:
在这里插入图片描述
仿真:

`timescale 1ns/1ns

module test_tb;

	 reg clk;
	 reg A;

	 wire Y ; //检测完成



 test u1 (
    
	 .clk(clk),
	 .A(A),
	 .Y(Y)


);

initial clk = 0;
    always #1 clk = ~clk;

initial begin
    A= 0;
    #1;
    A= 1;
	 #14;  
	 A=0;
	 #2;
	 A=1;
	 #16;
	 $stop;
end


endmodule

在这里插入图片描述
可看到波形输入A,两次为高电平,但是第一次高电平没有检测到,因为它没有延迟高电平大于等于7个clk,因此被滤除掉了,而第二次A为高电平的时候,延迟周期等于7,因此被检测到了。

11、有效 / 固有建立时间和保持时间

假设有效保持时间为Tsetup_valid。
对于D触发器,其本身的建立时间Tsu = 2ns,也就是数据在时钟有效沿来之前保持2ns的稳定,这样才能保证来自输入datatin的数据稳定地到达D端。
由于时钟来自于clock,也有着时钟延迟,且clk要早于触发器Toffest=1ns到达。

因此,考虑时钟延迟,得到有效保持时间:Tsetup_valid = Tsu - Toffest = 1ns
.
考虑数据路径延迟,得到 Tsetup_valid = Tsu - Toffest +Tcmob

有效保持时间Thold_valid也是同样的分析。

考虑时钟延迟的影响:

考虑到电路时钟对于触发器时钟早到Toffest = 1ns,所以电路有效保持时间Thold_valid = Thold + Toffest ;
.
考虑路径延迟影响:

数据需要经过一段组合逻辑之后才能保持稳定,因此电路的有效保持时间为:

Thold_valid = Thold + Toffest - Tcmob


题目:
T_offest为时钟偏移,求下图电路的固有建立时间和保持时间,系统最高频率。

在这里插入图片描述
固有建立时间: Tsu - Toffest + Tcmob = 2ns - 1.2ns + 0.9ns + 1.2 ns = 2.9ns
固有保持时间: Thold + Toffest - Tcmob = 1.5 + 1.2 - 0.9- 1.2 = 0.6ns
最小工作周期:Tmin = Tsu + Tcmob + Tco = 2ns + Tpd + 1.8ns = 5ns(找到两个触发器间的关键路径)
最高频率:1 / Tmin = 1/ 5ns = 200 Mhz

12、无损定点化误差的计算

详细的定点化学习


题目:(大疆2020芯片开发工程师A卷)
在这里插入图片描述
该题目需要注意的是需要进行无损定点化,当求最小位宽的时候给出了两种,12和13位,我们即可先对12位进行无损误差的计算验证,如果是无损误差,那么最小位宽就是12位。在根据我们上面给出的步骤以位宽为11进行量化误差的计算。

解题如下
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/H19981118/article/details/125071753