赞
踩
自从开始邀请同行加入笔试面试交流群之后,目前已经有40多位同行加入,大家踊跃发言,各抒己见,让各自受益匪浅。
今天的这篇博文是将近期部分题目做一次总结,我觉得有意思有意义的题目,当然之前也做了很多总结,但都是专题型的,这篇则不限专题。
后面还会有一篇关于FIFO专题的介绍,有时间在写。
如有路过的同行,想加入群,可以加我微信(ljs521615),备注csdn等,我拉你进群。
1.分析电路功能:
分析:看这个电路图,下面四个触发器和上面1个触发器构成,下面四个触发器的连接关系好像是分频器的连接,我们要分析这个电路的功能,就要画出每一个触发器的波形图,触发器的默认复位输出是0,当然Q反为1。
下面随手画了一个复位A时间够长的波形图:
用这张图给大家留一个初始印象,Q4的输出,可见是一个八分频输出,当然这不重要。
重要的是Y,当A为高电平的时候够长,我就能检测到A的高电平。
但大家请思考,如果A的高电平时间不够长,那么还没等到Q4的上升沿出现就变为低电平了,那么Y是永远也检测不到A的高电平的,那这个够长是多长呢?
数一下,是要大于等于7个时钟周期。
A的高电平时间必须大于等于7个时钟周期,否则,当成毛刺过滤掉。那么我不禁想这个电路到底什么功能呢?滤波电路!对于A的高电平时候小于7个时钟,我们就当做毛刺滤掉了。
好了,本想讨论到这里,但还是想通过仿真来实现一下,毕竟手画波形有点费劲。
我们先描述出这个电路:
- module freq_div(
- input clk,
- input A,
- output reg Y
- );
- wire A1;
- assign A1 = A;
- reg Q1_n, Q2_n ,Q3_n, Q4;
- 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
- always@(posedge Q4 or negedge A) begin
- if(~A) Y <= 1'b0;
- else Y <= A1;
- end
-
- endmodule
然后看看原理图是不是和题目差不多,如下,是一样的功能。
寄存器传输级电路:
仿真文件:
- module sim_freq(
-
- );
- reg A;
- reg clk;
- wire Y;
-
- initial begin
- clk = 0;
- forever
- #2 clk = ~clk;
- end
-
- initial begin
- A = 0;
- #3
- A = 1;
- #14
- A = 0;
- #20
- A = 1;
- #38
- A = 0;
-
- end
-
- freq_div inst_freq(
- .clk(clk),
- .A(A),
- .Y(Y)
- );
-
-
- endmodule
仿真波形:
从这个仿真图中可以看出,A的高电平持续时间不够7个时钟时候,就被滤除了。反之,能够检测到。
由于没有标准答案,所以,只能这么胡说。
欢迎给出评论!
2.
这是一个FIFO最小深度计算的题目,关键要算出突发写入数据量。
3.
考察阻塞赋值和非阻塞赋值:
initial内部上半部分是阻塞赋值,所谓阻塞赋值就是要等上一条语句执行完了,在执行下面一条语句,所以打印出来的数据应该是
A = 4, B = 5;
下半部分为非阻塞赋值,所谓非阻塞赋值,和阻塞赋值恰恰相反,没有先后顺序,A的初始值为3,则打印出来的数据应该为:
A = 4, B = 4;
相关的还有今天的汇顶科技的一个题目:
在测试文件里,always是一个循环,就像我们写生成时钟一样,有种写法就是:
- initial clk = 0;
-
- always begin
- #2 clk = ~clk;
-
- end
https://blog.csdn.net/Reborn_Lee/article/details/82227255
那这里的always同样也是循环语句的作用,内部是阻塞赋值,@(A)以及@(B)相当于触发条件,#2其实也属于这一类,过了2ns执行下面的语句,这里就是A变化了就触发,题目中说A在15ns以及25ns各触发一次,当A在15ns触发一次后,count = 2,然后等待@(B),可是B一直为X态,没有触发,所以就一直阻塞到这里了,再多的时间也没用。所以只能最后count = 2.
4、
题目的意思大概是能够检测出D的错误吧,若要D的错误能反应出来(输出),A和B的与要为0,让输出取决于下面的与门,当然C要为1,这样输出就取决于D了,那么D有问题,直接可以反映到输出上。
5、
考察最简单的SDC语法,最Xilinx FPGA的一定了解XDC文件,XDC与SDC的关系是XDC包含SDC,
可知,约束的时钟的频率600MHz,占空比为50%,时钟名字叫GTXCLK;选择ABD吧,时钟源延迟看不出来,这里时钟源都没给,更别提看出来延迟是多少了。
6、
这一题见博客:IC/FPGA笔试/面试题分析(七)建立时间和保持时间类型考题汇总分析
7、
看描述,对于Proc_A,接收到FIFO_A的几乎满信号后,会停止信号输入,但是内部有8级流水线,需要全部流入到FIFO后才能停止写入FIFO_A,由于发出几乎满信号,一定是FIFO内部有数据了(最小为1个数据,就产生afull信号),所以afull之后的突发写数据个数为8,需要8个时钟.而8个时钟bproc已经读出4个数据了,所以fifo的最小深度应该为8-4+1 = 5;
为什么会加1呢?按理说一般计算的套路应该为8-4 = 4就够了。但是我们还要考虑我们考虑的仅仅是afull之后的fifo最小深度,afull之所以为1,是因为fifo_A内部有数据了,而数据最小为1产生了afull信号,所以需要加1构成最终的fifo最小深度。
最后给出讨论群里的其他大佬的答案(第一个给出答案的):
fifo深度应该是1+4为5,前面一个时钟写一个,两个时钟读一个,也就是两个时钟fifo里面会有一个数写进去,实际上a端已经写了两个数了,只不过被读出去了一个,为什么要再加一呢,afull是为了让fifo可以写进去数据,所以afull为1
小伙伴们的讨论让我受益匪浅,真的很感谢了。
8、
最后一个题目,是序列产生器,循环产生如下序列:0010_1101_11.
当然你可以用状态机写,但是更好的办法是:
循环左移,输出高位。
-
- module seq_gen(
- input clk,
- input rst_n,
- output reg q
- );
-
- reg q_r;
- always@(posedge clk or negedge rst_n) begin
- if(~rst_n) begin
- q <= 0;
- q_r <= 10'b0010_1101_11;
- end
- else begin
- q <= q_r[9];
- q_r <= { q_r[8:0], q_r[9] };
- end
- end
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。