ASIC-WORLD Verilog(5)基础语法下篇

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

写在前面

        在自己准备写一些简单的verilog教程之前,参考了许多资料----asic-world网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。

        这是网站原文:http://asic-world.com/verilog/veritut.html

        这是系列导航:Verilog教程系列文章导航

模块(Modules)

  • 模块是verilog设计的基本组成形式
  • 你可以在模块中调用别的模块来实现层次化设计

        

        在下面的图片中可以看到:

  • 顶层模块分别由左、右上、右下三个子模块构成
  • 左边的模块由4个子模块组成;而右边的两个模块又分别由两个更小子模块组成

ASIC-WORLD Verilog(5)基础语法下篇

端口(Ports) 

  • 端口是不同模块间实现通讯的渠道
  • 除了顶层模块外的所有层级的模块都有端口(其实最顶层的模块也有端口,不过由于其一般连接到FPGA的管脚,所以一般叫Pins)
  • 端口间的例化有两种方式:顺序端口例化、命名端口例化

       

        像下面示例这种一行只声明一个端口的方式是个不错的编码习惯。

input              clk       ; // 时钟输入
input  [15:0]      data_in   ; // 16位数据输入总线
output [7:0]       count     ; // 8位计数器输出
inout              data_bi   ; // 双向数据总线

        下面请看一个全加器的示例代码:

//这是一个加法器示例
module addbit (
	a      , // 输入a
	b      , // 输入b
	ci     , // 进位输入
	sum    , // 加法结果输出
	co       // 进位输出
);

//输入声明
input a;
input b;
input ci;

//输出声明
output sum;
output co;

//端口的数据类型
wire  a;
wire  b;
wire  ci;
wire  sum;
wire  co;

//主代码部分
assign {co,sum} = a + b + ci;

endmodule // End of Module addbit

端口例化方法

        前面说了模块的例化有两种方法:顺序端口例化与命名端口例化。接下来分别看下这两种方法是如何使用的:

(1)顺序端口例化

        这种方法将需要例化的模块端口按照模块声明时端口的顺序与外部信号进行匹配连接,位置要严格保持一致。这种方法在增加或减少端口时会特别容易导致BUG,所以我个人不建议使用该方法。

        这是对上面提到的全加器模块的例化:

module adder_implicit (
result        , // Output of the adder
carry         , // Carry output of adder
r1            , // first input
r2            , // second input
ci              // carry input
);

// 输入端口声明      
input    [3:0]   r1         ;
input    [3:0]   r2         ;
input            ci         ;

// 输出端口声明
output   [3:0]  result      ;
output          carry       ;

// Wires端口
wire     [3:0]    r1        ;
wire     [3:0]    r2        ;
wire              ci        ;
wire     [3:0]    result    ;
wire              carry     ;

// 内部变量
wire              c1        ;
wire              c2        ;
wire              c3        ;

// 多次例化,按顺序
addbit u0 (
r1[0]           ,
r2[0]           ,
ci              ,
result[0]       ,
c1
);
//按顺序例化
addbit u1 (
r1[1]          ,
r2[1]          ,
c1             ,
result[1]      ,
c2
);
//按顺序例化
addbit u2 (
r1[2]          ,
r2[2]          ,
c2             ,
result[2]      ,
c3
);
//按顺序例化
addbit u3 (
r1[3]          ,
r2[3]          ,
c3             ,
result[3]      ,
carry
); 

endmodule // End Of Module adder 

(2)命名端口例化

        这种方法将需要例化的模块端口与外部信号按照其名字进行连接,端口顺序随意,可以与引用 module 的声明端口顺序不一致,只要保证端口名字与外部信号匹配即可。这种方法非常灵活,我个人强烈建议使用该方法。

        这是对上面提到的全加器模块的例化:

      

module adder_explicit (
	result        , // Output of the adder
	carry         , // Carry output of adder
	r1            , // first input
	r2            , // second input
	ci              // carry input
);

// 输入端口声明         
input    [3:0]   r1         ;
input    [3:0]   r2         ;
input            ci         ;

// 输出端口声明
output   [3:0]  result      ;
output          carry       ;

// Wires端口
wire     [3:0]    r1        ;
wire     [3:0]    r2        ;
wire              ci        ;
wire     [3:0]    result    ;
wire              carry     ;

// 内部变量
wire              c1        ;
wire              c2        ;
wire              c3        ;

// 多次例化,按对应名称
addbit u0 (
.a           (r1[0])        ,
.b           (r2[0])        ,
.ci          (ci)           ,
.sum         (result[0])    ,
.co          (c1)
);

addbit u1 (
.a           (r1[1])        ,
.b           (r2[1])        ,
.ci          (c1)           ,
.sum         (result[1])    ,
.co          (c2)
);

addbit u2 (
.a           (r1[2])        ,
.b           (r2[2])        ,
.ci          (c2)           ,
.sum         (result[2])    ,
.co          (c3)
);

addbit u3 (
.a           (r1[3])        ,
.b           (r2[3])        ,
.ci          (c3)           ,
.sum         (result[3])    ,
.co          (carry)
);

endmodule // End Of Module adder

端口连接规则

        Verilog中的端口连接规则是这样的:

  • 输入端口:内部必须是net,外部可以是net也可以是reg
  • 输出端口:内部可以是net也可以是reg,外部必须是net
  • 双向端口:内部和外部都只能是net
  • 位宽匹配:将位宽不同的内部和外部信号连接到一起是合法的。但是要注意,综合工具可能会报告警告或错误

  • 悬空端口:悬空端口可以使用","(顺序端口例化); 悬空端口也可以直接空着(命名端口例化)

ASIC-WORLD Verilog(5)基础语法下篇

        下面的例子展示了两种例化方法是如何处理悬空端口的:

module exam();
reg clk,d1,d2,rst,pre1,pre2;
wire q1,q2;

//顺序端口例化时,悬空的信号用","
dff u1 ( q1,,clk,d1,rst,pre1); 

//命名端口例化时,悬空的信号直接控制
dff u2 (  
	.q  	(q2),
	.d 		(d2),
	.clk 	(clk),
	.q_bar 	(),
	.rst 	(rst),
	.pre 	(pre2)
);

endmodule

// D fli-flop
module dff (q, q_bar, clk, d, rst, pre);
input clk, d, rst, pre;
output q, q_bar;
reg q;

assign q_bar = ~q;

always @ (posedge clk)
	if (rst == 1'b1) begin
	  q <= 0;
	end else if (pre == 1'b1) begin
	  q <= 1;
	end else begin
	  q <= d;
	end

endmodule

模块的层次结构

        由于模块之间具备的层次结构,所以可以使用名称索引的方式来找到不同模块的信号。

        示例:下面的adder_hier模块内4次调用了子模块addbit,将其分别例化为u0、u1、u2和u3。

module adder_hier (
	result        , // Output of the adder
	carry         , // Carry output of adder
	r1            , // first input
	r2            , // second input
	ci              // carry input
);

// Input Port Declarations       
input    [3:0]   r1         ;
input    [3:0]   r2         ;
input            ci         ;

// Output Port Declarations
output   [3:0]  result      ;
output          carry       ;

// Port Wires
wire     [3:0]    r1        ;
wire     [3:0]    r2        ;
wire              ci        ;
wire     [3:0]    result    ;
wire              carry     ;

// Internal variables
wire              c1        ;
wire              c2        ;
wire              c3        ;

// 调用addbit子模块
addbit u0 (r1[0],r2[0],ci,result[0],c1);
addbit u1 (r1[1],r2[1],c1,result[1],c2);
addbit u2 (r1[2],r2[2],c2,result[2],c3);
addbit u3 (r1[3],r2[3],c3,result[3],carry);

endmodule // End Of Module adder

        下面的代码展示了如何使用子模块内的信号:

module tb();

reg [3:0] r1,r2;
reg  ci;
wire [3:0] result;
wire  carry;

// Drive the inputs
initial begin
  r1 = 0;
  r2 = 0;
  ci = 0;
  #10 r1 = 10;
  #10 r2 = 2;
  #10 ci = 1;
  #10 $display("+--------------------------------------------------------+");
  $finish;
end

// Connect the lower module
adder_hier U (result,carry,r1,r2,ci);

// Hier demo here
initial begin
  $display("+--------------------------------------------------------+");
  $display("|  r1  |  r2  |  ci  | u0.sum | u1.sum | u2.sum | u3.sum |");
  $display("+--------------------------------------------------------+");
  $monitor("|  %h   |  %h   |  %h   |    %h    |   %h   |   %h    |   %h    |",
  r1,r2,ci, tb.U.u0.sum, tb.U.u1.sum, tb.U.u2.sum, tb.U.u3.sum); //这里分别展示了4个子模块的sum信号
end

endmodule

        代码中的   tb.U.u0.sum, tb.U.u1.sum, tb.U.u2.sum, tb.U.u3.sum  分别是4个子模块的内部信号sum,它们是不同的信号,只是名称相同。这种方法在调试时很有用。文章来源地址https://www.toymoban.com/news/detail-416788.html


  • 📣您有任何问题,都可以在评论区和我交流📃!
  • 📣本文由 孤独的单刀 原创,首发于CSDN平台🐵,博客主页:wuzhikai.blog.csdn.net
  • 📣您的支持是我持续创作的最大动力!如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!

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

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

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

相关文章

  • ASIC-WORLD Verilog(3)第一个Verilog代码

            在自己准备写一些简单的verilog教程之前,参考了许多资料----asic-world网站的Verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。         这是网站原文:Verilog Tutorial         这是系列导航:Verilo

    2023年04月16日
    浏览(37)
  • ASIC-WORLD Verilog(11)过程时序控制

            在自己准备写一些简单的verilog教程之前,参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。         这是网站原文:Verilog Tutorial         这是系列导航:

    2024年02月14日
    浏览(35)
  • ASIC-WORLD Verilog(10)编写测试脚本Testbench的艺术

            在自己准备写一些简单的verilog教程之前,参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。         这是网站原文:Verilog Tutorial         这是系列导航:

    2024年02月07日
    浏览(36)
  • ASIC-WORLD Verilog(8)if-else语句和case语句

            在自己准备写一些简单的verilog教程之前,参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。         这是网站原文:Verilog Tutorial         这是系列导航:

    2024年02月01日
    浏览(46)
  • 【Verilog】二、Verilog基础语法

    文章目录 前言 一、简单的Verilog知识 1.1、Verilog端口定义 1.2、Verilog的标识符 1.3、Verilog的逻辑值 1.4、Verilog的数字进制 1.5、Verilog的数据类型 1.5.1、reg型         1.5.2、wire型 1.5.3、参数类型 1.6、Verilog的运算符 1.6.1、算术运算符 1.6.2、关系运算符 1.6.3、逻辑运算符 1.6.4、条件

    2023年04月09日
    浏览(35)
  • Verilog 基础知识(一) Verilog 基础语法与注意事项

            Verilog中的module可以看成一个具有输入输出端口的黑盒子,该黑盒子有输入和输出接口(信号),通过把输入在盒子中执行某些操作来实现某项功能。(类似于C语言中的函数) 图1  模块示意图 0.1.1 模块描述 图1 所示的顶层模块(top_module)结构用Verilog语言可描述为: 模块

    2024年02月03日
    浏览(41)
  • Verilog 基础语法(题目)

    **本内容来自 牛客网Verilog基础语法** 1、四选一多路器 制作一个四选一的多路选择器,要求输出定义上为线网类型 状态转换: d0 11 d1 10 d2 01 d3 00 信号示意图: 波形示意图: 输入描述: 输入信号 d1,d2,d3,d4 sel 类型 wire 输出描述: 输出信号 mux_out 类型 wire 2、异步复位的串联

    2024年02月11日
    浏览(38)
  • verilog语法基础

      现在,我们已经通过了流水灯、按键控制led灯、按键控制蜂鸣器、状态机等项目的训练,对Veriolg也有初步的认识,但是我们没有系统的学习Verilog语法。相信你也遗留了很多关于Verilog的诸多问题,不用着急,本文将根据前期课程的实训内容,来学习Verilog语法。   硬件

    2024年02月05日
    浏览(36)
  • FPGA | Verilog基础语法

    菜鸟教程连接 举例(\\\"//\\\"符号后的内容为注释文字): initial $dumpfile (“myfile.dump”); //指定VCD文件的名字为myfile.dump,仿真信息将记录到此文件 可以指定某一模块层次上的所有信号,也可以单独指定某一个信号。 典型语法为$dumpvar(level, module_name); 参数level为一个整数,用于指

    2024年02月05日
    浏览(49)
  • 深入浅出学Verilog--基础语法

            Verilog的语法和C语言非常类似,相对来说还是非常好学的。和C语言一样,Verilog语句也是由一连串的令牌(Token)组成。1个令牌必须由1个或1个以上的字符(character)组成,令牌可以是: 注释(Comment) 空白符(White space) 运算符(Operator) 数字(Number) 字符串(

    2024年02月09日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包