【verilog】1. 流水灯例程



前言

数电课设


一、定义概念 + 缩写

1. verilog

  • Verilog 是一种以代码形式来描述数字系统和电路的硬件描述语言 (HDL)。它由 Gateway Design Automation 在 20 世纪 80年代中期开发,后来被Cadence Design Systems 收购。

二、性质

Verilog是一种硬件描述语言(HDL),用于描述和设计数字系统。它具有以下一些关键性质:

  1. 硬件并行性:Verilog能够描述并行硬件结构,这是它与许多传统的编程语言的主要区别。在Verilog中,多个操作可以同时发生,而不需要像在顺序执行的编程语言中那样等待前一个操作完成。

  2. 模块化:Verilog支持模块化设计,允许设计者将复杂的系统分解成较小的、可重用的模块。每个模块可以独立设计和测试,然后实例化到更大的系统中。

  3. 层次化:Verilog设计可以是层次化的,这意味着模块可以嵌套,即一个模块可以包含其他模块的实例。

  4. 并发和顺序建模:Verilog提供了并发(如always块和initial块)和顺序(如过程赋值语句和任务)建模的机制。

  5. 丰富的数据类型:Verilog提供了多种数据类型,包括线网类型(wire)、寄存器类型(reg)、参数(parameter)、整数(integer)、实数(real)、时间(time)等。

  6. 事件驱动和时钟驱动:Verilog的行为可以由事件(如信号的边沿)或时钟(通过always块)驱动。

  7. 时序控制:Verilog允许设计者精确地控制信号的时序,这对于设计同步数字电路至关重要。

  8. 可综合和仿真:Verilog代码可以用于两种主要的硬件设计流程:综合(将Verilog代码转换为门级网表)和仿真(在软件环境中测试Verilog代码的行为)。

  9. 可预测性:Verilog的设计和行为是可预测的,这使得设计者可以确信硬件在实际制造之前的行为。

  10. 广泛的工具支持:Verilog有着广泛的工具支持,包括综合工具、仿真工具、调试工具和验证工具。

  11. 标准化:Verilog是一种广泛接受的行业标准,由IEEE(电气和电子工程师协会)维护和更新。

  12. 可扩展性: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]


在这里插入图片描述

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值