仿真时间`timescale 1ns/1ps 的定义 延迟赋值与阻塞赋值非阻塞赋值的一个小问题

部分抄自李锐博恩博客:https://blog.csdn.net/Reborn_Lee/article/details/107888798

1.先再次说一下仿真时间`timescale 1ns/1ps 的定义

·timescale 定义仿真时间单位与精度,1ns是时间单位,即在仿真中用#10表示延迟10ns。1ps表示时间精度,比如你写 #3.5547968525 a <= 1;c <= 1;,那么它时间精度也只会有1ps(即在3.555ns时赋值语句便生效)。
在这里插入图片描述

2.最常见赋值间延迟语句

module top_module;
  reg  a, b, c, q;

  initial begin
    $monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);

    // Initialize all signals to 0 at time 0
    a <= 0;
    b <= 0;
    c <= 0;
    q <= 0;

    // Inter-assignment delay: Wait for #5 time units
    // and then assign a and c to 1. Note that 'a' and 'c'
    // gets updated at the end of current timestep
    #5  a <= 1;
    	c <= 1;

    // Inter-assignment delay: Wait for #5 time units
    // and then assign 'q' with whatever value RHS gets
    // evaluated to
    #5 q <= a & b | c;

    #20;
  end

endmodule

仿真结果
在这里插入图片描述
在这里插入图片描述
解读:0时刻结束时,a,b,c,q非阻塞赋值,全部被赋值为0;
延迟5ns结束后,a,c,非阻塞赋值,被赋值为1;
再延迟5ns结束时,q被非阻塞赋值。

Inter-assignment delay: Wait for #5 time units and then assign a and c to 1. Note that ‘a’ and ‘c’ gets updated at the end of current timestep
这是很基础的一句话,这句话说明了Verilog这门语言的基本特点,或者说Verilog中非阻塞赋值的基本特点,如下:

// Inter-assignment delay: Wait for #5 time units
    // and then assign a and c to 1. Note that 'a' and 'c'
    // gets updated at the end of current timestep
    #5  a <= 1;
    	c <= 1;

这条语句,在第5ns时候虽然给a与c均赋值了1,但是此刻并不生效,而会在当前时间步长结束时生效,例如,我们在此刻加一个语句,使用a与c的值:

  // Inter-assignment delay: Wait for #5 time units
    // and then assign a and c to 1. Note that 'a' and 'c'
    // gets updated at the end of current timestep
    #5  a <= 1;
    	c <= 1;
    	q <= a&c;

对上面这句话的理解可以是,在5ns这一时刻,将1这个值传递给a和c,但是传递总是需要时间的,而在5ns这一时刻,会捕获a&c的值,然后将这个值传递给q。捕获时还没来得及更新,自然是捕获的旧值。
在这里插入图片描述

3.赋值内延迟语句

module tb;
  reg  a, b, c, q;

  initial begin
    $monitor("[%0t] a=%0b b=%0b c=%0b q=%0b", $time, a, b, c, q);

	// Initialize all signals to 0 at time 0
    a <= 0;
    b <= 0;
    c <= 0;
    q <= 0;

    // Inter-assignment delay: Wait for #5 time units
    // and then assign a and c to 1. Note that 'a' and 'c'
    // gets updated at the end of current timestep
    #5  a <= 1;
    	c <= 1;

    // Intra-assignment delay: First execute the statement
    // then wait for 5 time units and then assign the evaluated
    // value to q
    q <= #5 a & b | c;

    #20;
  end
endmodule

在这里插入图片描述
在第5ns时候,a,b,q右边的值同时捕获,a和c在第5s被非阻塞赋值,也就是在第5ns末有效。
第5ns时,q值捕获到右边的表达式值,为0,然后再经过5秒,把这个0赋值给q.即q是在第5秒捕获到数据,但是在第10秒被赋值。
在这里插入图片描述

为了对比,我们在第5ns时,对a和c都进行阻塞赋值:
#5 a = 1;
c = 1;
q <= a & b | c;
在这里插入图片描述
#5 q <= a & b | c;
a = 1;
c = 1;
在这里插入图片描述
其实,阻塞赋值非阻塞赋值的本质区别就是。阻塞赋值,捕获完一个赋值一个,然后进行下一个,后面的赋值过程会被前一个堵住;而非阻塞赋值,全部同时捕获,然后同时赋值,赋值过程没有前后之分。
通过上面两个图,我们可以看出,当阻塞赋值,非阻塞赋值同时使用时,阻塞赋值会阻塞非阻塞赋值,非阻塞赋值内部还是同时捕获同时赋值。

#5 a = 1;
c = 1;
q <=#5 a & b | c;

在这里插入图片描述
这个的话,就是先阻塞赋值,将a,c进行赋值,然后同时在5ns这个时刻捕获q的值,然后再过5ns将这个值赋值给q。因为q的捕获被a,c的赋值过程给阻塞了,所以q捕获的是a,q的新值。

<think>嗯,用户想了解Verilog HDL中如何实现2选1多路选择器(MUX 2-1)模块。首先,我需要回忆一下MUX的基本功能。MUX 2-1有两个输入,一个选择信号,根据选择信号的值输出其中一个输入的数据。在Verilog中,实现这个功能有几种方法,比如使用条件运算符、if-else语句或者case语句。不同的方法可能在综合时产生不同的硬件结构,比如是否带有优先级或者并行结构,这可能需要参考一些资料中的编码风格。 根据用户提供的引用资料,特别是引用[2]中提到,Altera建议使用case语句代表并行多路选择器,而if-else if结构则代表带有优先级的。但这里的问题是实现一个简单的2-1 MUX,可能不需要复杂的优先级,所以条件运算符可能更简洁。例如,可以用assign语句配合三元运算符直接实现,这样代码既简洁又容易理解,综合后可能生成更高效的硬件。 另外,引用[3]中提到了在顶层模块中实例化多路选择器模块,并将开关和LED关联起来进行验证。所以在示例代码中可能需要包含模块的输入输出定义,比如两个输入a和b,一个选择信号sel,输出y。然后根据sel的值选择输出a或b。 需要注意的是,不同的编码风格可能导致不同的综合结果。例如,使用if-else语句可能会被综合成带有优先级的结构,但在这个简单的2选1情况下,可能和case或条件运算符效果相同。不过为了代码的清晰和可维护性,条件运算符可能更合适。 此外,引用[4]提到了定点数量化参数设计,虽然和MUX本身无关,但提醒我在代码中需要注意数据位宽的定义,确保输入输出的位宽一致,避免综合错误。因此,在代码示例中,应该明确指定输入输出的位宽,比如使用wire或reg类型,并考虑是否需要参数化设计,比如使用parameter定义位宽,增加模块的通用性。 最后,用户可能还关心如何验证这个模块的功能,比如通过testbench进行仿真,或者在实际的FPGA开发板上连接开关和LED进行测试。因此,在相关问题部分,可以提出关于验证方法、优化或扩展多路选择器的问题,帮助用户深入理解。</think>### Verilog HDL中MUX 2-1模块的实现 2选1多路选择器(MUX 2-1)是数字电路中的基础模块,用于根据选择信号(`sel`)在两个输入(`a`和`b`)之间选择输出(`y`)。以下是其实现方法及分析: --- #### 1. **基础实现方法** **方法一:条件运算符(三元运算符)** ```verilog module mux_2to1( input a, b, input sel, output y ); assign y = sel ? b : a; endmodule ``` - **说明**:通过三元运算符直接描述逻辑关系。当`sel=1`时输出`b`,否则输出`a`。 - **综合结果**:通常生成一个无优先级的并行多路选择器,硬件结构简单[^2]。 **方法二:`if-else`语句** ```verilog module mux_2to1( input a, b, input sel, output reg y ); always @(*) begin if (sel) y = b; else y = a; end endmodule ``` - **说明**:`if-else`语句隐含优先级,但在此简单场景中三元运算符等效。 --- #### 2. **关键设计考量** - **位宽定义**:若输入为多比特信号(如`input [3:0] a, b`),需统一位宽并扩展赋值逻辑。 - **资源优化**:对于复杂场景,可参考引用[4]中提到的并行/串行结构权衡,但MUX 2-1通常无需额外优化。 --- #### 3. **验证方法** 通过Testbench仿真或FPGA开发板验证功能: ```verilog module tb_mux_2to1; reg a, b, sel; wire y; mux_2to1 uut (a, b, sel, y); initial begin a = 0; b = 1; sel = 0; #10; // y = a sel = 1; #10; // y = b $finish; end endmodule ``` --- #### 4. **扩展应用** - **多级MUX**:通过级联实现更大规模选择器(如4-1、8-1)。 - **参数化设计**:使用`parameter`定义输入位宽,增强模块通用性: ```verilog module mux_2to1 #(parameter WIDTH=1) ( input [WIDTH-1:0] a, b, input sel, output [WIDTH-1:0] y ); assign y = sel ? b : a; endmodule ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值