报错如下:(想看解决方法直接划到最下面,后面带有我个人的一点理解,提供给大家交流)
我原本的代码是:
想要实现的是对Q1的异步清零,不清零的情况出现上升沿就给Q1赋值。(后来发现这样逻辑是不对的就再后面加个end if;但是还是报错)单只从我以前学过的C语言逻辑来看,先判断完RST的IF,再去判断上升沿的IF这是没问题的。但实际上问题就出在这里,如果按这样做的话会把清零的语句当成并行赋值语句,这里我也不太明白为什么,只是当我删除掉IF RST='0' then这句话时报错也是一样的才有这个推论。
(说明一下,这个结论我已经排除了挺多情况,比如then后面是可以跟不止一句的赋值语句的,也确实是可以跟IF语句的,也就是IF 引导IF是可以的)下面这样的更改就可以编译通过:
接下来就是我的猜想了,望大佬指正:鉴于和并行语句报错一样,故我认为这是因为发生了线与,即进程结束后Q1有两个赋值源。猜测是每一个带时钟的边沿检测IF语句一定会产生一个赋值源,所以不能对带时钟的边缘检测IF里的数据放到另外的IF中
因此我这次debug最终得到的结论是:一旦出现时钟边沿检测,边沿检测里进行的对信号赋值操作,在时钟检测外面”不能”再操作。如果要操作有以下方法可以解决:(1)改为if elsif结构(我最终的解决方法)(2)或者放弃异步改为同步清零(3)避免对同一信号操作。
又琢磨了一下,发现其实我找到的只是表层的解决方法。这个方法对不同的代码可能起不到效果。因此这里给个通解,同时也算是对我前面分析的纠正(对的,前面分析确实不太对)
核心的思想应该是尝试将你的代码用自己的话描述一下,从中发现bug。
一是要明确好组合电路和时序电路的概念,时钟边沿检测是时序电路的(也就是同步操作),而异步操作是组合电路的。这里就出现了一个要明确的点:一旦出现了时钟检测,里面的信号就会变成一个寄存器。
二是就是对于这样的一个寄存器,从我们学到的数电知识可知,当输入时钟有效时输出值只能有一个。
三则是这个输出值得到的过程是一个黑盒子,可以在同步的情况下进行异步操作是因为这个异步操作最终也是输出一个同步值不影响时钟的同步赋值。但是如果在同步时钟操作外再进行异步操作就不行了--形象的理解是时钟检测里的信号随便你怎么操作,但是时钟检测里有的信号外面不能操作。
自此得到的通解与网络上能查询到的所有错误例子均能适用。一般解决方法就是删掉else,或者把逻辑并入elsif。希望对你能有所帮助。