检测接收到的数字序列中出现“10011”的次数。
例如输入序列为40位:
1100_1001_1100_1001_0100_1100_1011_0010_1100_1011
从最高位开始检测,出现了2次:
1100_1001_1100_1001_0100_1100_1011_0010_1100_1011
所以,序列检测器的计数结果应该是2。
状态机如下:
当前状态current_state | 下一个状态next_state | |
下一个数字输入0 | 下一个数字输入1 | |
idel | idel | s1 |
s1 | s10 | s1 |
s10 | s100 | s1 |
s100 | idel | s1001 |
s1001 | s10 | s10011 |
s10011 | idel | s1 |
其他变量:
1 | clk | 时钟,上升沿有效,初始0,周期4ns,每2ns反相一次 |
2 | rst_p | 复位,高电平有效,上升沿有效, |
3 | din | 1位,数字序列输入,与data[39]相等(相连) |
4 | [2:0] current_state | 3位,用于表示当前状态和下一个状态。 iedl用000表示 s1用001表示 s10用010表示 s100用011表示 s1001用100表示 s10011用101表示 |
5 | [2:0] next_state | |
6 | y | 检测到10011时置为高电平,作为标识 |
7 | [3:0] y_cnt | 4位,统计10011出现的个数 |
8 | [39:0] data | 40位,每个时钟周期移位一次,将最高位的数字移到最低位。 data={data[38:0],data[39]} |
主程序:
module sequence_detector(input wire clk, rst_p, din,
output wire y, output reg [3:0]y_cnt);
reg [2:0] current_state, next_state;
localparam idel = 3'b000;
localparam s1 = 3'b001;
localparam s10 = 3'b010;
localparam s100 = 3'b011;
localparam s1001 = 3'b100;
localparam s10011 = 3'b101;
always @(*) begin
if(rst_p) begin
next_state <= idel;
end
else begin
case (current_state)
idel: next_state <= din?s1:idel;
s1: next_state <= din?s1:s10;
s10: next_state <= din?s1:s100;
s100: next_state <= din?s1001:idel;
s1001: next_state <= din?s10011:s10;
s10011: next_state <= din?s1:idel;
default: next_state <= idel;
endcase
end
end
always @(posedge clk or posedge rst_p) begin
if(rst_p) begin
current_state <= idel;
end
else begin
current_state <= next_state;
end
end
assign y = (current_state == s10011);
always @(posedge clk or posedge rst_p) begin
if(rst_p) begin
y_cnt <= 0;
end
else begin
if(y) begin
y_cnt <= y_cnt + 1;
end
end
end
endmodule
测试程序:
`timescale 1ns/1ns
module sequence_detector_tb();
reg clk, rst_p;
wire din, y;
wire [3:0] y_cnt;
reg [39:0] data;
initial begin
clk <= 0;
rst_p <= 1;
#10;
rst_p <= 0;
data <= 40'b1100_1001_1100_1001_0100_1100_1011_0010_1100_1011;
#160 $stop;
end
always #2 clk <= ~clk;
always @(posedge clk)
data <= {data[38:0], data[39]};
assign din = data[39];
sequence_detector u1(clk, rst_p, din, y, y_cnt);
endmodule
检测到40位数字序列中出现了2次“10011”,仿真结果:
标签:idel,s1,Modelsim,localparam,state,Verilog,1100,HDL,data From: https://blog.csdn.net/m0_69064909/article/details/140849796