前言
数电课设
一、定义概念 + 缩写
1. verilog
- Verilog 是一种以代码形式来描述数字系统和电路的硬件描述语言 (HDL)。它由 Gateway Design Automation 在 20 世纪 80年代中期开发,后来被Cadence Design Systems 收购。
二、性质
Verilog是一种硬件描述语言(HDL),用于描述和设计数字系统。它具有以下一些关键性质:
-
硬件并行性:Verilog能够描述并行硬件结构,这是它与许多传统的编程语言的主要区别。在Verilog中,多个操作可以同时发生,而不需要像在顺序执行的编程语言中那样等待前一个操作完成。
-
模块化:Verilog支持模块化设计,允许设计者将复杂的系统分解成较小的、可重用的模块。每个模块可以独立设计和测试,然后实例化到更大的系统中。
-
层次化:Verilog设计可以是层次化的,这意味着模块可以嵌套,即一个模块可以包含其他模块的实例。
-
并发和顺序建模:Verilog提供了并发(如always块和initial块)和顺序(如过程赋值语句和任务)建模的机制。
-
丰富的数据类型:Verilog提供了多种数据类型,包括线网类型(wire)、寄存器类型(reg)、参数(parameter)、整数(integer)、实数(real)、时间(time)等。
-
事件驱动和时钟驱动:Verilog的行为可以由事件(如信号的边沿)或时钟(通过always块)驱动。
-
时序控制:Verilog允许设计者精确地控制信号的时序,这对于设计同步数字电路至关重要。
-
可综合和仿真:Verilog代码可以用于两种主要的硬件设计流程:综合(将Verilog代码转换为门级网表)和仿真(在软件环境中测试Verilog代码的行为)。
-
可预测性:Verilog的设计和行为是可预测的,这使得设计者可以确信硬件在实际制造之前的行为。
-
广泛的工具支持:Verilog有着广泛的工具支持,包括综合工具、仿真工具、调试工具和验证工具。
-
标准化:Verilog是一种广泛接受的行业标准,由IEEE(电气和电子工程师协会)维护和更新。
-
可扩展性:Verilog允许设计者定义自己的数据类型和原语,以满足特定的设计需求。
这些性质使得Verilog成为设计复杂数字系统的强大工具,特别是在集成电路和FPGA设计领域。
三、代码分解释
- 模块声明,端口,类似 C 的结构体
// 模块声明和端口
module lamp( //文件名
input clk, //50MHz, 20ns周期
input rst_n, //复位按键,低电平
output reg [7:0] led //8个led,低电平亮
); //端口声明最后一行没有逗号
- 定义计数器
// 注释说明
// 程序功能说明
// 让8个led以每秒一次改变状态,循环32个不同的状态
// 需要产生一个周期1s,频率为1Hz的信号控制8个led的状态改变
// 由50MHz产生1Hz信号,需要设计计数器作为分频器,那么该计数器的模值是?
// 50000000Hz/1Hz=50000000,需要多少位二进制数来实现该模值计数器?
// 定义计数器和1Hz信号
reg [31:0] count; //定义计数器位数为32位
reg clk_1hz; //定义一个1Hz的输出信号
- 分频器
// 分频器逻辑
// 编写分频代码,产生clk_1hz信号
always@(posedge clk or negedge rst_n)//clk上升沿,rst_n下降沿
begin
if (!rst_n) //当rst_n为低电平时复位
begin
count <= 32'd0;
clk_1hz <= 1'b0;
end
else if (count < 32'd49999999)
begin
count <= count + 1'b1;
clk_1hz <= 1'b0;
end
else // count = 32'd49999999
begin
count <= 32'd0; //返回到初始状态 0
clk_1hz <= 1'b1;
end
end
- LED控制状态逻辑
// LED状态控制逻辑
// 前面产生了1hz的信号,下面用1hz的信号产生控制8个led的状态计数器
// 假设8个led有32种状态变化,需要设计一个模值为32的计数器
reg [4:0] cnt; //定义一个5位的状态信号
always@(posedge clk_1hz or negedge rst_n)
begin
if (!rst_n)
cnt <= 5'd0;
else
cnt <= cnt + 1'b1; //5位二进制加法计数器
//用cnt状态控制8个led灯的显示状态
case (cnt) //cnt有32个状态,从0~31
5'd0: led <= 8'b0111_1111; //实验板上led灯是低电平亮
5'd1: led <= 8'b1011_1111; //
5'd2: led <= 8'b1101_1111;
5'd3: led <= 8'b1110_1111;
5'd4: led <= 8'b1111_0111;
5'd5: led <= 8'b1111_1011;
5'd6: led <= 8'b1111_1101;
5'd7: led <= 8'b1111_1110;
5'd8: led <= 8'b1111_1110;
5'd9: led <= 8'b1111_1101;
5'd10:led <= 8'b1111_1011;
5'd11:led <= 8'b1111_0111;
5'd12:led <= 8'b1110_1111;
5'd13:led <= 8'b1101_1111;
5'd14:led <= 8'b1011_1111;
5'd15:led <= 8'b0111_1111;
5'd16:led <= 8'b0111_1110; //两边灯亮
5'd17:led <= 8'b1011_1101;
5'd18:led <= 8'b1101_1011;
5'd19:led <= 8'b1110_0111;
5'd20:led <= 8'b1101_1011;
5'd21:led <= 8'b1011_1101;
5'd22:led <= 8'b0111_1110;
5'd23:led <= 8'b0011_1111; //从左向右依次点亮led
5'd24:led <= 8'b0001_1111;
5'd25:led <= 8'b0000_1111;
5'd26:led <= 8'b0000_0111;
5'd27:led <= 8'b0000_0011;
5'd28:led <= 8'b0000_0001;
5'd29:led <= 8'b0000_0000; //8个led灯全亮
5'd30:led <= 8'b0101_0101; //间隔亮
5'd31:led <= 8'b1111_1111; //8个led灯全灭
endcase
end
- 结束模块
// 模块结束
endmodule
四、完整代码
// 模块声明和端口
module lamp( //文件名
input clk, //50MHz, 20ns周期
input rst_n, //复位按键,低电平
output reg [7:0] led //8个led,低电平亮
); //端口声明最后一行没有逗号
// 注释说明
// 程序功能说明
// 让8个led以每秒一次改变状态,循环32个不同的状态
// 需要产生一个周期1s,频率为1Hz的信号控制8个led的状态改变
// 由50MHz产生1Hz信号,需要设计计数器作为分频器,那么该计数器的模值是?
// 50000000Hz/1Hz=50000000,需要多少位二进制数来实现该模值计数器?
// 定义计数器和1Hz信号
reg [31:0] count; //定义计数器位数为32位
reg clk_1hz; //定义一个1Hz的输出信号
// 分频器逻辑
// 编写分频代码,产生clk_1hz信号
always@(posedge clk or negedge rst_n)//clk上升沿,rst_n下降沿
begin
if (!rst_n) //当rst_n为低电平时复位
begin
count <= 32'd0;
clk_1hz <= 1'b0;
end
else if (count < 32'd49999999)
begin
count <= count + 1'b1;
clk_1hz <= 1'b0;
end
else // count = 32'd49999999
begin
count <= 32'd0; //返回到初始状态 0
clk_1hz <= 1'b1;
end
end
// LED状态控制逻辑
// 前面产生了1hz的信号,下面用1hz的信号产生控制8个led的状态计数器
// 假设8个led有32种状态变化,需要设计一个模值为32的计数器
reg [4:0] cnt; //定义一个5位的状态信号
always@(posedge clk_1hz or negedge rst_n)
begin
if (!rst_n)
cnt <= 5'd0;
else
cnt <= cnt + 1'b1; //5位二进制加法计数器
//用cnt状态控制8个led灯的显示状态
case (cnt) //cnt有32个状态,从0~31
5'd0: led <= 8'b0111_1111; //实验板上led灯是低电平亮
5'd1: led <= 8'b1011_1111; //
5'd2: led <= 8'b1101_1111;
5'd3: led <= 8'b1110_1111;
5'd4: led <= 8'b1111_0111;
5'd5: led <= 8'b1111_1011;
5'd6: led <= 8'b1111_1101;
5'd7: led <= 8'b1111_1110;
5'd8: led <= 8'b1111_1110;
5'd9: led <= 8'b1111_1101;
5'd10:led <= 8'b1111_1011;
5'd11:led <= 8'b1111_0111;
5'd12:led <= 8'b1110_1111;
5'd13:led <= 8'b1101_1111;
5'd14:led <= 8'b1011_1111;
5'd15:led <= 8'b0111_1111;
5'd16:led <= 8'b0111_1110; //两边灯亮
5'd17:led <= 8'b1011_1101;
5'd18:led <= 8'b1101_1011;
5'd19:led <= 8'b1110_0111;
5'd20:led <= 8'b1101_1011;
5'd21:led <= 8'b1011_1101;
5'd22:led <= 8'b0111_1110;
5'd23:led <= 8'b0011_1111; //从左向右依次点亮led
5'd24:led <= 8'b0001_1111;
5'd25:led <= 8'b0000_1111;
5'd26:led <= 8'b0000_0111;
5'd27:led <= 8'b0000_0011;
5'd28:led <= 8'b0000_0001;
5'd29:led <= 8'b0000_0000; //8个led灯全亮
5'd30:led <= 8'b0101_0101; //间隔亮
5'd31:led <= 8'b1111_1111; //8个led灯全灭
endcase
end
// 模块结束
endmodule
matlab代码块
c代码块
参考文献
[1]