今天去做了FPGA的实验,把自己之前的代码打了上去当然发现了一些错误,快把我这个小白搞崩溃了,下面分享一下解决方案。其中第四个问题有点最麻烦,现在还没有解决.
第一个问题
1)关于信号赋初值的问题
信号赋初值的语句为:
SIGNAL X1:STD_LOGIC_VECTOR(0 to 9):“0000010100”;
如果不这样赋初值的话会出现类型不匹配的问题。
第二个问题
1)我这个设计那个滑块的左移和右移是通过那个外部的按键控制的,然后我之前的代码里面写的按键检测方法是:IF(rising_edge(MDL))THEN,我实在是不知道错到哪里了,用这种做按键检测就报错,然后我就换了一种写法:
IF(MDL='0')THEN--两次判断是为了消除按键的抖动 IF(MDL="0") THEN END IF; END IF;
然后很神奇这样写就好了,所以出现问题了要敢于尝试,我其实最烦的是我写的思路整体是没问题的但是老师只看你的结果对不对,只要你的代码出现了问题报错了老师就否定你的全部(注:我们老师提供了一种其他的编程思路,我自己又想了一下)
在外面吃个饭等会回宿舍继续写吧.
第三个问题
关于每个进程的启动信号的问题:
1)这是我之前下面滑块移动程序的启动信号:
PROCESS(MDR,MDL) BEGIN END PROCESS;
这是我现在滑块代码的启动信号(其实叫敏感信号更贴切)
PROCESS(Q2,MDR,MDL) BEGIN--Q2是啥,以及怎么得到的下面会讲 BEGIN IF(rising_edge(Q2))THEN --省略了一些下面滑块的运动代码,这个前面有 END IF; END PROCESS;
--Q这个信号是锁相环的输出信号,频率比较高为25MHz,然后我们需要把这个信号分一下频率,我这里把其分频为25Hz,输出为信号Q2,信号Q1就是一个中间量,起到辅助分频的作用。 25MHZ/25=1000000 转换为二进制是 1111 0100 0010 0100 000020位所以下面定义的Q1是20位的数据类型,Q2是一位的就行了 SIGNAL Q1:STD_LOGIC_VECTOR(0 to 19); SIGNAL Q2:STD_LOGIC; PROCESS(Q) BEGIN IF Q'EVENT AND Q='1' THEN IF Q1<999999 THEN Q1<=Q1+1; ELSE Q1<="00000000000000000000";--20位20个零 END IF; END IF; IF Q1=1 THEN Q2<='1'; ELSE Q2<='0'; END IF; END PROCESS;
2)自由移动物体的启动信号
PROCESS(Q2) BEGIN IF(rising_edge(Q2))THEN --省略了一些自由移动物体的运动代码 END IF; END PROCESS;
3)显示砖块、下面滑块、以及自由移动物体的那个代码的启动信号。
PROCESS(Q,X1,Y11,Y21,Y31,Y41,X11,X21,X31,X41) BEGIN IF(rising_edge(Q2))THEN --省略了砖块的显示代码 IF (Y1<HCNT AND HCNT<Y2 and X1<VCNT AND VCNT<X3)THEN --底部滑块的显示 R <= '1'; G <= '1'; B <= '0'; END IF; IF (Y11<HCNT AND HCNT<Y21 and X11<VCNT AND VCNT<X31)THEN --自由移动的那个滑块的显示 R <= '1'; G <= '1'; B <= '0'; END IF; END PROCESS;
第四个问题
我最服气的一个问题,就是关于我使用的变量数据类型的问题,已经内心泪流满面了。
我最开始调用了两个库
USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL;
然后我这个设计的精髓就是那个自由移动物体的触边反弹代码即下面这段,这里面有个在其他语言里面不算问题的问题
X11<=X11+X_shudu; Y11<=Y11+Y_shudu; X21<=X21+X_shudu; Y21<=Y21+Y_shudu; X31<=X31+X_shudu; Y31<=Y31+Y_shudu; X41<=X41+X_shudu; Y41<=Y41+Y_shudu; IF(X31>640)THEN X_shudu=!X_shudu;--就是这几句 X11<=X11+X_shudu; Y11<=Y11+Y_shudu; X21<=X21+X_shudu; Y21<=Y21+Y_shudu; X31<=X31+X_shudu; Y31<=Y31+Y_shudu; X41<=X41+X_shudu; Y41<=Y41+Y_shudu; END IF IF(X11<0)THEN X_shudu=!X_shudu;--就是这几句 X11<=X11+X_shudu; Y11<=Y11+Y_shudu; X21<=X21+X_shudu; Y21<=Y21+Y_shudu; X31<=X31+X_shudu; Y31<=Y31+Y_shudu; X41<=X41+X_shudu; Y41<=Y41+Y_shudu; END IF IF(Y11<0)THEN Y_shudu=!Y_shudu;--就是这几句 X11<=X11+X_shudu; Y11<=Y11+Y_shudu; X21<=X21+X_shudu; Y21<=Y21+Y_shudu; X31<=X31+X_shudu; Y31<=Y31+Y_shudu; X41<=X41+X_shudu; Y41<=Y41+Y_shudu; END IF IF(Y11>480)THEN Y_shudu=!Y_shudu;--就是这几句 X11<=X11+X_shudu; Y11<=Y11+Y_shudu; X21<=X21+X_shudu; Y21<=Y21+Y_shudu; X31<=X31+X_shudu; Y31<=Y31+Y_shudu; X41<=X41+X_shudu; Y41<=Y41+Y_shudu; END IF
我上面使用的库决定了我现在使用的所有数据都是没有符号的简单说就都是正数没有负数,我之前理解的反向就是把之前定义的那个速度变量的正负号改变一下就行了,于是就直接进行了取反操作,但是对于没有符号的数据类型取反是没有什么用的,不会改变它的正负,然后就不行了。
举个例子:对10001011取反: NOT 10001011;这样写就行了 结果是:01110100 如果你一开始使用了USE IEEE.STD_LOGIC_UNSIGNED.ALL;这个库那么数据就是没有符号的就都是正数 如果你一开始使用了USE IEEE.STD_LOGIC_SIGNED.ALL;这个库那么数据就是有符号的数,符号位是最高位
总结一下,这次做实验就发现了这四个比较严重的代码问题,当然还有一下简单的问题我没有写出来,明天还能去做一次实验,把第四个问题解决了就行了。
我第四个题打算把USE IEEE.STD_LOGIC_UNSIGNED.ALL;换为USE IEEE.STD_LOGIC_SIGNED.ALL;,换为有符号的库之后把之前的每个数据类型都加一位就行了,最高位是符号位,我那个速度之前是:
SIGNAL X_shudu,Y_shudu:STD_LOGIC_VECTOR(0 to 9);
现在变为11位:
--变为11位 SIGNAL X_shudu:STD_LOGIC_VECTOR(0 to 11); SIGNAL Y_shudu:STD_LOGIC_VECTOR(0 to 11); ```Y_shudu[10] 然后判断在那个自由运动的物体代码里面满足边界碰撞条件改变第11位的值就行了。 Y_shudu[10]=NOT Y_shudu[10]; X_shudu[10]=NOT X_shudu[10]; 继续去查那两个库的区别去了 找到了一个东西:https://www.jianshu.com/p/1733e1f01973朋友们可以看看这篇文章,对解决问题四可能就有点思路了,反正我是有思路了,明天看效果吧唉)