verilog 序列检测器 状态机 寄存器写法

状态机写法

在这里插入图片描述
能够检测重叠部分
在这里插入图片描述

// 2022-1-30 verilog学习
// 检测序列1011 状态机写法

module seq_detect(
			clk,
			res,
			en,
			din,
			match
			);

input		en,din,res,clk;
output		match;

reg[2:0]	state;
reg			match;
always@(posedge clk or negedge res)
if(~res) begin
	match<=0; state<=0;
end
else begin
	case(state)
	0: // 等待使能信号
	begin
		if(en)begin
			state<=1;
		end
		else begin
			state<=0;
		end
	end

	1: //s_idle 等待首字节1011的“1”011
	begin
		match<=0;
		if(din==1)begin
			state<=2;
		end
		else begin
			state<=1;
		end
	end

	2: //s_1
	begin
		match<=0;
		if(din==0)begin
			state<=3;
		end
		else begin
			state<=2;
		end
	end

	3: //s_10
	begin
		match<=0;
		if(din==1)begin
			state<=4;
		end
		else begin
			state<=1;
		end
	end

	4: //s_101
	begin
		if(din==1)begin
			state<=2;
			match<=1;  // 匹配1011
		end
		else begin
			state<=3;
		end
	end

	default: // 万一case>4
	begin
		state <= 0; 
		match<=0;
	end
	endcase
end

endmodule

//------testbench----
module seq_detect_tb;

reg 		clk,res,en;
reg[3:0]	din_send;  // 预存所有数据
wire		din;  // 已经预设好,不需要变化
wire		match;

seq_detect seq_detect(
			.clk(clk),
			.res(res),
			.en(en),
			.din(din),
			.match(match)
			);

initial begin
				clk<=0; res<=0; en<=1; din_send<=4'b1011;
		#17 	res<=1;
		#200	$stop;
end

always #5 clk = ~clk;

always@(posedge clk)begin  
	din_send[3:0] <= {din_send[2:0], din_send[3]}; // 每次时钟上升沿,循环左移
end

assign din = din_send[3];  // 将最高位输入到序列检测器中

endmodule


寄存器写法:

在这里插入图片描述

// 2022-1-30 verilog学习
// 检测序列1011 非状态机写法 寄存器写法

module seq_detect_sf(
			clk,
			res,
			en,
			din,
			match
			);

input		en,din,res,clk;
output		match;

reg[2:0]	sf_reg;  // 移动寄存器 shift_reg
reg			match;
always@(posedge clk or negedge res)
if(~res) begin
	match<=0; sf_reg<=0; 
end
else if(en) begin
	sf_reg <= {sf_reg[1:0], din};  // 左移寄存器  // 更新待比较序列
	if(sf_reg == 3'b101 && din==1) begin  
		match<=1;
	end
	else begin
		match<=0;
	end
end

endmodule 

//------testbench----
module seq_detect_sf_tb;

reg 		clk,res,en;
reg[3:0]	din_send;  
wire		din;  
wire		match;

seq_detect_sf seq_detect_sf(
			.clk(clk),
			.res(res),
			.en(en),
			.din(din),
			.match(match)
			);

initial begin
				clk<=0; res<=0; en<=1; din_send<=4'b1011;
		#17 	res<=1;
		#200	$stop;
end

always #5 clk = ~clk;

always@(posedge clk)begin  
	din_send[3:0] <= {din_send[2:0], din_send[3]}; // 每次时钟上升沿,循环左移
end

assign din = din_send[3];  // 将最高位输入到序列检测器中

endmodule


在这里插入图片描述


区别

移位寄存器需要存储所有的码字,因此如果序列长度为N,则该方法需要消耗的寄存器就是N个。此外,寄存器版本每来一个码元都要比较所有码字,因此需要消耗N个比较器。
状态机实现时,每个状态代表部分码字,如果使用十进制编码,则只需要使用log2(N)个寄存器即可编码所有状态,从寄存器资源的角度来看FSM实现起来代价较小。FSM的的状态寄存器state每一位在状态转移时都需要不同的译码逻辑,如果状态转移比较简单,组合逻辑可能会比移位寄存器少,状态转移复杂的化就不好说了。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值