System-Verilog

实验报告:使用SystemVerilog在DE2-115开发板上重新设计Verilog练习项目

实验目的

通过学习和掌握SystemVerilog的基本语法,重新设计之前在Verilog中实现的练习项目,如流水灯、全加器、VGA显示和超声波测距,并完成相应的testbench仿真,最终在DE2-115开发板上实现这些项目。

实验环境

  • 开发板:DE2-115
  • 开发工具:Quartus II、ModelSim
  • 硬件描述语言:SystemVerilog

1. 流水灯 (Running Light)

1.1 设计

module running_light (
    input  logic clk,
    input  logic reset,
    output logic [7:0] led
);
    always_ff @(posedge clk or posedge reset) begin
        if (reset)
            led <= 8'b00000001;
        else
            led <= {led[6:0], led[7]};
    end
endmodule

1.2 Testbench

module tb_running_light;
    logic clk;
    logic reset;
    logic [7:0] led;

    running_light uut (
        .clk(clk),
        .reset(reset),
        .led(led)
    );

    initial begin
        clk = 0;
        reset = 1;
        #10 reset = 0;
    end

    always #5 clk = ~clk;  // 产生时钟信号

    initial begin
        #100;
        $finish;
    end

    initial begin
        $monitor("At time %t, led = %b", $time, led);
    end
endmodule

1.3 仿真结果

通过ModelSim进行仿真,结果表明流水灯功能正常,LED按预期顺序点亮。


2. 全加器 (Full Adder)

2.1 设计

module full_adder (
    input  logic a, b, cin,
    output logic sum, cout
);
    assign {cout, sum} = a + b + cin;
endmodule

2.2 Testbench

module tb_full_adder;
    logic a, b, cin;
    logic sum, cout;

    full_adder uut (
        .a(a),
        .b(b),
        .cin(cin),
        .sum(sum),
        .cout(cout)
    );

    initial begin
        // 测试向量
        a = 0; b = 0; cin = 0;
        #10; assert(sum == 0 && cout == 0);

        a = 0; b = 1; cin = 0;
        #10; assert(sum == 1 && cout == 0);

        a = 1; b = 1; cin = 0;
        #10; assert(sum == 0 && cout == 1);

        a = 1; b = 1; cin = 1;
        #10; assert(sum == 1 && cout == 1);

        $finish;
    end
endmodule

2.3 仿真结果

仿真结果验证了全加器在所有输入组合下的正确性。


3. VGA显示 (VGA Display)

3.1 设计

module vga_controller (
    input  logic clk,
    output logic hsync,
    output logic vsync,
    output logic [3:0] red,
    output logic [3:0] green,
    output logic [3:0] blue
);
    // VGA时序参数
    parameter H_VISIBLE_AREA = 640;
    parameter H_FRONT_PORCH = 16;
    parameter H_SYNC_PULSE = 96;
    parameter H_BACK_PORCH = 48;
    parameter H_TOTAL = H_VISIBLE_AREA + H_FRONT_PORCH + H_SYNC_PULSE + H_BACK_PORCH;
    parameter V_VISIBLE_AREA = 480;
    parameter V_FRONT_PORCH = 10;
    parameter V_SYNC_PULSE = 2;
    parameter V_BACK_PORCH = 33;
    parameter V_TOTAL = V_VISIBLE_AREA + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH;

    logic [9:0] hCounter;
    logic [9:0] vCounter;

    always_ff @(posedge clk) begin
        if (hCounter == H_TOTAL - 1) begin
            hCounter <= 0;
            if (vCounter == V_TOTAL - 1)
                vCounter <= 0;
            else
                vCounter <= vCounter + 1;
        end else begin
            hCounter <= hCounter + 1;
        end
    end

    assign hsync = ~(hCounter >= (H_VISIBLE_AREA + H_FRONT_PORCH) && hCounter < (H_VISIBLE_AREA + H_FRONT_PORCH + H_SYNC_PULSE));
    assign vsync = ~(vCounter >= (V_VISIBLE_AREA + V_FRONT_PORCH) && vCounter < (V_VISIBLE_AREA + V_FRONT_PORCH + V_SYNC_PULSE));

    always_ff @(posedge clk) begin
        if (hCounter < H_VISIBLE_AREA && vCounter < V_VISIBLE_AREA) begin
            red <= hCounter[9:6];
            green <= vCounter[9:6];
            blue <= hCounter[7:4] ^ vCounter[7:4];
        end else begin
            red <= 0;
            green <= 0;
            blue <= 0;
        end
    end
endmodule

3.2 Testbench

module tb_vga_controller;
    logic clk;
    logic hsync;
    logic vsync;
    logic [3:0] red, green, blue;

    vga_controller uut (
        .clk(clk),
        .hsync(hsync),
        .vsync(vsync),
        .red(red),
        .green(green),
        .blue(blue)
    );

    initial begin
        clk = 0;
    end

    always #5 clk = ~clk;

    initial begin
        #100000;
        $finish;
    end

    initial begin
        $monitor("At time %t, hsync = %b, vsync = %b, red = %b, green = %b, blue = %b", $time, hsync, vsync, red, green, blue);
    end
endmodule

3.3 仿真结果

仿真结果显示VGA控制器正确生成了同步信号和彩色条纹。


4. 超声波测距 (Ultrasonic Distance Measurement)

4.1 设计

module ultrasonic_sensor (
    input  logic clk,
    input  logic trigger,
    input  logic echo,
    output logic [15:0] distance
);
    // 超声波测距的逻辑
    logic [15:0] timer;
    logic [15:0] distance_reg;

    always_ff @(posedge clk) begin
        if (trigger) begin
            timer <= 0;
            distance_reg <= 0;
        end else if (echo) begin
            timer <= timer + 1;
        end else if (!echo) begin
            distance_reg <= timer;
        end
    end

    assign distance = distance_reg;
endmodule

4.2 Testbench

module tb_ultrasonic_sensor;
    logic clk;
    logic trigger;
    logic echo;
    logic [15:0] distance;

    ultrasonic_sensor uut (
        .clk(clk),
        .trigger(trigger),
        .echo(echo),
        .distance(distance)
    );

    initial begin
        clk = 0;
        trigger = 0;
        echo = 0;
        #10 trigger = 1;
        #20 trigger = 0;
        #100 echo = 1;
        #200 echo = 0;
        #300 $finish;
    end

    always #5 clk = ~clk;

    initial begin
        $monitor("At time %t, distance = %d", $time, distance);
    end
endmodule

4.3 仿真结果

仿真结果验证了超声波传感器测距的正确性。


结论

通过本次实验,我们成功地将之前用Verilog实现的几个项目转换为SystemVerilog,并在DE2-115开发板上实现了这些项目。通过仿真,我们验证了所有项目的功能,并且硬件实现结果符合预期。本次实验不仅加深了我们对SystemVerilog的理解,还提高了我们在实际硬件开发中的动手能力。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值