三、7【Verilog HDL】RTL建模——数据流建模

前言

参考书籍:《Verilog HDL 数字设计与综合》第二版,本文档为第6章的学习笔记。由于本章也讲述的建模方式。当电路较大时,Verilog支持用户从数据流的角度对电路进行建模。数据流建模意味着根据数据在寄存器之间的流动和处理过程对电路进行描述,而不是直接对电路的逻辑门进行实例引用。计算机可以通过辅助工具将数据流级转换成门级结构,这个过程也称为逻辑综合

在数字设计领域,RTL(Register Transfer Leveel,寄存器传输级)通常是指数据流级建模和行为级建模(下节会讲)的结合。

学习目标

  • 掌握连续赋值语句(assign)、对于连续赋值语句的限制及隐式赋值语句
  • 赋值延迟、隐式赋值延迟以及用于连续赋值语句的线网声明延迟
  • 定义表达式、操作符和操作数
  • 列表解释所有类型的操作符
  • 用数据流对实际数字电路进行建模

6.1 连续赋值语句

连续赋值语句必须以关键词assign开始,其语法如下:

continuous_assign ::= assign [drive_strength] [delay3] 
                            list_of_net_assignments;
list_of_net_assignments ::= net_assignment{ , net_assignment}
net_assignment ::= net_lvalue = expression

语法中:[drive_strength] 驱动强度是可选项,其默认值为strong1和strong0。

               [delay3]延迟值是可选项,可以指定延迟时间 " #10 "表示10单位的时间延迟

  • 连续赋值语句在左值必须是一个标量或向量线网(wire),或者是标量或向量线网的拼接,而不能是向量或向量寄存器(reg);
  • 连续赋值语句总是处于激活状态。只要任意一个操作数发生变化,表达式就会立即重新计算,并且讲结果赋值给等号左边线网;
  • 操作数(=号右边)可以是标量或向量的线网或者寄存器,也可以是函数调用;
  • 赋值延迟用于控制对线网赋值的时间,根据仿真时间单位进行说明。

连续赋值语句举例 

//连续赋值语句举例
//线网变量赋值
    wire out, i1, i2;
    assign out = i1 & i2;
//向量线网的连续赋值语句
    wire [15:0] addr;
    reg  [15:0] addr1_bits, addr2_bits
    assign addr[15:0] = addr1_bits ^ addr2_bits;
//拼接操作
    assign {c_out, sum[3:0]} = a[3:0] + b[3:0] + c_in;

6.1.1 隐式连续赋值

线网可以在声明变量的时候对其进行赋值,由于线网只能被声明一次,因此对线网的隐式赋值也只能有一次。下面进行举例:

//普通的连续赋值
    wire out;
    assign out = in1 & in2;
//使用隐式连续赋值语句
    wire out = in1 & in2;

6.1.2 隐式线网声明

如果一个信号名被用在连续赋值语句的左侧,那么编译器认为该信号是一个隐式声明的线网。

//连续赋值,out为线网型
    wire i1, i2;
    assign out = i1 & i2;

6.2 延迟

指定赋值延迟的方法有三种:普通赋值延迟、隐式赋值延迟、线网声明延迟

  • 普通赋值延迟

如果设置10个单位的赋值语句,即当等号右侧数值发生变化时,经过十个时间单位才进行赋值,即惯性延迟。当脉冲宽度小于赋值延迟的输入变化也不会对输出产生影响。

        assign #10 out = in1 & in2;

  • 隐式连续赋值延迟

        wire #10 out = in1 & in2;

  • 线网声明延迟

        wire #10 out;

6.3 表达式、操作符和操作数

和C语言类似理解,,因为后面会介绍,这里不详细介绍了。

6.4操作符类型

要分清逻辑运算符和按位运算符,分清等价运算符与赋值运算符。

6.5 数据流级建模举例

6.5.1 四选一多路选择器

 方法一:使用逻辑等式

//用数据流描述的四选一多路选择器模块,采用逻辑方程
//用来与门级描述的模型进行比较
module mux4_1(out, i0, i1, i2, i3, s1, s0);
    output out;
    input i0, i1, i2, i3;
    input s1, s0;
    
    assign out = (~s1 & ~s0 & i0)|
                 (~s1 & s0  & i1)|
                 (s1  & ~s0 & i2)|
                 (s1  & s0  & i3);
endmodule

方法二:使用条件操作符

//用数据流描述的四选一多路选择器模块,采用条件操作语句
//用来与门级描述的模型进行比较
module mux4_1(out, i0, i1, i2, i3, s1, s0);
    output out;
    input i0, i1, i2, i3;
    input s1, s0;
//采用嵌套的条件操作语句    
    assign out = s1 ? (s0 ? i3 : i2) : (s0 ? i1 : i0);
endmodule

6.5.2 四位全加器

方法一:数据流操作符

module fulladd4(sum, c_out, a, b, c_in);
    output [3:0] sum;
    output c_out;
    input [3:0] a,b;
    input c_in;
//指定全加器的功能
    assign {c_out, sum} = a + b + c_cin
endmodule

方法二:带超前进位的全加器

比较麻烦不建议使用

6.5.3 脉动进位计数器

程序块 

//边沿D触发器
module edge_dff(q, qbar, d, clk, clear);
    output q, qbar;
    input d, clk, clear;
    
    wire s, sbar, r, rbar, cbar;
    assign cbar = ~clear;
    assign sbar = ~(rbar & s),
            s = ~(sbar & cbar & ~clk),
            r = ~(rbar & ~clk & s),
            rbar = ~(r & cbar & d);
    assign q = ~(s & qbar),
            qbar = ~(q & r & cbar);
endmodule
//T触发器
module T_FF(q, clock, reset);
    output q;
    input clock,reset;
//调用边沿触发的D触发器
//输出q反向后到输入d
//由于qbar未用到,所以直接将其悬空不需要连接
    edge_dff edff(q,  , ~q, clock, reset);
endmodule

//顶层模块四位脉动计数器
module counter4(Q, clock, clear);
    output [3:0] Q ;
    input clock, clear;
    
    T_FF tf0(Q[0], clock, clear);
    T_FF tf1(Q[1], Q[0], clear);
    T_FF tf2(Q[2], Q[1], clear);
    T_FF tf3(Q[3], Q[2], clear);
endmodule

逻辑综合和后的RTL视图 

激励块

module tb_counter4();
    reg CLOCK, CLEAR;
    wire [3:0] Q;
    
    initial 
        $monitor($time, "count Q=%b, clear=%b", Q[3:0], CLEAR);
    counter4 c(Q, CLOCK, CLEAR);
    
    initial begin
        CLEAR = 1'b1;
        #200 CLEAR = 1'b0;
        #400 CLEAR = 1'b1;
        #60 CLEAR = 1'b0;
    end 
    initial begin 
        CLOCK = 1'b0;
        forever #20 CLOCK = ~CLOCK;
    end 
 /*    initial begin
        #400 $finish;
    end */
endmodule

总结

 关于Verilog HDL语言的其他内容请参考,本人Verilog专栏:

https://blog.csdn.net/arm_qiao/category_11744094.htmlhttps://blog.csdn.net/arm_qiao/category_11744094.html关于数字电路技术基础请参考专栏:

https://blog.csdn.net/arm_qiao/category_11744079.htmlhttps://blog.csdn.net/arm_qiao/category_11744079.html关于FPGA开发教程请参考专栏:

https://blog.csdn.net/arm_qiao/category_11744088.htmlhttps://blog.csdn.net/arm_qiao/category_11744088.html

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐者-桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值