Verilog中阻塞与非阻塞赋值对比及其高级结构详解

需积分: 31 2 下载量 81 浏览量 更新于2024-07-12 收藏 642KB PPT 举报
阻塞与非阻塞赋值是Verilog编程中的关键概念,特别是在描述数字逻辑系统的行为时。阻塞赋值(如`b = y`)在Verilog中是同步操作,它会等待当前时钟周期结束,然后将右侧表达式的值赋给左侧变量,这种模式下,`b`会在下一个时钟周期结束后更新。在模块`bloc`中,由于使用了阻塞赋值,其设计实际上等效于一个D型触发器,`y`作为中间寄存器,实现了数据的暂存。 相比之下,非阻塞赋值(如`b <= y`)是异步操作,它不会等待当前时钟周期结束,而是立即将右侧表达式的值赋给左侧变量,使得`b`和`y`几乎同时更新。在模块`nonbloc`中,由于使用了非阻塞赋值,实际上创建了两个独立的D型触发器,一个用于`y`,另一个用于`b`,这样`b`的更新就不会依赖于`a`的最新值,而是存储了上一个时钟周期的`y`值。 在Verilog中,结构化设计是提高代码组织和复用性的关键。模块化是通过任务(task)和函数(function)实现的,它们各自具有不同的用途和特点: - **任务(task)**:主要用于调试和行为描述,可以包含时序控制(如#延迟和@、wait),支持输入(input)、输出(output)和inout参数,以及调用其他任务或函数。在任务中,输入信号如`clk`不能作为任务输入,因为它们仅传输一次。任务定义了一个新的作用域,可以通过`disable`关键字禁用任务。 - **函数(function)**:用于计算或描述组合逻辑,不包含任何延迟,执行时间视为零。函数只能有输入参数,通过函数名返回一个结果,不能调用任务,但可以调用其他函数。 模块`top`中的例子展示了任务的使用,其中定义了一个时钟翻转任务`neg_clocks`,接受一个计数输入并根据这个计数在负时钟边沿执行相应的操作。在`initial`块中,任务被多次调用,以模拟不同时钟周期的行为。 理解阻塞与非阻塞赋值的区别,以及如何利用任务和函数进行模块化设计,是Verilog编程中至关重要的技能。在实际应用中,正确选择赋值方式和使用任务/函数结构可以极大地提高代码的清晰度和可维护性。