流水灯

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
module top(
input reset,
input clk,
output[7:0] ctrcode
);
wire dclk;
wire[2:0] code;

divisor#(.DIV_CLK(5)) di1(reset,clk,dclk);
Counter c1(reset,dclk,code);
decoder de1(code,ctrcode);

endmodule

module Counter(
input reset,
input clk,
output reg[2:0] count
);

always @(posedge clk or negedge reset) begin
if(!reset) begin
count <= 3'b000;
end
else count <= count + 1;
end
endmodule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
module divisor 
#(parameter DIV_CLK = 50000000)
(
input rstn,
input clk,
output reg clk_divN
);

reg [$clog2(DIV_CLK/2)-1:0] cnt; // 自动计算合适的位宽(如果工具支持 SystemVerilog)

// 计数器逻辑
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
cnt <= 'b0;
end else if (cnt == (DIV_CLK/2)-1) begin
cnt <= 'b0;
end else begin
cnt <= cnt + 1'b1;
end
end

// 时钟分频逻辑
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
clk_divN <= 1'b0;
end else if (cnt == (DIV_CLK/2)-1) begin
clk_divN <= ~clk_divN; // 每次计数达到一半时翻转输出
end
end

endmodule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module decoder(
input [2:0] code,
output [7:0] decode
);

assign decode = (code == 3'b000) ? 8'b00000001 :
(code == 3'b001) ? 8'b00000010 :
(code == 3'b010) ? 8'b00000100 :
(code == 3'b011) ? 8'b00001000 :
(code == 3'b100) ? 8'b00010000 :
(code == 3'b101) ? 8'b00100000 :
(code == 3'b110) ? 8'b01000000 :
(code == 3'b111) ? 8'b10000000 :
8'b00000000; // 默认输出

endmodule

呼吸流水灯

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module top( 
input reset,
input clk,
output [7:0] ctrcode // 8 位 PWM 输出信号
);
parameter integer slowestFreq = 50000000; // 确保为整数
wire dclk; // 慢速时钟,用于控制滚动
wire bbclk; // 高频时钟,用于 PWM
wire [7:0] lighteSwitchResult; // LED 滚动控制信号
wire [7:0] brightnessPattern; // 滚动的亮度模式

// 调用分频器模块
divisor #(.DIV_CLK(slowestFreq / 2)) di1(reset, clk, dclk); // 2s 滚动时钟
divisor #(.DIV_CLK(slowestFreq / 1000000)) di2(reset, clk, bbclk); // 1us PWM 时钟

// 滚动逻辑模块
RollingController rc(
.reset(reset),
.clk(dclk),
.lighteSwitchResult(lighteSwitchResult), // 滚动灯信号
.brightnessPattern(brightnessPattern) // 滚动亮度信号
);

// 实例化 8 个 PWM 模块
pwmIP pwm0(.enable(lighteSwitchResult[0]), .reset(reset), .mode(brightnessPattern[1:0]), .clk2(bbclk), .pwm_out(ctrcode[0]));
pwmIP pwm1(.enable(lighteSwitchResult[1]), .reset(reset), .mode(brightnessPattern[3:2]), .clk2(bbclk), .pwm_out(ctrcode[1]));
pwmIP pwm2(.enable(lighteSwitchResult[2]), .reset(reset), .mode(brightnessPattern[5:4]), .clk2(bbclk), .pwm_out(ctrcode[2]));
pwmIP pwm3(.enable(lighteSwitchResult[3]), .reset(reset), .mode(brightnessPattern[7:6]), .clk2(bbclk), .pwm_out(ctrcode[3]));
pwmIP pwm4(.enable(lighteSwitchResult[4]), .reset(reset), .mode(brightnessPattern[1:0]), .clk2(bbclk), .pwm_out(ctrcode[4]));
pwmIP pwm5(.enable(lighteSwitchResult[5]), .reset(reset), .mode(brightnessPattern[3:2]), .clk2(bbclk), .pwm_out(ctrcode[5]));
pwmIP pwm6(.enable(lighteSwitchResult[6]), .reset(reset), .mode(brightnessPattern[5:4]), .clk2(bbclk), .pwm_out(ctrcode[6]));
pwmIP pwm7(.enable(lighteSwitchResult[7]), .reset(reset), .mode(brightnessPattern[7:6]), .clk2(bbclk), .pwm_out(ctrcode[7]));

endmodule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
module divisor 
#(parameter DIV_CLK = 50000000)
(
input rstn,
input clk,
output reg clk_divN
);

reg [$clog2(DIV_CLK/2)-1:0] cnt; // 自动计算合适的位宽(如果工具支持 SystemVerilog)

// 计数器逻辑
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
cnt <= 'b0;
end else if (cnt == (DIV_CLK/2)-1) begin
cnt <= 'b0;
end else begin
cnt <= cnt + 1'b1;
end
end

// 时钟分频逻辑
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
clk_divN <= 1'b0;
end else if (cnt == (DIV_CLK/2)-1) begin
clk_divN <= ~clk_divN; // 每次计数达到一半时翻转输出
end
end

endmodule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module pwmIP (
input wire enable, // 模块使能信号
input wire reset, // 异步复位信号
input wire [1:0] mode, // 外部输入的占空比模式
input wire clk2, // 用于 PWM 输出的时钟
output reg pwm_out // 1 位 PWM 输出信号
);
// 定义占空比的值
reg [6:0] duty_cycle; // 当前占空比
reg [6:0] counter; // PWM 时钟计数器

// 根据 mode 选择占空比
always @(*) begin
case (mode)
2'b00: duty_cycle = 7'd1; // 占空比模式 1
2'b01: duty_cycle = 7'd5; // 占空比模式 2
2'b10: duty_cycle = 7'd35; // 占空比模式 3
2'b11: duty_cycle = 7'd70; // 占空比模式 4
default: duty_cycle = 7'd1;
endcase
end

// PWM 输出逻辑
always @(posedge clk2 or negedge reset) begin
if (!reset) begin
counter <= 0; // 初始化计数器
pwm_out <= 0; // PWM 输出复位
end else if (enable) begin
counter <= counter + 1;
if (counter < duty_cycle)
pwm_out <= 1; // 在占空比范围内输出高电平
else
pwm_out <= 0; // 超出占空比范围输出低电平

if (counter == 7'd127) // 最大计数值
counter <= 0; // 计数器重置
end else begin
pwm_out <= 0; // 禁止状态下,输出低电平
end
end
endmodule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module RollingController (
input wire reset,
input wire clk, // 滚动时钟
output reg [7:0] lighteSwitchResult, // 滚动的灯亮信号
output reg [7:0] brightnessPattern // 滚动的亮度模式(每 2 位对应一个灯)
);
always @(posedge clk or negedge reset) begin
if (!reset) begin
lighteSwitchResult <= 8'b00001111; // 初始化为前 4 位灯亮
brightnessPattern <= 8'b00011011; // 初始化亮度模式
end else begin
// 滚动灯信号
lighteSwitchResult <= {lighteSwitchResult[6:0], lighteSwitchResult[7]};

// 滚动亮度模式,每个灯的模式也左移
brightnessPattern <= {brightnessPattern[6:0], brightnessPattern[7]};
end
end
endmodule