これは一般的な FPGA 設計の質問です。私は FPGA 設計は初めてで、最初の大規模なプロジェクトに着手したばかりで、優れた線形代数ソルバーを構築しています。システムはかなり大きいので、最初に正しく理解することが重要です。
シミュレーションが成功した後、私は現在合成していますが、悪夢に見舞われています。シミュレーションでのように動作するものは何もないため、コンポーネントごとにビルドしてテストする必要があります! 私は主に、出力が同期されていないステート マシンに問題があります。たとえば、これは私が使用しているデータ ローダーです。
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、および正しいデータが同期していることですが、合成では、addr と wr_en がデータと同期されておらず、前のものから半分を読み取ることがわかり続けています。前の状態から半分。
VHDL をより合成しやすいものにするには、どのようなデザイン プラクティスを使用する必要がありますか?
どうもありがとうサム