FPGA/IC笔试——乐鑫2022提前批

一、选择
1.以下关于System Verilog的描述,正确的 (D)

A:sv中可以用logic代替Verilog中的wire和reg类型(部分条件下不可代替,如:inout型端口只能用wire

B:sv中,定义成reg的信号会被综合成触发器(在组合逻辑中不被综合为触发器,如:不完全组合逻辑中reg变量也可以对应为锁存器

C:sv中的function语言不可被综合(可以综合

D:其他都不正确

E:sv是提供给验证使用的,因此不能被综合(可被综合

 

2.UVM层次化结构中,最顶层的部件类型是 (B)

A:uvm_test
B:uvm_root
C:uvm_top
D:uvm_component

【解析】uvm_root是验证平台中所有UVM components的“隐含”的top-level和phase控制器。用户不需要直接实例化uvm_root,UVM会自动创建uvm_root单一实例,用户可以使用全局变量(uvm_pkg范围内)uvm_top来访问uvm_root。

 

3.数字信号上采样时,一般需要添加什么样的滤波器,完成功能为 (C)

A:高通,抗混叠滤波

B:低通,抗周期延拓

C:低通,抗混叠滤波

D:高通,抗周期延拓

【解析】过采样技术的低通滤波器要同时完成量化噪声的滤除和降采样时抗混叠滤波的功能。

 

4.下列属于异步总线的是 (C)

A:SPI

B:USB

C:UART

D:IIC
【解析】(1) SPI——同步通信;串行通信;全双工;主从通信(某一时刻可以出现多个从机,但只能存在一个主机,主机通过片选线来确定要通信的从机)。(2) USB——同步通信;通用串行总线。(3) UART——异步通信;串行通信;全双工; 对等总线,没有仲裁机制,所以只能挂载两个同时收发数据的设备,双方都可以发送和接收。(4) I2C——同步通信;串行通信;半双工;主从通信(总线上支持多个主机和多个从机,总线上任何能够进行发送/接收数据的设备都可以占领总线。当然,任意时间点上只能存在一个主控。多主控,主器件同时争夺总线控制权时,可仲裁)。

 

5.(B)电路的逻辑功能特点是,任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关。

A:静态逻辑

B:组合逻辑

C:动态逻辑

D:时序逻辑

【解析】

  • 静态逻辑电路中靠稳定的输入信号使MOS晶体管保持导通或截止状态,从而维持稳定的输出状态。输入信号存在,对应的输出状态存在;只要不断电,输出信息可以长久保持;
  • 动态逻辑电路中利用电容的存储效应来保存信息,即使输入信号不存在,输出状态也可以保持,但由于泄漏电流的存在,信息不能长期保持;
  • 时序逻辑电路由存储电路和组合逻辑电路两部分组成,任何一个时刻的输出状态由当时的输入信号和电路原来的状态共同决定。

 

6.在芯片设计流程当中,通常会进行后仿真(post-simulation),关于后仿的作用,以下说法不正确的是 (B)

A:抽检netlist是否和RTL功能一致

B:抽检电路中是否出现有害的glitch

C:抽检时序是否有违规

D:抽检电路中是否存在亚稳态

 

7.以下关于异步处理正确的是 (C)

A:信号经过两级触发器即可完成异步信号的传递

B:只要信号传递的两端时钟频率不相等,即认为是异步信号

C:异步复位信号需要经过同步处理后再使用是安全的 (异步复位,同步释放)

D:异步FIFO中使用格雷码传递异步计数器可以保证每一拍传递的数据都是准确的

 

8.关于跨时钟域电路的设计,以下说法正确的是 (D)

A:单bit信号经两级D触发器同步后即可进行跨时钟域传递

B:采用单一时钟的电路不会产生亚稳态 (亚稳态产生原因是建立时间setup或保持时间hold不满足,单路时钟也有可能不满足)

C:异步FIFO的两个时钟频率相同也可以正常工作 (???)

D:跨时钟域电路当中的亚稳态无法消除 (只要系统中有异步元件,亚稳态就无法避免)

 【解析】几种方法跨时钟域处理方法:

  • 打两拍,两级触发器同步——单bit数据跨时钟域处理,适用于慢时钟域数据到快时钟域;
  • 异步双口RAM(异步FIFO可以实现同样效果)——多bit数据跨时钟域处理;
  • 格雷码转换;
  • 加握手信号。

9.衡量数字通信系统传输质量的指标是 (D)

A:信噪比

B:噪声功率

C:语音清晰度

D:误码率

 【解析】衡量数字通信系统传输质量的指标分为两种:可靠性和有效性指标,有效性主要指标为传输速率,可靠性主要指标误码率或者说是误信率

10.以下代码片段实现的电路功能是 (B、C)

input   [3:0] in;
output  [3:0] out;
wire    [3:0] a,b;
assign a = in<<1;
assign b = in>>3;
assign out = a|b;

A:对输入信号in先右移3位,再左移1位

B:对输入信号in循环左移1位

C:对输入信号in循环右移3位

D:对输入信号in先左移1位,再右移3位

 

二:填空

1.verilog 当中 a=4'b10x1; b=4'b10x1; 那么逻辑表达式 a==b 为(x)a===b为(1);

2.4bit的信号输入和8bit的信号输入的乘法器内部计算输出信号至少需要(12)bit的位宽;

3.通常情况下,芯片工作温度较(低),工作电压较(高),速度最快。

4.以下代码的打印输出是 (0)

always@(posedge clk)
begin
    a = 0;   //阻塞
    a <= 1;  //非阻塞
    $display("%0b",a);
end

注:%b使用固定宽度显示,以适应所显示表达式的最大可能值。 %0b显示最小宽度,禁止任何前导0或间隔。

5.全部使用组合逻辑实现复数A,B,C的运算|A*(B+C)|^2时, 共需使用()个乘法器与()个加法器

答案:6个乘法器,5个加法器

三、代码

题目描述1:使用verilog编写一根单向导线wire_a仿真模型,此导线的传输延迟为5ns,且不会过滤此波形。

`timescale 1ns/10ps
module wire_a(
    input      in,//输入
    output    out //输出
);
reg out_reg;

always@(*) begin
    out_reg <= #5 in;
end

assign out = out_reg;

endmodule

题目描述2:使用Verilog/SV撰写如下功能模块;求输入信号序列din在din_vld为高电平的时间段内的次小值和次小值出现的次数。接口信号如下:

module sec_min(
    input clk,           //时钟信号
    input rst_n,         //复位信号
    input [9:0] din,     //10bit无符号数
    input din_vld,       //输入数据有效信号
    output [9:0] dout,   //次小值
    output [8:0] cnt     //次小值出现的次数,溢出时重新计数
);

endmodule     

参考代码:(在July_714老哥基础上做出小修改)

  1 module sec_min(
  2     input   clk,                //时钟信号
  3     input   rst_n,              //复位信号
  4     input   [9:0]   din,        //10bit无符号数
  5     input   din_vld,            //输入数据有效信号
  6     output  [9:0]   dout,       //次小值
  7     output  [8:0]   cnt          //次小值出现的次数,溢出时重新计数
  8 );
  9 
 10 reg    [9:0]    min_data;
 11 reg    [9:0]    sub_data;
 12 reg    [9:0]    data_reg;
 13 reg    [1:0]    data_cnt;
 14 reg    [8:0]    sub_cnt;
 15 reg    [8:0]    min_cnt;
 16 reg    din_vld_r;
 17 //寄存一拍
 18 always@(posedge clk or negedge rst_n)begin
 19     if(!rst_n)begin
 20         data_reg <= 'd0;
 21         din_vld_r<= 'd0;
 22     end
 23     else if(din_vld) begin
 24         data_reg <= din;
 25         din_vld_r <= din_vld;
 26     end
 27     else begin
 28         data_reg<=data_reg;
 29         din_vld_r <= din_vld;
 30     end
 31 end
 32 
 33 
 34 //计数器,区分第一个数据,第二个数据,和其他的数据
 35 always@(posedge clk or negedge rst_n)begin
 36     if(!rst_n)begin
 37         data_cnt<='d0;
 38     end
 39     else if(din_vld) begin
 40         if(data_cnt<'d3)begin
 41             data_cnt<=data_cnt+1;
 42         end
 43         else begin
 44             data_cnt<='d3;
 45         end
 46     end
 47     else begin
 48         data_cnt<='d0;
 49     end
 50 end
 51 
 52 
 53 //分情况讨论,第一个数据来的时候,将第一个数据给最小值和次小值;在第二个数据来的时候,分情况讨论;在第三个及后面的数据来的时候,分情况讨论。
 54 always@(posedge clk or negedge rst_n )begin
 55     if(!rst_n)begin
 56         min_data<='d0;
 57         sub_data<='d0;
 58     end
 59     else if(din_vld_r) begin  //因为din打了一拍,这块使能也打一拍防止最后一个数漏检
 60         min_data<=data_reg;
 61         sub_data<=data_reg;
 62         if(data_cnt=='d1)begin
 63             min_data<=data_reg;
 64             sub_data<=data_reg;
 65         end
 66         else if(data_cnt=='d2)begin
 67             if(data_reg<min_data)begin
 68                 min_data<=data_reg;
 69                 sub_data<=min_data;
 70             end
 71             else begin
 72                 min_data<=min_data;
 73                 sub_data<=data_reg;
 74             end
 75         end
 76         else if(data_cnt=='d3) begin
 77             if(data_reg<min_data)begin
 78                 min_data<=data_reg;
 79                 sub_data<=min_data;
 80             end
 81             else if(data_reg==min_data)begin
 82                 min_data<=min_data;
 83                 sub_data<=sub_data;
 84             end
 85             else if(data_reg>min_data && sub_data==min_data)begin    //防止开局数为最小数
 86                 min_data<=min_data;
 87                 sub_data<=data_reg;
 88             end
 89             else if(data_reg<=sub_data)begin
 90                 min_data<=min_data;
 91                 sub_data<=data_reg;
 92             end
 93             else begin
 94                 min_data<=min_data;
 95                 sub_data<=sub_data;
 96             end
 97         end
 98     end
 99     else begin
100         min_data<=min_data;
101         sub_data<=sub_data;
102     end
103 end
104 
105 
106 //根据数据来的顺序和数值来进行次小值和最小值出现次数的计算
107 //然后分情况讨论,当新值比最小值小的时候,就要将min_cnt赋值给sub_cnt
108 //其他情况比较容易想到,有问题请留言讨论
109 always@(posedge clk or negedge rst_n)begin
110     if(!rst_n)begin
111         sub_cnt<='d0;
112         min_cnt<='d0;
113     end
114     else if(din_vld_r) begin
115         if(data_cnt==1)begin
116             sub_cnt<='d0;
117             min_cnt<='d1;
118         end
119         else if(data_cnt==2||data_cnt==3)
120         if(data_reg<min_data)begin
121             sub_cnt<=min_cnt;
122             min_cnt<='d1;
123         end
124         else if (data_reg==min_data)begin
125             sub_cnt<=sub_cnt;
126             min_cnt<=min_cnt+1;
127         end
128         else if(data_reg<sub_data)begin
129             sub_cnt<='d1;
130             min_cnt<=min_cnt;
131         end
132         else if(data_reg==sub_data) begin
133             sub_cnt<=sub_cnt+1;
134             min_cnt<=min_cnt;
135         end
136         else if(data_reg>min_data && sub_data==min_data) begin  
137             sub_cnt<=sub_cnt+1;
138             min_cnt<=min_cnt;
139         end
140         else begin
141             sub_cnt<=sub_cnt;
142             min_cnt<=min_cnt;
143         end
144     end
145     else begin
146         sub_cnt<=sub_cnt;
147         min_cnt<=min_cnt;
148     end
149 end
150 
151 //进行输出
152 assign    dout=sub_data;
153 assign    cnt=sub_cnt;
154 
155 endmodule

测试文件tb:

FPGA/IC笔试——乐鑫2022提前批_d3FPGA/IC笔试——乐鑫2022提前批_sed_02
 1 `timescale 1ns / 1ps
 2 
 3 module tb_submin;
 4 
 5     // Inputs
 6     reg clk;
 7     reg rst_n;
 8     reg [9:0] din;
 9     reg din_vld;
10 
11     // Outputs
12     wire [9:0] dout;
13     wire [8:0] cnt;
14 
15     // Instantiate the Unit Under Test (UUT)
16     sec_min uut_submin(
17         .clk(clk), 
18         .rst_n(rst_n), 
19         .din(din), 
20         .din_vld(din_vld), 
21         .dout(dout), 
22         .cnt(cnt)
23     );
24 always #5 clk = ~clk; 
25     initial begin
26         // Initialize Inputs
27         clk = 1;
28         rst_n = 0;
29         din = 0;
30         din_vld = 0;
31 
32         // Wait global reset to finish
33         #90;
34         rst_n = 1;
35         //first sequence
36         #10 din_vld = 1;
37             din = 10'd2;
38         #10 din = 10'd2;
39         #10 din = 10'd3;
40         #10 din = 10'd5;
41         #10 din = 10'd5;
42         #10 din = 10'd2;
43         #10 din_vld = 0;
44         //second sequence
45         #100 din_vld = 1;
46             din = 10'd10;
47         #10 din = 10'd10;
48         #10 din = 10'd6;
49         #10 din = 10'd5;
50         #10 din = 10'd5;
51         #10 din = 10'd2;
52         #10 din = 10'd5;
53         #10 din = 10'd2;
54         #10 din_vld = 0;
55         //reset
56         #100 rst_n = 0;
57         #10 rst_n = 1;
58 
59     end
60       
61 endmodule
testbench

 测试数据:2,2,3,5,5,2 ;则结果应为:dout = 3,cnt = 1 。

仿真结果:

FPGA/IC笔试——乐鑫2022提前批_sed_03

 注意:一个序列若第一个数为最小值,应注意次小值应比它大(如果只有两种数,那么次小值也是最大值);另外因为题目没有dout_vld信号所以一个序列检测完结果保持等待复位信号或下一个有效信号读入。

 

 

参考资料:乐鑫2022数字IC岗位提前批笔试题