Commit 90228750 authored by Lucas Russo's avatar Lucas Russo

modules/dbe_wishbone/*: add halt/rst logic to AXIS DDR write

This is needed because we can abort an acquisition
in the middle of a transaction, causing the AXI
datamover to be in an inconsistent state.

This fixes #57 github issue.
parent 1cc480d6
......@@ -1583,6 +1583,15 @@ package dbe_wishbone_pkg is
axis_s2mm_pld_tvalid_o : out std_logic;
axis_s2mm_pld_tready_i : in std_logic := '0';
axis_s2mm_rstn_o : out std_logic;
axis_s2mm_halt_o : out std_logic;
axis_s2mm_halt_cmplt_i : in std_logic := '0';
axis_s2mm_allow_addr_req_o : out std_logic;
axis_s2mm_addr_req_posted_i : in std_logic := '0';
axis_s2mm_wr_xfer_cmplt_i : in std_logic := '0';
axis_s2mm_ld_nxt_len_i : in std_logic := '0';
axis_s2mm_wr_len_i : in std_logic_vector(7 downto 0) := (others => '0');
axis_mm2s_cmd_tdata_o : out std_logic_vector(71 downto 0);
axis_mm2s_cmd_tvalid_o : out std_logic;
axis_mm2s_cmd_tready_i : in std_logic := '0';
......
......@@ -751,7 +751,21 @@ package acq_core_pkg is
axis_s2mm_pld_tkeep_o : out std_logic_vector(g_ddr_payload_width/8-1 downto 0);
axis_s2mm_pld_tlast_o : out std_logic;
axis_s2mm_pld_tvalid_o : out std_logic;
axis_s2mm_pld_tready_i : in std_logic
axis_s2mm_pld_tready_i : in std_logic;
axis_s2mm_rstn_o : out std_logic;
axis_s2mm_halt_o : out std_logic;
axis_s2mm_halt_cmplt_i : in std_logic;
axis_s2mm_allow_addr_req_o : out std_logic;
axis_s2mm_addr_req_posted_i : in std_logic;
axis_s2mm_wr_xfer_cmplt_i : in std_logic;
axis_s2mm_ld_nxt_len_i : in std_logic;
axis_s2mm_wr_len_i : in std_logic_vector(7 downto 0);
-- Debug Outputs
dbg_ddr_addr_cnt_axis_o : out std_logic_vector(g_ddr_addr_width-1 downto 0);
dbg_ddr_addr_init_o : out std_logic_vector(g_ddr_addr_width-1 downto 0);
dbg_ddr_addr_max_o : out std_logic_vector(g_ddr_addr_width-1 downto 0)
);
end component;
......
......@@ -93,7 +93,21 @@ port
axis_s2mm_pld_tkeep_o : out std_logic_vector(g_ddr_payload_width/8-1 downto 0);
axis_s2mm_pld_tlast_o : out std_logic;
axis_s2mm_pld_tvalid_o : out std_logic;
axis_s2mm_pld_tready_i : in std_logic
axis_s2mm_pld_tready_i : in std_logic;
axis_s2mm_rstn_o : out std_logic;
axis_s2mm_halt_o : out std_logic;
axis_s2mm_halt_cmplt_i : in std_logic;
axis_s2mm_allow_addr_req_o : out std_logic;
axis_s2mm_addr_req_posted_i : in std_logic;
axis_s2mm_wr_xfer_cmplt_i : in std_logic;
axis_s2mm_ld_nxt_len_i : in std_logic;
axis_s2mm_wr_len_i : in std_logic_vector(7 downto 0);
-- Debug Outputs
dbg_ddr_addr_cnt_axis_o : out std_logic_vector(g_ddr_addr_width-1 downto 0);
dbg_ddr_addr_init_o : out std_logic_vector(g_ddr_addr_width-1 downto 0);
dbg_ddr_addr_max_o : out std_logic_vector(g_ddr_addr_width-1 downto 0)
);
end acq_ddr3_axis_write;
......@@ -267,6 +281,12 @@ architecture rtl of acq_ddr3_axis_write is
signal ddr_rdy_cmd : std_logic;
signal ddr_rdy_pld : std_logic;
-- Halt/Rst signals
type t_hrst_state is (IDLE, HALT_GEN, WAIT_HALT_CMPLT, RST_GEN, RST1, RST2, RST3);
signal ddr_axis_rstn : std_logic := '1';
signal ddr_axis_halt : std_logic := '0';
signal hrst_state : t_hrst_state := IDLE;
begin
assert (g_ddr_payload_width = 256 or g_ddr_payload_width = 512)
......@@ -522,6 +542,11 @@ begin
-- To Flow Control module
ddr_addr_in_axis <= std_logic_vector(ddr_addr_cnt_axis);
-- Debug outputs
dbg_ddr_addr_cnt_axis_o <= std_logic_vector(ddr_addr_cnt_axis);
dbg_ddr_addr_init_o <= std_logic_vector(ddr_addr_init);
dbg_ddr_addr_max_o <= std_logic_vector(ddr_addr_max);
-----------------------------------------------------------------------------
-- Store DDR Trigger address
-----------------------------------------------------------------------------
......@@ -752,6 +777,77 @@ begin
fc_data_id_cmd <= fc_dout(c_acq_header_id_top_idx+c_fc_header_bot_idx downto
c_acq_header_id_bot_idx+c_fc_header_bot_idx);
-----------------------------------------------------------------------------
-- AXIS Soft Shutdown Interface
-----------------------------------------------------------------------------
-- We reset on two situations: a regular reset (startup or reset trigger) or
-- when we abort an acquisition (fsm_stop signal). For this to work seamlessly
-- with AXIS interface, we must drive the halt/rst signals properly
-- First, generate halt signal to force AXIS datamover to shutdown its engine.
-- We can use the same as rst, as it's long enough
-- Secondly, we must look into axis_S2mm_halt_cmplt_i signal. When it completes
-- its shutdown (asserted high),. we must then reset the AXIS core using
-- axis_s2mm_rstn_o signal
-- AXIS Halt/Rst state machine.
p_axis_halt_rst_fsm : process(ext_clk_i)
begin
if rising_edge(ext_clk_i) then
case hrst_state is
-- Waits for a halt command to start
when IDLE =>
ddr_axis_rstn <= '1';
ddr_axis_halt <= '0';
if ext_rst_n_i = '0' then
hrst_state <= HALT_GEN;
end if;
when HALT_GEN =>
ddr_axis_halt <= '1';
hrst_state <= WAIT_HALT_CMPLT;
when WAIT_HALT_CMPLT =>
-- Wait for AXIS core to gracefully shutdown then reset the core
-- and deasserts halt
if axis_s2mm_halt_cmplt_i = '1' then
ddr_axis_halt <= '0';
hrst_state <= RST_GEN;
end if;
-- Generates a reset for the core
when RST_GEN =>
ddr_axis_rstn <= '0';
hrst_state <= RST1;
-- Wait for a minimum of 3 clock cycles for a successful reset
-- (axi datamover v5.1, page 16, table 2-6, about m_axi_s2mm_aresetn)
when RST1 =>
hrst_state <= RST2;
when RST2 =>
hrst_state <= RST3;
-- Deasserts rst and go back to the beginning
when RST3 =>
ddr_axis_rstn <= '1';
hrst_state <= IDLE;
when others =>
ddr_axis_rstn <= '1';
ddr_axis_halt <= '0';
hrst_state <= IDLE;
end case;
end if;
end process;
axis_s2mm_rstn_o <= ddr_axis_rstn;
axis_s2mm_halt_o <= ddr_axis_halt;
-----------------------------------------------------------------------------
-- AXIS Interface
-----------------------------------------------------------------------------
......@@ -792,6 +888,9 @@ begin
axis_s2mm_cmd_tdata_o(c_axis_cmd_tdata_pad_top_idx downto
c_axis_cmd_tdata_pad_bot_idx) <= (others => '0'); -- cmd_pad
-- We always allow address request
axis_s2mm_allow_addr_req_o <= '1';
fc_eop_pld <= '1' when fc_dout(c_eop_high downto c_eop_low) = "1" else '0';
-- To/From AXIS Memory Mapped to Stream Commands
......
......@@ -156,6 +156,15 @@ port
axis_s2mm_pld_tvalid_o : out std_logic;
axis_s2mm_pld_tready_i : in std_logic := '0';
axis_s2mm_rstn_o : out std_logic;
axis_s2mm_halt_o : out std_logic;
axis_s2mm_halt_cmplt_i : in std_logic := '0';
axis_s2mm_allow_addr_req_o : out std_logic;
axis_s2mm_addr_req_posted_i : in std_logic := '0';
axis_s2mm_wr_xfer_cmplt_i : in std_logic := '0';
axis_s2mm_ld_nxt_len_i : in std_logic := '0';
axis_s2mm_wr_len_i : in std_logic_vector(7 downto 0) := (others => '0');
axis_mm2s_cmd_tdata_o : out std_logic_vector(71 downto 0);
axis_mm2s_cmd_tvalid_o : out std_logic;
axis_mm2s_cmd_tready_i : in std_logic := '0';
......@@ -376,6 +385,10 @@ architecture rtl of wb_acq_core is
signal test_data_en : std_logic;
signal ddr_trig_addr : std_logic_vector(g_ddr_addr_width-1 downto 0);
-- Debug outputs
signal dbg_ddr_addr_cnt_axis : std_logic_vector(30 downto 0);
signal dbg_ddr_addr_init : std_logic_vector(30 downto 0);
signal dbg_ddr_addr_max : std_logic_vector(30 downto 0);
------------------------------------------------------------------------------
-- Components
------------------------------------------------------------------------------
......@@ -1070,7 +1083,21 @@ begin
axis_s2mm_pld_tkeep_o => axis_s2mm_pld_tkeep_o,
axis_s2mm_pld_tlast_o => axis_s2mm_pld_tlast_o,
axis_s2mm_pld_tvalid_o => axis_s2mm_pld_tvalid_o,
axis_s2mm_pld_tready_i => axis_s2mm_pld_tready_i
axis_s2mm_pld_tready_i => axis_s2mm_pld_tready_i,
axis_s2mm_rstn_o => axis_s2mm_rstn_o,
axis_s2mm_halt_o => axis_s2mm_halt_o,
axis_s2mm_halt_cmplt_i => axis_s2mm_halt_cmplt_i,
axis_s2mm_allow_addr_req_o => axis_s2mm_allow_addr_req_o,
axis_s2mm_addr_req_posted_i => axis_s2mm_addr_req_posted_i,
axis_s2mm_wr_xfer_cmplt_i => axis_s2mm_wr_xfer_cmplt_i,
axis_s2mm_ld_nxt_len_i => axis_s2mm_ld_nxt_len_i,
axis_s2mm_wr_len_i => axis_s2mm_wr_len_i,
-- Debug Outputs
dbg_ddr_addr_cnt_axis_o => dbg_ddr_addr_cnt_axis,
dbg_ddr_addr_init_o => dbg_ddr_addr_init,
dbg_ddr_addr_max_o => dbg_ddr_addr_max
);
end generate;
......
......@@ -258,6 +258,15 @@ begin
axis_s2mm_cmd_tvalid_o => axis_s2mm_cmd_ma_o.tvalid,
axis_s2mm_cmd_tready_i => axis_s2mm_cmd_ma_i.tready,
axis_s2mm_rstn_o => axis_s2mm_cmd_ma_o.rstn,
axis_s2mm_halt_o => axis_s2mm_cmd_ma_o.halt,
axis_s2mm_halt_cmplt_i => axis_s2mm_cmd_ma_i.halt_cmplt,
axis_s2mm_allow_addr_req_o => axis_s2mm_cmd_ma_o.allow_addr_req,
axis_s2mm_addr_req_posted_i => axis_s2mm_cmd_ma_i.addr_req_posted,
axis_s2mm_wr_xfer_cmplt_i => axis_s2mm_cmd_ma_i.wr_xfer_cmplt,
axis_s2mm_ld_nxt_len_i => axis_s2mm_cmd_ma_i.ld_nxt_len,
axis_s2mm_wr_len_i => axis_s2mm_cmd_ma_i.wr_len,
axis_s2mm_pld_tdata_o => axis_s2mm_pld_ma_o.tdata,
axis_s2mm_pld_tkeep_o => axis_s2mm_pld_ma_o.tkeep,
axis_s2mm_pld_tlast_o => axis_s2mm_pld_ma_o.tlast,
......
......@@ -173,6 +173,8 @@ architecture rtl of wb_acq_core_mux is
-- AXI Data mover signals
signal axi_rst_n_array : std_logic_vector(c_num_max_acq_cores-1 downto 0);
signal axis_s2mm_rst_n_array_or : std_logic_vector(c_num_max_acq_cores-1 downto 0);
signal axis_mm2s_rst_n_array_or : std_logic_vector(c_num_max_acq_cores-1 downto 0);
signal axis_mm2s_cmd_mo_array : t_axis_cmd_master_out_array(g_acq_num_cores-1 downto 0);
signal axis_mm2s_cmd_mi_array : t_axis_cmd_master_in_array(g_acq_num_cores-1 downto 0);
......@@ -300,6 +302,15 @@ begin
axis_s2mm_cmd_tvalid_o => axis_s2mm_cmd_mo_array(i).tvalid,
axis_s2mm_cmd_tready_i => axis_s2mm_cmd_mi_array(i).tready,
axis_s2mm_rstn_o => axis_s2mm_cmd_mo_array(i).rstn,
axis_s2mm_halt_o => axis_s2mm_cmd_mo_array(i).halt,
axis_s2mm_halt_cmplt_i => axis_s2mm_cmd_mi_array(i).halt_cmplt,
axis_s2mm_allow_addr_req_o => axis_s2mm_cmd_mo_array(i).allow_addr_req,
axis_s2mm_addr_req_posted_i => axis_s2mm_cmd_mi_array(i).addr_req_posted,
axis_s2mm_wr_xfer_cmplt_i => axis_s2mm_cmd_mi_array(i).wr_xfer_cmplt,
axis_s2mm_ld_nxt_len_i => axis_s2mm_cmd_mi_array(i).ld_nxt_len,
axis_s2mm_wr_len_i => axis_s2mm_cmd_mi_array(i).wr_len,
axis_s2mm_pld_tdata_o => axis_s2mm_pld_mo_array(i).tdata,
axis_s2mm_pld_tkeep_o => axis_s2mm_pld_mo_array(i).tkeep,
axis_s2mm_pld_tlast_o => axis_s2mm_pld_mo_array(i).tlast,
......@@ -336,15 +347,25 @@ begin
port map (
-- Memory Mapped to Stream
m_axi_mm2s_aclk => ext_clk_i,
m_axi_mm2s_aresetn => axi_rst_n_array(i),
m_axi_mm2s_aresetn => axis_mm2s_rst_n_array_or(i),
mm2s_err => open,
m_axis_mm2s_cmdsts_aclk => ext_clk_i,
m_axis_mm2s_cmdsts_aresetn => axi_rst_n_array(i),
m_axis_mm2s_cmdsts_aresetn => axis_mm2s_rst_n_array_or(i),
s_axis_mm2s_cmd_tvalid => axis_mm2s_cmd_mo_array(i).tvalid,
s_axis_mm2s_cmd_tready => axis_mm2s_cmd_mi_array(i).tready,
s_axis_mm2s_cmd_tdata => axis_mm2s_cmd_mo_array(i).tdata,
s2mm_halt => axis_s2mm_cmd_mo_array(i).halt,
s2mm_halt_cmplt => axis_s2mm_cmd_mi_array(i).halt_cmplt,
s2mm_allow_addr_req => axis_s2mm_cmd_mo_array(i).allow_addr_req,
s2mm_addr_req_posted => axis_s2mm_cmd_mi_array(i).addr_req_posted,
s2mm_wr_xfer_cmplt => axis_s2mm_cmd_mi_array(i).wr_xfer_cmplt,
s2mm_ld_nxt_len => axis_s2mm_cmd_mi_array(i).ld_nxt_len,
s2mm_wr_len => axis_s2mm_cmd_mi_array(i).wr_len,
s2mm_dbg_sel => c_axi_dbg_sel_zeros,
s2mm_dbg_data => open,
m_axis_mm2s_sts_tvalid => open,
m_axis_mm2s_sts_tready => c_axi_sl_one,
m_axis_mm2s_sts_tdata => open,
......@@ -374,10 +395,10 @@ begin
-- Stream to Memory Mapped
m_axi_s2mm_aclk => ext_clk_i,
m_axi_s2mm_aresetn => axi_rst_n_array(i),
m_axi_s2mm_aresetn => axis_s2mm_rst_n_array_or(i),
s2mm_err => open,
m_axis_s2mm_cmdsts_awclk => ext_clk_i,
m_axis_s2mm_cmdsts_aresetn => axi_rst_n_array(i),
m_axis_s2mm_cmdsts_aresetn => axis_s2mm_rst_n_array_or(i),
s_axis_s2mm_cmd_tvalid => axis_s2mm_cmd_mo_array(i).tvalid,
s_axis_s2mm_cmd_tready => axis_s2mm_cmd_mi_array(i).tready,
......@@ -413,6 +434,9 @@ begin
s_axis_s2mm_tvalid => axis_s2mm_pld_mo_array(i).tvalid,
s_axis_s2mm_tready => axis_s2mm_pld_mi_array(i).tready
);
axis_s2mm_rst_n_array_or(i) <= axi_rst_n_array(i) and axis_s2mm_cmd_mo_array(i).rstn;
axis_mm2s_rst_n_array_or(i) <= axi_rst_n_array(i);
end generate;
-- Assign dummy data to other unassigned records. We just need to assign signals
......
......@@ -26,6 +26,7 @@ package bpm_axi_pkg is
-- AXIS CMD constants
constant c_axis_cmd_tdata_width : natural := 72;
constant c_axis_cmd_tkeep_width : natural := c_axis_cmd_tdata_width/8;
constant c_axis_cmd_wr_len_width : natural := 8;
-- CMD Data Ranges
constant c_axis_cmd_tdata_btt_width : natural := 23;
......@@ -60,6 +61,7 @@ package bpm_axi_pkg is
constant c_axi_slv_zero : std_logic_vector(0 downto 0) := "0";
constant c_axi_qos_zeros : std_logic_vector(c_aximm_qos_width-1 downto 0) := (others => '0');
constant c_axi_sl_one : std_logic := '1';
constant c_axi_dbg_sel_zeros : std_logic_vector(3 downto 0) := (others => '0');
-- AXIMM subtypes
subtype t_aximm_id is
......@@ -111,9 +113,12 @@ package bpm_axi_pkg is
std_logic_vector(c_axis_cmd_tdata_width-1 downto 0);
subtype t_axis_cmd_tkeep is
std_logic_vector(c_axis_cmd_tkeep_width-1 downto 0);
subtype t_axis_cmd_wr_len is
std_logic_vector(c_axis_cmd_wr_len_width-1 downto 0);
type t_axis_cmd_tdata_array is array(natural range <>) of t_axis_cmd_tdata;
type t_axis_cmd_tkeep_array is array(natural range <>) of t_axis_cmd_tkeep;
type t_axis_cmd_wr_len_array is array(natural range <>) of t_axis_cmd_wr_len;
-- AXI PLD subtypes
subtype t_axis_pld_tdata is
......@@ -216,16 +221,24 @@ package bpm_axi_pkg is
-- AXIS CMD records
type t_axis_cmd_slave_out is record
tready : std_logic;
tready : std_logic;
halt_cmplt : std_logic;
addr_req_posted : std_logic;
wr_xfer_cmplt : std_logic;
ld_nxt_len : std_logic;
wr_len : t_axis_cmd_wr_len;
end record t_axis_cmd_slave_out;
subtype t_axis_cmd_master_in is t_axis_cmd_slave_out;
type t_axis_cmd_slave_in is record
tvalid : std_logic;
tdata : t_axis_cmd_tdata;
tkeep : t_axis_cmd_tkeep;
tlast : std_logic;
tvalid : std_logic;
tdata : t_axis_cmd_tdata;
tkeep : t_axis_cmd_tkeep;
tlast : std_logic;
rstn : std_logic;
halt : std_logic;
allow_addr_req : std_logic;
end record t_axis_cmd_slave_in;
subtype t_axis_cmd_master_out is t_axis_cmd_slave_in;
......@@ -311,10 +324,13 @@ package bpm_axi_pkg is
(others => 'X');
constant cc_dummy_axis_cmd_tkeep : std_logic_vector(c_axis_cmd_tkeep_width-1 downto 0) :=
(others => 'X');
constant cc_dummy_axis_cmd_wr_len : std_logic_vector(c_axis_cmd_wr_len_width-1 downto 0) :=
(others => 'X');
constant cc_dummy_axis_cmd_slave_in : t_axis_cmd_slave_in :=
('0', cc_dummy_axis_cmd_tdata, cc_dummy_axis_cmd_tkeep, 'X');
constant cc_dummy_axis_cmd_master_in : t_axis_cmd_master_in := (tready => 'X');
('0', cc_dummy_axis_cmd_tdata, cc_dummy_axis_cmd_tkeep, 'X', '1', '0', '1');
constant cc_dummy_axis_cmd_master_in : t_axis_cmd_master_in := ('X',
'0', 'X', 'X', 'X', cc_dummy_axis_cmd_wr_len);
-- AXIS PLD dummy constants
constant cc_dummy_axis_pld_tdata : std_logic_vector(c_axis_pld_tdata_width-1 downto 0) :=
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment