hdlbit刷后感

目录

Notgate

generate使用

bit位拼接

Module cseladd

阻塞赋值与非阻塞赋值

 多个if层次

Always case2

三目运算符

 exams/ece241_2014_q4

 exams/ece241_2013_q7

Edgedetect

Countbcd

Count clock

Shift18

 Exams/ece241 2013 q4

Lemmings1

Fsm serial

Exams/2014 q3fsm

Exams/2012 q2fsm

Exams/2013 q2afsm

 Exams/2013 q2bfsm


Notgate

!与 ~的区别,!是逻辑取反,~是按位取反;当操作数只有一位时才无区别;

其它逻辑门理解;

NOR(或非);全部0,则为1;

XNOR(同或);相异则为0,相同则为1;

XOR(异或);相异则为1,相同则为0;

这里需要明白的一个点是逻辑运算与按位运算之间的差别;

关于的按位运算的一些用法;

  1. 1.对单个数据进行“&”操作,判断是否全位为1,全1,则最后结果为1;
  2. 2.进行 “|”可以判断是否全0,全0则结果为0;
  3. 3.进行“^”可以由此可以判断为1的位数是奇数还是偶数;奇数个1则结果为1,偶数个则为0;

异或运算还可以比较两个值是否相等;a ^ b = 0;则代表a与b各bit位均相等,则a==b;并且异或判断的效率比直接判断a==b要快;

generate使用

在使用的时候需要提前声明一个genvar变量;后同过该变量进行次数的控制;注意红框中的需要写一个标识,另外就是该循环中只有一条语句也需要写begin_end;另外generate只是代码简化了,电路该有的还是有;

bit位拼接

需要将24用也用括号包起来;

Module cseladd

 

 典型的以面积换时间,不管你低位的进位是啥,我就先算好,低位算好后直接根据进位高低进行选就好;

阻塞赋值与非阻塞赋值

阻塞赋值可以理解成我就当前执行到,当前赋值结束后才会执行后续的语句,而非阻塞赋值则直接进入后面的语句,无需等到该赋值完成;

 多个if层次

如下代码;

在该代码中需要考虑的一个点是if中的条件,是分开还是合并;这里需要根据实际进行选择;正常是希望if语句的层次尽量的小些;(资源上就是对选择器和与门之间的选择);

Always case2

整个的理解就是case 只会把“?”认为是可以匹配任何值(0,1,x,z);casez会把“?”,“z”认为可以匹配任何值;casex会把“?”,“z”,“x”匹配任何值;

具体可以参考;【Arcanis the Omnipotent】从今天起弄明白case/casez/casex - poiu_elab - 博客园 (cnblogs.com)

 

case的其它玩法;

先将赋值语句写在前面,可以省略default语句;这里其实也体现了阻塞赋值的,后面的会把前面的覆盖掉;另外case语句中写default可以将值设置成‘bx;仿真时是一个不知道的状态,综合时会被忽略;

三目运算符

 三目运算符只是代码上看起来简练了很多,但是和分开写if语句资源上没差;所以没必要使用很复杂的嵌套三目运算符;

 exams/ece241_2014_q4

 

对应代码和电路图,可以明显的感受到电路的实现,第一个框框就是时钟之前组合逻辑的值,经过3个触发器到下一个时钟,后组合逻辑送出;可以看出电路计算其实都是组合逻辑,时序逻辑就是把上一次的组合逻辑的值保存下来了而已;

 exams/ece241_2013_q7

法一根据真值表,利用了3个选择器,和3个与门;

法二根据JK触发器方程式用了2个与门,2个非门,1个或门;

法二的面积应该会更优,从此可以看出不同的实现方式会决定电路的面积;

Edgedetect

边沿检测,就是去比较当前时刻的值与上一时刻值的一个区别;如果上一时刻为0,当前时刻为1,则为上升沿,以此类推,时序逻辑计算的会在下一拍体现;另外双边沿检测的话直接用异或就可以了; 

Countbcd

千位计数器;

 图有点不清楚,这里说下思路把;

先组合逻辑计算出ena,后根据ena来计算相应的位数;十位的ena根据的是个位计数是否达到9;百位的ena根据的是十位是否已经为9,并且此时还有进位;

Count clock

 

​ 可以参考​​​​​ HDLBits--(Verilog在线学习)--"105: Count Clock" - 知乎 (zhihu.com)

 对比该答案,觉得自己的top_down思想还不够强烈,对于比较大的模块,有top_down思想会清晰好多;模块的重用,也会使得代码简洁许多;

Shift18

左移右移操作符的优先级搞清楚,所以最好加上括号;另外就是算术右时补的是符号位; 

 Exams/ece241 2013 q4

 个人解答;

 根据水位定的状态,s1最低,s4最高;

参考答案;

对比不足;

  1. 参考答案将状态分的更加细节,后续输出的时候只需要考虑当前状态就可以,不需要考虑次态,相比之下本人写的就比较low了,需要根据次态,也就不算是一个moore状态机了;
  2. 参考答案进行状态转移的时候只需要考虑到s的特定比特位,更有状态转移的实际意义,如s不会直接从000->111;不像本人写的笼统的考虑全部bit位,但是这样可以确保传感器坏了的时候还可以正常;
  3. 输出端口将bit位合并进行赋值可以参考这种写法,代码看起来会简洁很多;
  4. 添加default为 ’x ,可以使得仿真没有复位前状态的一个未知情况,综合时会被忽略掉;

Lemmings1

本人答案;

比较简单,朝left只需考虑是否bump_left;撞了就换;同理右边也是;

另外看到网上有答案是将输入的bump合并成一个信号,后case中根据该信号进行选择;感觉没必要这样做,如上所说,朝左就考虑bump_left就够了,右边也是同理;

Lemmings4

对比参考答案思考;

  1. 其实差不多,但是不同的点是,cnt的计数条件使用的是nex_st,还是cur_st,其实这个core点,在空中时间刚刚好处于20个cycle时以上的代码是错的,因为此时结束了ground状态,但是cnt还没计数到20,就会导致不能正确跳到die状态;使用nxt做条件更加合理;在哪看到过一句话;时序逻辑用nxt_st,组合逻辑用cur_st,确实一般是这样;
  2. 另外一个是cnt的锁存,不锁存的话怕计数超出bit位,造成错误;

Fsm serial

在许多(较旧的)串行通信协议中,每个数据字节都与一个起始位和一个停止位一起发送,以帮助接收方将字节与位流分隔开来。一种常见的方案是使用一个起始位 (0)、8 个数据位和 1 个停止位 (1)。当没有任何内容被传输(空闲)时,该行也位于逻辑 1 处。

设计一个有限的状态机,该状态机将在给定位流时识别何时正确接收字节。它需要识别起始位,等待所有8个数据位,然后验证停止位是否正确。如果停止位未按预期出现,则 FSM 必须等到找到停止位后再尝试接收下一个字节。

法一;

 法二;

 

 解析:利用法一的话,代码简洁许多,不需要去新建一个cnt来进行计数,计数直接就在状态中体现了,法二中,需要注意的点,1.cnt的计数条件使用的是nxt_st,还是cur_st,这就会导致cnt的计数会差一拍,因为cnt的计数会影响data->stop情况,所以需要对应上;

关于状态机,比较想说的;

  1. 定好状态;
  2. 确定状态转移条件;
  3. 构建一些值的时候使用现态还是次态的后果需要清楚该值的时序;

Exams/2014 q3fsm

 

 解题思路:这边需要是根据状态来进行3个cycle中有几个w为1情况;我们要做的是到了三个cycyle后,s1状态需要根据cnt以及w同时决定次态;以此类推s2;但s0,s3状态无需考虑cnt,因为他们的次态只和w有关(读者可以试着考虑为啥);

代码如下;

对比网上其它答案:

(62条消息) [HDLbits]——Exams/2014 q3fsm_StevenHuang5v的博客-CSDN博客

该答主感觉思路会比较清晰,状态也就有两个,一个是不统计状态A,一个统计状态B;后用两个cnt来分别识别3个cycle和周期内w的个数;同样需要注意的点是cntr==3后赋值是1,不是0;因为3个cycle完了后马上跟着下一个周期;

对比感觉自己的好球复杂,还有那么多个状态,状态之间的跳转也需要进行思考,很容易出错,稍微哪里没思考清楚就错了;慢慢进步!!!

Exams/2012 q2fsm

 

 观察以上的状态图,和之前的状态转移图,发现只需要将输入的w进行取反再来进行状态转移就一致了所以直接复制之前的代码,并对w进行处理;

Exams/2013 q2afsm

 

 根据状态进行写就完事了;对比网上其它网友答案;

的这种写法,我觉得这种第二个elseif其实没必要将~r[1]加入,因为r[1]为真那第一个条件已经进去了,不会来到第二个,同理第三个elseif只需要保留r[3]即可;应该可以省几个与门;

 Exams/2013 q2bfsm

解答状态转移:

A:复位状态;

F:需要输出f;

S0:没有检测到匹配字;

S1: 匹配到1;

S10:匹配到10;

S101:匹配到101;

G0:第一次cycle时y=0;

G00:两个cycle,y都为0;

G1:两个cycle内y存在为1;

代码如下;

对比该网站答案:(62条消息) Exams/2013 q2bfsm_乔巴137的博客-CSDN博客

  1. 需要考虑是否用宏定义(主要考虑这边模块状态位会不会变)
  2. 是否使用独热码;(寄存器资源,效率等)
  3. 另外

建议改成:next_state[STRT_X_MNT] = state[AFT_RST] | (state[STRT_X_MNT] & x==0) |(state[X10] & x==0);

这样比较好懂一些,但是资源上好像上是变多了,还是收回我的建议吧;第一个只需要一个选择器和两个或门;

改了之后的需要 一个或门,两个与门,还有两个取反器;

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汶.z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值