2026年数字IC设计诺瓦科技笔试带答案解析
文章目录
- 一、试卷结构
- 二、单选题(共10题,每题3分,共30分)
- 三、简答题(共6题,每题5分,共30分)
- 四、编程题(共2题,每题20分,共40分)
一、试卷结构
| 项目 | 说明 |
|---|---|
| 笔试岗位 | 数字IC设计工程师 |
| 题型分布 | 单选题10题(每题3分,共30分) + 简答题6题(每题5分,共30分) + 编程题2题(每题20分,共40分) |
| 总分 | 100分 |
| 考试时长 | 90分钟 |
二、单选题(共10题,每题3分,共30分)
1.状态机的编码风格包括一段式、两段式和三段式,下列描述正确的是( )
A. 一段式寄存器输出,易产生毛刺,不利于时序约束
B. 二段式组合逻辑输出,不产生毛刺,有利于时序约束
C. 三段式寄存器输出,不产生毛刺,有利于时序约束
D. 所有描述风格都是寄存器输出,易产生毛刺,有利于时序约束
答案:C
解析:三段式状态机将状态寄存器、次态逻辑和输出逻辑分离,输出采用寄存器打拍,可有效消除组合逻辑输出的毛刺,且利于时序约束。一段式将所有逻辑混在一起,易产生毛刺;二段式通常为组合逻辑输出,仍存在毛刺风险。
2.线网中的值被解释为无符号数。在连续赋值语句中,assign addr[3:0] = -3;,addr被赋予的值是( )
A. 4’b1101
B. 4’b0011
C. 4’bxx11
D. 4’bzz11
答案:A
解析:在Verilog中,负数以补码形式表示。-3的二进制补码计算:3的二进制为0011,取反得1100,加1得1101。因此-3对应的4bit补码为4’b1101。
3.a = 4'b11001; b = 4'bx110;选出正确的运算结果( )
A. a & b = 0
B. a && b = 1
C. b & a = x
D. b & a = x
答案:B
解析:注意a为5bit(11001),b为4bit(x110),存在位宽不匹配。a && b是逻辑与,只要两个操作数都非零即为1。a=11001(非零),b=x110(虽含x,但非全0,逻辑值视为1),因此a && b = 1。&是按位与,结果含x,不一定为0或全x。
4.下列描述代码可综合的是( )
A.fork...join
B.assign/deassign
C.if...else和case
D.repeat和forever
答案:C
解析:if...else和case是基本的可综合条件语句。fork...join、assign/deassign(过程连续赋值)、repeat和forever通常不可综合或仅用于仿真。
5.reg [255:0] mem [7:0];正确的赋值是( )
A.mem[5] == 3'd0;
B.mem[10] = 8'd1;
C.mem = 0;
D.mem[5][3:0] = 4'd1;
答案:D
解析:mem是一个深度为8、位宽为256的存储器数组。A使用==是比较而非赋值;B索引mem[10]超出深度范围(0~7);C不能对数组整体赋值;D正确,对第5个元素的低4bit进行部分赋值。
6.以下关于逻辑综合中解决congestion问题描述不正确的是( )
A. 禁用多引脚标准单元,例如4输入引脚以上的标准单元
B. 使用partial blockage以降低congestion区域的cell density
C. 过多使用MUX单元不利于congestion的优化,因此MUX单元要尽可能禁用
D. 尽可能使用DCG做逻辑综合
答案:C
解析:MUX单元是常用逻辑单元,不能“尽可能禁用”,只能根据拥塞情况适当控制使用比例。A、B、D均为合理的拥塞优化策略:禁用多引脚单元可减少局部绕线密度;partial blockage降低单元密度;DCG(Design Compiler Graphical)具有物理感知能力,可优化congestion。
7.综合不包括下面哪一个过程( )
A. Translation
B. Routing
C. Mapping
D. Logic Optimization
答案:B
解析:综合(Synthesis)包含翻译(Translation)、逻辑优化(Logic Optimization)和映射(Mapping)。布线(Routing)属于物理设计阶段,不在综合流程内。
8.下面关于FIFO的描述正确的是( )
A. FIFO的读写必须属于同一时钟域
B. FIFO是先进先出的存储器
C. 外部不可以直接操作FIFO的读写地址
D. FIFO的空信号在写时钟域产生,满信号在读时钟域产生
答案:B
解析:FIFO的基本特性是先进先出(First In First Out)。A错误:FIFO分为同步FIFO和异步FIFO;C错误:外部通过读写指针间接操作地址;D错误:异步FIFO的空信号在读时钟域产生,满信号在写时钟域产生。
9.Verilog语言中,下列哪些语句不可以被综合( )
A.generate语句块
B.for语句块
C.function语句块
D.force语句
答案:D
解析:force和release是仿真用的过程连续赋值语句,不可综合。generate、可综合风格的for(常量循环)、function均可综合。
10.下面表达式中结果位1’b1的是( )
A.4'b1010 & 4'b1101
B.!4'b1001 || !4'b0000
C.&4'b1101
D.~4'b1100
答案:B
解析:逐项分析:A按位与得4’b1000,非单bit 1;B中!4'b1001为0,!4'b0000为1,逻辑或得1;C为缩减与,4’b1101相与得0;D为按位取反得4’b0011,非单bit 1。
三、简答题(共6题,每题5分,共30分)
11.(5分)简述流水线设计的方法和作用。
答案:
方法:将组合逻辑路径分割为多个较短的阶段,每个阶段之间插入寄存器(流水线寄存器)。数据在每个时钟周期前进一级,多组数据可同时在不同阶段处理。
作用:
- 提升系统吞吐率:缩短关键路径,提高时钟频率
- 提高资源利用率:各阶段并行工作
- 代价:增加延迟(Latency)和面积(寄存器开销)
12.(5分)怎样用D触发器、与门、或门、非门组成二分频电路?请画出电路图。
答案:
工作原理:D触发器的Q非端(或Q端经反相器)连接至D输入端。每个时钟上升沿,输出Q翻转一次,实现二分频。
13.(5分)请根据下面的设计描述,尽可能多地列出你所能想到的用于功能验证的测试点。
一个异步FIFO,rdata和wdata均为8位数据,FIFO深度为16。当rst_n输入为低时,FIFO被复位。当wclk的上升沿采样到wr为高时,数据被写入FIFO;当rclk的上升沿采样到rd为高时,FIFO输出数据。此外,当FIFO为空时,empty信号输出为高;当FIFO满时,full信号输出为高。
答案:
测试点清单:
- 复位测试:复位后FIFO内数据清空,empty=1,full=0,读数据无效。
- 单次写入读出:写1个数据后读出,验证数据正确性。
- 满标志测试:连续写入16个数据,验证full信号在第16个写操作后拉高,且继续写入数据不被覆盖。
- 空标志测试:写满后连续读出16个数据,验证empty信号在第16个读操作后拉高,且继续读出数据无效或保持。
- 写满后读空:写满→读空循环,验证指针正确回绕。
- 并发读写测试:读写时钟异步,同时进行读写操作,验证数据不乱序、不丢失。
- 背靠背读写:连续快速读写,验证无亚稳态导致的功能错误。
- 格雷码指针同步验证:检查读写指针跨时钟域同步是否正确。
- 几乎满/几乎空测试:若设计包含almost_full/almost_empty标志,需测试阈值。
- 边界条件测试:写时钟远快于读时钟(快写慢读)导致满;读时钟远快于写时钟(快读慢写)导致空。
- 错误注入:在满时写入、空时读出,验证FIFO行为符合规格(通常忽略写或读出无效数据)。
- 随机读写测试:随机化读写间隔和有效信号,配合Scoreboard比对数据。
14.(5分)用D触发器搭建4进制计数器。
答案:
说明:两个D触发器级联,DFF0的D端接~Q0(通过反相器),每个时钟翻转,实现二分频(Q0为CLK/2)。DFF1的D端接Q0 ⊕ Q1,在Q0的上升沿翻转。最终Q1Q0输出00→01→10→11→00,实现4进制计数。
15.(5分)设计一个同步FIFO,读写时钟相同。其中写入时每100个时钟周期会写10个,具体哪个时刻写入不确定;读出侧每10个cycle会读1个。计算FIFO的最小深度。
答案:
分析:
- 写侧平均速率:10/100 = 0.1 word/cycle
- 读侧平均速率:1/10 = 0.1 word/cycle
- 平均速率相等,因此平均意义上FIFO不会无限累积。
最坏情况分析:
写入的10个数据可能在100周期内连续出现(背靠背写入),此时写突发长度为10。读侧每10周期读1个,即读取速率固定为0.1 word/cycle。
在连续10个写周期内,FIFO中累积的数据量为:
写入10个 - 读出10×0.1 = 10 - 1 = 9个。
因此,在最坏情况下FIFO需要能够容纳9个数据。考虑写读使能的不确定性,可能上一轮的残留数据与新突发叠加,但最坏情况仍由突发长度和速率差决定。
答案:最小深度为9。通常再增加1~2作为余量,取10或11。题目问最小深度,答案为9。
16.(5分)如下代码在综合时是否可以综合出时钟门控电路?如果能,画出时钟门控示意图;如果不能,请修改使信号out可以综合出时钟门控电路。
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) out <= 64'b0; else if (out_en) out <= data; else out <= 64'b0; end答案:
不能综合出时钟门控电路。
原因:在else分支中out被赋值为64'b0,这意味着当out_en为0时寄存器被强制清零,而非保持原值。时钟门控的前提是寄存器在使能无效时保持当前值(即out <= out)。
修改后代码(可综合出时钟门控):
always @(posedge clk or negedge rst_n) begin if(rst_n == 1'b0) out <= 64'b0; else if (out_en) out <= data; // 移除 else 分支,out 保持原值 end时钟门控示意图:
说明:综合工具将out_en信号作为时钟门控使能,out_en为0时关闭寄存器时钟,寄存器保持原值,从而节省动态功耗。
四、编程题(共2题,每题20分,共40分)
17.(20分)用Verilog语言实现一个带使能的模100异步清零计数器;模块定义为module count(out, count_en, clr, clk);
答案:
module count ( output reg [6:0] out, // 0~99需要7bit (2^7=128) input wire count_en, input wire clr, // 异步清零,高有效 input wire clk ); always @(posedge clk or posedge clr) begin if (clr) begin out <= 7'd0; // 异步清零 end else if (count_en) begin if (out == 7'd99) out <= 7'd0; // 计到99回0 else out <= out + 1'b1; end end endmodule设计要点:
clr为异步复位信号,高有效,在敏感列表中使用posedge clr实现异步清零。- 模100计数:0~99循环,达到99后下一个使能周期归零。
- 输出位宽:ceil(log₂100)=7bit。
count_en为高时计数使能,为低时保持。
18.(20分)画出可以检测“11101”序列的状态转移图,并用Verilog实现FSM。要求每检测到一次该序列,输出2个周期的高电平信号;要求使用低功耗的状态机编码方式。
答案:
(1)状态转移图
状态说明:
- IDLE:初始状态,未检测到任何有效序列。
- S1:检测到1。
- S11:检测到11。
- S111:检测到111。
- S1110:检测到1110。
- DET1:检测到11101,输出高电平第1拍。
- DET2:输出高电平第2拍,结束后根据当前输入跳转(实现重叠检测)。
重叠检测说明:序列“11101”的后缀“1”可与后续“1101”组成新序列。在DET2状态,若输入为1,则相当于已匹配到“1”,跳转至S111(因DET2前状态为DET1,而DET1由S1110+1得来,此时输入1意味着已有连续三个1?需根据具体设计调整重叠逻辑。实际上在输出两拍期间继续采样,DET2后的下一状态由输入决定:若输入1,相当于新序列已有一个“1”,但考虑到前面序列末尾的“1”,可能已匹配到更长的前缀。具体实现时,在DET2状态根据输入决定回到哪个状态,保证不丢失重叠序列。
(2)Verilog实现(低功耗状态机编码)
module seq_detector_11101 ( input wire clk, input wire rst_n, input wire din, output reg out ); // 状态编码采用格雷码(低功耗:状态跳转时只有1bit翻转) localparam IDLE = 4'b0000; // 0 localparam S1 = 4'b0001; // 1 localparam S11 = 4'b0011; // 3 localparam S111 = 4'b0010; // 2 localparam S1110 = 4'b0110; // 6 localparam DET1 = 4'b0111; // 7 localparam DET2 = 4'b0101; // 5 reg [3:0] curr_state, next_state; // 状态寄存器 always @(posedge clk or negedge rst_n) begin if (!rst_n) curr_state <= IDLE; else curr_state <= next_state; end // 次态逻辑(三段式状态机) always @(*) begin next_state = IDLE; case (curr_state) IDLE: next_state = din ? S1 : IDLE; S1: next_state = din ? S11 : IDLE; S11: next_state = din ? S111 : IDLE; S111: next_state = din ? S111 : S1110; S1110: next_state = din ? DET1 : IDLE; DET1: next_state = DET2; // 无条件进入第二拍输出 DET2: begin // 重叠处理:DET2后根据当前输入跳转 if (din) next_state = S111; // 输入1,相当于已匹配到111 else next_state = S1; // 输入0,相当于已匹配到1 end default: next_state = IDLE; endcase end // 输出逻辑(Moore型,仅由状态决定) always @(posedge clk or negedge rst_n) begin if (!rst_n) out <= 1'b0; else out <= (curr_state == DET1) || (curr_state == DET2); end endmodule设计要点:
- 低功耗编码:使用格雷码编码状态,相邻状态间仅1bit翻转,减少组合逻辑和状态寄存器翻转功耗。
- 三段式状态机:状态寄存器、次态组合逻辑、输出逻辑分离,利于时序收敛和毛刺消除。
- 重叠检测:在DET2状态根据输入din跳转到合适状态,保证连续序列(如“111011101”)可被连续检测。
- 输出2周期高电平:设置DET1和DET2两个状态,两个状态下out均为1,实现两拍输出。
