当前位置:   article > 正文

电力电子转战数字IC20220524day8——模三检测器_模三检测器模三检测器的实质是一个判断输入序列的序列检测器,一个输入被三除,

模三检测器模三检测器的实质是一个判断输入序列的序列检测器,一个输入被三除,

这里看的时候并不能理解,找了几篇别人的文章综合看完才想明白原理。

1.原理:首先明确的是,任何一个数除以3只能得到3个余数,0,1,2。此时的数字表示为

3a+b=c,b是余数,c是被除数。

检测完c后,序列向左移动,进来一个新的数如果是0,此时c变成了2c!

(这里可以这样理解:如果c是十进制的2,左移1位后就变成20=2*10,因为十进制是缝10进位,多1位就多1个进制的倍数,原来的个位2相当于被进了一次位变成了十位,而个位由新进来的0补上,所以二进制的假设为01进位10,1变成了2^1位,新进来的0为2^0位,c就变成了2c。)

序列向左移动,进来一个新的数如果是1,此时c变成了3a+b+1,也就是原来的余数再+1。

那么,假设新进来的是0:

当b=0,原来的3a*2=2c,依然可以被整除,所以余数还是0,输出1。

当b=1,新的数变成3a*2+1*2=2c,相当于余数翻倍变成2,输出0.

当b=2,新的数变成3a*2+2*2=2c,相当于余数翻倍变成4,新的余数是1,输出0.

那么,假设新进来的是1:

当b=0,原来的3a*2=2c+1,余数变成1,输出0。

当b=1,新的数变成3a*2+1*2+1=2c+1,余数变成0,输出1.

当b=2,新的数变成3a+2*2+1=2c+1,余数2变成5,新的余数是2,输出0.

总结成表格如下,当前余数用state,新的余数用nextstate

当前余数对应状态输出输入的数a新的余数对应状态新的输出
0

zero

100zero1
1one002two0
2two004(1)one0
0zero111one0
1one010zero1
2two015(2)two0
画成状态图为

 

  1. //模三检测器
  2. //目的:判断输入序列能否被三整除,能的时候输出1,不能的时候输出0
  3. //逻辑:不管一个数是多少位都对应一个十进制整数,任何数除以3必然可以得到3个余数。整除时得到的余数是0,不能整除时得到的余数是12
  4. module mo3 (clk,rst,a,result);
  5. input clk,rst,a;
  6. output result;
  7. reg [2:0] state,nextstate;
  8. //定义状态
  9. parameter idle=3'd0,one=3'd1,two=3'd2,zero=3'd3;
  10. //先写每个时钟沿产生一次可能的状态变化
  11. always@ (posedge clk or negedge rst)
  12. if(!rst)
  13. state<=idle;
  14. else state<=nextstate;
  15. //产生下一个状态的组合逻辑
  16. always@(*)
  17. begin
  18. case(state)
  19. idle: nextstate= a? one:zero;
  20. one: nextstate= a? zero:two;
  21. two: nextstate= a? two:one;
  22. zero: nextstate= a? one:zero;
  23. default state<=3'dx;
  24. endcase
  25. end
  26. assign result= (state==one)? 1:0;
  27. endmodule
  1. `timescale 1ns/1ps
  2. module mo3test;
  3. reg clk,rst;
  4. reg a;
  5. wire result;
  6. mo3 t1(.clk(clk), .rst(rst), .a(a), .result(result));
  7. always #5 clk=~clk;
  8. always #9.99 a=$random;
  9. initial
  10. begin
  11. clk=0;rst=1;
  12. #5 rst=0;
  13. #10 rst=1;
  14. #1000 $stop;
  15. end
  16. endmodule

 到点了,感觉不太对。先回家,女朋友等了一晚上。

——————————————————————————————————————————

感谢华为树枝江哥的指导,记录在此,作为接下来的准则。

1,if后和always块都要用begin end
2,输出的信号一般用reg,就是寄存器打一拍,这样给其他模块,降低组合逻辑,时序会好很多,
3,default不要写x态,不确定,让他会到idle状态就好了,状态机保证异常条件下不会挂死,能跳出异常回到idle既可
4,default信号名错了,组合逻辑是用阻塞写法

5,定义一个信号定义一行,不要写一齐

6,代码尽量对齐

7,组合逻辑用阻塞赋值=,时序逻辑用非阻塞赋值<=

8,这种inital task function都是仿真的,逻辑代码不要出现,你代码想要信号有初始值,把他写在复位的分支里面就可以
9,一个alway块里面放一个信号就好,不然很容易出错,代码可读信差,conut一个always,clk2r一个always,然后把clk2r放在复位的分支里,就有初始值了

10,default,是去操作你always块的信号的,不用去操作你case的条件的

___________________________________________________________________________

第二天仔细检查后发现,还是一开始的逻辑不对,算错了,真值表和状态图也跟着错,就是rst置1后连续采到两个1不会输出1。

修改后的结果图为

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/566948
推荐阅读
相关标签
  

闽ICP备14008679号