在基于System verilog的序列检测器一文中,我们通过状态机进行了实现,今天,博主介绍另外一种序列检测的实现方式:移位寄存器。
我们仍然以10010这个序列为例,主要的设计思想如下:
1.设置一个5位的移位寄存器,以及一个计数器;
2.每个时钟周期,该移位寄存器进行一次左移,并将最新的bit输入最低位,计数器自增1;
3.每个周期,都将移位寄存器的值和10010进行比较,若相同,且计数器的值大于等于4(这么做主要为了避免10010010被检测出两次),则说明检测到该序列,此时计数器的值归零。
RTL实现
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/02/23 19:53:01
// Design Name:
// Module Name: top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module top(
input logic clk,
input logic rst,
input logic bit_in,
input logic valid, //标志当前bit有效
output logic detected
);
logic [4:0] shift_reg;
logic [31:0] count;
//shift_reg
always_ff@(posedge clk,posedge rst)
if(rst)
shift_reg[4:0]<=0;
else if(valid)
shift_reg[4:0]<={shift_reg[3:0],bit_in};
//count
always_ff@(posedge clk,posedge rst)
if(rst)
count<=0;
else if(valid)
begin
if(detected)
count<=0;
else
count<=count+1;
end
//
assign detected=(5'b10010==shift_reg&&count>=4)?1'b1:1'b0;
endmodule
测试平台
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/02/23 14:00:13
// Design Name:
// Module Name: test_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module test_tb;
logic clk;
logic rst;
logic bit_in;
logic valid;
logic detected;
logic [31:0] cnt;
initial begin
clk=0;
forever begin
#5 clk=~clk;
end
end
initial
begin
rst=1;
#20
rst=0;
end
//cnt
always_ff@(posedge clk,posedge rst)
if(rst)
cnt<=0;
else if(cnt==2)
cnt<=0;
else
cnt<=cnt+1;
//
always_ff@(posedge clk,posedge rst)
if(rst)
bit_in<=0;
else if(cnt==2)
bit_in<=1; //检测10010
else
bit_in<=0;
//valid
always_ff@(posedge clk,posedge rst)
if(rst)
valid<=0;
else
valid<=1;
//inst
top U(.*);
// input logic clk,
// input logic rst,
// input logic bit_in,
// input logic valid, //标志当前bit有效
// output logic detected
endmodule
仿真波形,可以看到,10010010只会被检测出一次: