FPGA 04 线性序列机——LED实验

文章详细描述了一系列关于LED灯的控制实验,包括单个灯的定时亮灭、用户自定义模式、多个灯的独立操作以及定时状态循环。涉及的代码设计、testbench和仿真波形展示了各种控制逻辑的实现过程。
摘要由CSDN通过智能技术生成

目录

1 实验1:单个灯,2条件亮灭

1.1设计代码

1.2 testbench

1.3 仿真波形

2 实验2:单个灯,4条件亮灭

2.1 设计代码

2.2 testbench

2.3 仿真波形

3 实验3:单个灯,用户指定

3.1 设计代码

3.2 testbench

3.3 仿真波形

4 实验4:单个灯,用户指定2

4.1 设计代码

4.2 testbench

4.3 仿真波形

5 实验5:多个灯,独立亮灭

5.1 设计代码

5.2 testbench

5.3 仿真波形

 6 实验6:每10ms,led状态循环一次

6.1 设计代码

6.2 testbench

6.3 仿真波形

 7 实验7:每隔10ms,led状态循环一次

7.1 设计代码

7.2 testbench

7.3 仿真波形


1 实验1:单个灯,2条件亮灭

        Q:亮0.25s,灭0.75s循环

1.1设计代码

dge clk or negedge reset_n)
    if(!reset_n)
        counter <= 0;
    else if(counter == MCNT-1)
        counter <= 0;
    else
        counter <= counter+1'b1;
    
    reg [2:0]cnt;
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        cnt <= 0;
    else if(counter == MCNT-1)
        cnt <= cnt+1'd1;
    else if(cnt == 4)
        cnt <= 0;
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        led <= 0;
    else case(cnt)
        0:led = 0;
        1:led = 1;
        2:led = 0;
        3:led = 0;
        4:led = 0;
        default:led = 0;
    endcase 
    
endmodule

1.2 testbench

        将MCNT设置为12500,为了将循环时间从1s缩短至1ms。

`timescale 1ns / 1ps

module LSM_LED_1_tb;
    reg clk;
    reg reset_n;
    wire led;
    
    LSM_LED_1 LSM_LED_1(
        .clk(clk),
        .reset_n(reset_n),
        .led(led)
        );
    defparam LSM_LED_1.MCNT = 12500;
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    initial begin
        reset_n = 0;
        #201;
        reset_n = 1;
        #5000000;
        $stop;
    end
endmodule

1.3 仿真波形

        灯亮0.25ms,灭0.75ms,整个循环为1ms。

 

2 实验2:单个灯,4条件亮灭

        Q:亮0.25s,灭0.5s,亮0.75s,灭1s循环

2.1 设计代码

module LSM_LED_2(
    clk,
    reset_n,
    led
    );
    
    input clk;
    input reset_n;
    output reg led;
    
    reg [25:0]counter;
    parameter MCNT = 12500000;
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter <= 0;
    else if(counter == MCNT-1)
        counter <= 0;
    else
        counter <= counter+1'b1;
    
    reg [3:0]cnt;
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        cnt <= 0;
    else if(counter == MCNT-1)
        cnt <= cnt+1'd1;
    else if(cnt == 10)
        cnt <= 0;
        
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        led <= 0;
    else case(cnt)
        0:led = 0;
        1:led = 1;
        2:led = 0;
        3:led = 0;
        4:led = 1;
        5:led = 1;
        6:led = 1;
        7:led = 0;
        8:led = 0;
        9:led = 0;
        10:led = 0;
        default:led = 0;
    endcase
endmodule

2.2 testbench

        同1.2testbench。

2.3 仿真波形

3 实验3:单个灯,用户指定

        Q:用户指定亮暗模式,0.25s一个状态,8个状态1个循环

3.1 设计代码

`timescale 1ns / 1ps
//用户指定状态,0.25s一个状态,8个状态为1个循环
module LSM_LED_3(
    clk,
    reset_n,
    ctrl,
    led
    );
    
    input clk;
    input reset_n;
    input [7:0]ctrl;
    output reg led;
    
    reg [25:0]counter;
    parameter MCNT = 12500000;
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter <= 0;
    else if(counter == MCNT-1)
        counter <= 0;
    else
        counter <= counter + 1'b1;
        
    reg [2:0]cnt;
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        cnt <= 0;
    else if(counter == MCNT-1)
        cnt <= cnt+1'b1;
         
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        led <= 0;
    else begin
        case(cnt)
            0:led <= ctrl[0];
            1:led <= ctrl[1];
            2:led <= ctrl[2];
            3:led <= ctrl[3];
            4:led <= ctrl[4];
            5:led <= ctrl[5];
            6:led <= ctrl[6];
            7:led <= ctrl[7];
            default:led <= led;
        endcase
    end
endmodule

3.2 testbench

`timescale 1ns / 1ns

module LSM_LED_3_tb;
    reg clk;
    reg reset_n;
    reg [7:0]ctrl;
    wire led;
    
    LSM_LED_3 LSM_LED_3(
        .clk(clk),
        .reset_n(reset_n),
        .ctrl(ctrl),
        .led(led)
        );
    defparam LSM_LED_3.MCNT = 12500;
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    initial begin
        reset_n = 0;
        ctrl = 0;
        #201;
        reset_n = 1;
        #2000;
        ctrl = 8'b10010110;
        #50000000;
        $stop;
    end
endmodule

3.3 仿真波形

4 实验4:单个灯,用户指定2

        Q:按用户指定模式亮灭,8个状态一个周期,每个状态时间不确定。

4.1 设计代码

module LSM_LED_4(
	clk,
	reset_n,
	CTRL,
	Time,
	led
);
	
	input clk;
	input reset_n;
	input [7:0]CTRL;
	input [31:0]Time;
	output reg led;

	reg [31:0]counter;
	always@(posedge clk or negedge reset_n)
	if(!reset_n)
		counter <= 0;
	else if(counter == Time)
		counter <= 0;
	else
		counter <= counter + 1'b1;

	reg [2:0]cnt;
	always@(posedge clk or negedge reset_n)
	if(!reset_n)
		cnt <= 0;
	else if(counter == Time)
		cnt <= cnt+1'b1;
	//else if(cnt == 7)
		//cnt <= 0;

	always@(posedge clk or negedge reset_n)
	if(!reset_n)
		led <= 0;
	else begin
		case(cnt)
			0:led <= CTRL[0];
			1:led <= CTRL[1];
			2:led <= CTRL[2];
			3:led <= CTRL[3];
			4:led <= CTRL[4];
			5:led <= CTRL[5];
			6:led <= CTRL[6];
			7:led <= CTRL[7];
			default: led <= led;
		endcase
	end
endmodule

4.2 testbench

`timescale 1ns/1ns

module LSM_LED_4_tb;
	reg clk;
	reg reset_n;
	reg [7:0]CTRL;
	reg [31:0]Time;
	wire led;

	LSM_LED_4 LSM_LED_4(
		.clk(clk),
		.reset_n(reset_n),
		.CTRL(CTRL),
		.Time(Time),
		.led(led)
	);
	
	initial clk = 1;
	always #10 clk = ~clk;

	initial begin
		reset_n = 0;
		CTRL = 0;
		Time = 0;
		#201;
		reset_n = 1;
		Time = 2499;
		CTRL = 8'b10001100;
		#5000000;
		$stop;
	end
endmodule

4.3 仿真波形

5 实验5:多个灯,独立亮灭

        Q:让多个LED 灯按照设置的模式各自在一个变化循环内独立亮灭变化

5.1 设计代码

module LSM_LED_5(
	clk,
	reset_n,
	CtrlA,
	CtrlB,
	CtrlC,
	Time,
	led);

	input clk;
	input reset_n;
	input [3:0] CtrlA,CtrlB,CtrlC;
	input [31:0]Time;
	output reg [2:0]led;

	reg [31:0] counter;
	always@(posedge clk or negedge reset_n)
	if(!reset_n)
		counter <= 0;
	else if(counter == Time-1)
		counter <= 0;
	else
		counter <= counter + 1'b1;

	reg [1:0]cnt;
	always@(posedge clk or negedge reset_n)
	if(!reset_n)
		cnt <= 0;
	else if(counter == 1)
		cnt <= cnt+1'b1;
	
	always@(posedge clk or negedge reset_n)
	if(!reset_n)
		led <= 0;
	else begin
		case(cnt)
			0:begin 
			    led[0] <= CtrlA[0];
			    led[1] <= CtrlB[0];
			    led[2] <= CtrlC[0];
			end
			1:begin 
			    led[0] <= CtrlA[1];
			    led[1] <= CtrlB[1];
			    led[2] <= CtrlC[1];
			end
			2:begin 
			    led[0] <= CtrlA[2];
			    led[1] <= CtrlB[2];
			    led[2] <= CtrlC[2];
			end
			3:begin 
			    led[0] <= CtrlA[3];
			    led[1] <= CtrlB[3];
			    led[2] <= CtrlC[3];
			end
			default:led<=led;
	   endcase
	end
endmodule

5.2 testbench

`timescale 1ns/1ns
module LSM_LED_5_tb;
    reg clk;
	reg reset_n;
	reg [3:0] CtrlA,CtrlB,CtrlC;
	reg [31:0]Time;
	wire [2:0]led;
    
    LSM_LED_5 LSM_LED_5(
       .clk(clk),
	   .reset_n(reset_n),
	   .CtrlA(CtrlA),
	   .CtrlB(CtrlB),
	   .CtrlC(CtrlC),
	   .Time(Time),
	   .led(led)
        );
        
        initial clk = 1;
        always #10 clk = ~clk;
        
        initial begin
            reset_n = 0;
            CtrlA = 0;
            CtrlB = 0;
            CtrlC = 0;
            Time = 0;
            #201;
            reset_n= 1;
            #200;
            CtrlA = 4'b1010;
            CtrlB = 4'b0110;
            CtrlC = 4'b0101;
            Time = 2499;
            #200000000;
            $stop;
        end
endmodule

5.3 仿真波形

 6 实验6:每10ms,led状态循环一次

        Q:每隔10ms,8个led灯状态循环一次(总周期10ms)

6.1 设计代码

//每隔10ms,8个led灯状态循环一次

module LSM_LED_6(
    clk,
    reset_n,
    Time,
    Ctrl,
    led
    );
    
    input clk;
    input reset_n;
    input [31:0]Time;
    input [7:0]Ctrl;
    output reg led;
    
    reg [18:0]counter1;//10ms计数器
    reg [31:0]counter2;//每个led状态计数器
    reg [2:0]counter3;//8个状态计数器
    reg EN;//是否传输led信号
     
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter1 <= 0;
    else if(counter1 == 499999)
        counter1 <= 0;
    else
        counter1 <= counter1 + 1'b1;       
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter2 <= 0;
    else if(EN)begin
        if(counter2 == Time)
            counter2 <= 0;
        else 
            counter2 <= counter2 + 1'b1;
    end
    else
        counter2 <= 0;    

    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter3 <= 0;
    else if(EN)begin
        if(counter2 == Time)
            counter3 <= counter3 + 1'b1;
    end
    else
        counter3 <= 0;    
            
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        EN <= 0;
    else if((counter3 == 7)&&(counter2 == Time))
        EN <= 0; 
    else if(counter1 == 1)
        EN <= 1;
        
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        led <= 0;
    else begin
        case(counter3)
            0:led <= Ctrl[0];
			1:led <= Ctrl[1];
			2:led <= Ctrl[2];
			3:led <= Ctrl[3];
			4:led <= Ctrl[4];
			5:led <= Ctrl[5];
			6:led <= Ctrl[6];
			7:led <= Ctrl[7];
			default: led <= led;
        endcase
    end   
endmodule

6.2 testbench

`timescale 1ns / 1ns
module LSM_LED_6_tb;
    reg clk;
    reg reset_n;
    reg [31:0]Time;
    reg [7:0]Ctrl;
    wire led;
    
    LSM_LED_6 LSM_LED_6(
        .clk(clk),
        .reset_n(reset_n),
        .Time(Time),
        .Ctrl(Ctrl),
        .led(led)
        );
        
    initial clk =1;
    always #10 clk = ~clk;
    
    initial begin
        reset_n = 0;
        Time = 0;
        Ctrl = 0; 
        #201;
        reset_n = 1;
        Time = 24999;
        Ctrl = 8'b10011010;
        $stop;
    end
endmodule

6.3 仿真波形

 7 实验7:每隔10ms,led状态循环一次

        Q:每隔10ms,8个led灯状态循环一次(总周期=10ms+8个状态时间)

7.1 设计代码

        代码存在问题:一开始不能实现led状态传输,必须等10ms后开始

//每隔10ms,8个led灯状态循环一次

module LSM_LED_7(
    clk,
    reset_n,
    Time,
    Ctrl,
    led
    );
    
    input clk;
    input reset_n;
    input [31:0]Time;
    input [7:0]Ctrl;
    output reg led;
    
    reg [18:0]counter1;//10ms计数器
    reg [31:0]counter2;//每个led状态计数器
    reg [2:0]counter3;//8个状态计数器
    reg EN;//是否传输led信号
     
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter1 <= 0;
    else if(counter1 == 499999)
        counter1 <= 0;
    else
        counter1 <= counter1 + 1'b1;       
    
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter2 <= 0;   
    else if(EN)begin
        if(counter2 == Time)
            counter2 <= 0;
        else 
            counter2 <= counter2 + 1'b1;
    end
    else
        counter2 <= 0;    

    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        counter3 <= 0;       
    else if(EN)begin
        if(counter2 == Time)
            counter3 <= counter3 + 1'b1;
    end
    else
        counter3 <= 0;    
            
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        EN <= 0;
    else if((counter3 == 7)&&(counter2 == Time))
        EN <= 0; 
    else if(counter1 == 499999)
        EN <= 1;
        
    always@(posedge clk or negedge reset_n)
    if(!reset_n)
        led <= 0;
    else begin
        case(counter3)
            0:led <= Ctrl[0];
			1:led <= Ctrl[1];
			2:led <= Ctrl[2];
			3:led <= Ctrl[3];
			4:led <= Ctrl[4];
			5:led <= Ctrl[5];
			6:led <= Ctrl[6];
			7:led <= Ctrl[7];
			default: led <= led;
        endcase
    end   
endmodule

7.2 testbench

        同6.2

7.3 仿真波形

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值