电力电子转战数字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,不能的时候输出0
//逻辑:不管一个数是多少位都对应一个十进制整数,任何数除以3必然可以得到3个余数。整除时得到的余数是0,不能整除时得到的余数是1或2,
module mo3 (clk,rst,a,result);

input clk,rst,a;
output result;
reg [2:0] state,nextstate;

//定义状态
parameter idle=3'd0,one=3'd1,two=3'd2,zero=3'd3;
//先写每个时钟沿产生一次可能的状态变化
always@ (posedge clk or negedge rst)
if(!rst)
	state<=idle;
else state<=nextstate;
//产生下一个状态的组合逻辑
always@(*)
begin
	case(state)
	idle: nextstate=  a? one:zero;
	one: nextstate=  a? zero:two;
	two: nextstate=  a? two:one;
	zero: nextstate=  a? one:zero;
	default state<=3'dx;
	endcase
end
assign result= (state==one)? 1:0;
endmodule
	
`timescale 1ns/1ps

module mo3test;
reg clk,rst;
reg a;
wire result;

mo3 t1(.clk(clk), .rst(rst), .a(a), .result(result));

always #5 clk=~clk;

always #9.99 a=$random; 
initial
	begin
	clk=0;rst=1;
	#5 rst=0;
	#10 rst=1;
	#1000 $stop;
	end

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。

修改后的结果图为

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值