FSM Design T6
实现6路彩灯的控制程序,要求可以依次演示以下2种花型:
1)6路彩灯从左到右逐个变亮(每次只有1路亮)
2)6路彩灯亮灭相间,交替亮灭3次(相邻的两个为不同的亮灭状态)
复位信号有效后开始演示第一种花型,第一种花型演示完毕后才转向演示第二种,两个花型依次演示,演示完两路花型后6路彩灯均熄灭。6路彩灯分别为L1-L6,Li=1表示该路彩灯亮,Li=0表示该路彩灯灭,i=1-6。注:输入信号至少包含reset和clock,输出L1-L6分别为6路彩灯名,请同学们按照此命名编写Verilog代码。
1. Analysis
根据题意可知需要实现2种花型的六路循环灯,假设六路循环灯的每一个灯的亮为1、灭为0,则可以使用一个6位的寄存器变量来代替某个瞬间的亮灭状态。某种类型的花型可以通过多次改变该寄存器类型变量来实现,以达到一次性同时控制所有小灯亮灭的效果。本文考虑到小灯阵列的输出仅与当前状态有关,因此可以使用Moore型的FSM来实现以上设计。
2. FSM Diagram
3. Port List
Port Name | Attribute | Width | Meaning |
---|---|---|---|
clock | input | 1 bit | 时钟信号 |
reset | input | 1 bit | 复位信号 |
L1, L2, L3, L4, L5, L6 | output | 1 bit | 小灯亮灭状态 |
4. Verilog Code
`timescale 1ns/1ps
module exercise6 (CLK, RST, LED);
input wire CLK;
input wire RST;
output reg [5:0] LED;
reg [3:0] cs;
reg [3:0] ns;
parameter s0 = 4'b0000;
parameter s1 = 4'b0001;
parameter s2 = 4'b0010;
parameter s3 = 4'b0011;
parameter s4 = 4'b0100;
parameter s5 = 4'b0101;
parameter s6 = 4'b0110;
parameter s7 = 4'b0111;
parameter s8 = 4'b1000;
parameter s9 = 4'b1001;
parameter s10 = 4'b1010;
parameter s11 = 4'b1011;
parameter s12 = 4'b1100;
always @ (posedge CLK or negedge RST) begin
if (!RST) begin
cs <= s0;
end
else begin
cs <= ns;
end
end
always @ (*) begin
case (cs)
s0: ns = s1;
s1: ns = s2;
s2: ns = s3;
s3: ns = s4;
s4: ns = s5;
s5: ns = s6;
s6: ns = s7;
s7: ns = s8;
s8: ns = s9;
s9: ns = s10;
s10: ns = s11;
s11: ns = s12;
s12: ns = s0;
default: ns = s0;
endcase
end
always @ (*) begin
case (cs)
s0: LED = 6'b000000;
s1: LED = 6'b100000;
s2: LED = 6'b010000;
s3: LED = 6'b001000;
s4: LED = 6'b000100;
s5: LED = 6'b000010;
s6: LED = 6'b000001;
s7: LED = 6'b010101;
s8: LED = 6'b101010;
s9: LED = 6'b010101;
s10: LED = 6'b101010;
s11: LED = 6'b010101;
s12: LED = 6'b101010;
endcase
end
endmodule
5. Testbench Code
`timescale 1ns/1ps
module exercise6_test;
reg CLK;
reg RST;
wire [5:0] LED;
parameter half_cycle = 5;
parameter s0 = 4'b0000;
parameter s1 = 4'b0001;
parameter s2 = 4'b0010;
parameter s3 = 4'b0011;
parameter s4 = 4'b0100;
parameter s5 = 4'b0101;
parameter s6 = 4'b0110;
parameter s7 = 4'b0111;
parameter s8 = 4'b1000;
parameter s9 = 4'b1001;
parameter s10 = 4'b1010;
parameter s11 = 4'b1011;
parameter s12 = 4'b1100;
exercise6 exercise6_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
# (50 * half_cycle) $finish;
end
initial begin
$fsdbDumpfile("./verdiFsdb/exercise6.fsdb");
$fsdbDumpvars(0);
end
endmodule