最新模板:
模板:LED灯
//在Verilog中,#()是一个参数化的模块声明,用于重新定义模块的默认参数。
//这些参数可以在模块实例化时被传递,以便在模块内部使用。
//#()中的参数可以是数字、字符串或其他参数化模块。具体说明如下:
//
//1. #()中的参数可以是数字、字符串或其他参数化模块。
//2. 参数可以在模块实例化时被传递,以便在模块内部使用。
//3. #()中的参数可以有默认值,如果没有传递参数,则使用默认值。
//4. #()中的参数可以在模块内部使用,例如用于计算延迟时间等。
//
//下面是一个简单的Demo,展示了如何在Verilog中使用#()声明一个参数化模块:
//
`define sysclk FPGA_CLK_50M_b5 // 编译的时候,只做替换 [`sysclk]
`define key1 key1_k18
`define key2 key2_n17
`define led2 led2_c15
`define led4 led4_b12
module top_PGL22G //【顶层】是托盘,水果不能大于托盘
#(
parameter CNT_1US_MAX = 6'd49,// 默认参数。 因为主晶振50MHz【计数0~49】
parameter CNT_1MS_MAX = 10'd999,
parameter CNT_1S_MAX = 10'd999
//最后一个参数不加【,】逗号
)
(
//模块的io,跟PLC的io一样【顶层绑定硬件io,再传给模块io,再由模块控制硬件io动作】
//在Verilog中,input wire clk和input clk的区别在于,
//input wire clk定义的是一个输入信号,它是一个组合逻辑输出,
//而input clk定义的是一个输入信号,它是一个寄存器输出。
//也就是说,input wire clk是一个纯粹的线,而input clk是一个寄存器的时钟输入。
//在设计中,一般来说,时钟信号需要使用寄存器输出,以保证时序的正确性和稳定性。
input `sysclk,// 这个是顶层io脚 FPGA_CLK_50M_b5 [`sysclk]
input reset_e8,
input `key1, // 再演示一遍 `define key1 key1_k18
input `key2,
input key3_n18,
input key4_h17,
//
output led1_d15,
output `led2,
output led3_a12,
output `led4,
output beep_h13// 无源蜂鸣器
//最后一个参数不加【,】逗号
);
//===================================
//===顶层内部成员
reg [6:0] cnt_1us;
reg [9:0] cnt_1ms;
reg [9:0] cnt_1s;
//实例化Timer模块
Timer
#(//先 修改Timer类型的默认参数 //不修改的话是使用默认参数
.CNT_1US_MAX ( CNT_1US_MAX ),// 顶层的参数传给模块的【默认参数】
.CNT_1MS_MAX ( CNT_1MS_MAX ),
.CNT_1S_MAX ( CNT_1S_MAX )
)
timer1 //实例化Timer模块
(
.clk ( `sysclk ),// 顶层绑定硬件io,再传给模块io,再由模块控制硬件io动作】
.rst ( reset_e8 ),// 【注,我的复位键,按下是0v】
.button( key1_k18 ),
.led ( led1_d15 )
);
//===顶层并联运行的程序
//===================================
// always @(posedge clk or posedge rst)
//
// assign `led1 = ~`key1 ;
//assign led2_c15 = key2_n17;
assign `led2 = ~`key2 ;
assign `led4 = `sysclk ;
endmodule// 程序从顶层开始
//===其他功能模块【请放在独立的文件夹里:功能块】
//=============================================================
module Timer //一个项目只能有一个顶层【main】模块。这个Timer是【非顶层模块】软件可以设置哪个为顶层
#(
parameter CNT_1US_MAX = 6'd49,// 默认参数。 因为主晶振50MHz【计数0~49】
parameter CNT_1MS_MAX = 10'd999,
parameter CNT_1S_MAX = 10'd999
//最后一个参数不加【,】逗号
)
// 实例化后,这个位置填儿子的名字
(
//模块的io,跟PLC的io一样
input clk , // .clk ( ),
input rst , // .rst ( ),
input button , // .button( ),
output reg led // .led ( )
//最后一个参数不加【,】逗号
);
//===模块内部成员
//===================================
reg [6:0] cnt_1us;
reg [9:0] cnt_1ms;
reg [9:0] cnt_1s;
//===模块并联运行的程序
//===================================
// always @(posedge clk or posedge rst)
// clk <= FPGA_CLK_50M_b5;
//always @(posedge clk or posedge rst)begin // 定时器 【Demo 注释一个功能,收缩成一行再注释】
//
// if (rst)begin // 复位
//
// cnt_1us <= 0;
// cnt_1ms <= 0;
// cnt_1s <= 0;
// end
// else begin // 开始计数
//
// if (cnt_1us == CNT_1US_MAX)begin//【1】us满
//
// cnt_1us <= 0;
// cnt_1ms <= cnt_1ms + 1;
// end
// else begin // us加1
//
// cnt_1us <= cnt_1us + 1;
// end
//
// if (cnt_1ms == CNT_1MS_MAX)begin//【2】ms满
//
// cnt_1ms <= 0;
// cnt_1s <= cnt_1s + 1;
// end
//
// if (cnt_1s == CNT_1S_MAX)begin//【3】s满
//
// cnt_1s <= 0;
// // if (button)
// // begin
// led <= ~led; // 1秒闪烁
//
// // end
// end
// end
// end// 功能结束
always @(posedge clk or negedge rst)begin // 定时器 // 【注,我的复位键,按下是0v】
if (~rst)begin // 复位 // 【注,我的复位键,按下是0v】
cnt_1us <= 0;
cnt_1ms <= 0;
cnt_1s <= 0;
// led4_b12 <= 0; // 【注】output `led4 默认是wire,所以不能在always里运行
led <= 0 ;
end
else begin // 开始计数
if (cnt_1us == CNT_1US_MAX)begin//【1】us满
cnt_1us <= 0;
cnt_1ms <= cnt_1ms + 1;
end
else begin // us加1
cnt_1us <= cnt_1us + 1;
end
if (cnt_1ms == CNT_1MS_MAX)begin//【2】ms满
cnt_1ms <= 0;
cnt_1s <= cnt_1s + 1;
end
if (cnt_1s == CNT_1S_MAX)begin//【3】s满
cnt_1s <= 0;
// if (button)
// begin
led <= ~led; // 1秒闪烁
// end
end
end
end// 功能结束
endmodule
Demo
好的,以下是一个全面的Verilog模块示例,它包含了一个计数器模块和一个LED显示模块:
```verilog
module CounterLED(
input wire clk,
input wire reset,
output reg [3:0] counter,
output reg led
);
reg [3:0] mem [0:1023]; // 1024位宽的内存数组
// 计数器初始化
initial begin
counter <= 0;
led <= 0;
end
// 计数器更新
always @(posedge clk) begin
if (reset) begin
counter <= 0;
led <= 0;
end else if (mem[counter] != 1023) begin
counter <= counter + 1;
mem[counter] <= led; // 将LED状态存储到内存中
led <= ~led; // LED状态翻转
end else begin
counter <= 0; // 达到最大值,重置计数器
end
end
// LED显示模块
assign led = mem[counter]; // 从内存中读取LED状态并输出到LED显示接口
endmodule
```
这个模块包含了一个计数器和一个LED显示模块。计数器使用一个内存数组来存储LED的状态,每次计数器更新时,都会将当前LED状态存储到内存中,并在下一次时钟上升沿时从内存中读取LED状态并输出到LED显示接口。LED显示模块输出一个四位的二进制数,代表了每个LED的状态。如果计数器达到最大值,则重置计数器并输出LED初始状态。可以使用此模块作为LED控制器的组成部分之一。