Verilog基本代码结构及常用语句always、begin...end解读

这篇具有很好参考价值的文章主要介绍了Verilog基本代码结构及常用语句always、begin...end解读。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


在老板的要求下,我开始学习接触FPGA相关内容。而我们所用到的FPGA综合开发软件为vivado,虽然还没练习时长两年半,但也有一定的经验,接下来我把学习中遇到的问题记录如下,希望能帮助到刚入门的萌新。如果有一定的语言基础(例如c、matlab、Python等等),则搞懂以下问题,对于verilog语言的学习就会非常简单。

1.1 基本代码结构

在创建工程项目后,代码页面会自动生成如下语句(工程的创建及测试testbench等博主闲了再出教程敷衍大家)

module csdn(
//括号内为端口列表
    );
//此处为I/O说明
//内部信号声明(也可理解为中间变量声明)
//主要的代码功能定义
endmodule

我们的代码内容写在module…endmodule中,对于括号内应进行输入输出端口的定义,该定义和测试testbench中相对应。

括号外则进行变量的声明及相关代码的撰写。(具体内容如下例1.2)

1.2 简例

1.2.1 简单的与或非运算

module csdn(
    input a,
    input b,
    output  [5:0] y
//此处定义三个端口,a,b为两个一位的输入端口,y为一个六位的输出端口
//未定义位数则自动按一位
    );
	assign y[0] = a & b;
	assign y[1] = ~(a & b);
	assign y[2] = a | b;
	assign y[3] = ~(a | b);
	assign y[4] = a ^ b;
	assign y[5] = a ~^ b;
//此处assign声明语句
//此处为a,b的与 或 非 异或运算赋值到y的各个位中
endmodule

此程序为我接触verilog语言学习的第一个程序,很适合新手去当做入门仿真的练习。接下来还有一个程序,则为我的项目所涉及到的部分代码,此程序更偏向于应用,且更符合第一部分介绍的基本代码结构

1.2.2 线性反馈移位寄存器(此部分可在看懂always和begin后详细了解)

如下图,是为了方便讲解而手绘的简易六位线性反馈移位寄存器。其寄存器在每个时钟周期右移一位,即寄存器R0的1-5位移到2-6位,寄存器R0的第一位赋值为反馈值,该反馈值为寄存器第三位和第六位的异或值。其第六位在每个周期输出一次,该值记为code。其输入初值为L1C,该初值在程序开始时对寄存器R0进行赋值。
Verilog基本代码结构及常用语句always、begin...end解读
该线性反馈移位寄存器实现代码如下:(预告:接下来的程序测试testbench可能用这个程序来讲解)

module L1C(
        clk,
		work,
		l1c,
		code
//端口列表
    );
input clk;
input work;
input [5:0]l1c;
output code;
wire   code;  
//I/O端口说明
//此处的input output也可以写到括号内,看个人习惯,我习惯括号内声明端口,然后再去对I/O进行具体的说明  
reg  [5:0]r0; //寄存器RO
wire feedback; //反馈值
//中间变量定义
// -----------------------------------------------------------------------------------------------------
// ------------------------------Code Generator Part ---------------------------------------------------
// -----------------------------------------------------------------------------------------------------
always @(posedge clk) //此语句用法下文会讲,在这里主要看代码的结构
   begin
     if(!work)
   begin
     r0 <= l1c;
//对寄存器r0赋初值,初值l1c在testbench中会讲到
   end else
   begin
     r0 <= {r0[4:0],feedback};
//此处为上文讲解的移位和反馈操作
   end
   end
assign feedback = r0[2] ^ r0[5];  //反馈值
assign code = r0[5];              //输出值
endmodule

此程序如果有一定的基础,应该很简单,如果没有基础,则可以忽略其中的语法,继续往下看,下面将具体讲解其中always和begin…end的用法,而这里主要看代码的结构,其结构主要包括的即为1.1中所介绍的。

注:程序中的input值在testbench中输入。对于c、matlab中一般都直接赋值,或者通过读取指令进行赋值。此处可当做其需要读取,但其实际赋值过程在testbench中进行。

2.1 always 常用结构

此语句对于初学者可能是个麻烦,但其所完成的操作其实很简单,相当于一个判断语句,其可类比我们所熟悉的if语句,在if()语句中,其括号内的值为1(真)则执行其下面的语句。而对于always而言,其主要针对的是时钟,在硬件中,一般通过设置时钟进行操作,always则是判断你所设置的时钟,在时钟的上升沿或者下降沿进行其下面的语句。

always @()    

对于always而言最常用到的莫过于下面语句

always @(posedge clk or negedge rst)    
//异步复位 clk上升沿,rst下降沿 满足其中一个条件即开始执行
begin 
end

具体clk及rst的值可在测试端testbench中设定,testbench后续会教大家怎么创建

3.1 begin…end 用法解读

begin…end其实很好理解,在此语句中的程序顺序执行(begin语句算是verilog语言的一个习惯,在每个执行的语句前加上,养成好的习惯)

如果没有begin…end则对于多个语句而言,只会执行一个(相当于一个框,对于判断语句而言,框到的地方即为需要执行的地方)

具体如下

always @(posedge clk) //通过判断clk上升沿执行以下操作
begin
     r0 <= l1c;
     r1 <= l1c;
end
//在此语句中r0和r1的值都会随着l1c在不同的clk上升沿值变
always @(posedge clk)
     r0 <= l1c;
     r1 <= l1c;
//如果没有begin...end限制,则通过always判断后,只执行其下面一个语句
//当然在实际操作中这样肯定会报错,博主想表达的意思为,没有begin...end限制,其r1 <= l1c就不属于always中的语句了
//而普通的等式则需要用assign去定义,r1 <= l1c则可变成assign r1 = l1c

3.2 简例

我们用到的程序是1.2.2中我自己写的一个比较简单的反馈移位寄存器具体操作部分

always @(posedge clk) 
//clk上升沿执行always对应的下面begin...end中的语句
   begin       //此处begin对应最末尾的end
     if(!work) //如果work为0,则开始执行其begin...end中的语句,对r0进行赋值
   begin
     r0 <= l1c;//初值l1c在testbench中会讲到
   end else    //如果work为1则执行else下面的begin语句
   begin
     r0 <= {r0[4:0],feedback};//此处为移位反馈操作
               //r0的0-4位放在高位,r0的最低位为feedback值
   end
   end

每个begin对应一个end,相距最近的begin和end为一对,其程序的执行在一对begin…end中顺序执行

总结

硬件语言和软件语言大体差不多,如果认真学习过一门语言,我觉得想上手其他的语言将会非常简单,只是其定义和语法可能有一些差异。我对于verilog语言的学习源自于老板直接扔给我几千行的代码让我看,其代码很好懂,但仿真折磨了我许久。之后我会继续把仿真testbench过程做一个详细的讲解,但在仿真之前最好把1.2.2的线性反馈移位寄存器看懂(虽然不看懂也没啥影响,看懂的话可以明白其仿真中各个信号波形的含义)文章来源地址https://www.toymoban.com/news/detail-448406.html

到了这里,关于Verilog基本代码结构及常用语句always、begin...end解读的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • verilog always的用法

    目录 简介: 应用场景: 语法简介: 敏感列表的定义与作用:     always语句块从仿真0时刻开始执行其中的行为语句;最后一条执行完成后,再开始执行其中的第一条语句,如此往复循环,直到整个仿真结束。因此,always语句块常用于对数字电路中一组反复执行的活动进行建模

    2024年02月15日
    浏览(39)
  • Verilog中always @*

    ‘always @*’ 是 Verilog 中一种常用的敏感性列表的写法,它表示敏感于表达式中使用的所有信号。也称为“无条件敏感性列表”或“自动敏感性列表”。 这种写法的好处是可以让编译器自动检测敏感的信号,不需要手动列出敏感性列表,同时也可以避免遗漏信号。因此,使用

    2024年02月15日
    浏览(69)
  • (Verilog) wire和reg,以及always

    For combinational always blocks, always use a sensitivity list of (*). Explicitly listing out the signals is error-prone (if you miss one), and is ignored for hardware synthesis. If you explicitly specify the sensitivity list and miss a signal, the synthesized hardware will still behave as though (*) was specified, but the simulation will not and not matc

    2024年02月14日
    浏览(40)
  • Verilog Tutorial(5)使用always块实现时序逻辑电路

    在自己准备写verilog教程之前,参考了许多资料----FPGA Tutorial网站的这套verilog教程即是其一。这套教程写得不错,只是没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。 这是网站原文:https://fpgatutorial.com/verilog/ 这是系列导航:Verilog教程系列文章导航 这篇文

    2023年04月21日
    浏览(36)
  • 【Verilog HDL】FPGA-Verilog文件的基本结构

    🎉欢迎来到FPGA专栏~Verilog文件的基本结构 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ Verilog HDL系列博客参考书籍 《

    2024年02月04日
    浏览(82)
  • 【算法基础】java基础——基本结构、数据类型、表达式、语句

    Java程序的基本结构:         一段Java程序或者一个静态库,会用到下面7种语法         1、原始数据类型:在计算机程序中精确到定义整数、浮点数、布尔值等         2、语句:通过创建变量并对其赋值,它们能够被组合为类似数学公式定义的表达式         3、数组  

    2024年01月16日
    浏览(43)
  • case when then else end语句的用法

    case具有两种格式。简单case函数和case搜索函数。 --简单case函数             case sex             when \\\'1\\\' then \\\'男\\\'             when \\\'2\\\' then \\\'女\\\'             else \\\'其他\\\' end  --case搜索函数--经常用的是这个             case when sex = \\\'1\\\' then \\\'男\\\'  

    2024年02月10日
    浏览(68)
  • 分享一些常用的数据库结构表和字段语句(BI系统数据源部分可能会用到)

    获取该数据库的表(表名,行数,表注释) 获取该表的字段信息(字段名,字段类型,字段注释) 获取该数据库的表(表名,行数,表注释) 获取该表的字段信息(字段名,字段类型,字段注释) 获取该数据库的表(表名,行数,表注释) 获取该表的字段信息(字段名,

    2024年02月15日
    浏览(44)
  • 理解case when then else end 的使用,基础概念,建表语句,用例讲解

    case :表示需要处理的字段 when :表示条件 then :表示当when执行为true时,再执行的语句 else :表示当所有的when执行为false时,再执行的语句 end:表示 case 语句结束的结尾 图形化表格 执行sql语句 结果 讲解:进行匹配的是名字name,首先匹配第一行,name是等于张三,所以返回

    2024年02月08日
    浏览(64)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包