Loading

P1-Verilog简单部件与状态机

通过本文,您的收获可能有:从课下部分,了解一些基本部件搭建时可能遇到的坑点,稍微深入一点理解两种状态机的区别;从课上测试部分,可以了解重点的考察内容,明白设计时状态机的类型在评测中可能遇到的问题。更优质的内容可以移步roife.github.io

省流助手:P1需要注意同步与异步复位的实现方法,两种状态机的代码模板,符号数及其运算的正确实现等问题。

课下测试部分:

课下测试主要考察了splitter的实现,ALU的实现,格雷码计数器的实现,扩位器的实现,以及合法表达式判别的有限状态机问题。本次课下部分比较简单,正好让下周工作量爆炸的我缓一口气。

1.splitter实现:

  实现的方式就是用拼接运算符(大括号)直接把信号拼起来。需要注意的一点是,如果发现提交之后是CE,那么一定要检查一下是不是交错了文件,以及,文件名是不是正确。神TMD知道我之前就写过一个叫spliter的东西,然后交上去了,后来反应过来好像日期对不上;接着我又交现在的,还是CE,过了好久我才反应过来:我文件名字拼写从很久之前起就是错的。真是要命的低级失误!考虑到课上测试的时候会有3分钟保护时间不让提交,所以这样的失误会耽误时间,也会很影响心情,一定要避免。

2.ALU的实现:

  关于如何将无符号数变成有符号数,请移步:https://blog.csdn.net/adaliu1998/article/details/80459262

  在verilog中运算时,如果同时出现有符号数和无符号数,有符号数会被处理为无符号数进行运算;所以当{hi,lo}不加signed时,$signed(A)的有符号化无效,仍然是作为无符号A

3.扩位器的实现:

  加强版的第一题,仍然利用拼接运算符即可。不会写if_else或者case的话还是最好回归课本,把前七章重新学一遍,会省很多事情。室友昨天因为case没有放在过程块always中,debug好久,这在课上可是耽误不得!熟悉基本语法很重要!可以通过hdlbits.01xz.net上的练习来熟悉语法。

4.格雷码计数器:

  也是属于语法回顾题,考察了case语句。坑点可能是reset忘记给overflow置零,或者是在溢出之后回到0的时候由于不合理的逻辑,导致overflow被误置为0。同步复位信号的always块的最开始只需要写always @(posedge clk)即可,如果加上了其他东西,比如写成了always @(posedge clk,clr)之类的,就不是同步复位了,有兴趣的可以单步调试一下,会发现出了意想不到的错误。另外,记得初始化(其实自己测试的时候应该就能想起来应该先初始化,不然会出现不定值)。

5.表达式状态机:

 

 

 

 

 

 

 

  这个状态机我考虑了四个状态:没有字符的empty状态,是合法表达式的yes状态,必定不是表达式的hopeless状态(比如上来就是个符号,或者途中出现连续数字,或者出现连续符号,更有甚者,出现题目要求之外的符号),还有希望是表达式的hope状态(比如从1变成1+的这种可以通过加数字变成合法表达式的情况)。状态想好之后,转移也比较容易能写出来了。不清楚评测数据有没有输入非法字符,为了稳重,还是要考虑0-9以及+*之外的字符。

  异步置位的写法:要clr为1,就要把状态置为0,另外,本题的数据是在时钟上升沿才会传过去的,综上可知,always应该写成always @(posedge clk,posedge clr),如果加了in的变化(always @(posedge clk,posedge clr,in)),也会出现上一个题中说到的意想不到的错误,可以自行尝试。//2019.10.21补充,为什么要在触发条件里面写posedge clr呢?因为我们要求异步复位,也就是说clr只要变为1,则从变成1的那一刻起就应该马上重置。如果把posedge clr写成了clr,在ISE语法检查的时候不会报错,在HDLBits上会CE,如果又干脆不写clr的变化,就成了同步复位,如图:

 

 

至于always @(posedge clk,posedge clr)与always @(posedge clk,clr)在ISE中波形的区别,这属于很细节的问题了,有意者可以自行设计testbench进行探索。

 

 

 

 

  本题我犯了一个很沙雕的错误:状态的编码采用独热编码是4位,但是我定义的state变量最开始是reg state;事实上应该是reg [3:0] state。这个地方如果错了,测试的时候会发现很多该变化状态的时候没有变化。以后一定要引以为戒啊!!!

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

备考P1阶段经验总结:

做了hdlbits.01xz.net上的问题:Lemmings2 ,以练习有限状态机的verilog实现,发现做该题的时候出现的问题蛮多,且十分典型,值得反省:

1.一个玄学问题:if-else报错但case没问题。这个问题出现在case中嵌套使用if-else时,至今也不知道为什么错了,只知道只要改成case就完全没问题。不管了

2.信号位数问题:这个问题在之前P1课下测试里面已经犯过了,这次犯得更难以发现一点:赋值时rightmove=3'b001写成了rightmove=001,然后就会出现以下报错:

 

 

 重要的是后两行报错信息。在ISE中并不会给出这种报错,而这个网站为了帮助学习给出了这个报错,才让我意识到可能是赋值时漏写了位数和进制。推荐把一些常用的数都声明成parameter型,然后仔细检查两遍parameter,仔细考虑一下各个parameter的命名怎样好,这样在以后赋值的时候就不会出现这种难以察觉的问题了。

3.reset。没错又是复位,这次不是不会同步异步,而是干脆没写。。。这个在自己做测试的时候还是容易发现的。

4.初始化是个好东西,希望你写的时候记得它。

5.verilog下的moore型与mealy型状态机:

具体如何去写,参见ISE模板(这几天见到的版本太多已经有些凌乱了)

用verilog的时候我没有明确区分过,因为我把所有的逻辑都集中在case里面了,这样很不好!还记得P0的时候有很多同学因为状态机的类型错误,吃了大亏,所以要慌,问题很大!之后两天的训练里面要试着把状态转移,状态保存和输出逻辑分开写。

考虑下面的状态机:(图片来自P1教程部分)

 

 猛的一看,这好像是个mealy型状态机,因为它写的代码看起来是输入和状态共同决定输出。但是,仔细想一下,如果现在是3状态,即state=3被存到了状态存储电路中,状态转移电路里面需要转换的是state=3与一个输入in,时钟上升沿时,in与状态转移电路里的state (=3)算出来一个新状态,然后,新状态瞬间传到了状态存储电路里面,在这一瞬间之后,状态存储电路就被锁死了不可变了,而我们的输出,就是由这时候被锁住的状态决定的。综上所述,这是一个moore型状态机(ISE模板中便是以这个给出的)

更新:关于mealy型状态机

Mealy型状态机的输出不仅仅在时钟上升沿时改变,而Moore型状态机的输出只在时钟上升沿时改变。所以模板中输出使用的assign

课上测试:

第一题:考察有符号数的比较,四位有符号数输入,输出较大的一个。有符号数输入的是补码。这个需要了解补码是怎么回事儿,正数的补码是本身,负数的补码是这个数除了符号位之外的位取反加1。考试的时候为了保险起见,我先写了一个简单的输入输出,写了一个tb,仿真了一下,把输出调成有符号数,嗯,的确是这个规则(突然变得有底气了)。然后就是比较了。这个先比符号位,比不出来再从高到低逐位比(不知道为什么题目不让用>,<,<=号)。写个tb试试各种情况即可。

经验:有不太确定的知识点可以利用工具进行一波验证,比如上次的算数右移(用Logisim自带移位器造输入输出看输出规律)和这次的原码补码。

第二题:又是卖东西的状态机,和p0的差不多,只是题目要求有点绕。注意退币的两种情况:输入2'b11或者大于等于2元。注意reset是异步复位,前面已经介绍过异步复位办法,所以总体不难写。读题多花点时间是应该而且有必要的,这个题的退币以及状态转移是需要仔细读题的,有时还需要仔细读题目给出的测试波形(本题的测试波形能读得和自己的理解一样的话,题意理解上就没什么问题了)。写代码时注意上面说的易错点,并做足下面的测试,有很大希望不用被卡等待时间。

经验:题意看不懂时,逐步分析题给波形。

第三题:正则表达式匹配(此处是幂函数的格式),和p1的差不多,就是状态有所增加(我写了9种,可能多了)。记忆版题面是匹配满足 ^[+-]?(\d+\*)?x(\^[+-]?\d+)? 的表达式。根据题意,从none开始,考虑下面几种输入:+,-,数字,^,x,*,即可逐步找到每个可能出现的状态。常数较多,写parameter比较好。

经验:建立状态机要慢,coding手速要快。

posted @ 2019-10-18 21:59  BUAA-Wander  阅读(2428)  评论(1编辑  收藏  举报