02-初识Verilog

这篇具有很好参考价值的文章主要介绍了02-初识Verilog。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.开发环境搭建

需要使用的软件:

  • QuartusII
  • ModelSim
  • Visio
  • Notepad++

2.初识Verilog

2.1 Verilog HDL简介

  • Verilog HDL是一种硬件描述语言,以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图\逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能
  • Verilog语法自由,易学易用,适用于算法级,门级设计,代码简介,发展较快
  • Verilog从C语言发展而来的

2.2 逻辑值

  • 0 -- 逻辑低电平,条件为假
  • 1 -- 逻辑高电平,条件为真
  • z -- 高阻态,无驱动
  • x -- 未知逻辑电平
  • 实际电路中存在0,1,z,亚稳态

2.3 关键字

module example(
  input wire  sys_rst_n,//输入信号
  inout wire sda,//输入输出信号,基本不用
  
  output wire po_flag  // 输出信号
);
  // 只有输入信号是不能直接得到输出信号的
  // 需要通过一些数据和参数对输入信号进行处理,得到输出信号
  // 一般需要对输入信号进行处理之后得到输出信号
  
  // 线网型变量 -- wire可以被看作是物理连接 -- 被综合成物理连线
  wire [0:0] flag;

  // 寄存器型变量 -- 具有对某一时间点的状态进行保持的功能
  // 可综合电路中被综合成寄存器
  reg [7:0] cnt;
  
  // 参数的定义
  // parameter 可以在顶层模块通过实例化对参数进行修改
  parameter CNT_MAX = 100;

  //localparam -- 只用在模块内部,不能在实例化的时候进行修改
  localparam CNT_MAX = 100;
  
  // 模块的实例化
  example
  #(
    .CNT_MAX (8'd100) // 实例化时参数可以修改
  ) 
  example_inst
  (
    .sys_clk (sys_clk),
    .sys_rst_n (sys_rst_n),
    .po_flag (po_flag)
  );

  /*
    常量
    表示方法: [换算为二进制数之后的位宽]'[进制符号][与数值对应的进制数]
    8'd171
    d -- 十进制
    b -- 二进制
    h -- 十六进制
    
    不写位宽 -- verilog会自动进行匹配
    总位宽大于实际位宽,自动补0,总位宽小于实际位宽,则自动截断左边超出的位数
    d'7  8'd7   -- 8'b0000_0111   前面补5个0
    2'd7 换算位二进制是 2'b11 (7换成二进制是111),总长度位2位,所以截掉左侧的部分
    直接写参数 100 ,表示位宽为32bit的十进制数100
  */

  // 赋值方式
  // 阻塞赋值 = 
  // 阻塞赋值可以看作是顺序执行,每条语句执行完成之后才能执行下一条语句
  a = 1;
  b = 2;
  c = 3;
  begin
    a = b;
    c = a;
  end
  a = 2;
  b = 2;
  c = 2;
  // 非阻塞赋值 <= 并行执行
  a = 1;
  b = 2;
  c = 3;
  begin
    a <= b;  // 同一时刻,这两条语句是同时执行的
    c <= a;
  end
  a = 2;
  b = 2;
  c = 1;

  // always语句
  always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
      cnt <= 8'b0; // 进行寄存器复位
    else if (cnt == CNT_MAX) // 寄存器中的值记到最大的时候,维持最大值
      cnt <= CNT_MAX;
    else
      cnt <= cnt + 8'd1;    // 每个周期都加1
  

  // assign语句
  assign po_flag = (cnt == CNT_MAX) ? 1'b1 : 1'b0;
endmoudle

2.4 算术运算符

+
-
* -- 一般不用
/ -- 一般不用
% -- 求余数,两边都为整型数据

2.5 归约运算符\按位运算符

  • & -- 既可以作为单目运算符又可以作为双目运算符
// & 作为单目运算符,&m,将m的所有bit相与,得到结果是1bit
4'b1111 = 1&1&1&1 = 1'b1
4'b1101 = 1&1&0&1 = 1'b0

// & 作为双目运算符表示按位与,m&n,是将m的每个bit与n的每个bit相与,在运算的时候保证m和n的bit数相等,最后结果位数和m(n)的bit数相等
4'b1010&4'b0101 = 4'b0000
  • &,^,^,|,~| -- 这些运算符都有相同的看法

2.6 逻辑运算符

  • &&/||/! -- 与或非三种逻辑运算,返回值为0或者是1
  • 逻辑运算符两边非0位真,0为假
a = 4'ha
b = 4'd0
c = a && b   // c的值为0

2.7 关系运算符

a < b
a > b
a <= b
a >= b

2.8 移位运算符

  • 移位运算符是二元运算符,<<和>>,将运算符左边的数左移或者是右移指定的位数,用0来补充空闲位
b <= a << 1; // a的每一位都左移一位,结果赋值给b
b <= a >> 1; // a的没一位都右移一位,结果赋值给b
  • 在应用移位运算符的时候一定要注意他的特性:就是空闲位使用0来补充,也就是说,一个二进制数不管原来的数值是多少,只要一直移位,最终都会变为0
4'b1000 >> 3;  // 4'b0001
4'b1000 >> 4;  // 4'b0000
  • 移位运算符可以代替乘法和除法,左移一位可以看成是乘2,右移一位可以看成是除2,但是要注意位拓展

2.9 拼接运算符

  • {,} -- 位拼接运算符
a = 8'b1011_1111;
b = 3'b011;
c = 5'b11011;
{a,b,c} ; // 拼接成16bit

2.10 三元运算符

[表达式1]?表达式2:表达式3
a = 6;
b = 7;
c = (a>b)?a:b;

2.11 优先级

  • 一元运算符>二元运算符>三元运算符
  • != > 按位运算 > && > || > 条件运算
  • 归约运算符 > 算术运算符 > 移位运算符 > 关系运算符 > == 和 !=
  • 使用()提升优先级

2.12 if-else语句

if(表达式)   // 这种写法在always语句块产生组合逻辑的时候中会产生latch,不推荐使用
  语句块;

if(表达式)
  语句块1;
else if(表达式2)
  语句块2;
....
else
  语句;    // 这种是最常用的写法

2.12 case语句

switch(表达式)
  case value1 : 语句1;
  case value2 : 语句2;
  ....
  default: 语句;

2.13 系统函数

`timescale 1ns/1ns  // 时间尺度预编译指令 时间单位/时间精度
时间单位和时间精度有由1,10及100以及s,ms,ns,us,ps,fs组成
时间单位:定义仿真过程中所有与时间相关量的单位
仿真中使用#数字表示延迟相应的时间单位的时间,例如#10表示延时10个时间单位,即10ns

时间精度:决定时间相关量的精度及仿真显示的最小单位
`timescale 1ns/10ps  // 精度0.01, #10.11 表示延迟10110ps

`timescale 100ps/1ns // 错误,时间单位不能比时间精度小
// 主要的函数,在支持verilog语法的编译器中都会显示为高亮的关键字
$display    //打印信息,自动换行
$write      //打印信息
$strobe     //打印信息,自动换行,最后执行
$monitor    //检测变量
$stop       //暂停仿真
$finish     //结束仿真
$time       //时间函数
$random     //随机函数
$readmemb   //读取文件的函数

$display()

$display(); //  输出,打印信息
$display("%b+%b = %d",a,b,c);
// %d %D -- 十进制
// %o %O -- 八进制
// %b %B -- 二进制
// %d %D -- 十六进制
// 不指定进制,默认为十进制数
`timescale 1ns/1ns

module tb_test();
  reg [3:0] a;
  reg [3:0] b;
  reg [3:0] c;
  
  // initial只在仿真中使用,是不可综合的
  // 仿真开始,只执行一次
  initial begin
    $display("Hello");
    $display("EmbedFire");
    a = 4'd5;
    b = 4'd6;
    c = a + b;
    #100;
    $display("%b + %b = %d",a,b,c);
    
  end
endmodule

result:
Hello
EmbedFire
010 + 0110 = 11

$write()

  • write() -- 输出打印信息 -- 函数不会自动进行换行
`timescale 1ns/1ns

module tb_test();
  reg [3:0] a;
  reg [3:0] b;
  reg [3:0] c;
  
  // initial只在仿真中使用,是不可综合的
  // 仿真开始,只执行一次
  initial begin
    $write("Hello");
    $write("EmbedFire");
    a = 4'd5;
    b = 4'd6;
    c = a + b;
    #100;
    $write("%b + %b = %d",a,b,c);
    
  end
endmodule

$strobe()

  • 输出打印函数 -- 在最后进行执行
`timescale 1ns/1ns

module tb_test();
  reg [3:0] a;
  reg [3:0] b;
  reg [3:0] c;
  
  // initial只在仿真中使用,是不可综合的
  // 仿真开始,只执行一次
  initial begin
    $strobe("strobe:Hello"); // 写在最前面,但是执行在最后
    a = 4'd5;
    $display("EmbedFire");
    $display("display:%b + %b = %d",a,b,c);  // 在执行这条语句的时候b,c都没有进行赋值
                                             // 所以b,c未知的x
    b = 4'd6;
    c = a + b;
    #100;
  
  end
endmodule

$monitor()

  • 检测变量,只要打印的变量发生了变化,就会执行一次
`timescale 1ns/1ns

module tb_test();

	reg [3:0] a;
	reg [3:0] b;
	reg [3:0] c;

	initial begin
		a = 4'd5;
		#100;
		b = 4'd6;
		#100;
		c = a + b;
	end

	initial begin
		$monitor("%b + %b = %d",a,b,c);
	end
endmodule

$stop

  • 暂停执行仿真
`timescale 1ns/1ns

module tb_test();
  initial begin
    $display("hello");
    $display("EmbedFire");
    #100;
    $display("Stop Simulation");
    $stop;
    #100;
    $display("Finish Simulation");
    $finish; // 结束仿真
  end
endmodule

$time

`timescale 1ns/1ns

module tb_test();
  reg [3:0] a;
  always #10 a = $random;  
  initial $monitor("a = %d @time %d",a,$time);
endmodule

$readmemb 和 $readmemh

  • $readmemb -- 用于读取二进制文件函数
  • $readmemh -- 用于读取十六进制文件函数
$readmemb("数据文件名",存储器名);
$readmemh("数据文件名",存储器名);
`timescale 1ns/1ns

module tb_test();

  integer i;
  reg [7:0] a [20:0]; // a 为宽度为8bit,深度为21bit的存储器
  
  initial begin
    $readmemb("EmbedFire.txt",a);
    for(i = 0;i<=20;i=i+1) begin
      #10;
      $write("%s",a[i]);  // Welcome to EmbedFire! 
    end
  end
endmodule

读取的文件
02-初识Verilog文章来源地址https://www.toymoban.com/news/detail-451938.html

到了这里,关于02-初识Verilog的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【雕爷学编程】MicroPython动手做(02)——尝试搭建K210开发板的IDE环境3

    4、下载MaixPy IDE,MaixPy 使用Micropython 脚本语法,所以不像 C语言 一样需要编译,要使用MaixPy IDE , 开发板固件必须是V0.3.1 版本以上(这里使用V0.5.0), 否则MaixPy IDE上会连接不上, 使用前尽量检查固件版本和IDE 版本,都更新到最新版以保障能正常使用。 https://cn.dl.sipeed.com/MAI

    2024年02月15日
    浏览(49)
  • 智芯MCU软件开发环境搭建

    智芯科技的MCU主要应用于汽车行业,属于车规级的MCU,目前上市的MCU型号较少,相关资料也不多,所以这里出一期开发环境搭建的教程给需要的朋友。 智芯MCU开发需要的软件主要是编译的IDE以及烧录工具。IDE可以用Keil uVision,也可以用IAR或者其他,本文只介绍Keil的搭建,所

    2024年02月11日
    浏览(44)
  • [Openwrt]一步一步搭建MT7981A uboot、atf、openwrt-21.02开发环境操作说明

    软件安装包 ubuntu-18.04-desktop-amd64.iso  sudo passwd [sudo] password for w1804:  Enter new UNIX password:  Retype new UNIX password:  passwd: password updated successfully sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup 将以下内容添加到sources.list文件

    2024年02月12日
    浏览(137)
  • 【FPGA Verilog开发实战指南】初识Verilog HDL-基础语法

    就是用代码来描述硬件结构 语言有VHDL与Verilog HDL Verilog HDL 是从C语言来的,学的快 ###例子 也叫保留字,一般是小写 module 表示模块的开始 endmodule 模块的结束 模块名 一般与.v文件的名字一致 输入信号 input 输出信号 output 既做输入也做输出 inout 需要一些变量和参数对输

    2024年02月21日
    浏览(45)
  • windows 下 搭建 ElasticSearch 环境,前端开发常用软件

    打开浏览器测试: http://localhost:9200 彻底关闭ES 第三步:将ElasticSearch安装为Windows服务 进入bin目录下执行命令: elasticsearch-service.bat install 在windows服务中查看 elasticsearch-service.bat后面还可以执行这些命令 install: 安装Elasticsearch服务 remove: 删除已安装的Elasticsearch服务(如果启动则

    2024年04月13日
    浏览(58)
  • Xilinx Alveo加速卡Vitis软件开发环境搭建

    本文主要介绍FPGA的软件开发方式,区别于传统使用HDL语言的硬件开发。软件开发无需学习复杂的硬件知识,使用C++即可开发,开发周期也大幅缩短到天为单位。 2021年第一次接触FPGA加速卡和OpenCL,当时开发环境还不友好,装完环境就花了一个月,给我折磨的不要不要的。AMD收

    2024年02月15日
    浏览(65)
  • keil5软件安装&开发环境搭建教程(mdk,c51通用)

    这是我在csdn上写的第一篇文章,心情激动兴奋。因为之前都是看别人写的博客,从来没想过自己去写一篇,在学长的鼓励下,尝试完成人生第一篇博客。仍有不足,希望大佬多多指正! 写这篇的目的是因为keil5的安装是许多人入门嵌入式的第一步,而且以后遇到许多不知名的

    2024年02月05日
    浏览(56)
  • ARM(IMX6U)嵌入式软件裸机开发之环境搭建与配置

    目录 前沿 Ubuntu 和 Windows 文件互传 Ubuntu 下 NFS 和 SSH 服务开启  Ubuntu 交叉编译工具链安装 Source Insight 软件安装和使用 Visual Studio Code 软件的安装和使用 为什么我们要学习裸机开发呢?         1、裸机开发是了解所使用的 CPU 最直接、最简单的方法,比如使用的 I.MX6U,跟

    2023年04月15日
    浏览(44)
  • 【初识Linux】:背景介绍以及环境搭建

    朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux的基础知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏: C语言:从入门到精通 数据结构专栏: 数据结构 个  人  主  页 : stackY、 目录 1. Linux背景介绍    

    2024年02月06日
    浏览(35)
  • vscode搭建Verilog环境

    最近实验室要做FPGA相关的工作,于是笔者开始自学相关技术。目前市面上最成熟的工具应该是VCS+Verdi,但是考虑到该工具链仅支持Linux,而且软件画面过于古早,安装和使用都过于冗杂,并且对新手来说学习成本实在太高。 因此我整理了各种资料,记录了本人使用vscode搭建轻

    2024年01月25日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包