课下测试部分:
课下测试主要考察了splitter的实现,ALU的实现,格雷码计数器的实现,扩位器的实现,以及合法表达式判别的有限状态机问题。本次课下部分比较简单,正好让下周工作量爆炸的我缓一口气。
1.splitter实现:
实现的方式就是用拼接运算符(大括号)直接把信号拼起来作为答案。需要注意的一点是,如果发现提交之后是CE,那么一定要检查一下是不是交错了文件,以及,文件名是不是正确。神TMD知道我之前就写过一个叫spliter的东西,然后交上去了,后来反应过来好像日期对不上;接着我又交现在的,还是CE,过了好久我才反应过来:我文件名字拼写从很久之前起就是错的。真是要命的低级失误!考虑到课上测试的时候会有3分钟保护时间不让提交,所以这样的失误会耽误时间,也会很影响心情,一定要避免。
2.ALU的实现:
还没写,昨天讨论到一点,关于逻辑右移,有点晕了,等下明白了再写。
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)),也会出现上一个题中说到的意想不到的错误,可以自行尝试。
本题我犯了一个很沙雕的错误:状态的编码采用独热编码是4位,但是我定义的state变量最开始是reg state;事实上应该是reg [3:0] state。这个地方如果错了,测试的时候会发现很多该变化状态的时候没有变化。以后一定要引以为戒啊!!!