Verilog电路设计思路

使用Verilog设计电路的一些思路

注意事项:

时序逻辑电路使用非阻塞赋值

组合逻辑电路使用阻塞赋值

组合逻辑电路

  • 概念:输出仅由当前的输入决定
  • 注意:不能蕴含触发器的逻辑,即==不具有记忆功能==(case语句的default子句、连续赋值语句、电平敏感的always语句)
  • 常见的组合逻辑电路:复用器、译码器、编码器、三态缓冲器、比较器、加法器、乘法器。
  • 实现方法:
    • 使用assign连续赋值语句(数据流级)和==电平敏感==的always行为语句(行为级)
    • 使用always引导的语句块实现对于中间变量的逻辑运算
    • 使用assign引导的连续赋值语句实现==简单变换和多路输出==(如果有的话)
    • 注意:always的使用的中间变量为reg型,assign和子模块使用的中间变量为wire型
  • 设计思路:
    • 给定==电路原理图==:使用门原语和模块实例
    • 给定布尔方程:使用连续赋值语句和==布尔运算==(真值表得到布尔方程)
    • 给定模块功能/IO(==真值表==):使用行为级描述(if/case配合真值表)
  • 可采用的设计模式:
    • assign连续赋值语句 + 条件表达式(?:) + 布尔运算
    • always语句块 + 条件表达式(?:)
    • always语句块 + 条件语句(if/case)
    • assign连续赋值语句 + 函数(function [automatic])可以在数据流语句中引入行为级语句逻辑
    • always语句块 + 函数(function [automatic])
    • always语句块 + 任务(task [automatic])
    • 建议不直接修改输出变量,而是使用中间变量,在输出时使用assign实现(综合好像能得到一个buf)

时序电路

  • 概念:输出由当前输入和内部的状态决定
  • 注意:具有记忆功能,内部包含==锁存器latch(电平敏感)和触发器flip-flop(边沿敏感)==等储存器件,case语句的default子句可以为空
  • 常见时序电路:锁存器latch、触发器flip-flop
  • 实现方法:
    • 使用always引导的语句块(电平敏感或边沿敏感)实现逻辑运算
    • 使用assign引导的连续赋值语句实现简单变换和多路输出(例如assign qbar=~q)
    • ==不能使用门原语==,门原语定义的时序电路不可综合(例如使用两个与非门实现的RS锁存器)
  • 时序逻辑:
    • 同步控制(复位/置位):
      • 只有在时钟信号的有效跳变沿状态才能改变
      • always的事件控制列表没有复位/置位信号
      • 语句块中先检查复位/置位信号,然后执行其他逻辑。使用嵌套的if-else可以控制复位/置位/输入逻辑的优先级(==复位>置位>其他逻辑==)
    • 异步控制(复位/置位):
      • 复位/置位信号激活时立即响应
      • always的控制列表中包括时钟边沿和复位/置位信号边沿
      • 语句块中先检查是时钟触发的还是复位/置位信号触发的,并执行相应的逻辑。使用嵌套的if-else指定优先级(==复位>置位>其他逻辑==)

可综合电路

  • 关键:使用Verilog HDL中的可综合子集
  • 可综合的Verilog HDL结构
    • 端口:input, inout, output
    • 参数:parameter
    • 模块定义:module
    • 信号和变量:wire, reg, tri 允许向量
    • 实例调用:module instance primitive gate instance
    • 函数任务:function, task 不考虑时序结构
    • 过程:always, if, then, else, case ==不支持initial==
    • 过程块:begin, end, named block, disable
    • 数据流:assign ==不考虑#延迟信息==
    • 循环:for, while, forever 需要包含@(posedge clock)或@(negedge clock)
  • 使用复位机制取代initial进行初始化
  • 赋值
    • 组合逻辑电路使用阻塞赋值=
    • 时序电路使用非阻塞赋值<=
    • 同时描述时序和组合逻辑使用非阻塞赋值<=
  • 编码风格
    • 有意义的信号和变量名
    • ==避免混合使用上升沿触发和下降沿触发==
    • 使用圆括号而不是运算优先级
    • 条件语句中说明所有的可能情况
    • 不要多个always对同一变量赋值

常见改错题思路

  • 变量类型错误
    • 注意input和output的端口类型检查
  • 变量位宽
  • 赋值方式
    • 阻塞赋值和非阻塞赋值
  • 敏感量列表
    • always的敏感量列表是电平触发还是边沿触发
  • 位运算/逻辑运算
Lei Yang
Lei Yang
PhD candidate

My research interests include visual speech recognition and semantics segmentation.