使用system verilog进行流水灯和VGA打印字符

2024-06-03 22:52

本文主要是介绍使用system verilog进行流水灯和VGA打印字符,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用system verilog进行流水灯和VGA打印字符

目录

  • **使用system verilog进行流水灯和VGA打印字符**
    • **system verilog的优点**
    • **VGA程序编写**
      • VGA 控制器模块
      • 字符生成模块
      • 顶层模块
      • 测试基准程序
      • **效果**
    • **流水灯程序设计**
      • **效果**
    • **总结**

system verilog的优点

面向对象编程:SystemVerilog 引入了面向对象的编程特性,如类(class)和继承,这有助于创建可重用的代码和设计模式。

增强的验证能力:SystemVerilog 支持断言(assertions)和覆盖率(coverage)分析,这些是验证复杂设计的关键工具。

并发建模:SystemVerilog 允许更自然地建模并发事件,通过使用 fork-join 语句来创建并行线程。

更丰富的数据类型:SystemVerilog 增加了多种数据类型,例如枚举(enum)、结构体(struct)、联合体(union)和数组,这些使得数据建模更加灵活和强大。

参数化编程:通过宏和参数化编程,SystemVerilog 允许更灵活的设计,可以更容易地创建可配置和可重用的设计组件。

改善的模块间连接:SystemVerilog 引入了接口(interface)的概念,简化了模块间的连接,并使得设计更加模块化。

更高级的建模能力:SystemVerilog 支持更高层次的抽象建模,有助于设计者在系统级别进行设计和验证。

随机化测试:SystemVerilog 支持随机化测试,可以自动生成测试向量,这有助于更全面地验证设计。

更有效的代码复用:通过封装和模块化,SystemVerilog 促进了代码的复用,提高了设计效率。

标准和兼容性:SystemVerilog 作为 IEEE 标准的一部分,确保了设计和验证方法的兼容性和标准化。

VGA程序编写

VGA 控制器模块

首先是 VGA 控制器模块,负责生成 VGA 信号和像素坐标。

module VGAController (input logic clk,      // 时钟input logic reset,    // 复位output logic hsync,   // 水平同步信号output logic vsync,   // 垂直同步信号output logic [9:0] pixelX,  // 像素 X 坐标output logic [9:0] pixelY,  // 像素 Y 坐标output logic displayOn       // 是否显示像素
);// 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 or posedge reset) beginif (reset) beginhCounter <= 0;vCounter <= 0;end else beginif (hCounter == H_TOTAL - 1) beginhCounter <= 0;if (vCounter == V_TOTAL - 1) beginvCounter <= 0;end else beginvCounter <= vCounter + 1;endend else beginhCounter <= hCounter + 1;endendend// 生成同步信号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);// 输出像素坐标和显示信号assign pixelX = hCounter;assign pixelY = vCounter;assign displayOn = (hCounter < H_VISIBLE_AREA) && (vCounter < V_VISIBLE_AREA);
endmodule

字符生成模块

接下来是字符生成模块,根据像素坐标生成 “你好FPGA” 字符。

module CharGen (input logic clk,          // 时钟input logic reset,        // 复位input logic [9:0] pixelX, // 像素 X 坐标input logic [9:0] pixelY, // 像素 Y 坐标input logic displayOn,    // 是否显示像素output logic [3:0] red,   // 红色分量output logic [3:0] green, // 绿色分量output logic [3:0] blue   // 蓝色分量
);// 字符映射表,可以通过像素坐标获取相应的像素值reg [63:0] charMap [0:6] = '{64'h7C121212127C00, 64'h42427E424200, 64'h7E0909090000, 64'h7E0909090600, 64'h3E414949493200, 64'h7E09097E0000, 64'h00000000000000};// 计算字符索引和像素在字符中的位置reg [3:0] charIndex;reg [2:0] charRow, charCol;reg [2:0] pixelXInChar, pixelYInChar;reg charPixel;always_ff @(posedge clk or posedge reset) beginif (reset) begincharIndex <= 0;charRow <= 0;charCol <= 0;pixelXInChar <= 0;pixelYInChar <= 0;charPixel <= 0;end else begin// 计算当前字符索引charCol <= pixelX / 8;charRow <= pixelY / 12;charIndex <= charCol + (charRow * 8);// 计算像素在字符中的位置pixelXInChar <= pixelX % 8;pixelYInChar <= pixelY % 12;// 获取当前像素值charPixel <= (charMap[charIndex])[63 - (pixelYInChar * 8 + pixelXInChar)];endend// 生成 RGB 信号always_comb begincase (charPixel)1'b0: beginred = 4'h0;green = 4'h0;blue = 4'h0;end1'b1: beginred = 4'hF;green = 4'hF;blue = 4'hF;enddefault: beginred = 4'h0;green = 4'h0;blue = 4'h0;endendcaseend
endmodule

顶层模块

以下是顶层模块,将 VGA 控制器和字符生成模块结合在一起,并输出到开发板上。

module Top (input logic clk,   // 时钟input logic reset, // 复位output logic [3:0] red,     // 红色信号output logic [3:0] green,   // 绿色信号output logic [3:0] blue,    // 蓝色信号output logic hsync,         // 水平同步信号output logic vsync          // 垂直同步信号
);// 实例化 VGA 控制器和字符生成模块VGAController vgaController (.clk(clk),.reset(reset),.hsync(hsync),.vsync(vsync),.pixelX(pixelX),.pixelY(pixelY),.displayOn(displayOn));CharGen charGen (.clk(clk),.reset(reset),.pixelX(pixelX),.pixelY(pixelY),.displayOn(displayOn),.red(red),.green(green),.blue(blue));endmodule

测试基准程序

最后是测试基准程序,用于测试顶层模块的功能。

module Top_tb;// 时钟和复位信号logic clk;logic reset;// VGA 控制器和字符生成模块的信号logic hsync;logic vsync;logic [9:0] pixelX;logic [9:0] pixelY;logic displayOn;logic [3:0] red;logic [3:0] green;logic [3:0] blue;// 实例化被测试的模块Top dut (.clk(clk),.reset(reset),.hsync(hsync),.vsync(vsync),.red(red),.green(green),.blue(blue));// 时钟生成always #5 clk = ~clk;// 复位信号生成initial beginreset = 1;#10;reset = 0;#10000;$finish;end// 输出测试结果always @(posedge clk) begin$display("hsync: %b, vsync: %b, red: %h, green: %h, blue: %h", hsync, vsync, red, green, blue);endendmodule

效果

在这里插入图片描述

流水灯程序设计

流水灯模块

module LED(input clk,input rst_n,  // _n低电平有效output logic [3:0] led
);// 1.5s计数器
logic [27:0] cnt;
parameter int TIME_1_5S = 75_000_000;
// 由于cnt已经声明为logic类型,不需要额外的信号声明logic add_cnt;logic end_cnt;// 赋值语句不需要阻塞赋值的begin-end结构
always_ff @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt <= 28'd0;end else if (add_cnt) beginif (end_cnt) begincnt <= 28'd0;end else begincnt <= cnt + 1;endend
end// 使用always_comb声明组合逻辑
always_comb beginadd_cnt = 1'b1;end_cnt = add_cnt && cnt == (TIME_1_5S - 1);
end// 拼接法控制LED
always_ff @(posedge clk or negedge rst_n) beginif (!rst_n) beginled <= 4'b1110;end else if (end_cnt) beginled <= {led[2:0], led[3]}; // 流水灯end
endendmodule

顶层模块设计

`timescale 1ns/1ns
module     LED_tb();reg   tb_clk;
reg   tb_rst_n;
wire  [3:0]tb_led;LED #(.TIME_1_5S(750))           inst_LED(.clk      (tb_clk     ) ,.rst_n    (tb_rst_n   ) ,.led      (tb_led )   
);parameter cycle =20 ;//时钟周期为20nsalways#(cycle/2)tb_clk=~tb_clk;//过时钟周期一半取反initial begintb_clk=1'b0;tb_rst_n=1'b0;#(cycle*3);tb_rst_n=1'b1;#(cycle*751*16);$stop;endendmodule

效果

在这里插入图片描述

在这里插入图片描述

总结

这次对system verilog的编写让我对system verilog有了清晰的认识。

这篇关于使用system verilog进行流水灯和VGA打印字符的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028347

相关文章

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用