lixiaoxu186 发表于 2022-1-17 11:14:47

FPGA 一块代码有的执行有的不执行?

使用 altera EP3C16F484C8 的芯片,发现断电后再上电会有一定几率有问题,没有问题的板子怎么断电重启都正常(测试上千次),有问题的板子出现的概率较多,刚开始以为板子问题,但是经过时序分析,发现异常时,在一段代码中 后面的执行了前面的语句不执行。



lixiaoxu186 发表于 2022-1-17 11:17:26

下面的是正常时的时序图

wye11083 发表于 2022-1-17 11:28:17

正常。彻查你代码。注意以下点务必100%确保:

状态机跳转,或case跳转,或if跳转,或?:条件执行等,任何条件语句中,不得出现任何异步信号。否则很容易出现竞争冒险造成状态失效。你这种很大概率是上面的if没有用同步信号,造成随机的异常现象。

至于部分执行也很容易理解,短的路径跑到了,长的路径没有跑到。

sunrn123 发表于 2022-1-17 11:52:04

FPGA和MCU是不一样的
写FPGA程序的时候,首先要想到是在设计逻辑电路,是在设计硬件电路,他们的时序要理解是同步的,不是你把代码写在第一行,就先运行第一个时序
还要充分了解FPGA内部的各个逻辑单元(门)的工作逻辑和开关断时间,所以同样的程序,下载到不同型号的FPGA里面运行,结果都有可能不一样,有时温度也会有影响的

lixiaoxu186 发表于 2022-1-17 16:16:22

wye11083 发表于 2022-1-17 11:28
正常。彻查你代码。注意以下点务必100%确保:

状态机跳转,或case跳转,或if跳转,或?:条件执行等,任何 ...

您好,非常感谢您的指导。您说的if没有用同步信号是指?
我之前使用的时CASE ,发现有问题,改成if 问题仍然存在。
这个是 case的代码
       
case in_data_state is
       
                when 0 =>       
                if(switch_in_buf/= switch_in)then
                      switch_in_buf <=switch_in;
                  end if;               
                       
                 if(inst_in_buf/= inst_in)then
                   inst_in_buf <=inst_in;
                end if;
                                       
                if(inst_in_buf ='0')then
                                  if(pulse_state_buf /=pulse_state) then   
                                              in_data_state<= 1;
                                              pulse_state<=pulse_state_buf;
                                              pulse_test_buf <= NOT pulse_test_buf;
                                              number_save<=3;
                                              data_save(3)<=Count_get;
                                              send_time<=0;
                                       else
                                             in_data_state<=0;
                                          end if;
                else   
                                       if(pulse_state2_buf /=pulse_state2) then
                                                   pulse_state2<=pulse_state2_buf;
                                                    in_data_state<= 1;
                                                  number_save<=0;
                                                  data_save(0)<=Count_get2(7 downto 0)&Count_get2(15 downto 8)&conv_std_logic_vector(1, 8)&save_in(7 downto 0);
                                                  data_save(1)<=ad_in(7 downto 0)&ad_in(15 downto 8)& conv_std_logic_vector(2, 8)&save_in(7 downto 0);
                                                  data_save(2)<=ad_in(23 downto 16)&ad_in(31 downto 24)& conv_std_logic_vector(3, 8)&save_in(7 downto 0);
                                                  data_save(3)<=ad_in(39 downto 32)&ad_in(47 downto 40)& conv_std_logic_vector(4, 8)&save_in(7 downto 0);

                                                    send_time<=0;
                                          else
                                                  in_data_state<=0;
                                          end if;
                                               
                                       end if;
                                       
           when 1 =>
                       send_time<=send_time+1;
                         if(send_time =1) then
                              if f1_fi_wrusedw>=conv_std_logic_vector(2**AW-128,AW) then
                              f1_wr_hfullbuf        <= act_on;
                         else
                               f1_wr_hfullbuf        <= act_off;
                         end if;
                                                  
                       if(send_time >=2) then
                                if(inst_in_buf ='1') then
                                     if(switch_in_buf ='1')then
                                           f1_wr_hfullbuf2<=act_off;
                                     else
                                           f1_wr_hfullbuf2<=act_on;
                                  end if;
                               else
                                   f1_wr_hfullbuf2<=act_off;
                                end if;
                             f1_wr_hfull<=f1_wr_hfullbuf or f1_wr_hfullbuf2;
                                 send_time<=0;
                                 wr_clock<='1';   
                                 in_data_state<=in_data_state + 1;--
                        end if;
                                                       
           when 2 =>
                  send_time<=send_time+1;      
                  f1_fi_wrreq        <= act_off;
                  if(send_time >=1) then
                             if DATA_DIR_IN='0' and f1_wr_hfull=act_off then        --DATA_DIR_IN->0->EXT TO USB
                              f1_fi_wrreq        <= act_on;
                              f1_fi_din         <= data_save(number_save);
                         end if;
                           number_save<=number_save+1;               
                          in_data_state<=in_data_state + 1;--
                          send_time<=0;
                end if;
                when 3 =>--
                        send_time<=send_time+1;   
                       if(send_time >=1) then
                                if(number_save <4)then
                                        in_data_state<=1;
                                else
                                        in_data_state<=0;
                                end if;       
                     
                                send_time<=0;
                               wr_clock<='0';
                                fifo_test_buf<= NOT fifo_test_buf;
                       end if;
                when others =>
                        in_data_state <= 0;
        end case;



下面是目前用的if

    if(in_data_state = 0) then
       
          if(switch_in_buf/= switch_in)then
              switch_in_buf <=switch_in;
       end if;               
                       
          if(inst_in_buf/= inst_in)then
              inst_in_buf <=inst_in;
               end if;
                                       
                if(inst_in_buf ='0')then
                        if(pulse_state_buf /=pulse_state) then   
                                in_data_state<=1;
            pulse_state<=pulse_state_buf;
                                pulse_test_buf <= NOT pulse_test_buf;
                                number_save<=3;
                                data_save(3)<=Count_get;
                           send_time<=0;
            end if;
                  end if;
                if(inst_in_buf ='1')then       
                                if(pulse_state2_buf /=pulse_state2) then
                                       in_data_state<=1;
                pulse_state2<=pulse_state2_buf;
                                       
                                          --fifo_test_buf<= NOT fifo_test_buf;
                                          number_save<=0;
                                          data_save(0)<=Count_get2(7 downto 0)&Count_get2(15 downto 8)&conv_std_logic_vector(1, 8)&save_in(7 downto 0);
                                          data_save(1)<=ad_in(7 downto 0)&ad_in(15 downto 8)& conv_std_logic_vector(2, 8)&save_in(7 downto 0);
                                          data_save(2)<=ad_in(23 downto 16)&ad_in(31 downto 24)& conv_std_logic_vector(3, 8)&save_in(7 downto 0);
                                          data_save(3)<=ad_in(39 downto 32)&ad_in(47 downto 40)& conv_std_logic_vector(4, 8)&save_in(7 downto 0);
                                       
                                     send_time<=0;
         end if;       
              end if;
   elsif(in_data_state = 1)then
                        send_time<=send_time+1;
                        if(send_time =1) then
                                                --if f1_fi_wrusedw>=conv_std_logic_vector(2**AW-8,AW) then
                          if f1_fi_wrusedw>=conv_std_logic_vector(2**AW-128,AW) then
                        f1_wr_hfullbuf        <= act_on;
                else
                        f1_wr_hfullbuf        <= act_off;
                end if;
                       end if;          
                       
                   if(send_time >=2) then
                                if(inst_in_buf ='1') then
                                        if(switch_in_buf ='1')then
                                                f1_wr_hfullbuf2<=act_off;
                                        else
                                                f1_wr_hfullbuf2<=act_on;
                                       end if;
                               else
                                        f1_wr_hfullbuf2<=act_off;
                               end if;
                                               
                               f1_wr_hfull<=f1_wr_hfullbuf or f1_wr_hfullbuf2;
                               send_time<=0;
                     wr_clock<='1';   
                               in_data_state<=in_data_state + 1;
          end if;
   elsif(in_data_state = 2)then
                  send_time<=send_time+1;      
                  f1_fi_wrreq        <= act_off;
                  if(send_time >=1) then
                             if DATA_DIR_IN='0' and f1_wr_hfull=act_off then        --DATA_DIR_IN->0->EXT TO USB
                           f1_fi_wrreq        <= act_on;
                                     f1_fi_din         <= data_save(number_save);
                end if;
                          number_save<=number_save+1;       
                          in_data_state<=in_data_state + 1;
                          send_time<=0;
                        end if;
   elsif(in_data_state = 3)then
                   send_time<=send_time+1;   
                       if(send_time >=1) then
                                if(number_save <4)then
                                   in_data_state<= 1;
                                else
                                         in_data_state<=0;
                                end if;       
                                send_time<=0;
                               wr_clock<='0';
                                fifo_test_buf<= NOT fifo_test_buf;
                       end if;
   else
          in_data_state<=0;
        end if;



lixiaoxu186 发表于 2022-1-17 16:21:46

sunrn123 发表于 2022-1-17 11:52
FPGA和MCU是不一样的
写FPGA程序的时候,首先要想到是在设计逻辑电路,是在设计硬件电路,他们的时序要理解 ...

感谢您的回复,您说的不是顺序执行我理解,不像单片机或者电脑顺序一行行的执行,通过仿真发现是这条语句没有得到执行{:sleepy:}         我觉得应该是 wye11083 这位大侠说的问题。

wye11083 发表于 2022-1-17 17:19:40

lixiaoxu186 发表于 2022-1-17 16:16
您好,非常感谢您的指导。您说的if没有用同步信号是指?
我之前使用的时CASE ,发现有问题,改成if 问题仍 ...

你仔细查你的代码。if()之类里面不能用到异步信号,这个要你自己查关联信号了。条件/分支等地方使用异步信号会导致状态丢失,我前面已经说的很清楚了。我不怎么用vhdl,所以你只能先自己仔细分析代码。

lixiaoxu186 发表于 2022-1-18 11:54:32

wye11083 发表于 2022-1-17 17:19
你仔细查你的代码。if()之类里面不能用到异步信号,这个要你自己查关联信号了。条件/分支等地方使用异 ...

嗯 好的 谢谢您

dukelec 发表于 2022-1-18 11:57:59

sdc 約束通過沒?還有代碼對齊是最基本的。

lixiaoxu186 发表于 2022-1-18 13:20:51

dukelec 发表于 2022-1-18 11:57
sdc 約束通過沒?還有代碼對齊是最基本的。

您好感谢您的答复。代码是没有对齐{:biggrin:} ,没有做约束,{:shy:} ,学习的比较浅,也上网收了,建议做约束。我再学习研究下,怎么做下约束。

ackyee 发表于 2022-1-18 13:51:44

编程思路一定要从C 语言中 调整过来   

gwj221 发表于 2022-1-18 14:11:44

看一下生存的原理图 是不是被优化了。

qinxg 发表于 2022-1-18 17:28:31

是不是没有复位语句.所有信号都加复位, 不要省.
test bench文件写的详细些. 就算比源代码长好几倍也是值得的.

三年模拟 发表于 2022-1-19 11:10:55

楼主的代码 if else 这么多,建议摒弃这么多

qinxg 发表于 2022-1-19 13:16:47

仿真时把关键信号也添加进去呀, 如 inst_in_buf , pulse_state_buf ...

laciel666 发表于 2023-10-16 20:41:28

代码太多了,建议把状态机跳转逻辑和输出逻辑分开写。而且连时序还是组合都看不出来,这别人没法回答你。
页: [1]
查看完整版本: FPGA 一块代码有的执行有的不执行?