Verilog HDL:FSM有限状态机设计(3)

FSM Design T3

设计一个电路,其可以接收串行比特流(假设信息流的注入模式是0111B,数据流的最低有效位(二进制数的最右边位)首先到达状态机),并产生串行输出。考虑如下情形:(1)当识别出输入序列为0111时,输出在一个时钟周期内为高电平;(2)在再次检测出0111之前,输出将维持低电平;(3)在第二次检测到0111出现时,输出将再次为一个时钟周期的高电平,如此继续。(4)当它检测到6个0111序列之后就停止检测,直到复位信号有效后重新检测。用Verilog完成设计。(输入信号至少包含reset和clock)注:输入信号名为IN,输出信号名为OUT,testbench编写时应包括(4)中检测到6个序列之后就停止检测的情况。

1. Analysis

根据题意可知需要实现一个数据检测器,当电路接收指定的数据流(0111)时产生高电平输出,否则电路一直保持低电平输出状态。因此,电路的输出不仅与当前状态有关也和输入信号有关,本文可以利用Mealy型的FSM来实现以上要求,通过预先设置四个状态S0、S1、S2、S3,每接收1位二进制信号就计算并实现状态跳转。对于题目中要求检测6次0111序列后停止检测,本文可以设置一个寄存器类型的计数变量cnt,每实现一次0111检测就自动加一,只有当该计数变量cnt小于6时才有高电平输出。

2. FSM Diagram

T2

3. Port List

Port NameAttributeWidthMeaning
clockinput1 bit时钟信号
resetinput1 bit复位信号
ininput1 bit状态机输入信号IN
outoutput1 bit状态机输出信号OUT

4. Verilog Code

`timescale 1ns/1ps

module exercise3 (CLK, RST, IN, OUT);

input wire CLK;
input wire RST;
input wire IN;
output reg OUT;

reg [3:0] cs;
reg [3:0] ns;
reg [5:0] cnt;

parameter s0 = 4'b0001;
parameter s1 = 4'b0010;
parameter s2 = 4'b0100;
parameter s3 = 4'b1000;

always @ (posedge CLK or negedge RST) begin
	if (!RST) begin
		cs <= s0;
		cnt <= 6'd0;
	end
	else if ((cs == s2) && (ns == s3)) begin
		cs <= ns;
		cnt <= cnt + 6'd1;
	end
	else begin
		cs <= ns;
	end
end

always @ (*) begin
	case (cs)
		s0: begin
			if (IN == 1'b1) begin
				ns = s1;
			end
			else begin
				ns = s0;
			end
		end
		s1: begin
			if (IN == 1'b1) begin
				ns = s2;
			end
			else begin
				ns = s0;
			end
		end
		s2: begin
			if (IN == 1'b1) begin
				ns = s3;
			end
			else begin
				ns = s0;
			end
		end
		s3: begin
			if (IN == 1'b1) begin
				ns = s3;
			end
			else begin
				ns = s0;
			end
		end
		default: ns = s0;
	endcase
end

always @ (posedge CLK or negedge RST) begin
	case (ns)
		s3: begin
			if ((cs == s2) && (cnt < 6'd6)) begin
				OUT <= 1'b1;
			end
			else begin
				OUT <= 1'b0;
			end
		end
		default: OUT <= 1'b0;
	endcase
end

endmodule

5. Testbench Code

`timescale 1ns/1ps

module exercise3_test;

reg CLK;
reg RST;
reg IN;
wire OUT;

parameter half_cycle = 5;

parameter s0 = 4'b0001;
parameter s1 = 4'b0010;
parameter s2 = 4'b0100;
parameter s3 = 4'b1000;

exercise3 exercise3_inst (
	.CLK(CLK),
	.RST(RST),
	.IN(IN),
	.OUT(OUT)
);

initial begin
	CLK = 0;
	forever begin
		CLK = # half_cycle ~ CLK;
	end
end

initial begin
	RST = 1;
	# (1 * half_cycle) RST = 0;
	# (2 * half_cycle) RST = 1;
end

initial begin
	IN = 0;
	# (6 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 0;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 1;
	# (2 * half_cycle) IN = 0;
end

initial begin
	# (100 * half_cycle) $finish;
end

initial begin
	$fsdbDumpfile("./verdiFsdb/exercise3.fsdb");
	$fsdbDumpvars(0);
end

endmodule

6. Experiment(VCS+Verdi)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值