基于System-Verilog点亮LED灯

发布于:2024-06-16 ⋅ 阅读:(21) ⋅ 点赞:(0)

一、System-Verilog介绍

1.1System-Verilog

SystemVerilog是一种硬件描述和验证语言(HDVL),它基于IEEE1364-2001 Verilog硬件描述语言(HDL),并对其进行了扩展,包括扩充了C语言数据类型、结构、压缩和非压缩数组、 接口、断言等等,这些都使得SystemVerilog在一个更高的抽象层次上提高了设计建模的能力。
SystemVerilog由Accellera开发,它主要定位在芯片的实现和验证流程上,并为系统级的设计流程提供了强大的连接能力。下面我们从几个方面对SystemVerilog所作的增强进行简要的介绍,期望能够通过这个介绍使大家对SystemVerilog有一个概括性的了解。

二、简单的语法介绍

2.1接口实例

interface chip_bus;// 定义接口
 
wireread_request, read_grant;
 
wire [7:0]address, data;
 
endinterface: chip_bus
module RAM(chip_bus io, // 使用接口
 
inputclk);
 
//可以使用io.read_request引用接口中的一个信号
 
endmodule
module CPU(chip_busio, input clk);
 
...
 
endmodule
module top;
 
reg clk = 0;
 
chip_busa; // 实例接口
 
//将接口连接到模块实例
 
RAM mem(a,clk);
 
CPU cpu(a,clk);
 
endmodule

2.2全局声明和语句实例

reg error_flag; // 全局变量
 
function compare(...); // 全局函数
always@(error_flag) // 全局语句
...
module test;
chip1 u1(...)
endmodule
module chip1(...);
FSM u2(...);
always@(data)
error_flag= compare(data, expected);
endmodule
module FSM(...);
...
always @(state)
error_flag= compare(state, expected);
endmodule

2.3时间单位和精度

在Verilog中,表示时间的值使用一个数来表示,而不带有任何时间单位。例如:

`forever #5clock= ~clock;`

SystemVerilog为了控制时间单位加入了两个重要的增强。首先,时间值可以显式地指定一个单位。时间单位可以是s、ms、ns、ps或fs。时间单位作为时间值的后缀出现。例如:

forever #5nsclock= ~clock;

其次,SystemVerilog允许使用新的关键字(timeunits和timeprecision)来指定时间单位和精度。这些声明可以在任何模块中指定,同时也可以在$root空间中全局指定。时间单位和精度必须是10的幂,范围可以从s到fs。例如:

timeunits 1ns;
 
 
 
 
timeprecision 10ps;

2.4用户定义的类型

Verilog不允许用户定义新的数据类型。SystemVerilog通过使用typedef提供了一种方法来定义新的数据类型,这一点与C语言类似。用户定义的类型可以与其它数据类型一样地使用在声明当中。例如:

typedefunsigned int uint;
 
 
 
 
uint a, b;

一个用户定义的数据类型可以在它的定义之前使用,只要它首先在空的typedef中说明,例如:

typedef int48; // 空的typedef,在其他地方进行完整定义
 
 
 
 
int48 c;

2.5 枚举类型

在Verilog语言中不存在枚举类型。标识符必须被显式地声明成一个线网、变量或参数并被赋值。SystemVerilog允许使用类似于C的语法产生枚举类型。一个枚举类型具有一组被命名的值。缺省情况下,值从初始值0开始递增,但是我们可以显式地指定初始值。枚举类型的例子如下:

enum {red,yellow, green} RGB;
 
 
 
 
enum {WAIT=2’b01, LOAD, DONE} states;

我们还可以使用typedef为枚举类型指定一个名字,从而允许这个枚举类型可以在许多地方使用。例如:

typedefenum {FALSE=1’b0, TRUE} boolean;
 
 
 
 
boolean ready;
 
 
 
 
booleantest_complete;

三、流水灯

ed_flow.sv

module led_flow (
    input logic clk,       // 时钟信号
    input logic rst_n,     // 复位信号(低有效)
    output logic [7:0] led // 8位LED输出
);

    logic [23:0] counter;  // 24位计数器,用于产生慢时钟信号

    // 计数器逻辑
    always_ff @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            counter <= 24'd0;
        else
            counter <= counter + 1;
    end

    // LED流水灯逻辑
    always_ff @(posedge counter[23] or negedge rst_n) begin
        if (!rst_n)
            led <= 8'b0000_0001;
        else
            led <= {led[6:0], led[7]};
    end
endmodule


testbench

module led_flow_tb;
    logic clk;
    logic rst_n;
    logic [7:0] led;

    // 实例化待测试的流水灯模块
    led_flow uut (
        .clk(clk),
        .rst_n(rst_n),
        .led(led)
    );

    // 时钟信号生成
    initial begin
        clk = 0;
        forever #10 clk = ~clk; // 50MHz时钟周期为20ns
    end

    // 测试逻辑
    initial begin
        // 初始化信号
        rst_n = 0;
        #100;
        rst_n = 1;

        // 仿真运行一段时间后结束
        #1000000;
        $stop;
    end
endmodule


效果
在这里插入图片描述

参考

System Verilog简介