题目:让多个LED灯按照各自指定的亮灭模式亮灭,亮灭模式未知,由用户随机指定。8个变化状态为一个循环,每个变化状态的时间值由用户提前输入。
代码:
module LED_contrl( input Clk, //本实例选择频率为50MHZ的时钟,即每20ns为一个周期 input Reset_n, //复位信号 input [7:0]in0, //控制信号0 input [7:0]in1, //控制信号1 input [25:0]Time, //可指定的LED灯亮灭间隔,范围为0-1秒, //计算方式为MAX=1秒*1000,000,000 //(转换为ns)÷20ns=50,000,000, //再转换为二进制为26位 output reg [1:0]led //led输出信号 ); reg [25:0] counter; //计数器1 reg [2:0]counter2; //计数器2 always@(posedge Clk or negedge Reset_n) if (!Reset_n) counter<=0; else if (counter==Time-1) //Time-1而不是Time,是因为包括了跳回0这一段, //举例:要求计数4次,那么包含0-1,1-2,2-3, //3-0这4次变化,即为计数到“4-1” counter<=0; else counter<=counter+1'b1; //此段用于控制一个单独变化状态所用的时间值 always@(posedge Clk or negedge Reset_n) if (!Reset_n) counter2<=0; else if(counter==Time-1) counter2<=counter2+1'b1; //此段用于控制8个状态为一个周期, //因为counter2上限只有8位, //超过8位限制后数值会自动清零, //因此不许单独写复位程序 always@(posedge Clk or negedge Reset_n) if (!Reset_n) led<=2'b00; else case(counter2) 0:begin led[0]<=in0[0];led[1]<=in1[0];end 1:begin led[0]<=in0[1];led[1]<=in1[1];end 2:begin led[0]<=in0[2];led[1]<=in1[2];end 3:begin led[0]<=in0[3];led[1]<=in1[3];end 4:begin led[0]<=in0[4];led[1]<=in1[4];end 5:begin led[0]<=in0[5];led[1]<=in1[5];end 6:begin led[0]<=in0[6];led[1]<=in1[6];end 7:begin led[0]<=in0[7];led[1]<=in1[7];end default:led<=led; endcase //此处仅用了两个输入端口,如果需要 //可以使用更多 endmodule
对写完的代码进行仿真:
`timescale 1ns / 1ns
module LED_contrl_tb( );//测试模块不需接口
reg Clk,Reset_n;
reg [7:0]in0;
reg [7:0]in1;
reg [25:0]Time;
wire [1:0]led;
LED_contrl LED_contrl_inst0( //例化模块
.Clk(Clk),
.Reset_n(Reset_n),
.in0(in0),
.in1(in1),
.led(led),
.Time(Time)
);
initial Clk=1;
always #10 Clk=!Clk; //每10ns翻转一次模拟时钟变化
initial begin
Reset_n=0;
#201; //防止200ns与时钟边沿重合,方便观察
Time=1250;//为了减少仿真时间,将单个时间状态设为25微秒,
Reset_n=1;
#2000;
in0<= 8'b1000_0110;
in1<= 8'b0001_1101;
#200000;
$stop;
end
endmodule
代码仿真成果:
查看仿真结果,符合预期