Я пытаюсь использовать компонент памяти DDR3 на моей плате Arty (https://reference.digilentinc.com/reference/programmable-logic/arty/reference-manual?redirect=1),, в которой есть часть памяти MT41K128M16JT-125 от Micron.
ПЛИС представляет собой Artix-7 xc7a35ticsg324-1L.
Я реализовал свой проект на VHDL и использую IP-адрес MIG для создания примера проекта, из которого я написал свой собственный файл "top_level.vhd".
В файле "top_level.vhd" компоненты UART_RX
и UART_TX
предназначены для передачи байтов данных с использованием UART, а компонент mig_7series_o
сгенерирован инструментом MIG.
Я разделил свой вопрос на более мелкие сегменты:
1) Насколько я понял, MIG будет сам генерировать тактовые сигналы и подавать мне тактовый сигнал ui_clk
, который в моем коде называется clk
.
Но когда код синтезирован, я подозреваю, что тактовый сигнал не работает должным образом, и это приводит к тому, что весь мой дизайн вообще не работает. Может ли кто-нибудь дать мне представление о том, как заставить часы работать как надо?
2) Кроме того, я не могу смоделировать свой дизайн, так как у меня нет модели для ОЗУ, но, насколько я понял, мой дизайн должен быть в Verilog, чтобы использовать Microns Моделирование ОЗУ моделей, которых нет. Это привело меня к ситуации, когда я должен синтезировать проект, чтобы проверить, работает ли он, что делает его отладку довольно сложной.
3) Или, может быть, есть кто-то, у кого есть рабочий интерфейс на плате Arty (или аналогичной плате), который был бы так рад поделиться модулем для взаимодействия с оперативной памятью DDR3?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity top_level is
Port (
-- Inouts
ddr3_dq : inout std_logic_vector(31 downto 0);
ddr3_dqs_p : inout std_logic_vector(3 downto 0);
ddr3_dqs_n : inout std_logic_vector(3 downto 0);
-- Outputs
ddr3_addr : out std_logic_vector(13 downto 0);
ddr3_ba : out std_logic_vector(2 downto 0);
ddr3_ras_n : out std_logic;
ddr3_cas_n : out std_logic;
ddr3_we_n : out std_logic;
ddr3_reset_n : out std_logic;
ddr3_ck_p : out std_logic_vector(0 downto 0);
ddr3_ck_n : out std_logic_vector(0 downto 0);
ddr3_cke : out std_logic_vector(0 downto 0);
ddr3_cs_n : out std_logic_vector(0 downto 0);
ddr3_dm : out std_logic_vector(3 downto 0);
ddr3_odt : out std_logic_vector(0 downto 0);
-- Inputs
-- Differential system clocks
sys_clk_p : in std_logic;
sys_clk_n : in std_logic;
-- differential iodelayctrl clk (reference clock)
clk_ref_p : in std_logic;
clk_ref_n : in std_logic;
tg_compare_error : out std_logic;
init_calib_complete : out std_logic;
-- System reset - Default polarity of sys_rst pin is Active Low.
-- System reset polarity will change based on the option
-- selected in GUI.
sys_rst : in std_logic;
led1 : out std_logic;
led2 : out std_logic;
but : in std_logic_vector(3 downto 0);
rx_bit : in std_logic;
tx_bit : out std_logic
--test_clock : in std_logic
);
end top_level;
architecture Behavioral of top_level is
component UART_RX
generic (
g_CLKS_PER_BIT : integer := 723 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_RX_Serial : in std_logic;
o_RX_DV : out std_logic;
o_RX_Byte : out std_logic_vector(7 downto 0)
);
end component;
component UART_TX
generic (
g_CLKS_PER_BIT : integer := 723 -- Needs to be set correctly
);
port (
i_Clk : in std_logic;
i_TX_DV : in std_logic;
i_TX_Byte : in std_logic_vector(7 downto 0);
o_TX_Active : out std_logic;
o_TX_Serial : out std_logic;
o_TX_Done : out std_logic
);
end component;
component mig_7series_0
port(
ddr3_dq : inout std_logic_vector(31 downto 0);
ddr3_dqs_p : inout std_logic_vector(3 downto 0);
ddr3_dqs_n : inout std_logic_vector(3 downto 0);
ddr3_addr : out std_logic_vector(13 downto 0);
ddr3_ba : out std_logic_vector(2 downto 0);
ddr3_ras_n : out std_logic;
ddr3_cas_n : out std_logic;
ddr3_we_n : out std_logic;
ddr3_reset_n : out std_logic;
ddr3_ck_p : out std_logic_vector(0 downto 0);
ddr3_ck_n : out std_logic_vector(0 downto 0);
ddr3_cke : out std_logic_vector(0 downto 0);
ddr3_cs_n : out std_logic_vector(0 downto 0);
ddr3_dm : out std_logic_vector(3 downto 0);
ddr3_odt : out std_logic_vector(0 downto 0);
app_addr : in std_logic_vector(27 downto 0);
app_cmd : in std_logic_vector(2 downto 0);
app_en : in std_logic;
app_wdf_data : in std_logic_vector(255 downto 0);
app_wdf_end : in std_logic;
app_wdf_mask : in std_logic_vector(31 downto 0);
app_wdf_wren : in std_logic;
app_rd_data : out std_logic_vector(255 downto 0);
app_rd_data_end : out std_logic;
app_rd_data_valid : out std_logic;
app_rdy : out std_logic;
app_wdf_rdy : out std_logic;
app_sr_req : in std_logic;
app_ref_req : in std_logic;
app_zq_req : in std_logic;
app_sr_active : out std_logic;
app_ref_ack : out std_logic;
app_zq_ack : out std_logic;
ui_clk : out std_logic;
ui_clk_sync_rst : out std_logic;
init_calib_complete : out std_logic;
-- System Clock Ports
sys_clk_p : in std_logic;
sys_clk_n : in std_logic;
-- Reference Clock Ports
clk_ref_p : in std_logic;
clk_ref_n : in std_logic;
device_temp : out std_logic_vector(11 downto 0);
sys_rst : in std_logic
);
end component mig_7series_0;
constant DATA_WIDTH : integer := 32;
constant PAYLOAD_WIDTH : integer := DATA_WIDTH;
constant nCK_PER_CLK : integer := 4;
constant ADDR_WIDTH : integer := 28;
constant APP_DATA_WIDTH : integer := 2*nCK_PER_CLK * PAYLOAD_WIDTH;
constant APP_MASK_WIDTH : integer := APP_DATA_WIDTH / 8;
signal app_addr : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal init_calib_complete_i : std_logic;
signal device_temp : std_logic_vector(11 downto 0);
signal app_cmd : std_logic_vector(2 downto 0);
signal app_en : std_logic;
signal app_rdy : std_logic;
signal app_wdf_data : std_logic_vector(APP_DATA_WIDTH-1 downto 0);
signal app_wdf_end : std_logic;
signal app_ref_ack : std_logic;
signal app_zq_ack : std_logic;
signal app_wdf_wren : std_logic;
signal app_rd_data : std_logic_vector(APP_DATA_WIDTH-1 downto 0);
signal app_rd_data_end : std_logic;
signal app_rd_data_valid : std_logic;
signal app_wdf_mask : std_logic_vector(APP_MASK_WIDTH-1 downto 0);
signal app_wdf_rdy : std_logic;
signal app_sr_active : std_logic;
signal clk : std_logic;
--Mine signaler
type state_type is (reset, init, idle, prep_write, do_write, do_wait_after_write, prep_read, do_read, do_wait_after_read, clean_up, end_state);
signal state : state_type;
type init_state_type is (step1, step2, step3, step4);
signal init_state : init_state_type;
signal init_count : integer range 0 to 127 := 0;
constant c_CLKS_PER_BIT : integer := 723;
signal tx_done, rx_dv, tx_active, tx_dv, wait_for_tx_done, wait_for_but_release : STD_LOGIC;
signal tx_byte, rx_byte : STD_LOGIC_VECTOR(7 downto 0);
signal count : integer range 0 to 127 := 0;
signal data_read : std_logic_vector(31 downto 0);
signal first_init : std_logic := '1';
signal sys_rst_test, rst : std_logic := '1';
begin
x2: UART_RX generic map (
g_CLKS_PER_BIT => c_CLKS_PER_BIT
)
port map( i_Clk => clk,
i_RX_Serial => rx_bit,
o_RX_DV => rx_dv,
o_RX_Byte => rx_byte);
x3: UART_TX generic map (
g_CLKS_PER_BIT => c_CLKS_PER_BIT
)
port map( i_Clk => clk,
i_TX_DV => tx_dv,
i_TX_Byte => tx_byte,
o_TX_Active => tx_active,
o_TX_Serial => tx_bit,
o_TX_Done => tx_done);
u_mig_7series_0 : mig_7series_0
port map (
-- Memory interface ports
ddr3_addr => ddr3_addr,
ddr3_ba => ddr3_ba,
ddr3_cas_n => ddr3_cas_n,
ddr3_ck_n => ddr3_ck_n,
ddr3_ck_p => ddr3_ck_p,
ddr3_cke => ddr3_cke,
ddr3_ras_n => ddr3_ras_n,
ddr3_reset_n => ddr3_reset_n,
ddr3_we_n => ddr3_we_n,
ddr3_dq => ddr3_dq,
ddr3_dqs_n => ddr3_dqs_n,
ddr3_dqs_p => ddr3_dqs_p,
init_calib_complete => init_calib_complete_i,
device_temp => device_temp,
ddr3_cs_n => ddr3_cs_n,
ddr3_dm => ddr3_dm,
ddr3_odt => ddr3_odt,
-- Application interface ports
app_addr => app_addr,
app_cmd => app_cmd,
app_en => app_en,
app_wdf_data => app_wdf_data,
app_wdf_end => app_wdf_end,
app_wdf_wren => app_wdf_wren,
app_rd_data => app_rd_data,
app_rd_data_end => app_rd_data_end,
app_rd_data_valid => app_rd_data_valid,
app_rdy => app_rdy,
app_wdf_rdy => app_wdf_rdy,
app_sr_req => '0',
app_ref_req => '0',
app_zq_req => '0',
app_sr_active => app_sr_active,
app_ref_ack => app_ref_ack,
app_zq_ack => app_zq_ack,
ui_clk => clk,
ui_clk_sync_rst => rst,
app_wdf_mask => app_wdf_mask,
-- System Clock Ports
sys_clk_p => sys_clk_p,
sys_clk_n => sys_clk_n,
-- Reference Clock Ports
clk_ref_p => clk_ref_p,
clk_ref_n => clk_ref_n,
sys_rst => sys_rst
);
process(clk)
begin
-- if(rising_edge(clk)) then
-- if(but(0) = '1') then
-- rst <= '1';
-- end if;
-- end if;
if(rising_edge(clk)) then
case(state) is
when reset =>
--rst <= '1';
led1 <= '0';
led2 <= '0';
state <= init;
when init =>
led2 <= '1';
-- if(count > 20) then
-- rst <= '0';
-- else
-- count <= count + 1;
-- rst <= '1';
-- end if;
--rst <= '0';
app_en <= '0';
app_wdf_end <= '0';
app_wdf_wren <= '0';
app_addr <= (others => '0');
app_cmd <= (others => '0');
app_wdf_data <= (others => '0');
app_wdf_mask <= (others => '0');
if(init_calib_complete_i = '1') then
--led2 <= '1';
state <= idle;
end if;
when idle =>
led1 <= '1';
--led2 <= '1';
tx_dv <= '1';
tx_byte <= X"47";
state <= end_state;
when end_state =>
--led1 <= '1';
--led2 <= '1';
tx_dv <= '0';
when others =>
state <= idle;
end case;
end if;
end process;
end Behavioral;