FSM Design T4
一个测试过程的实现包括:启动准备状态s1、启动测试s2、停止测试s3、查询测试结果s4、显示测试结果s5和测试结束后返回初始化s0,共6个步骤,需要在100s内完成。其中启动准备20s,启动后经过30s测试完成,停止测试需要20s,查询结果需要10s,然后显示10s测试结果。需要实现的功能为通过编写Verilog代码,使用有限状态机显示当前所处的状态,通过三个指示灯亮灭的情况来表示当前的状态,指示灯亮灭的规则([LED2 LED1 LED0]相当于3位二进制码,其亮灭顺序遵循二进制规律)如下表。注:输入信号至少包含reset和clock,S0-S5为状态机的状态名,LED0-LED2为三个指示灯的名称,请同学们按照此命名编写Verilog代码。
1. Analysis
根据题目要求可知需要实现一个测试过程,该功能可以划分为5个不同的过程,分别对应状态机中的S0、S1、S2、S3、S4、S5等状态,LED0、LED1、LED2是状态机的输出变量。由于FSM的输出仅与当前状态有关,因此可以采用Moore型状态机实现。对于题目中要求的延时(10s、20s、30s),可以设置合适的时钟周期、利用计数变量来实现。
2. FSM Diagram
3. Port List
Port Name | Attribute | Width | Meaning |
---|---|---|---|
clock | input | 1 bit | 时钟信号 |
reset | input | 1 bit | 复位信号 |
LED0, LED1, LED2 | output | 1 bit | 输出信号 |
4. Verilog Code
`timescale 1s/1s
module exercise4 (CLK, RST, LED);
input wire CLK;
input wire RST;
output reg [2:0] LED;
reg [5:0] cs;
reg [5:0] ns;
reg [5:0] cnt;
parameter s0 = 6'b000001;
parameter s1 = 6'b000010;
parameter s2 = 6'b000100;
parameter s3 = 6'b001000;
parameter s4 = 6'b010000;
parameter s5 = 6'b100000;
always @ (posedge CLK or negedge RST) begin
if (!RST) begin
cs <= 6'bX;
end
else begin
cs <= ns;
end
end
always @ (posedge CLK or negedge RST) begin
if (!RST) begin
cnt <= 6'd0;
end
else if (cnt < 6'd50) begin
cnt <= cnt + 6'd1;
end
else begin
cnt <= 6'd1;
end
end
always @ (*) begin
if (!RST) begin
ns = s0;
end
else begin
case (cs)
s0: begin
if (cnt == 6'd5) ns = s1;
else ns = ns;
end
s1: begin
if (cnt == 6'd15) ns = s2;
else ns = ns;
end
s2: begin
if (cnt == 6'd30) ns = s3;
else ns = ns;
end
s3: begin
if (cnt == 6'd40) ns = s4;
else ns = ns;
end
s4: begin
if (cnt == 6'd45) ns = s5;
else ns = ns;
end
s5: begin
if (cnt == 6'd50) ns = s0;
else ns = ns;
end
default: ns = s0;
endcase
end
end
always @ (*) begin
if (!RST) begin
LED = 3'bXXX;
end
else begin
case (cs)
s0: begin
LED = 3'b001;
end
s1: begin
LED = 3'b010;
end
s2: begin
LED = 3'b011;
end
s3: begin
LED = 3'b100;
end
s4: begin
LED = 3'b101;
end
s5: begin
LED = 3'b000;
end
default: LED = 3'bXXX;
endcase
end
end
endmodule
5. Testbench Code
`timescale 1s/1s
module exercise4_test;
reg CLK;
reg RST;
wire [2:0] LED;
parameter half_cycle = 1;
parameter s0 = 6'b000001;
parameter s1 = 6'b000010;
parameter s2 = 6'b000100;
parameter s3 = 6'b001000;
parameter s4 = 6'b010000;
parameter s5 = 6'b100000;
exercise4 exercise4_inst (
.CLK(CLK),
.RST(RST),
.LED(LED)
);
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
# (210 * half_cycle) $finish;
end
initial begin
$fsdbDumpfile("./verdiFsdb/exercise4.fsdb");
$fsdbDumpvars(0);
end
endmodule