Maybe跨时钟域?同步性太差?

写SPI的时候,想接收SDO传过来的数据。检测SCLK的上升沿,对SDO进行移位存储。

然后就出现一个很神奇的事,write_cnt从10到18只有7个clk进行了数据的存储。

//rdata 	
	always @ (posedge SCLK or negedge rst_n) begin 
		if(!rst_n) begin
			rdata <= 8'd0 ;
		end else begin
			if(swith[15] == 1'b1 && write_cnt > 8'd10 && write_cnt <= 8'd18) begin
				rdata <= {rdata[6:0],SDO} ;
			end else begin
				rdata <= 8'd0 ;
			end 
		end 
	end


同步性太差导致的?看一下write_cnt==20时写数据看是什么时序。果然是有问题的,cnt为20时,已经存数据了。

//rdata	
	always @ (posedge SCLK or negedge rst_n) begin 
		if(!rst_n) begin
			rdata <= 8'd0 ;
		end else begin
			if(swith[15] == 1'b1 && write_cnt > 8'd10 && write_cnt <= 8'd18) begin
				rdata <= {rdata[6:0],SDO} ;
			end else if(write_cnt == 8'd20) begin
				rdata <= 8'haa ;
			end else begin
				rdata <= 8'b0 ;
			end 
		end 
	end	


所以我们用一个SCLK取反来对SDO进行读取,这样确保SCLK_r的上升沿在write_cnt的中间。结果证明时序是正确的。

//rdata
	wire 	SCLK_R ;
	assign 	SCLK_R = ~SCLK ;
	
	always @ (posedge SCLK_R or negedge rst_n) begin 
		if(!rst_n) begin
			rdata <= 8'd0 ;
		end else begin
			if(swith[15] == 1'b1 && write_cnt > 8'd10 && write_cnt <= 8'd18) begin
				rdata <= {rdata[6:0],SDO} ;
			end else begin
				rdata <= 8'd0 ;
			end
		end 
	end


因为SCLK是由50M时钟clk产生的,我们用产生SCLK的信号,对SDO进行存储。也是正确的。

//rdata 	
	always @ (posedge clk or negedge rst_n) begin 
		if(!rst_n) begin
			rdata <= 8'd0 ;
		end else begin
			if (clk_25M == 1'b1 && clk_12M == 1'b0) begin
				if(swith[15] == 1'b1 && write_cnt > 8'd10 && write_cnt <= 8'd18) begin
					rdata <= {rdata[6:0],SDO} ;
				end else begin
					rdata <= 8'd0 ;
				end
			end 
		end 
	end


最后得出的结论就是,用系统时钟clk分频出来的SCLK对write_cnt 进行读取是存在问题的。


基于STM32F407,使用DFS算法实现最短迷宫路径检索,分为三种模式:1.DEBUG模式,2. 训练模式,3. 主程序模式 ,DEBUG模式主要分析bug,测量必要数据,训练模式用于DFS算法训练最短路径,并将最短路径以链表形式存储Flash, 主程序模式从Flash中….zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
### 回答1: 可能的Monad是一种在函数式编程语言中使用的概念,它允许您在不改变函数签名的情况下增加额外的行为。 Maybe Monad是一个具体的实现,它可以让您将可能未定义的值包装到一个可以操作的存在中,以便在处理可能未定义值时减少错误。 ### 回答2: Maybe Monad和Either Monad都属于函数式编程中的Monad概念的应用,用于处理可能存在错误或者异常情况的计算结果。它们的区别主要在于处理错误的方式和在函数式编程中的使用场景。 1. 错误处理方式:Maybe Monad用于表示可能存在错误或者异常的计算结果,但只保留了可能有值的情况,没有值的情况返回空值(Nothing)。而Either Monad则是同时保留了可能的正确结果和错误结果,正确结果用Right表示,错误结果用Left表示。 2. 使用场景:Maybe Monad主要用于处理可能为空的情况,例如在一个计算中可能会产生空值的情况。它适用于不需要关心具体错误或者异常信息的场景,只需要知道是否存在错误即可。而Either Monad则适用于需要处理具体错误或者异常情况的场景,可以将错误信息作为左值返回,便于在代码中进行进一步处理。 总结起来,Maybe Monad和Either Monad的不同主要在于处理错误的方式和使用场景。Maybe Monad适用于简单的错误处理,只关心是否存在错误;而Either Monad适用于复杂的错误处理,需要获取具体错误信息。 ### 回答3: Maybe Monad和Either Monad是两种常见的函数式编程中常用的Monad。它们之间有着一些不同之处。 首先,Maybe Monad主要用来处理可能为空的值。在Maybe Monad中,存在两种情况:Just和Nothing。当我们操作一个Maybe Monad时,可以将其看作是一个包裹在Maybe的容器中的值。如果值存在,那么Maybe Monad就是一个Just值;如果值为空,那么Maybe Monad就是一个Nothing值。 与此不同,Either Monad主要用来处理可能发生错误的情况。在Either Monad中,存在两种情况:Left和Right。当我们操作一个Either Monad时,可以将其看作是一个包裹在Either的容器中的值。通常情况下,Left用于表示错误或异常情况,Right用于表示正常的值。 换言之,Maybe Monad更关注值的存在与否,而Either Monad更关注错误的发生与否。 其次,Maybe Monad在处理可能为空的值时更为简洁。由于Maybe Monad只有两种情况,所以在进行操作时,我们只需要考虑值存在的情况和值为空的情况即可。而Either Monad则需要考虑错误的发生和值存在的两种情况,使得代码相对复杂一些。 最后,Maybe Monad和Either Monad在使用场景上也有所不同。Maybe Monad通常用于表示可选值,比如一个函数的返回值可能为空。而Either Monad则常用于表示可能发生错误的情况,比如在处理多个操作时,某个操作可能会失败。 综上所述,Maybe Monad和Either Monad在处理不同的情况下有不同的表现,分别用于处理可能为空的值和可能发生错误的情况。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值