FPGA 一块代码有的执行有的不执行?
使用 altera EP3C16F484C8 的芯片,发现断电后再上电会有一定几率有问题,没有问题的板子怎么断电重启都正常(测试上千次),有问题的板子出现的概率较多,刚开始以为板子问题,但是经过时序分析,发现异常时,在一段代码中 后面的执行了前面的语句不执行。下面的是正常时的时序图
正常。彻查你代码。注意以下点务必100%确保:
状态机跳转,或case跳转,或if跳转,或?:条件执行等,任何条件语句中,不得出现任何异步信号。否则很容易出现竞争冒险造成状态失效。你这种很大概率是上面的if没有用同步信号,造成随机的异常现象。
至于部分执行也很容易理解,短的路径跑到了,长的路径没有跑到。 FPGA和MCU是不一样的
写FPGA程序的时候,首先要想到是在设计逻辑电路,是在设计硬件电路,他们的时序要理解是同步的,不是你把代码写在第一行,就先运行第一个时序
还要充分了解FPGA内部的各个逻辑单元(门)的工作逻辑和开关断时间,所以同样的程序,下载到不同型号的FPGA里面运行,结果都有可能不一样,有时温度也会有影响的 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;
sunrn123 发表于 2022-1-17 11:52
FPGA和MCU是不一样的
写FPGA程序的时候,首先要想到是在设计逻辑电路,是在设计硬件电路,他们的时序要理解 ...
感谢您的回复,您说的不是顺序执行我理解,不像单片机或者电脑顺序一行行的执行,通过仿真发现是这条语句没有得到执行{:sleepy:} 我觉得应该是 wye11083 这位大侠说的问题。 lixiaoxu186 发表于 2022-1-17 16:16
您好,非常感谢您的指导。您说的if没有用同步信号是指?
我之前使用的时CASE ,发现有问题,改成if 问题仍 ...
你仔细查你的代码。if()之类里面不能用到异步信号,这个要你自己查关联信号了。条件/分支等地方使用异步信号会导致状态丢失,我前面已经说的很清楚了。我不怎么用vhdl,所以你只能先自己仔细分析代码。 wye11083 发表于 2022-1-17 17:19
你仔细查你的代码。if()之类里面不能用到异步信号,这个要你自己查关联信号了。条件/分支等地方使用异 ...
嗯 好的 谢谢您 sdc 約束通過沒?還有代碼對齊是最基本的。 dukelec 发表于 2022-1-18 11:57
sdc 約束通過沒?還有代碼對齊是最基本的。
您好感谢您的答复。代码是没有对齐{:biggrin:} ,没有做约束,{:shy:} ,学习的比较浅,也上网收了,建议做约束。我再学习研究下,怎么做下约束。 编程思路一定要从C 语言中 调整过来 看一下生存的原理图 是不是被优化了。 是不是没有复位语句.所有信号都加复位, 不要省.
test bench文件写的详细些. 就算比源代码长好几倍也是值得的. 楼主的代码 if else 这么多,建议摒弃这么多 仿真时把关键信号也添加进去呀, 如 inst_in_buf , pulse_state_buf ... 代码太多了,建议把状态机跳转逻辑和输出逻辑分开写。而且连时序还是组合都看不出来,这别人没法回答你。
页:
[1]