赞
踩
我将从七个方面总结数字IC设计笔试面试中会遇到的问题。这些问题大多来自于网络上大佬们分享的面经,在学习这些资料的过程中,我发现短时间内去学会所有的问题时不可能的,最关键的还是要学会分析问题的方法,找到问题的根本(听上去像是废话,但事实就是这样)。我的导师对我的评价是,非要别人把饭做好了、嚼碎了喂到嘴里你才会吃。这句话本身没有什么问题,无非是想让我学会做饭的方法。注意,这里是分三个层次的,一是学方法,二是学别人的思路,三是看了别人的思路还不行,还要别人掰开了揉碎了你才能懂。总而言之,第三种是绝对不可取的,希望看我文章的同学,可以先学思路(人无完人,请抱着质疑的态度的看,如有错误,欢迎指正),自己分析之后再总结出方法。
语法问题主要是可综合的语法问题,不可综合的语法不在这里讨论。
Verilog可综合的语法非常少,但是复杂的芯片就是通过这些语法实现的。所以语法问题十分重要。语法问题重点理解可综合的语法与其综合生成的电路的映射关系。
1.阻塞与非阻塞的区别是什么,什么时候使用?
阻塞赋值在Verilog的操作符是 = ,在组合逻辑电路中使用。只有当前的赋值操作完成,才能执行之后的语句。代码与生成的电路如下:
非阻塞赋值在Verilog的操作符是 <= , 用描述时序逻辑里的触发器。可以理解为使用非阻塞赋值的语句是并行执行的。
上边的解释简洁明了,对于即将参加面试的你肯定是可以理解的。这里重点理解阻塞与非阻塞赋值综合生成的电路的区别,B&A生成了一个与门,如果是阻塞赋值C=B&A,这个与门的输出就是C。如果是非阻塞赋值C<=B&A,这里可以认为 “<=”就是一个触发器,<=的右边连接触发器的D端,<=的左边是触发器的Q。显然按位运算符“&”一定会生成一个与门,非阻塞赋值“<=”则生成触发器(必须是时序逻辑)。
2.解释逻辑运算符和按位运算符的不同。
逻辑运算符包括:&&、 ||、 !
位运算符包括:&、 |、 ~、 ^、 ^~
//位运算符的与
assign C = A & B;//这里的&生成与门,如果A B是多bit信号,必须位宽一致,C是A B对应bit相与的结果。
//但是实际中不会让两个多bit信号相与,因为多bit信号的延时不同。
//逻辑运算符的与
if(A==1'b1 && B==1'b1) //这里生成三个与门
/................................................../
//位运算符的或
assign C = A | B;//这里的|生成或门
//逻辑运算符的与
if(A==1'b1 || B==1'b1) //这里生成两个与门一个或门
/................................................../
assign A = ~B;//这里~生成非门
if(!rst)//条件运算符的非
//位运算符中的异或 同或类似
逻辑运算符只能用在条件判断中。
位运算符一般在赋值操作中使用,但是当判断条件中的变量是单bit时也可使用,例如:
if(A == 1’b1 && B == 1’b1) 可修改为if(A & B)
3 Verilog中逻辑门:and, or, nand, nor, xor, xnor
assign C = A & B; //与门
assign C = A | B; //或门
assign C = A ^ B; //异或门
assign C = ~(A & B);//与非门
assign C = ~(A | B);//或非
assign C = ~(A ^ B);//同或
4 位缩减运算符
&, |, ^ 这三个位运算符作为单目运算符使用时,是按位缩减运算。
wire[15:0] data;
wire all_one;
wire odd;
wire not_zero;
assign all_one = &data; //data的16bit按位相与,结果是1说明data全1
assign odd = ^data; //data的16bit按位异或,常用来做奇偶校验,结果是1说明有奇数个1,反之有偶数个。
assign not_zero = |data; //按位或,可用来检测是否全0
5 怎么做2的整数倍乘除法?
对于数字电路来说直接做乘除法是不可能的。
但是移位运算符可以做到2的整数倍乘除法。
assign C = A<<2; //左移两位表示乘4
assign C = A>>3; //右移三位表示除8,其中A必须是2的整数倍
但是使用移位运算做乘除法必然会遇到最高位或最低位丢失的问题,所以要根据具体的情况使用。
6、位扩展
reg[4:0] A;
wire [9:0] C;
assign C = {{5{A[0]}},a}; //
7、三种代码实现4选1mux及其综合的电路区别
方式1: assign output = (select == 2'b00)?A: (select == 2'b01)?B: (select == 2'b10)?C:D; 方式2: always @(*)begin if(select == 2'b00) output <= A; else if(select == 2'b01) output <= B; else if(select == 2'b10) output <= C; else output <= D; end 方式3: always @(*)begin case(select) 2'b00:output <= A; 2'b01:output <= B; 2'b10:output <= C; 2'b11:output <= D; endcase end
方式1和方式2综合的电路相同:
方式3生成的电路:
两种电路的区别:方式3对应的电路延时更小,多选1尽量使用case实现。但是当A为关键路径时可能使用第一种方式更好。A如果是关键路径,延时必然更大,使用级联的2选1可以让时序变好。
8、同步复位与异步复位的区别
9、Verilog code 实现latch和Flip Flop 并画出时序图
//latch代码
always @(*)begin
if(clk = 1'b1)
Q_latch <= input;
end
//触发器代码
always @(posedge clk)
Q_flop <= input;
时序图如下:
使用always描述的组合逻辑在两种情况下会产生latch,一是if语句没有else,二是case语句没有default。根本原因是条件没有写全,导致出现未知条件时输出会保持,组合逻辑出现“保持”的情况就会产生锁存器。总之,使用always描述的组合逻辑中条件分支一定要写全,不能出现未知的情况。
下期预告:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。