Arrays VHDL奇怪的位错误似乎毫无意义
我有一个Micro Nova FPGA开发板和一个Xilinx Spartan-3A。我试图让它通过GPIO在raspberry pi上使用3个引脚进行位通信:REQ、ACK、DATA。如果我取消对bit_数据赋值的注释并注释掉“bit_data:=data_out(data_of s);”并且在Pi上得到一个连续的10101010,那么代码工作正常。。。等,但如果我留下的代码粘贴在下面,我会得到错误的位在随机时间,如10101100。。。等等 知道有什么问题吗 FPGA上的VHDL:Arrays VHDL奇怪的位错误似乎毫无意义,arrays,vhdl,bit,fpga,Arrays,Vhdl,Bit,Fpga,我有一个Micro Nova FPGA开发板和一个Xilinx Spartan-3A。我试图让它通过GPIO在raspberry pi上使用3个引脚进行位通信:REQ、ACK、DATA。如果我取消对bit_数据赋值的注释并注释掉“bit_data:=data_out(data_of s);”并且在Pi上得到一个连续的10101010,那么代码工作正常。。。等,但如果我留下的代码粘贴在下面,我会得到错误的位在随机时间,如10101100。。。等等 知道有什么问题吗 FPGA上的VHDL: libr
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity xclock is
Port(CLK : in STD_LOGIC;
REQ : in STD_LOGIC;
ACK : out STD_LOGIC;
DATA : out STD_LOGIC);
end xclock;
architecture Behavioral of xclock is
begin
process(CLK)
variable data_ofs : integer range 0 to 2 := 0;
variable data_out : std_logic_vector(1 downto 0) := "01";
variable bit_data : std_logic := '0';
variable ack_data : std_logic := '0';
variable LASTREQ : std_logic := '0';
variable seconds : integer range 0 to 50000000 := 0;
variable tick : integer range 0 to 50000000 := 0;
begin
if CLK'event and CLK = '1' then
tick := tick + 1;
if tick = 49999999 then
tick := 0;
seconds := seconds + 1;
if seconds = 49999999 then
seconds := 0;
end if;
end if;
if seconds > 1 then
if REQ /= LASTREQ and REQ /= ack_data then
LASTREQ := REQ;
if REQ = '1' then
--bit_data := '1';
ack_data := '1';
else
--bit_data := '0';
ack_data := '0';
end if;
bit_data := data_out(data_ofs);
data_ofs := data_ofs + 1;
if data_ofs = 2 then
data_ofs := 0;
end if;
end if;
end if;
DATA <= bit_data;
ACK <= ack_data;
end if;
end process;
end Behavioral;
REQ=27
ACK=17
DATA=22
gpio -g mode $REQ out
gpio -g mode $ACK in
gpio -g mode $DATA in
gpio -g write $REQ 1
e=1
while [ 1 ]; do
while [ 1 ]; do
if [ `gpio -g read $ACK` -eq 1 ]; then
while [ 1 ]; do
d=`gpio -g read $DATA`
echo $d
if [ $d -ne $e ]; then
echo error DATA should be $e
sleep 1
else
if [ $e -eq 0 ]; then
e=1
else
e=0
fi
break
fi
done
gpio -g write $REQ 0
break;
fi
done
while [ 1 ]; do
if [ `gpio -g read $REQ` -eq 0 ]; then
while [ 1 ]; do
d=`gpio -g read $DATA`
echo $d
if [ $d -ne $e ]; then
echo error DATA should be $e
sleep 1
else
if [ $e -eq 0 ]; then
e=1
else
e=0
fi
break
fi
done
gpio -g write $REQ 1
break;
fi
sleep 1
done
done
任何帮助都将不胜感激。这件事让我毛骨悚然 我花了一些时间试图弄清楚您的代码应该如何工作(协议是什么),但我放弃了。根据其他人的建议,您可以尝试进行以下修改,看看是否有什么不同
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity xclock is
port(CLK : in STD_LOGIC;
REQ : in STD_LOGIC;
ACK : out STD_LOGIC;
DATA : out STD_LOGIC);
end xclock;
architecture Behavioral of xclock is
signal req_reg1, req_reg2, req_int, last_req : std_logic := '0';
signal bit_data_reg, ack_reg : std_logic;
begin
process(CLK)
variable data_ofs : integer range 0 to 2 := 0;
variable data_out : std_logic_vector(1 downto 0) := "01";
variable bit_data : std_logic := '0';
variable ack_data : std_logic := '0';
variable seconds : integer range 0 to 50000000 := 0;
variable tick : integer range 0 to 50000000 := 0;
begin
if CLK'event and CLK = '1' then
-- Input registers help prevent metastability on REQ line
-- Note that if there is significant bounce or glitching, then
-- you will also need a deglitcher.
req_reg1 <= REQ;
req_reg2 <= req_reg1;
req_int <= req_reg2;
tick := tick + 1;
if tick = 49999999 then
tick := 0;
seconds := seconds + 1;
if seconds = 49999999 then
seconds := 0;
end if;
end if;
if seconds > 1 then
-- Using the registered inputs instead of the direct REQ input.
if req_int /= last_req and req_int /= ack_data then
last_req <= req_int;
if req_int = '1' then
ack_data := '1';
else
ack_data := '0';
end if;
bit_data := data_out(data_ofs);
data_ofs := data_ofs + 1;
if data_ofs = 2 then
data_ofs := 0;
end if;
end if;
end if;
-- Register outputs to ensure consistent OREG packing, if enabled
bit_data_reg <= bit_data;
ack_reg <= ack_data;
DATA <= bit_data_reg;
ACK <= ack_reg;
end if;
end process;
end Behavioral;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
实体xclock是
端口(时钟:在标准逻辑中;
REQ:标准逻辑中;
确认:输出标准逻辑;
数据:输出标准(U逻辑);
端xclock;
xclock的体系结构是
信号req_reg1、req_reg2、req_int、last_req:std_逻辑:='0';
信号位\数据\寄存器、确认\寄存器:标准\逻辑;
开始
过程(CLK)
变量数据_of s:整数范围0到2:=0;
变量数据输出:标准逻辑向量(1到0):=“01”;
可变位_数据:标准_逻辑:='0';
变量ack_数据:标准逻辑:='0';
可变秒数:整数范围0到50000000:=0;
变量勾号:从0到50000000的整数范围:=0;
开始
如果CLK'事件和CLK='1',则
--输入寄存器有助于防止REQ线上的亚稳态
--请注意,如果存在明显的反弹或毛刺,则
--您还需要一个除雾器。
req_reg1没有详细说明代码应该做什么,这听起来像个问题。例如,您在无任何同步的时钟过程中使用一些顶级模块输入信号。您的VHDL编码风格也是非常“C-ish”的。如果是亚稳态,为什么它会通过使用bit_data:=data_out(data_of s);?我怎样才能避开这个问题呢?还有,这将如何写为“VHDL ish”?您的设计存在问题的主要原因之一是您使用变量的方式使代码中的许多逻辑在锁存器中实现。为fpga FPGAI编写代码时的经验法则是避免使用变量。您模拟过您的设计吗?它是否像您在模拟中预期的那样工作?