4个按键控制4种四个花样流水灯程序verilog_和测试程序
时间: 2023-06-19 22:06:54 浏览: 1391
基于Verilog实现旋转按钮控制八个LED灯_verilog旋转编码器控制led灯
5星 · 资源好评率100%
下面是一个基于FPGA的Verilog代码,可以控制四个按键,分别控制四种不同的流水灯程序。在这个设计中,有一个时钟模块,它用于生成时钟信号。还有一个计数器模块,它用于控制流水灯模式。最后还有一个顶层模块,它将计数器模块与流水灯模块相连,并使用按键模块进行控制。
```
// 时钟模块,用于生成时钟信号
module clk_divider(
input clk, // 输入时钟信号
input [3:0] divide_by, // 用于分频的计数器
output reg out // 输出分频后的时钟信号
);
reg [3:0] counter; // 计数器
always @(posedge clk) begin
counter <= counter + 1; // 计数器自增
if (counter == divide_by) begin
counter <= 0; // 计数器清零
out <= ~out; // 输出信号取反
end
end
endmodule
// 流水灯模块
module led(
input clk, // 输入时钟信号
input rst, // 复位信号
input [1:0] mode, // 流水灯模式选择
output reg [3:0] leds // 输出流水灯状态
);
reg [1:0] counter; // 计数器
always @(posedge clk, posedge rst) begin
if (rst) begin
leds <= 4'b0000; // 复位时所有灯都灭
counter <= 2'b00; // 计数器清零
end else begin
case (mode)
2'b00: begin // 模式0:左移
if (counter == 2'b00) begin
leds <= {leds[2:0], leds[3]}; // 左移
counter <= 2'b01; // 计数器自增
end else begin
counter <= 2'b00; // 计数器清零
end
end
2'b01: begin // 模式1:右移
if (counter == 2'b00) begin
leds <= {leds[0], leds[3:1]}; // 右移
counter <= 2'b01; // 计数器自增
end else begin
counter <= 2'b00; // 计数器清零
end
end
2'b10: begin // 模式2:交替闪烁
if (counter == 2'b00) begin
leds <= 4'b1010; // 交替闪烁
counter <= 2'b01; // 计数器自增
end else begin
leds <= 4'b0101; // 交替闪烁
counter <= 2'b00; // 计数器清零
end
end
2'b11: begin // 模式3:全部闪烁
if (counter == 2'b00) begin
leds <= 4'b1111; // 全部点亮
counter <= 2'b01; // 计数器自增
end else begin
leds <= 4'b0000; // 全部熄灭
counter <= 2'b00; // 计数器清零
end
end
endcase
end
end
endmodule
// 顶层模块
module top(
input clk, // 输入时钟信号
input rst, // 复位信号
input [3:0] buttons, // 输入按键信号
output [3:0] leds // 输出流水灯状态
);
reg [1:0] mode; // 流水灯模式选择
clk_divider divider(.clk(clk), .divide_by(4), .out(clk_2x)); // 时钟分频
led led1(.clk(clk_2x), .rst(rst), .mode(mode), .leds(leds)); // 流水灯模块
// 按键模块
always @(*) begin
case (buttons)
4'b0001: mode <= 2'b00; // 按键1选择模式0
4'b0010: mode <= 2'b01; // 按键2选择模式1
4'b0100: mode <= 2'b10; // 按键3选择模式2
4'b1000: mode <= 2'b11; // 按键4选择模式3
default: mode <= mode; // 其他情况不改变模式选择
endcase
end
endmodule
```
下面是一个测试程序,它可以用来测试上面的Verilog代码。在这个测试程序中,我们使用了一个时钟发生器,它可以产生一个1MHz的时钟信号。还有四个按键模拟器,它们可以模拟按下不同的按键。最后,我们将LED的输出连接到了示波器上,以便我们可以观察流水灯的效果。
```
`timescale 1ns / 1ps
module testbench;
reg clk; // 时钟信号
reg rst; // 复位信号
reg [3:0] buttons; // 按键信号
wire [3:0] leds; // 流水灯状态
top top1(.clk(clk), .rst(rst), .buttons(buttons), .leds(leds));
initial begin
clk <= 0; // 初始时钟为0
forever #0.5 clk <= ~clk; // 时钟周期为2ns,产生1MHz时钟信号
rst <= 1; // 复位信号为1
#10 rst <= 0; // 10个时钟周期后复位信号变为0
end
initial begin
buttons <= 4'b1111; // 初始所有按键都没有按下
#20 buttons <= 4'b0111; // 模拟按下按键1
#20 buttons <= 4'b1011; // 模拟按下按键2
#20 buttons <= 4'b1101; // 模拟按下按键3
#20 buttons <= 4'b1110; // 模拟按下按键4
#100 $finish; // 模拟结束
end
endmodule
```
阅读全文