【数字IC手撕代码】Verilog序列检测器|题目|原理|设计|仿真

Verilog序列检测器

    • 前言
    • 序列检测器题目
    • 序列检测器原理
    • RTL设计
    • testbench设计
    • 仿真图像

前言

本系列旨在提供100%准确的数字IC设计/验证手撕代码环节的题目,原理,RTL设计,Testbench和参考仿真波形,每篇文章的内容都经过仿真核对。快速导航链接如下:

奇数分频
偶数分频
半整数分批
小数/分数分频
序列检测器
模三检测器
饮料机
异步复位,同步释放
边沿检测(上升沿,下降沿,双边沿)
全加器,半加器
格雷码转二进制
单bit跨时钟域(打两拍,边沿同步,脉冲同步)
同步FIFO

应当说,手撕代码环节是面试流程中既重要又简单的一个环节,跟软件类的岗位相比起来,数字IC的手撕代码题目固定,数量有限,属于整个面试中必得分的一个环节,在这个系列以外,笔者同样推荐数字IC求职者使用“HdlBits”进行代码的训练
链接如下
HDLBits — Verilog Practice

序列检测器题目

1.使用verilog代码,设计电路,检测序列为1001,检测到的时候输出1,没检测到的时候输出0

这里的序列可以替换成任意一个,采用相同的思路进行设计即可

序列检测器原理

【数字IC手撕代码】Verilog序列检测器|题目|原理|设计|仿真_第1张图片

不管是什么样的序列检测器,我们都可以采用状态机的方法进行设计,以例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

仿真图像

【数字IC手撕代码】Verilog序列检测器|题目|原理|设计|仿真_第2张图片

结果分析,当时钟上升沿到来时采到的信号为1001时,output输出为1,其余结果输出为0,设计符合预期

你可能感兴趣的:(数字IC手撕代码,fpga开发,verilog,fpga,芯片,硬件架构)