芯片设计验证社区·芯片爱好者聚集地·硬件相关讨论社区·数字verifier星球 |
---|
四社区联合力荐!近500篇数字IC精品文章收录! |
【数字IC精品文章收录】学习路线·基础知识·总线·脚本语言·芯片求职·EDA工具·低功耗设计Verilog·STA·设计·验证·FPGA·架构·AMBA·书籍 |
一、前言
本系列旨在提供100%准确的数字IC设计/验证手撕代码环节的题目,原理,RTL设计,Testbench和参考仿真波形,每篇文章的内容都经过仿真核对。快速导航链接如下:
1.奇数分频
2.偶数分频
3.半整数分批
4.小数/分数分频
5.序列检测器
6.模三检测器
7.饮料机
8.异步复位,同步释放
9.边沿检测(上升沿,下降沿,双边沿)
10.全加器,半加器
11.格雷码转二进制
12.单bit跨时钟域(打两拍,边沿同步,脉冲同步)
13.奇偶校验
14.伪随机数生成器[线性反馈移位寄存器]
15.同步FIFO
16.无毛刺时钟切换电路
应当说,手撕代码环节是面试流程中既重要又简单的一个环节,跟软件类的岗位相比起来,数字IC的手撕代码题目固定,数量有限,属于整个面试中必得分的一个环节,在这个系列以外,笔者同样推荐数字IC求职者使用“HdlBits”进行代码的训练
链接如下
HDLBits — Verilog Practice
二、序列检测器题目
1.使用verilog代码,设计电路,检测序列为1001,检测到的时候输出1,没检测到的时候输出0
这里的序列可以替换成任意一个,采用相同的思路进行设计即可
三、序列检测器原理
不管是什么样的序列检测器,我们都可以采用状态机的方法进行设计,以例1为参考,检测1001,我们需要5个状态,当复位信号到来的时候,返回IDLE状态,正常输入序列1001至状态S4时,output=1,其余时候output都为0,需要注意针对s1,s2,s3,s4,非1001序列输入的状态跳变并非全部到IDLE,也有跳变到相邻状态的可能性
这里再提出一种方法,使用4bit移位寄存器,每个时钟信号到来时,右移一位输入序列并进行比较,当移位寄存器内的data为1001时,输出1,其余状态输出0.
四、RTL设计
module sequence_check(clk,rst_n,sequence,test);
input clk;
input rst_n;
input sequence;
output test;
parameter IDLE = 3'b000, s1 = 3'b001 ,s2 = 3'b010, s3 = 3'b011 , s4 = 3'b100;
reg [2:0] state,nstate;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
state <= IDLE;
else
state <= nstate;
end
always@(*)
begin
case(state)
IDLE: nstate = sequence?s1:IDLE;
s1: nstate = !sequence?s2:s1;
s2: nstate = !sequence?s3:s1;
s3: nstate = sequence ?s4:IDLE;
s4: nstate = sequence ?s1:IDLE;
default nstate = IDLE;
endcase
end
assign test = state == s4 ? 1 : 0 ;
endmodule
五、testbench设计
`timescale 1ns/1ps
module sequence_check_tb();
reg clk;
reg rst_n;
reg sequence;
wire test;
sequence_check u1(.clk(clk),.rst_n(rst_n),.sequence(sequence),.test(test));
always #5 clk = !clk;
always #9.999 sequence = $random;
initial
begin
clk = 0;
rst_n = 1;
#10 rst_n = 0;
#16 rst_n = 1;
#2000
$stop;
end
endmodule
六、仿真分析
结果分析,当时钟上升沿到来时采到的信号为1001时,output输出为1,其余结果输出为0,设计符合预期