注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
飞鸿浩劫的个人空间 https://home.eeworld.com.cn/space-uid-589053.html [收藏] [复制] [分享] [RSS]
日志

序列检测器

已有 1300 次阅读2015-9-3 12:21 |个人分类:verilog数字系统设计教程| 检测器

/*序列检测器,检测序列10010,rst低电平有效*/
module seqdet(x,z,clk,rst);
input x,clk,rst;
output z;

reg[2:0]state;//保存当前状态
wire z;//输出信号

parameter s0=3'd0,s1=3'd1,s2=3'd2,s3=3'd3,s4=3'd4,s5=3'd5,s6=3'd6,s7=3'd7;
assign z=(state==s4&&x==0)?1:0;//状态4时输入0则检测到序列,z输出1
always@(posedge clk or negedge rst)
if(!rst) state<=s0;//复位
else
case(state)//状态之间转换关系
s0:
if(x==1)state<=s1;
else state<=s0;
s1:
if(x==0)state<=s2;
else state<=s1;
s2:
if(x==0)state<=s3;
else state<=s6;
s3:
if(x==1)state<=s4;
else state<=s7;
s4:
if(x==0)state<=s5;
else state<=s1;
s5:
if(x==1)state<=s1;
else state<=s3;
s6:
if(x==1)state<=s1;
else state<=s2;
s7:
if(x==1)state<=s6;
else state<=s7;
default:state<=s0;
endcase
endmodule

//testbench
`timescale 1 ns/ 1 ns
`define halfpriod 20

module seqdet_vlg_tst();

reg clk,rst;
reg [23:0]data;
// wires                                               
wire z,x;

assign x=data[23];//输入序列
initial                                                
begin                                                  
clk=0;
rst=1;
#2 rst=0;
#30 rst=1;
data=20'b1100_1001_0000_1001_0100;
#(`halfpriod*1000)$stop;       
$display("Running testbench");                       
end           

always #(`halfpriod)clk=~clk;//产生时钟
always@(posedge clk)
#2 data={data[22:0],data[23]};//序列移位
//调用序列检测模块
seqdet i1(
.clk(clk),
.rst(rst),
.x(x),
.z(z));                                         
                                           
endmodule

序列检测是数字电路中的经典案例,用verilog实现时并没有什么值得注意的地方,主要是对逻辑状态转换的理解。
两个状态转换图都表示在状态S1收到高电平1时转换到状态S2并输出低电平0
上述代码中实现了对10010的序列检测,testbench模拟了1100_1001_0000_1001_0100的输入,波形图如下

全部作者的其他最新日志
评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章