前言:由于是写单片机出身,受串行思维的影响,做事老是先去想for循环,计数等,这种思想总会对一段很简洁的verilog代码干扰。都说学会了c语言,上手verilog很容易,我认为不然,两者的思想完全不一样,一个串行,一个并行,刚从单片机转到fpga写程序,很容易搞混,还不如什么都不知道从零开始写verilog思路清晰。这几天正在写fpga与单片机的spi通讯,就以这个为例做简要说明。
需求:假设要发送一个80位的数据,先发高位。
若用单片机写,流程大致就是定义一个10个长度的char型数组,用for循环发送每一位:
for(i = 0; i < 10; i++)
{
for(j = 0; j < 8; j++)
{
out =!! (buf[i]&bit(j));
}
}
而在fpga,当然也可以这样,我之前是这样写的:
下面语句发生在clk的上升沿:
if(r7b_128bitcnt == 7'd79) begin
r7b_128bitcnt <= 7'd0;
o_mcu_miso <= i80b_spitx[0];
o_spitxoverhp <= 1'b1;
end
else begin
o_mcu_miso <= i80b_spitx[7'd79 - r7b_128bitcnt];
r7b_128bitcnt <= r7b_128bitcnt + 1'b1;
end
这样当然也能实现,功能上没问题,但是老大跟我说直接用移位就可以实现了,讲解了一下,原来就是这样:
assign o_mcu_miso = i80b_spitx[79];
i80b_spitx[79:0] <= {i80b_spitx[78:0], 1'b0};
瞧,这样一句话也就完事了,上面的assign是在clk的always之外的。
小结:真是神奇,这样看来只需要用下移位(80个D触发器),就可以完成了。这不单单是省略简洁了代码,更重要的是节省了资源和提高了效率。fpga和单片机的程序毕竟是不一样啊,以后写代码,尽量不要从单片机的思维去考虑,多想想用移位怎么实现。老大说,程序就那点东西,三斧头的事,只要把D触发器用好了,什么都解决了,实际应用几乎用不到别的触发器。之前写单片机,从来不考虑触发器的事,以后该往这方面想想了,多想想电路,触发器,写程序还得细细斟酌才是。
一周热门 更多>