提示:这篇文章也在作者的博客上发布,协议为 CC BY-NC-ND 4.0。
依旧是在遇到了大量突发情况下惊险完成了P1,于是想着将我的想法与遇到的问题写下,期望能够对大家有些许的启发www~
T1:P1_L1_dotProduct_2023
题解:
法一:暴力大法好
应该有不少同学和我一样,考试中不确定for怎么写,直接ctrl+c
ctrl+v
写了32位的🤪🤪
硬要说有什么优化的话…vector_a和vector_b字数太长了,看着有点烦容易打错字,可以自己定义两个32位wire替代~
1 | wire [31:0] a; |
当然,你也可以在C或者Python或者JAVA(或者verilog)中打表来减少复制时间
1 | for (int i = 0;i < 32;i++) |
法二:for循环
在Verilog里写for循环优雅地解决问题当然是我们最提倡的方式
一般来说,verilog里的for循环可以这么写
1 | integer i; |
将进行位运算的步骤放进for循环里,很轻松就可以求解问题
T2:P1_L4_coloring_2023
题解:
本题有两种设计状态的方式:
用一个变量存储当前状态
当前序列 编码 无颜色 000 红 001 红红 010 绿 011 绿绿 100 蓝 101 蓝蓝 110 用两个变量存储当前状态
当前颜色 当前数量 无颜色 0 红 1 2 绿 1 2 蓝 1 2
从状态数上,两种方法差不多,但在实际编程中,第二种表示方法由于可以用if合并一些情况的处理方式,也许会稍微快一点
下面以方法二模式列出代码
1 | reg [1:0] now; //当前颜色 |
有以下两点需要注意一下:
- 本题为异步复位,且为低电平有效,假如实在想不起来
negedge
,就只能试试用组合逻辑实现清零操作了(据说有佬成功了orz) - 在初始化的时候,不建议把颜色清成0,否则当下一个输入1的时候电路就会出错。解决办法为特判一下或者一开始就把颜色清成2,这样就不会和任何输入冲突。(因为这个挂了好几次~😿)
T3:numberNest
题意:
定义两个相同数字之间的部分为“数字匹配”,对于数字匹配,有以下要求:
- 一个数字的匹配中的数字必须比这个数大,如123321是合理的,而121121是不合理的
- 一个数字匹配的下一个数字只能比这个数字大1,如1234444321是合理的,而1331是不合理的
输入:串行输入的数字序列
输出:当前输入的序列是否合理,合理输出0;不合理输出1,并将当前序列清空
(由于记忆问题,题目描述可能有略微区别,还请大家多多谅解www~)
题解:
本题依旧有两个解法:
法一:状态机大法
题目对数据限制了最多为5,据此可以列出状态机
相信一定会有别的大佬详细讲解这种方法的,我就不献丑啦🎶~
法二:两个if法
定义一个状态state,为当前正在进行匹配的数字,如123的state为3,122的state为1,空串的state为0
不难发现,在任何情况下,我们的合理输入(用in表示)只有两种:
in = state + 1
序列开始了下一个匹配,需要将state加一
in = state
序列结束了当前匹配,需要将state减一
(这么说可能稍微有点抽象,大家可以自己构造几个数据跑一跑)
相反,只要不满足上面的情况,就说明序列不合理
我们可以简单地写出代码
1 | reg [2:0] state; |
这种方法的优点在于代码比较短,可拓展性比较好(指对数据范围的依赖小)
总结:
本次考试的三个题目,并没有简单地考查状态机或组合电路等基本知识,而是要求考生对Verilog编程语言具有较深刻的理解和熟练掌握,才能较为轻松地解决。
同时,本次考试加大了对测试块(TB)编写的要求,对于P4及以后的练习,很可能会出现不编写测试块就无法解决的问题。愿我们都能在此之前武装到牙齿,能够从容面对即将到来的挑战~