这是一个普遍的FPGA设计问题,我是FPGA设计的新手,刚刚开始了我的第一个大型项目,构建了一些不错的线性代数求解器 . 系统非常大,所以第一次正确使用非常重要 .
在成功模拟之后,我现在正在进行sythensizing,但是我有一个噩梦,我不得不逐个构建和测试它,因为它没有像在模拟中那样表现!我主要遇到输出未同步的状态机问题,例如这是我正在使用的数据加载器:
entity TriDiag_Data_Scheduler is
generic( W : integer :=16;
AW : integer := 10 -- address width
);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC; --attatched to data finished
d_ready : in STD_LOGIC;
din : in STD_LOGIC_VECTOR (W-1 downto 0);
wr_en : out STD_LOGIC_VECTOR (3 downto 0);
dout_a, dout_b, dout_c, dout_y : out STD_LOGIC_VECTOR (W-1 downto 0);
addr_out : out STD_LOGIC_VECTOR (AW-1 downto 0));
end TriDiag_Data_Scheduler;
architecture Behavioral of TriDiag_Data_Scheduler is
type state is (a,b,c,y);
signal state_pr, state_next : state := y;
signal addr_reg, addr_next : std_logic_vector(AW-1 downto 0) :=(others =>'1');
signal wr_en_next : std_logic_vector(3 downto 0);
--data buffer
signal d_buff, d_buff_a, d_buff_b, d_buff_c, d_buff_y : std_logic_vector (W-1 downto 0) :=(others =>'0');
signal d_buff_a_reg, d_buff_b_reg, d_buff_c_reg, d_buff_y_reg : std_logic_vector (W-1 downto 0) :=(others =>'0');
begin
process(clk,rst)
begin
if(clk'event and clk ='1') then
state_pr <= state_next;
d_buff_a <= d_buff_a_reg;
d_buff_b <= d_buff_b_reg;
d_buff_c <= d_buff_c_reg;
d_buff_y <= d_buff_y_reg;
addr_reg <= addr_next;
wr_en <= wr_en_next;
end if;
end process;
addr_out <= addr_reg;
dout_a <= d_buff_a;
dout_b <= d_buff_b;
dout_c <= d_buff_c;
dout_y <= d_buff_y;
--Data out logic
process(state_pr, d_buff_a, d_buff_b, d_buff_c, d_buff_y, d_buff)
begin
d_buff_a_reg <= d_buff_a;
d_buff_b_reg <= d_buff_b;
d_buff_c_reg <= d_buff_c;
d_buff_y_reg <= d_buff_y;
case state_pr is
when a => --move data to a reg
d_buff_a_reg <= d_buff;
when b => --move data to b reg
d_buff_b_reg <= d_buff;
when c => --move data to c reg
d_buff_c_reg <= d_buff;
when y =>
d_buff_y_reg <= d_buff;
end case;
end process;
--next state and addr logic
process(state_pr, d_ready, rst, din)
begin
state_next <= state_pr;
addr_next <= addr_reg;
wr_en_next <= (others => '0');
if(rst = '1') then
state_next <= a;
addr_next <= (others =>'1');
wr_en_next <= (others => '0');
elsif(d_ready = '1') then
--Read in the data to the buffer
d_buff <= din;
--next state logic
case state_pr is
when a => --move data to a reg
addr_next <= addr_reg + 1;
-- d_buff_a_reg <= din;
wr_en_next <= "0001";
state_next <= b;
when b => --move data to b reg
wr_en_next <= "0010";
-- d_buff_b_reg <= din;
state_next <= c;
when c => --move data to c reg
wr_en_next <= "0100";
-- d_buff_c_reg <= din;
state_next <= y;
when y =>
-- d_buff_y_reg <= din;
wr_en_next <= "1000";
state_next <= a;
end case;
end if;
end process;
end Behavioral;
基本上,当通过UART模块接收数据时,其作业是加载到正确的存储器中(由write_en信号控制) . 问题在于,在我的所有设计中(这是修订版7),所有addr_out,wr_en和正确的数据都在syn中,但在综合中我一直发现addr和wr_en不与数据同步,并从前面读取一半和前一个州的一半 .
我应该使用哪些设计实践,以便我的VHDL更易于合成,因为按照这个速度,我将不得不重新编写我以前为每个组件所做的所有努力工作!
非常感谢Sam
1 回答
在工作设计中,旧设计遭受了从另一个模块断言的d_ready信号与此模块clk之间的偏差 . 因此,没有像第一个希望同步的变化 . 为了修复这个I但是在d_tick_next信号中,该信号断言本地同步信号d_tick,它允许所有正确的行为 . 学到的一个教训(如果我错了,请纠正我)是你不能依赖假设的外部时钟信号(例如d_ready)与接收模块clk同步 .
结束行为;