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

FSM Design T5

实现两层的简易电梯指示灯系统。电梯有4个按键:1楼外的向上按键(A0),2楼外的向下按键(A1),电梯内的1楼和2楼按键(F1和F2)。电梯有4个指示灯:
L0:按下A0键,若电梯不在1楼,则L0亮。
L1:按下A1键,若电梯不在2楼,则L1亮。
L2:电梯在2楼,按F1键, 则L2亮,电梯到1楼后L2灭。
L3:电梯在1楼,按F2键, 则L3亮,电梯到2楼后L3灭。
注:输入信号至少包含reset和clock,A0、A1、F1、F2为电梯的4个按键,L0~L3分别为电梯的四个指示灯,请同学们按照此命名编写Verilog代码。

1. Analysis

根据题目中描述的电梯按键及电梯信号灯,可以将四个电梯按键A0、A1、F1、F2作为逻辑输入变量,将四个电梯信号灯L0、L1、L2、L3作为逻辑输出变量。假设按下电梯键为1、不按电梯键为0,电梯信号灯亮为1、电梯信号灯不亮为0,现设置表征电梯所在楼层数的状态变量S1(电梯现位于一楼)、S2(电梯现位于二楼),利用Mealy类型的FSM(状态机输出和当前状态、输入信号均有关)可以实现题中需求。

考虑到A0、A1、F1、F2等按键的时间可长可短,即:按键可以按下一段较长的时间,也可以按下一段较短的时间,但是无论时间的长短,以上任意的按键一旦按下,则电梯、信号灯必须作出相应的反应,只有这样才符合实际生活的常识。因此,本文设计了keep变量,用于检测A0、A1、F1、F2的电平变化,并将FSM的下一状态保存在keep寄存器中。本文设计了四个不同的testbench测试文件,其区别在于A0、A1、F1、F2等按键的时间长短不同,以测试、验证Verilog代码的健壮性。

2. FSM Diagram

T5

3. Port List

Port NameAttributeWidthMeaning
clockinput1 bit时钟信号
resetinput1 bit复位信号
A0, A1, F1, F2input1 bit电梯按键输入信号
L0, L1, L2, F3output1 bit电梯信号灯输出信号

4. Verilog Code

`timescale 1ns/1ps

module exercise5 (CLK, RST, A0, A1, F1, F2, L0, L1, L2, L3);

input wire CLK;
input wire RST;

input wire A0, A1, F1, F2;
output reg L0, L1, L2, L3;

reg cs;
reg ns;

reg keep;

parameter s0 = 1'b0;
parameter s1 = 1'b1;

always @ (posedge CLK or negedge RST) begin
	if (!RST) begin
		cs <= s0;
	end
	else begin
		cs <= ns;
	end
end

always @ (*) begin
	if (!RST) begin
		keep = s0;
	end
	else begin
		case (cs)
			s0: begin
				if ((F2 == 1'b1) || (A1 == 1'b1)) begin
					keep = s1;
					ns = keep;
				end
				else begin
					ns = keep;
				end
			end
			s1: begin
				if ((F1 == 1'b1) || (A0 == 1'b1)) begin
					keep = s0;
					ns = keep;
				end
				else begin
					ns = keep;
				end
			end
			default: begin
				keep = s0;
				ns = s0;
			end
		endcase
	end
end

always @ (*) begin
	case (cs)
		s0: begin
			L0 = 1'b0;
			L2 = 1'b0;
			if (A1 == 1'b1) begin
				L1 = 1'b1;
			end
			else if (F2 == 1'b1) begin
				L3 = 1'b1;
			end
			else begin
				L1 = L1;
				L3 = L3;
			end
		end
		s1: begin
			L1 = 1'b0;
			L3 = 1'b0;
			if (A0 == 1'b1) begin
				L0 = 1'b1;
			end
			else if (F1 == 1'b1) begin
				L2 = 1'b1;
			end
			else begin
				L0 = L0;
				L2 = L2;
			end
		end
		default: begin
			L0 = 1'b0;
			L1 = 1'b0;
			L2 = 1'b0;
			L3 = 1'b0;
		end
	endcase
end

endmodule

5. Testbench Code

`timescale 1ns/1ps

module exercise5_test;

reg CLK;
reg RST;
reg A0, A1, F1, F2;
wire L0, L1, L2, L3;

parameter half_cycle = 5;

parameter s0 = 1'b0;
parameter s1 = 1'b1;

exercise5 exercise5_inst (
	.CLK(CLK),
	.RST(RST),
	.A0(A0),
	.A1(A1),
	.F1(F1),
	.F2(F2),
	.L0(L0),
	.L1(L1),
	.L2(L2),
	.L3(L3)
);

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
	A0 = 0;
	A1 = 0;
	F1 = 0;
	F2 = 0;
	# (4 * half_cycle) A1 = 1;
	# (2 * half_cycle) A1 = 0;
	# (4 * half_cycle) F1 = 1;
	# (2 * half_cycle) F1 = 0;
	# (4 * half_cycle) F2 = 1;
	# (2 * half_cycle) F2 = 0;
	# (4 * half_cycle) A0 = 1;
	# (2 * half_cycle) A0 = 0;
end

//initial begin
//	A0 = 0;
//	A1 = 0;
//	F1 = 0;
//	F2 = 0;
//	# (4 * half_cycle) A1 = 1;
//	# (1 * half_cycle) A1 = 0;
//	# (3 * half_cycle) F1 = 1;
//	# (1 * half_cycle) F1 = 0;
//	# (3 * half_cycle) F2 = 1;
//	# (1 * half_cycle) F2 = 0;
//	# (3 * half_cycle) A0 = 1;
//	# (1 * half_cycle) A0 = 0;
//end

//initial begin
//	A0 = 0;
//	A1 = 0;
//	F1 = 0;
//	F2 = 0;
//	# (4 * half_cycle) A1 = 1;
//	# (0.6 * half_cycle) A1 = 0;
//	# (4 * half_cycle) F1 = 1;
//	# (0.6 * half_cycle) F1 = 0;
//	# (4 * half_cycle) F2 = 1;
//	# (0.6 * half_cycle) F2 = 0;
//	# (4 * half_cycle) A0 = 1;
//	# (0.6 * half_cycle) A0 = 0;
//end

//initial begin
//	A0 = 0;
//	A1 = 0;
//	F1 = 0;
//	F2 = 0;
//	# (4 * half_cycle) A1 = 1;
//	# (0.2 * half_cycle) A1 = 0;
//	# (4 * half_cycle) F1 = 1;
//	# (0.2 * half_cycle) F1 = 0;
//	# (4 * half_cycle) F2 = 1;
//	# (0.2 * half_cycle) F2 = 0;
//	# (4 * half_cycle) A0 = 1;
//	# (0.2 * half_cycle) A0 = 0;
//end

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

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

endmodule

6. Experiment(VCS+Verdi)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值