Commit 5818355e authored by Tomasz Wlostowski's avatar Tomasz Wlostowski Committed by Tristan Gingold

rtl/acam_databus_interface: make design fully synchronous, extend read cycle…

rtl/acam_databus_interface: make design fully synchronous, extend read cycle length to ensure correct Empty Flag timing
parent 560fc342
...@@ -81,6 +81,7 @@ use IEEE.NUMERIC_STD.all; -- conversion functions ...@@ -81,6 +81,7 @@ use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library -- Specific library
library work; library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities use work.tdc_core_pkg.all; -- definitions of types, constants, entities
use work.gencores_pkg.all;
--================================================================================================= --=================================================================================================
...@@ -123,7 +124,7 @@ entity acam_databus_interface is ...@@ -123,7 +124,7 @@ entity acam_databus_interface is
wr_n_o : out std_logic; -- ACAM write enable, active low wr_n_o : out std_logic; -- ACAM write enable, active low
-- Signals to the data_engine unit -- Signals to the data_engine unit
ack_o : out std_logic; -- WISHBONE ack ack_o : out std_logic; -- WISHBONE ack
dat_o : out std_logic_vector(31 downto 0)); -- ef1 & ef2 & 0 & 0 & 28 bits ACAM data_bus_io dat_o : out std_logic_vector(31 downto 0)); -- ef1 & ef2 & 0 & 0 & 28 bits ACAM data_bus_io
end acam_databus_interface; end acam_databus_interface;
...@@ -135,12 +136,13 @@ end acam_databus_interface; ...@@ -135,12 +136,13 @@ end acam_databus_interface;
architecture rtl of acam_databus_interface is architecture rtl of acam_databus_interface is
type t_acam_interface is (IDLE, RD_START, RD_FETCH, RD_ACK, WR_START, WR_PUSH, WR_ACK); type t_acam_interface is (IDLE, RD_START, RD_FETCH, RD_FETCH2, RD_FETCH3, RD_ACK, WR_START, WR_PUSH, WR_ACK);
signal acam_data_st, nxt_acam_data_st : t_acam_interface; signal acam_data_st, nxt_acam_data_st : t_acam_interface;
signal ef1_synch, ef2_synch : std_logic_vector(1 downto 0) := (others =>'1'); signal ef1_synch, ef2_synch : std_logic;
signal ack, rd, rd_extend : std_logic; signal ack, rd, rd_extend : std_logic;
signal wr, wr_extend, wr_remove : std_logic; signal wr, wr_extend, wr_remove : std_logic;
signal rst_n : std_logic;
--================================================================================================= --=================================================================================================
-- architecture begin -- architecture begin
...@@ -149,33 +151,31 @@ begin ...@@ -149,33 +151,31 @@ begin
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
-- Input Synchronizers -- -- Input Synchronizers --
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
-- Do not convert this to gc_sync_ffs, the ACAM readout process depends on it. rst_n <= not rst_i;
-- see also data_engine_fsm_comb process in data_engine.vhd.
-- Because there is a reset, Xilinx will not use shift registers here and the
-- sync chain will be implemented using FFs, no need for a "shreg_extract" attribute.
input_registers: process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
ef1_synch <= (others =>'1');
ef2_synch <= (others =>'1');
else
ef1_synch <= ef1_i & ef1_synch(1);
ef2_synch <= ef2_i & ef2_synch(1);
end if;
end if;
end process;
cmp_sync_ef1: gc_sync_ffs
port map (
clk_i => clk_i,
rst_n_i => rst_n,
data_i => ef1_i,
synced_o => ef1_synch);
cmp_sync_ef2: gc_sync_ffs
port map (
clk_i => clk_i,
rst_n_i => rst_n,
data_i => ef2_i,
synced_o => ef2_synch);
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
-- FSM -- -- FSM --
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
-- The following state machine implements the slave side of the WISHBONE interface -- The following state machine implements the slave side of the WISHBONE interface
-- and converts the signals for the ACAM proprietary bus interface. The interface respects the -- and converts the signals for the ACAM proprietary bus interface. The interface respects the
-- timings specified in page 7 of the ACAM datasheet. -- timings specified in page 7 of the ACAM datasheet.
databus_access_seq_fsm: process (clk_i) databus_access_seq_fsm: process (clk_i)
begin begin
if rising_edge (clk_i) then if rising_edge (clk_i) then
...@@ -212,20 +212,42 @@ begin ...@@ -212,20 +212,42 @@ begin
nxt_acam_data_st <= IDLE; nxt_acam_data_st <= IDLE;
end if; end if;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_START => when RD_START =>
----------------------------------------------- -----------------------------------------------
ack <= '0'; ack <= '0';
rd_extend <= '1'; rd_extend <= '1';
wr_extend <= '0'; wr_extend <= '0';
wr_remove <= '0'; wr_remove <= '0';
----------------------------------------------- -----------------------------------------------
nxt_acam_data_st <= RD_FETCH; nxt_acam_data_st <= RD_FETCH;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_FETCH => when RD_FETCH =>
-----------------------------------------------
ack <= '0';
rd_extend <= '1';
wr_extend <= '0';
wr_remove <= '0';
-----------------------------------------------
nxt_acam_data_st <= RD_FETCH2;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_FETCH2 =>
-----------------------------------------------
ack <= '0';
rd_extend <= '1';
wr_extend <= '0';
wr_remove <= '0';
-----------------------------------------------
nxt_acam_data_st <= RD_FETCH3;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when RD_FETCH3 =>
----------------------------------------------- -----------------------------------------------
ack <= '0'; ack <= '0';
rd_extend <= '1'; rd_extend <= '1';
...@@ -248,7 +270,7 @@ begin ...@@ -248,7 +270,7 @@ begin
nxt_acam_data_st <= IDLE; nxt_acam_data_st <= IDLE;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_START => when WR_START =>
----------------------------------------------- -----------------------------------------------
ack <= '0'; ack <= '0';
...@@ -258,7 +280,7 @@ begin ...@@ -258,7 +280,7 @@ begin
----------------------------------------------- -----------------------------------------------
nxt_acam_data_st <= WR_PUSH; nxt_acam_data_st <= WR_PUSH;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_PUSH => when WR_PUSH =>
...@@ -270,7 +292,7 @@ begin ...@@ -270,7 +292,7 @@ begin
----------------------------------------------- -----------------------------------------------
nxt_acam_data_st <= WR_ACK; nxt_acam_data_st <= WR_ACK;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when WR_ACK => when WR_ACK =>
...@@ -282,7 +304,7 @@ begin ...@@ -282,7 +304,7 @@ begin
----------------------------------------------- -----------------------------------------------
nxt_acam_data_st <= IDLE; nxt_acam_data_st <= IDLE;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
when others => when others =>
----------------------------------------------- -----------------------------------------------
...@@ -300,12 +322,12 @@ begin ...@@ -300,12 +322,12 @@ begin
ack_o <= ack; ack_o <= ack;
-- to the 28 bits databus output we add the ef flags to arrive to a 32 bits word -- to the 28 bits databus output we add the ef flags to arrive to a 32 bits word
dat_o <= ef1_synch(0) & ef2_synch(0) & "00" & data_bus_io; dat_o <= ef1_synch & ef2_synch & "00" & data_bus_io;
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
-- Outputs to ACAM -- -- Outputs to ACAM --
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
output_registers: process (clk_i) output_registers: process (clk_i)
begin begin
...@@ -324,7 +346,7 @@ output_registers: process (clk_i) ...@@ -324,7 +346,7 @@ output_registers: process (clk_i)
oe_n_o <= '1'; oe_n_o <= '1';
rd <= ((stb_i and cyc_i and not(we_i)) or rd_extend) and (not(ack)); rd <= ((stb_i and cyc_i and not(we_i)) or rd_extend) and (not(ack));
wr <= ((stb_i and cyc_i and we_i) or wr_extend) and (not(wr_remove)) and (not(ack)); wr <= ((stb_i and cyc_i and we_i) or wr_extend) and (not(wr_remove)) and (not(ack));
-- the wr signal has to be removed to respect the ACAM specs -- the wr signal has to be removed to respect the ACAM specs
data_bus_io <= dat_i(27 downto 0) when we_i='1' else (others =>'Z'); data_bus_io <= dat_i(27 downto 0) when we_i='1' else (others =>'Z');
adr_o <= adr_i(3 downto 0); adr_o <= adr_i(3 downto 0);
...@@ -334,12 +356,8 @@ output_registers: process (clk_i) ...@@ -334,12 +356,8 @@ output_registers: process (clk_i)
-- EF to the data_engine -- -- EF to the data_engine --
--------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------
ef1_o <= ef1_synch(0); -- ef1 after two synchronization registers ef1_o <= ef1_synch; -- ef1 after two synchronization registers
ef1_meta_o <= ef1_synch(1); -- ef1 after one synchronization register ef2_o <= ef2_synch; -- ef1 after two synchronization registers
ef2_o <= ef2_synch(0); -- ef1 after two synchronization registers
ef2_meta_o <= ef2_synch(1); -- ef1 after one synchronization register
end rtl; end rtl;
--================================================================================================= --=================================================================================================
......
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