米联客-FPGA程序设计Verilog语法入门篇连载-10 Verilog语法_一般设计规范

news2024/9/23 11:22:13

软件版本:无

操作系统:WIN10 64bit

硬件平台:适用所有系列FPGA

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

1概述

本小节讲解Verilog语法的一般设计规范,需要掌握时序或组合电路设计中需要注意的几点,掌握设计避免出现锁存器。

2设计规范

上一节课我们讲解了竞争与冒险,其实我们在编写代码中,多注意设计规范,能够减少大多数的竞争与冒险的问题。

在verilog编程时需要注意以下几点:

(1)时序电路建模时,用非阻塞赋值(<=)。

(2)锁存器电路建模时,用非阻塞赋值(<=)。

(3)用always和组合逻辑建模时,用阻塞赋值(=)。

(4)在同一个always块中建立时序和组合逻辑模型时,用非阻塞赋值(<=)。

(5)在同一个always块中不要既用阻塞赋值又用非阻塞赋值(<=)。

(6)不要在多个always块中为同一个变量赋值。

阻塞赋值“=”对应组合逻辑电路赋值,并且会阻塞后面的赋值操作,有先后顺序。非阻塞赋值“<=”对应时序逻辑电路赋值,所有非阻塞赋值操作在同一时刻进行赋值。

2.1 时序逻辑电路中,对寄存器用非阻塞赋值。

时序电路中使用非阻塞赋值可以有效消除竞争与冒险。

比如下面代码描述,由于无法确定 a 与 b 阻塞赋值的操作顺序,也就是实际延迟时间未知,就有可能带来竞争冒险。

always @(posedge clk)

begin

    a = b ;        //阻塞赋值,关键词“ = ”

    b = a ;        //阻塞赋值,关键词“ = ”

end

如果使用非阻塞赋值,两个赋值操作是同时进行的,因此就不会带来竞争冒险。例:

 always @(posedge clk) begin

    a <= b ;     //非阻塞赋值,关键词“ <= ”

    b <= a ;     //非阻塞赋值,关键词“ <= ”

end

2.2 组合逻辑电路中,对寄存器用阻塞赋值。

设计实现 C = A&B, F=C&D 的组合逻辑功能,也就是F= A&B&D,用非阻塞赋值语句设计如下。

always @(*)

begin

    C <= A & B ;  //非阻塞赋值,关键词“ <= ”

    F <= C & D ;  //非阻塞赋值,关键词“ <= ”

end

两条赋值语句同时赋值,F <= C & D 中使用的是信号 C 的旧值,因此导致此时的逻辑是错误的,F 的逻辑值不等于 A&B&D。

而且,此时要求信号 C 具有存储功能,但不是时钟驱动,所以 C 可能会被综合成锁存器(latch),导致竞争冒险。

对代码进行如下修改,F = C & D 的操作一定是在 C = A & B 之后,此时 F 的逻辑值等于 A&B&D,符合设计。

always @(*)

begin

    C = A & B ;  //阻塞赋值,关键词“ = ”

    F = C & D ;  //阻塞赋值,关键词“ = ”

end

2.3 同一个 always 块中建立时序和组合逻辑模型时,用非阻塞赋值。

在时序电路中常常可能会涉及组合逻辑,但是如果赋值操作使用非阻塞赋值,会可能导致出现问题。

例:

always @(posedge clk or negedge rst_n)

begin

    if (!rst_n) begin

        q <= 1'b0;     //非阻塞赋值,关键词“ <= ”

    end

    else begin

        q <= a || b;   //非阻塞赋值,关键词“ <= ”

     end

end

2.4 同一个 always 块中不要既使用阻塞赋值又使用非阻塞赋值。

always 语句涉及的组合逻辑中,既有阻塞赋值又有非阻塞赋值时,可能会导致意外的结果。例:

always @(*) begin

    C = A & B ;        //阻塞赋值,关键词“ = ”

    F <= C & D ;      //非阻塞赋值,关键词“ <= ”  ,不能同时使用

end

此时信号 C 阻塞赋值完毕以后,信号 F 才会被非阻塞赋值,结果可能正确。

如果 F 信号有其他的负载,F 的最新值并不能马上传递出去,数据有效时间还是在下一个触发时刻。此时要求 F 具有存储功能,可能会被综合成 latch,导致竞争与冒险。例:

always @(*)

begin

    C <= A & B ;         //非阻塞赋值,关键词“ <= ”

    F = C & D ;           //阻塞赋值,关键词“ = ”

end

信号 C 被非阻塞赋值,下一个触发时刻才会有效。而 F = C & D 虽然是阻塞赋值,但是信号 C 不是阻塞赋值,所以 F 逻辑中使用的还是 C 的旧值。

在时序电路里既有阻塞赋值,又有非阻塞赋值会怎样呢?例:

always @(posedge clk or negedge rst_n)

begin

    if (!rst_n)

begin 

        q <= 1'b0;       //非阻塞赋值,关键词“ <= ”

    end

    else 

begin

        q = a & b;       //阻塞赋值,关键词“ = ”

    end

end

假如复位信号与时钟同步,那么由于复位导致的信号 q 为 0,是在下一个时钟周期才有效。如果是信号 a 或 b 导致的 q 为 0,则在当期时钟周期内有效。假如 q 还有其他负载,就会导致 q 的时序特别混乱,显然不符合设计需求。

2.5 不允许在多个 always 块中为同一个变量赋值

Verilog语法中不允许在多个 always 块中为同一个变量赋值。如果这样做了,该信号拥有多驱动源,这种行为是禁止的。当然,也不允许 assign 语句为同一个变量进行多次连线赋值。从信号角度来讲,多驱动时,同一个信号变量在很短的时间内进行多次不同的赋值结果,就有可能产生竞争冒险。从语法来讲,很多编译器检测到多驱动时,也会报错的。

2.6 设计避免产生latch

Latch是锁存器,是一种对脉冲电平敏感的存储单元电路,它们可以在特定输入脉冲电平作用下改变状态。锁存,就是把信号暂存以维持某种电平状态。锁存器的最主要作用是缓存,其次完成高速的控制器与慢速的外设的不同步问题,再其次是解决驱动的问题,最后是解决一个 I/O 口既能输出也能输入的问题。锁存器是利用电平控制数据的输入,它包括不带使能控制的锁存器和带使能控制的锁存器。

如图所示:

触发器(flip-flop),是边沿敏感的存储单元,数据存储的动作(状态转换)由某一信号的上升沿或者下降沿进行同步的。

如图所示:

寄存器(register),在FPGA中用来暂时存放中间运算的数据和结果的变量。一个变量声明为寄存器时,它既可以被综合成触发器,也可能被综合成 Latch。但是大多数情况下我们希望它被综合成触发器,但是有时候由于代码书写问题,它会被综合成不期望的 Latch。

锁存器与触发器最大区别在于,锁存器是电平触发,而触发器是边沿触发。锁存器在不锁存数据时,输出随输入变化,但一旦数据锁存时,输入对输出不产生任何影响。

Latch 的主要危害有:

(1)输入状态可能多次变化,容易产生毛刺,增加了下一级电路的不确定性。

(2)在大部分 FPGA 的资源中,可能需要比触发器更多的资源去实现 Latch 结构。

(3)锁存器的出现使得静态时序分析变得更加复杂。

Latch 多用于门控时钟(clock gating)的控制,一般设计时,应当避免 Latch 的产生。

Latch 的产生主要有下面几种情况:

1、在组合逻辑中,不完整的if-else结构,会产生latch。

避免此类latch的方法主要有两种,一种是补全if-else结构,或者对信号赋初值。

但是在时序逻辑中,不完整的if-else结构,不会产生latch,这是因为,寄存器具有存储功能,且其值在时钟的边沿下才会改变。

2、 在组合逻辑中,当 case 选项列表不全且没有加 default 关键字,或有多个赋值语句不完整时,也会产生 Latch。

消除此种 latch 的方法也是 2 种,将 case 选项列表补充完整,或对信号赋初值。

补充完整 case 选项列表时,可以罗列所有的选项结果,也可以用 default 关键字来代替其他选项结果。

总之,为避免 latch 的产生,在组合逻辑中,需要注意以下几点:

1)if-else 或 case 语句,结构一定要完整;

2)不要将赋值信号放在条件判断中;

3)敏感信号列表建议多用 always@(*)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2038773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

照片回收利器:最新数据恢复软件推荐

照片回收利器&#xff1a;最新数据恢复软件推荐 在今天的数字化时代&#xff0c;我们将大量珍贵的照片和个人数据存储在电脑、手机和其他设备中。然而&#xff0c;由于各种原因&#xff0c;这些数据可能会意外删除或丢失&#xff0c;这对我们来说是一个巨大的损失。因此&#…

【Redis】List类型

目录 List列表 命令 LPUSH LPUSHX RPUSH RPUSHX LRANGE LPOP RPOP LINDEX LINSERT LLEN lrem ltrim lset 阻塞版本命令 BLPOP BRPOP 内部编码 使用场景 消息队列 分频道的消息队列 作为栈或者队列 List列表 列表类型是⽤来存储多个有序的字符串&…

5 大场景上手通义灵码企业知识库 RAG

大家好&#xff0c;我是通义灵码&#xff0c;你的智能编程助手&#xff01;最近我又升级啦&#xff0c;智能问答功能全面升级至 Qwen2&#xff0c;新版本在各个方面的性能和准确性都得到了显著提升。此外&#xff0c;行间代码补全效果也全面优化&#xff0c;多种编程语言生成性…

python-小理和他的猫(赛氪OJ)

[题目描述] 今天小理又要为他的猫小咪准备好吃的猫粮了&#xff0c;你愿意帮助一下他们么&#xff1f; 小理现在拥有的金钱数为 N &#xff0c;有 M 种小咪喜欢的猫粮从左到右排列&#xff0c;已知每种猫粮的价格 ai​ &#xff0c;他的购买规则如下&#xff1a; 1.必须按照从左…

数据结构与算法--图的存储与遍历

文章目录 回顾提要图的定义和表示图的表示完全图和子图顶点的度路径与回路连通图 邻接矩阵权和网 邻接表示例 深度优先遍历 (DFS)广度优先遍历 (BFS)广度优先遍历过程总结邻接矩阵存储结构邻接表存储结构 回顾 线索化二叉树&#xff1a;在某种次序遍历过程中创建线索&#xff…

简单数学运算(c语言)

1.描述 //牛牛最近学会了一些简单的数学运算&#xff0c;例如 //∑i1 ∑i 1 //请你帮他模拟一下这个运算。 &#xff08;即 1 2 3.... n - 1 n) //输入描述&#xff1a; //输入仅一个正整数 n //输出描述&#xff1a; //请你计算 //∑i1n 2.就是递归函数 方法一&#xf…

40.【C语言】指针(重难点)(E)

目录 13.指针的使用和传址调用 14.数组名的理解 *数组名就是数组首元素的地址 *两个例外 *使用指针访问数组 *一维数组的传参本质 往期推荐 承接上篇39.【C语言】指针&#xff08;重难点&#xff09;&#xff08;D&#xff09; 13. 指针的使用和传址调用 见29.【C语言】函数系…

Linux系统编程(9)

一、wait函数 1.wait函数 #include <sys/wait.h> pid_t wait(int *status);wait函数有两个作用&#xff1a; 1.获取子进程 的退出状态 当父进程要获取子进程的退出状态时&#xff0c;子进程里需要使用exit函数&#xff08;exit&#xff08;退出状态值&#xff09;退出…

10:【stm32】USART与串口通信一:USART(上)

USART&#xff08;上&#xff09; 1、串口通信1.1、简介1.2、数据帧1.2.1、简介1.2.2、校验规则1.2.3、停止位的长度 1.3、异步通信的波特率1.3.1、同步通信1.3.2、异步通信1.3.3、硬件流控 2、USART2.1、简介2.2、工作的原理2.3、相关寄存器 3、标准库编程3.1、编程接口USART_…

day16-测试自动化之selenium的PO模式

一、PO模式介绍 PO&#xff08;Page Object&#xff09;模式是一种在自动化测试中常用的设计模式&#xff0c;将页面的每个元素封装成一个对象&#xff0c;通过操作对象来进行页面的交互。 一般分为六个版本&#xff0c;现在大部分企业都用的V4版本&#xff0c;三层结构…

redis面试(十六)公平锁释放和排队加锁

锁释放 RedissonFairLock.unlockInnerAsync()方法 这和加锁的逻辑没有太大区别 也就是说在客户端A他释放锁的时候&#xff0c;也会走while true的脚本逻辑&#xff0c;看一下有序集合中的元素的timeout时间如果小于了当前时间&#xff0c;就认为他的那个排队就过期了&#xf…

Spring自动注册-<bean>标签和属性解析

xml文件中最常见也最核心的就是<bean>,<Import>,<beans>,<alias>标签,关于它们的解析主要是BeanDefinitionParserDelegate类中.<bean>标签的解析最为复杂和重要. <bean>标签 processBeanDefinition(ele, delegate)方法中,主要是是对…

数据库管理-Redis

数据库管理-Redis 一、关系型数据库和非关系型数据库1、关系型数据库&#xff08;Relational Database Management System, RDBMS&#xff09;&#xff1a;2、非关系型数据库&#xff08;NoSQL Database Management System&#xff09;&#xff1a; 二、redis简述 redis是把数据…

苦WPS云盘已久矣

主要因为软件更新后&#xff0c;设置位置都会跑到其他地方 打开wps客户端后&#xff0c;点击电脑底部任务栏的云朵图标。 2. 找到存储位置后&#xff0c;点击“更换位置”。 来自https://www.wps.cn/mlearning/question/detail/id/333165.html

Java | Leetcode Java题解之第328题奇偶链表

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode oddEvenList(ListNode head) {if (head null) {return head;}ListNode evenHead head.next;ListNode odd head, even evenHead;while (even ! null && even.next ! null) {odd.next even.nex…

编程学习笔记秘籍:开启高效学习之旅

引言&#xff1a; “计算机科学教育不能使人成为程序员&#xff0c;就像学画笔和颜料不能使人成为画家一样。”——埃里克雷蒙德。在当今数字化的时代&#xff0c;编程如同一把神奇的钥匙&#xff0c;能够打开无数机遇的大门。然而&#xff0c;编程知识的海洋广阔无垠&#xff…

正也科技:医药营销管理数字化建设的重要性及其迭代方向

第三届MAH合作与创新大会暨浙江省医药产业博览会于上周在杭州圆满结束。会议汇集了众多医药领域的专家、行业领袖和企业家&#xff0c;共同探讨医药行业的转型之路与实战经验。在中国医药新趋势分论坛&#xff0c;与会人员重点讨论了当前中国医药产业在新环境下所面临的挑战、变…

文心快码 Baidu Comate 前端工程师观点分享:行业现状(二)

本系列视频来自百度工程效能部的前端研发经理杨经纬&#xff0c;她在由开源中国主办的“AI编程革新研发效能”OSC源创会杭州站105期线下沙龙活动上&#xff0c;从一款文心快码&#xff08;Baidu Comate&#xff09;前端工程师的角度&#xff0c;分享了关于智能研发工具本身的研…

Hackademic.RTB1靶机复现

查看靶机的MAC地址 使用nmap进行扫描 使用dirsearch进行目录扫描 网站登录 点击紫色字体 进一步进行目录扫描 进行拼接 拼接wp-content 拼接wp-includes 点击Got root 测试发现不存在SQL注入 点击posted in Uncategorized 测试发现存在SQL注入 测试数据库 python sqlmap.py…

Linux-Shell三剑客grep,awk,sed-08

awk、grep、sed是linux操作文本的三大利器&#xff0c;合称文本三剑客&#xff0c;也是必须掌握的linux命令之一。三者的功能都是处理文本&#xff0c;但侧重点各不相同&#xff0c;其中属awk功能最强大&#xff0c;但也最复杂。grep更适合单纯的查找或匹配文本&#xff0c;sed…