From ba044cda0a97a76952cea09ab06f778ae2d14bc2 Mon Sep 17 00:00:00 2001 From: Tobias Weber Date: Wed, 17 Oct 2018 10:07:44 +0200 Subject: [PATCH] trying to improve timing with trbnet clock. somewhat successfull. --- .../sources/Datapath/MuPixDataLink_new.vhd | 30 ++-- mupix/Mupix8/sources/MupixBoard.vhd | 16 +- .../sources/Simulation/FrameGeneratorMux.vhd | 16 +- .../Mupix8/sources/Simulation/Generator3.vhd | 49 +++--- .../sources/Simulation/LinkSimulation.vhd | 31 ++-- .../sources/Simulation/Mupix8StateMachine.vhd | 10 +- .../sources/SlowControl/MupixBoardDAC.vhd | 17 +- .../sources/SlowControl/PixelControl.vhd | 71 ++++---- mupix/Mupix8/tb/CircularMemoryTest.vhd | 160 +++++++++++++----- mupix/Mupix8/tb/DataGenTest.vhd | 16 +- mupix/Mupix8/tb/ReadoutControllerTest.vhd | 24 ++- mupix/Mupix8/trb3_periph.prj | 3 + 12 files changed, 273 insertions(+), 170 deletions(-) diff --git a/mupix/Mupix8/sources/Datapath/MuPixDataLink_new.vhd b/mupix/Mupix8/sources/Datapath/MuPixDataLink_new.vhd index 078104b..e681891 100644 --- a/mupix/Mupix8/sources/Datapath/MuPixDataLink_new.vhd +++ b/mupix/Mupix8/sources/Datapath/MuPixDataLink_new.vhd @@ -1,5 +1,6 @@ ------------------------------------------------------------------ --- Mupix data 10b8b readout with internal FIFO +-- Mupix data 10b8b readout with internal FIFO and Unpacker +-- relation between Mupix data out and serdes input: --T. Weber, Ruhr Universität Bochum ------------------------------------------------------------------ library ieee; @@ -160,6 +161,11 @@ architecture rtl of MupixDataLinkWithUnpacker is signal reset_quad_i : std_logic := '0'; signal reset_fifos_i : std_logic := '0'; + signal SLV_READ_IN_i : std_logic; + signal SLV_WRITE_IN_i : std_logic; + signal SLV_DATA_IN_i : std_logic_vector(31 downto 0); + signal SLV_ADDR_IN_i : std_logic_vector(15 downto 0); + begin gen_receive_clock_rec : if g_useRecoveredClock = c_Yes generate @@ -601,28 +607,32 @@ begin slv_unknown_addr_out <= '0'; reset_quad_i <= '0'; reset_fifos_i <= '0'; - if slv_write_in = '1' then - case slv_addr_in is + SLV_ADDR_IN_i <= SLV_ADDR_IN; + SLV_DATA_IN_i <= SLV_DATA_IN; + SLV_READ_IN_i <= SLV_READ_IN; + SLV_WRITE_IN_i <= SLV_WRITE_IN; + if SLV_WRITE_IN_i = '1' then + case SLV_ADDR_IN_i is when x"0160" => slv_ack_out <= '1'; - reset_counters_i <= slv_data_in(0); + reset_counters_i <= SLV_DATA_IN_i(0); when x"0161" => slv_ack_out <= '1'; - reset_quad_i <= slv_data_in(0); + reset_quad_i <= SLV_DATA_IN_i(0); when x"0162" => slv_ack_out <= '1'; - reset_fifos_i <= slv_data_in(0); + reset_fifos_i <= SLV_DATA_IN_i(0); when x"0163" => slv_ack_out <= '1'; - serdes_channel_select <= to_integer(unsigned(slv_data_in(1 downto 0))); + serdes_channel_select <= to_integer(unsigned(SLV_DATA_IN_i(1 downto 0))); when x"016c" => - fifo_enable_i <= slv_data_in(3 downto 0); + fifo_enable_i <= SLV_DATA_IN_i(3 downto 0); slv_ack_out <= '1'; when others => slv_unknown_addr_out <= '1'; end case; - elsif slv_read_in = '1' then - case slv_addr_in is + elsif SLV_READ_IN_i = '1' then + case SLV_ADDR_IN_i is when x"0163" => slv_ack_out <= '1'; slv_data_out(1 downto 0) <= std_logic_vector(to_unsigned(serdes_channel_select, 2)); diff --git a/mupix/Mupix8/sources/MupixBoard.vhd b/mupix/Mupix8/sources/MupixBoard.vhd index 2234a22..3fad486 100644 --- a/mupix/Mupix8/sources/MupixBoard.vhd +++ b/mupix/Mupix8/sources/MupixBoard.vhd @@ -21,7 +21,7 @@ entity MupixBoard8 is --Clock signal clk : in std_logic; --trb system clock for slow control fast_clk : in std_logic; --200 MHz clock for hitbus sampling - data_clk : in std_logic; --mupix clock + data_clk : in std_logic; --mupix clock reset : in std_logic; --reset input --slow control signals @@ -37,8 +37,8 @@ entity MupixBoard8 is dac4_dout : in std_logic; --serial data in from threshold dac spi_clk : out std_logic; --serial clock spi_din : out std_logic; --serial data out - spi_ld_tmp_dac : out std_logic; --load temperature dac - spi_cs_adc : out std_logic; --load adc + spi_ld_tmp_dac : out std_logic; --load temperature dac + spi_cs_adc : out std_logic; --load adc spi_ld_thres : out std_logic; --load threshold and injection dac hitbus : in std_logic; --hitbus signal @@ -47,7 +47,7 @@ entity MupixBoard8 is --resets timestampreset_in : in std_logic; --time stamp reset - eventcounterreset_in : in std_logic; --event number reset + eventcounterreset_in : in std_logic; --event number reset --TRB trigger connections TIMING_TRG_IN : in std_logic; @@ -185,7 +185,7 @@ architecture Behavioral of MupixBoard8 is spi_dout_adc : in std_logic; --adc serial data from board spi_clk : out std_logic; --serial clock spi_din : out std_logic; --serial data out - spi_ld_tmp_dac : out std_logic; --load temperature dac + spi_ld_tmp_dac : out std_logic; --load temperature dac spi_ld_thres : out std_logic; --load threshold and injection dac spi_cs_adc : out std_logic; --load adc injection_pulse : out std_logic; --injection pulse to board @@ -367,7 +367,7 @@ begin -- Behavioral PORT_NUMBER => NUM_PORTS, PORT_ADDRESSES => ( - 0 => x"0070", -- Hitbus Histograms + 0 => x"0070", -- Hitbus Histograms 1 => x"0080", -- Mupix DAC and Pixel Control 2 => x"0090", -- Board Control 3 => x"0100", -- mupix readout @@ -376,7 +376,7 @@ begin -- Behavioral 6 => x"0160", -- mupix serdes others => x"0000"), PORT_ADDR_MASK => ( - 0 => 4, -- HitBus Histograms + 0 => 4, -- HitBus Histograms 1 => 4, -- Mupix DAC and Pixel Control 2 => 4, -- Board Control 3 => 4, -- mupix readout @@ -401,7 +401,7 @@ begin -- Behavioral DAT_NO_MORE_DATA_OUT => REGIO_NO_MORE_DATA_OUT, DAT_UNKNOWN_ADDR_OUT => REGIO_UNKNOWN_ADDR_OUT, - -- Control Registers + -- Control Registers BUS_READ_ENABLE_OUT => slv_read, BUS_WRITE_ENABLE_OUT => slv_write, BUS_DATA_OUT => slv_data_wr, diff --git a/mupix/Mupix8/sources/Simulation/FrameGeneratorMux.vhd b/mupix/Mupix8/sources/Simulation/FrameGeneratorMux.vhd index fa478ac..1f8fc33 100644 --- a/mupix/Mupix8/sources/Simulation/FrameGeneratorMux.vhd +++ b/mupix/Mupix8/sources/Simulation/FrameGeneratorMux.vhd @@ -48,8 +48,8 @@ architecture Behavioral of FrameGeneratorMux is clk : in std_logic; reset : in std_logic; start_gen : in std_logic; - data_num : in std_logic_vector(31 downto 0); - data_pause : in std_logic_vector(31 downto 0); + data_num : in std_logic_vector(15 downto 0); + data_pause : in std_logic_vector(15 downto 0); data_down : in std_logic_vector(31 downto 0); chan_sel : in std_logic_vector(1 downto 0); data_out : out std_logic_vector(iWIDTH - 1 downto 0); @@ -116,8 +116,8 @@ architecture Behavioral of FrameGeneratorMux is -- Internal signals: Data Generator signal gen_start : std_logic := '0'; - signal gen_num : std_logic_vector(31 downto 0) := (others => '0'); - signal gen_pause : std_logic_vector(31 downto 0) := (others => '0'); + signal gen_num : std_logic_vector(15 downto 0) := (others => '0'); + signal gen_pause : std_logic_vector(15 downto 0) := (others => '0'); signal gen_down : std_logic_vector(31 downto 0) := (others => '0'); signal gen_wren : std_logic_vector(3 downto 0) := (others => '0'); signal gen_chansel : chan_type := ("00", "01", "10", "11"); @@ -229,10 +229,10 @@ begin -- Behavioral if SLV_READ_IN_i = '1' then case SLV_ADDR_IN_i is when x"0141" => - SLV_DATA_OUT <= gen_num; + SLV_DATA_OUT(15 downto 0) <= gen_num; SLV_ACK_OUT <= '1'; when x"0142" => - SLV_DATA_OUT <= gen_pause; + SLV_DATA_OUT(15 downto 0) <= gen_pause; SLV_ACK_OUT <= '1'; when x"0143" => SLV_DATA_OUT <= gen_down; @@ -250,10 +250,10 @@ begin -- Behavioral gen_start <= SLV_DATA_IN_i(0); SLV_ACK_OUT <= '1'; when x"0141" => - gen_num <= SLV_DATA_IN_i; + gen_num <= SLV_DATA_IN_i(15 downto 0); SLV_ACK_OUT <= '1'; when x"0142" => - gen_pause <= SLV_DATA_IN_i; + gen_pause <= SLV_DATA_IN_i(15 downto 0); SLV_ACK_OUT <= '1'; when x"0143" => gen_down <= SLV_DATA_IN_i; diff --git a/mupix/Mupix8/sources/Simulation/Generator3.vhd b/mupix/Mupix8/sources/Simulation/Generator3.vhd index fe052e7..fe49418 100644 --- a/mupix/Mupix8/sources/Simulation/Generator3.vhd +++ b/mupix/Mupix8/sources/Simulation/Generator3.vhd @@ -20,8 +20,8 @@ entity Generator3 is clk : in std_logic; reset : in std_logic; start_gen : in std_logic; - data_num : in std_logic_vector(31 downto 0); - data_pause : in std_logic_vector(31 downto 0); + data_num : in std_logic_vector(15 downto 0); + data_pause : in std_logic_vector(15 downto 0); data_down : in std_logic_vector(31 downto 0); chan_sel : in std_logic_vector(1 downto 0); data_out : out std_logic_vector(iWIDTH - 1 downto 0); @@ -34,16 +34,16 @@ architecture Behavior of Generator3 is type state is (idle, gen, pause, down); type chan_type is array (0 to 3) of std_logic_vector(15 downto 0); - signal data_fsm : state := idle; - signal writeEn_int : std_logic := '0'; - signal num_ctr : unsigned(31 downto 0) := (others => '0'); - signal pause_ctr : unsigned(31 downto 0) := (others => '0'); - signal down_ctr : unsigned(31 downto 0) := (others => '0'); + signal data_fsm : state := idle; + signal writeEn_int : std_logic := '0'; + signal num_ctr, num_ctr_reg : unsigned(15 downto 0) := (others => '0'); + signal pause_ctr, pause_ctr_reg : unsigned(15 downto 0) := (others => '0'); + signal down_ctr, down_ctr_reg : unsigned(31 downto 0) := (others => '0'); constant chan_sig : chan_type := ( - 0 => x"C01C", - 1 => x"C02C", - 2 => x"C03C", - 3 => x"C04C" + 0 => x"AAC0", + 1 => x"BBC1", + 2 => x"CCC2", + 3 => x"DDC3" ); signal data_out_i : std_logic_vector(iWIDTH - 1 downto 0) := (others => '0'); @@ -61,6 +61,9 @@ begin writeEn_int <= '0'; else + num_ctr_reg <= num_ctr; + pause_ctr_reg <= pause_ctr; + down_ctr_reg <= down_ctr; case data_fsm is when idle => @@ -76,12 +79,10 @@ begin when gen => if unsigned(data_num) > 0 then - pause_ctr <= (others => '0'); - down_ctr <= (others => '0'); writeEn_int <= '1'; num_ctr <= num_ctr + 1; - if num_ctr < unsigned(data_num) - 1 then - if unsigned(data_pause) > 0 then + if num_ctr_reg < unsigned(data_num) then + if unsigned(data_pause) > 1 then data_fsm <= pause; else data_fsm <= gen; @@ -95,12 +96,13 @@ begin when pause => writeEn_int <= '0'; - if unsigned(data_pause) > 0 then - if pause_ctr < unsigned(data_pause) - 1 then + if unsigned(data_pause) > 1 then + if pause_ctr_reg < unsigned(data_pause) - 1 then data_fsm <= pause; pause_ctr <= pause_ctr + 1; else - data_fsm <= gen; + data_fsm <= gen; + pause_ctr <= (others => '0'); end if; else data_fsm <= idle; @@ -109,8 +111,9 @@ begin when down => writeEn_int <= '0'; num_ctr <= (others => '0'); - if unsigned(data_down) > 0 then - if down_ctr < unsigned(data_down) - 1 then + down_ctr <= (others => '0'); + if unsigned(data_down) > 1 then + if down_ctr_reg < unsigned(data_down) - 1 then data_fsm <= down; down_ctr <= down_ctr + 1; else @@ -122,7 +125,7 @@ begin end case; end if; writeEn_i <= writeEn_int; - data_out_i <= chan_sig(to_integer(unsigned(chan_sel))) & std_logic_vector(num_ctr(15 downto 0)) & x"BE"; + data_out_i <= chan_sig(to_integer(unsigned(chan_sel))) & std_logic_vector(num_ctr_reg(15 downto 0)) & x"BE"; end if; end process generator; @@ -130,8 +133,8 @@ begin begin -- process output if rising_edge(clk) then -- rising clock edge if reset = '1' then -- synchronous reset (active lowhigh) - writeEn <= '0'; - data_out <= (others => '0'); + writeEn <= '0'; + data_out <= (others => '0'); else writeEn <= writeEn_i; data_out <= data_out_i; diff --git a/mupix/Mupix8/sources/Simulation/LinkSimulation.vhd b/mupix/Mupix8/sources/Simulation/LinkSimulation.vhd index 6ab27c1..878a8f1 100644 --- a/mupix/Mupix8/sources/Simulation/LinkSimulation.vhd +++ b/mupix/Mupix8/sources/Simulation/LinkSimulation.vhd @@ -88,7 +88,7 @@ begin -- architecture rtl register_reset_data: process (data_clk_i) is begin -- process register_reset_data if rising_edge(data_clk_i) then -- rising clock edge - reset_reg2 <= reset_reg; + reset_reg2 <= reset; end if; end process register_reset_data; @@ -101,16 +101,6 @@ begin -- architecture rtl LOCK => open); end generate gen_mupix_sim_pll_40; - gen_mupix_sim_pll_80 : if g_clock_speed = c_80MHz generate - mupix_pll_sim_1 : mupix_pll_sim_80 - port map ( - CLK => pllclk, -- 200 MHz - CLKOP => data_clk_i, -- 80 MHz - CLKOS => sim_clk_i, -- 200 MHz - LOCK => open); - end generate gen_mupix_sim_pll_80; - - MupixStateMachine_1 : entity work.MupixStateMachine port map ( clk => data_clk_i, @@ -130,8 +120,8 @@ begin -- architecture rtl RdClock => sim_clk_i, WrEn => fifo_wren_i, RdEn => fifo_rden_i, - Reset => reset_reg, - RPReset => reset_reg, + Reset => reset_reg2, + RPReset => reset_reg2, Q => fifo_data_out, Empty => fifo_empty_i, Full => open); @@ -146,11 +136,22 @@ begin -- architecture rtl dataout => data_out_i); + data_out: process(sim_clk_i) + begin + if rising_edge(sim_clk_i) then + if reset_reg = '1' then + data_out_reg <= (others => '0'); + else + data_out_reg <= data_out_i; + end if; + end if; + end process data_out; + simlink_oddr : ODDRXD1 port map ( SCLK => sim_clk_i, - DA => data_out_i(0), - DB => data_out_i(1), + DA => data_out_reg(0), + DB => data_out_reg(1), Q => data_out); dataclk <= data_clk_i; diff --git a/mupix/Mupix8/sources/Simulation/Mupix8StateMachine.vhd b/mupix/Mupix8/sources/Simulation/Mupix8StateMachine.vhd index ced8b0e..e030f5a 100644 --- a/mupix/Mupix8/sources/Simulation/Mupix8StateMachine.vhd +++ b/mupix/Mupix8/sources/Simulation/Mupix8StateMachine.vhd @@ -45,8 +45,8 @@ architecture rtl of MupixStateMachine is signal binary_counter : unsigned(23 downto 0) := (others => '0'); signal column, row : unsigned(7 downto 0) := (others => '0'); - signal timestamp : unsigned(7 downto 0) := (others => '0'); - signal tot : unsigned(7 downto 0) := (others => '0'); + signal timestamp : unsigned(9 downto 0) := (others => '0'); + signal tot : unsigned(5 downto 0) := (others => '0'); signal word_cnt_i : unsigned(4 downto 0) := (others => '0'); signal slowdown_cnt_i : unsigned(15 downto 0) := (others => '0'); @@ -218,7 +218,7 @@ begin -- architecture rtl mupix_data_i <= std_logic_vector(binary_counter(7 downto 0)); elsif cnt4 = 2 then komma_en_i <= '0'; - mupix_data_i <= std_logic_vector(timestamp); + mupix_data_i <= std_logic_vector(timestamp(7 downto 0)); else mupix8_state <= readcol1; mupix_data_i <= k28_5; @@ -231,13 +231,13 @@ begin -- architecture rtl else cnt4 <= 0; mupix8_state <= readcol2; - mupix_data_i <= std_logic_vector(timestamp); + mupix_data_i <= std_logic_vector(timestamp(9 downto 2)); komma_en_i <= '0'; end if; when readcol2 => cnt4 <= cnt4 + 1; if cnt4 = 0 then - mupix_data_i <= std_logic_vector(tot); + mupix_data_i <= std_logic_vector(timestamp(1 downto 0)) & std_logic_vector(tot); komma_en_i <= '0'; elsif cnt4 = 1 then mupix_data_i <= std_logic_vector(column); diff --git a/mupix/Mupix8/sources/SlowControl/MupixBoardDAC.vhd b/mupix/Mupix8/sources/SlowControl/MupixBoardDAC.vhd index e88005a..86b3ebf 100644 --- a/mupix/Mupix8/sources/SlowControl/MupixBoardDAC.vhd +++ b/mupix/Mupix8/sources/SlowControl/MupixBoardDAC.vhd @@ -85,6 +85,8 @@ architecture RTL of MupixBoardDAC is pulse_o : out std_logic ); end component injection_generator; + + signal reset_reg : std_logic := '0'; constant c_bits_threshold_dacs : integer := 64; --4*16 bit of the four DACs signal start_write_threshold : std_logic := '0'; @@ -118,6 +120,13 @@ architecture RTL of MupixBoardDAC is begin + reset_proc : process(clk) + begin + if rising_edge(clk) then + reset_reg <= reset; + end if; + end process reset_proc; + spi_din <= spi_data_to_chip_threshold or spi_data_to_chip_temperature or spi_data_to_chip_adc; spi_clk <= spi_clk_threshold or spi_clk_temperature_temperature or spi_clk_adc; @@ -129,7 +138,7 @@ begin ) port map( clk => clk, - reset => reset, + reset => reset_reg, start_write => start_write_threshold, spi_data_in => spi_data_in_threshold, spi_data_from_chip => dac4_dout, @@ -147,7 +156,7 @@ begin ) port map( clk => clk, - reset => reset, + reset => reset_reg, start_write => start_write_temperature, spi_data_in => spi_data_in_temperature, spi_data_from_chip => spi_dout_dac, @@ -165,7 +174,7 @@ begin ) port map( clk => clk, - reset => reset, + reset => reset_reg, start_write => start_write_adc, config_in => config_adc, spi_data_from_chip => spi_dout_adc, @@ -177,7 +186,7 @@ begin injection_gen_1 : component injection_generator port map( - rst => reset, + rst => reset_reg, clk => clk, pulse_length => pulse_length_i, pulse_pause => pulse_pause_i, diff --git a/mupix/Mupix8/sources/SlowControl/PixelControl.vhd b/mupix/Mupix8/sources/SlowControl/PixelControl.vhd index 0ac9536..6e92049 100644 --- a/mupix/Mupix8/sources/SlowControl/PixelControl.vhd +++ b/mupix/Mupix8/sources/SlowControl/PixelControl.vhd @@ -32,6 +32,8 @@ end PixelControl; architecture Behavioral of PixelControl is + signal reset_reg : std_logic := '0'; + constant c_fifo_word_width : integer := 32; constant c_clk_div_max : integer := fpga_clk_speed/spi_clk_speed - 1; signal clk_div_cnt : integer range 0 to c_clk_div_max - 1 := 0; @@ -41,23 +43,18 @@ architecture Behavioral of PixelControl is signal bitcouner_word : integer range 0 to c_fifo_word_width - 1 := c_fifo_word_width - 1; --index to current bit in word from fifo --fifos storage of configuration bits - component STD_FIFO - generic( - DATA_WIDTH : positive := 8; - FIFO_DEPTH : positive := 256 - ); - port( - CLK : in std_logic; - RST : in std_logic; - WriteEn : in std_logic; - DataIn : in std_logic_vector(c_fifo_word_width - 1 downto 0); - ReadEn : in std_logic; - DataOut : out std_logic_vector(c_fifo_word_width - 1 downto 0); - Empty : out std_logic; - Full : out std_logic - ); - end component STD_FIFO; - + component FIFO_32_512 + port ( + Data: in std_logic_vector(31 downto 0); + Clock: in std_logic; + WrEn: in std_logic; + RdEn: in std_logic; + Reset: in std_logic; + Q: out std_logic_vector(31 downto 0); + Empty: out std_logic; + Full: out std_logic); + end component FIFO_32_512; + component CRC generic( detect_enable_edge : boolean := false @@ -144,21 +141,23 @@ architecture Behavioral of PixelControl is begin -- Behavioral - fifo_1 : entity work.STD_FIFO - generic map( - DATA_WIDTH => c_fifo_word_width, - FIFO_DEPTH => 128 - ) + reset_proc : process(clk) + begin + if rising_edge(clk) then + reset_reg <= reset; + end if; + end process reset_proc; + + fifo_1 : entity work.FIFO_32_512 port map( - CLK => CLK, - RST => reset, - WriteEn => WriteEn, - DataIn => DataIn, - ReadEn => ReadEn, - DataOut => DataOut, - Empty => Empty, - Full => Full - ); + Data => DataIn, + Clock => clk, + WrEn => WriteEn, + RdEn => ReadEn, + Reset => reset_reg, + Q => DataOut, + Empty => Empty, + Full => Full); crc_in : entity work.CRC generic map(detect_enable_edge => false) @@ -190,7 +189,7 @@ begin -- Behavioral AddressWidth => c_ram_address_width) port map ( clk => clk, - reset => reset, + reset => reset_reg, WrEn => readback_mem_wren_i, WrAddr => readback_wr_addr, Din => readback_data_in, @@ -202,7 +201,7 @@ begin -- Behavioral readback_proc : process (clk) is begin -- process readback_proc if rising_edge(clk) then -- rising clock edge - if reset = '1' or reset_readback_i = '1' then + if reset_reg = '1' or reset_readback_i = '1' then mupix_clk1_edge <= (others => '0'); mupix_load_edge <= (others => '0'); readback_cnt_i <= 0; @@ -250,7 +249,7 @@ begin -- Behavioral sendpix_bits : process(clk) is begin if rising_edge(clk) then - if reset = '1' or reset_fastcontrol_i = '1' then + if reset_reg = '1' or reset_fastcontrol_i = '1' then send_bits_fsm <= idle; mupix_ctrl_i.clk1 <= '0'; mupix_ctrl_i.clk2 <= '0'; @@ -338,7 +337,7 @@ begin -- Behavioral configure_proc : process(clk) is begin if rising_edge(clk) then - if reset = '1' or reset_fastcontrol_i = '1' then + if reset_reg = '1' or reset_fastcontrol_i = '1' then mupix_ctrl_i.load <= '0'; config_fsm <= idle; config_busy <= '0'; @@ -512,7 +511,7 @@ begin -- Behavioral output_pipe : process(clk) is begin if rising_edge(clk) then - if reset = '1' then + if reset_reg = '1' then mupix_ctrl_reg <= c_mupix_slctrl_init; else mupix_ctrl_reg <= mupix_ctrl_sel; diff --git a/mupix/Mupix8/tb/CircularMemoryTest.vhd b/mupix/Mupix8/tb/CircularMemoryTest.vhd index 1d2268f..e82a85e 100644 --- a/mupix/Mupix8/tb/CircularMemoryTest.vhd +++ b/mupix/Mupix8/tb/CircularMemoryTest.vhd @@ -4,9 +4,9 @@ use ieee.numeric_std.all; entity CircularMemoryTest is end entity CircularMemoryTest; - + architecture sim of CircularMemoryTest is - + component CircularMemory generic( g_datawidth : integer := 32; @@ -18,7 +18,7 @@ architecture sim of CircularMemoryTest is wr_en : in std_logic; data_in : in std_logic_vector(g_datawidth - 1 downto 0); rd_en : in std_logic; - offset_en : in std_logic; + offset_en : in std_logic; offset : in std_logic_vector(g_addresswidth - 1 downto 0); data_out : out std_logic_vector(g_datawidth - 1 downto 0); empty : out std_logic; @@ -26,15 +26,15 @@ architecture sim of CircularMemoryTest is full : out std_logic; almost_full : out std_logic; fillcnt : out std_logic_vector(g_addresswidth - 1 downto 0); - inword_freq : out std_logic_vector(31 downto 0); - outword_freq : out std_logic_vector(31 downto 0) + inword_freq : out std_logic_vector(31 downto 0); + outword_freq : out std_logic_vector(31 downto 0) ); end component CircularMemory; - + constant c_data_width : integer := 32; constant c_address_width : integer := 3; constant c_clk_period : time := 10 ns; - + signal clk : std_logic; signal rst : std_logic := '0'; signal wr_en : std_logic := '0'; @@ -46,13 +46,43 @@ architecture sim of CircularMemoryTest is signal empty : std_logic; signal almost_empty : std_logic; signal full : std_logic; - signal almost_full : std_logic; - signal fillcnt : std_logic_vector(c_address_width downto 0); + signal fillcnt : std_logic_vector(c_address_width - 1 downto 0); signal inword_freq : std_logic_vector(31 downto 0); signal outword_freq : std_logic_vector(31 downto 0); - + + type write_fsm_t is (idle, writing); + signal fsm_write : write_fsm_t := idle; + signal start_write : std_logic := '0'; + signal words_write : integer range 0 to 31 := 0; + signal data_write : unsigned(31 downto 0) := (others => '0'); + + type read_fsm_t is (idle, reading); + signal fsm_read : read_fsm_t := idle; + signal start_read : std_logic := '0'; + + procedure WriteMem ( + signal start : out std_logic; + signal words : out integer range 0 to 31; + constant nWords : in integer range 0 to 31; + constant clk_period : in time := 10 ns) is + begin + start <= '1'; + words <= nWords; + wait for clk_period; + start <= '0'; + end procedure WriteMem; + + procedure ReadMem ( + signal start : out std_logic; + constant clk_period : in time := 10 ns) is + begin + start <= '1'; + wait for clk_period; + start <= '0'; + end procedure ReadMem; + begin - + dut : entity work.CircularMemory generic map( g_datawidth => c_data_width, @@ -71,12 +101,11 @@ begin empty => empty, almost_empty => almost_empty, full => full, - almost_full => almost_full, fillcnt => fillcnt, inword_freq => inword_freq, outword_freq => outword_freq ); - + clk_gen : process is begin clk <= '0'; @@ -84,42 +113,93 @@ begin clk <= '1'; wait for c_clk_period/2; end process clk_gen; - + + write_mem : process(clk) + variable cnt : integer range 0 to 31 := 0; + begin + if rising_edge(clk) then + case fsm_write is + when idle => + cnt := 0; + wr_en <= '0'; + if start_write = '1' then + fsm_write <= writing; + end if; + when writing => + wr_en <= '1'; + data_write <= data_write + 1; + cnt := cnt + 1; + if cnt = words_write then + fsm_write <= idle; + end if; + end case; + end if; + end process write_mem; + data_in <= std_logic_vector(data_write); + + read_mem : process(clk) + begin + if rising_edge(clk) then + case fsm_read is + when idle => + if start_read = '1' then + fsm_read <= reading; + end if; + when reading => + rd_en <= '1'; + if almost_empty = '1' then + rd_en <= '0'; + fsm_read <= idle; + end if; + end case; + end if; + end process read_mem; + stimulus : process is begin wait for 100 ns; - --general read/write test - for i in 1 to 15 loop - wr_en <= '1'; - data_in <= std_logic_vector(to_unsigned(i, c_data_width)); - wait for c_clk_period; - end loop; - wr_en <= '0'; - wait for 50 ns; - for i in 1 to 9 loop - rd_en <= '1'; - wait for c_clk_period; - end loop; - rd_en <= '0'; - --test offset for read pointer + -- general read/write test + WriteMem(start_write, words_write, 4); + wait for 100 ns; + ReadMem(start_read); + wait for 150 ns; + WriteMem(start_write, words_write, 4); + wait for 100 ns; + ReadMem(start_read); wait for 100 ns; - offset <= std_logic_vector(to_unsigned(4, c_address_width)); + WriteMem(start_write, words_write, 4); + wait for 100 ns; + ReadMem(start_read); + wait for 100 ns; + -- overflow after writing and then normal operation + rst <= '1'; wait for c_clk_period; - offset_en <= '1'; + rst <= '0'; + WriteMem(start_write, words_write, 12); + wait for 200 ns; + ReadMem(start_read); + wait for 200 ns; + WriteMem(start_write, words_write, 3); + wait for 100 ns; + ReadMem(start_read); + wait for 150 ns; + -- write into overflow and start reading + rst <= '1'; + wait for c_clk_period; + rst <= '0'; + WriteMem(start_write, words_write, 21); + wait for 120 ns; + ReadMem(start_read); + wait for 200 ns; + -- test offset + offset <= std_logic_vector(to_unsigned(5, c_address_width)); wait for c_clk_period; - offset_en <= '0'; - for i in 1 to 3 loop - wr_en <= '1'; - data_in <= std_logic_vector(to_unsigned(i, c_data_width)); - wait for c_clk_period; - end loop; - wr_en <= '0'; offset_en <= '1'; wait for c_clk_period; offset_en <= '0'; + ReadMem(start_read); wait; end process stimulus; - - -end architecture sim; + +end architecture sim; diff --git a/mupix/Mupix8/tb/DataGenTest.vhd b/mupix/Mupix8/tb/DataGenTest.vhd index 74be8f2..8ba96e4 100644 --- a/mupix/Mupix8/tb/DataGenTest.vhd +++ b/mupix/Mupix8/tb/DataGenTest.vhd @@ -14,22 +14,22 @@ architecture sim of GeneratorTest is clk : in std_logic; reset : in std_logic; start_gen : in std_logic; - data_num : in std_logic_vector(31 downto 0); - data_pause : in std_logic_vector(31 downto 0); + data_num : in std_logic_vector(15 downto 0); + data_pause : in std_logic_vector(15 downto 0); data_down : in std_logic_vector(31 downto 0); chan_sel : in std_logic_vector(1 downto 0); data_out : out std_logic_vector(iWIDTH - 1 downto 0); writeEn : out std_logic); end component Generator3; - constant iWIDTH : natural := 32; + constant iWIDTH : natural := 40; constant clk_period : time := 10 ns; signal clk : std_logic; signal reset : std_logic := '0'; signal start_gen : std_logic := '0'; - signal data_num : std_logic_vector(31 downto 0) := (others => '0'); - signal data_pause : std_logic_vector(31 downto 0) := (others => '0'); + signal data_num : std_logic_vector(15 downto 0) := (others => '0'); + signal data_pause : std_logic_vector(15 downto 0) := (others => '0'); signal data_down : std_logic_vector(31 downto 0) := (others => '0'); signal chan_sel : std_logic_vector(1 downto 0) := (others => '0'); signal data_out : std_logic_vector(iWIDTH - 1 downto 0); @@ -62,9 +62,9 @@ begin stimulus : process is begin -- process stimulus wait for 100 ns; - data_num <= x"0000000a"; - data_pause <= x"00000001"; - data_down <= x"0000000b"; + data_num <= x"000a"; + data_pause <= x"0000"; + data_down <= x"00000005"; start_gen <= '1'; wait for clk_period; start_gen <= '0'; diff --git a/mupix/Mupix8/tb/ReadoutControllerTest.vhd b/mupix/Mupix8/tb/ReadoutControllerTest.vhd index a512454..4148391 100644 --- a/mupix/Mupix8/tb/ReadoutControllerTest.vhd +++ b/mupix/Mupix8/tb/ReadoutControllerTest.vhd @@ -13,7 +13,7 @@ end entity ReadoutControllerTest; architecture sim of ReadoutControllerTest is constant c_datawidth : integer := 32; -constant c_addresswidth : integer := 6; +constant c_addresswidth : integer := 13; constant c_clockspeed : integer := 1e8; constant c_clk_period : time := 10 ns; @@ -35,8 +35,7 @@ component CircularMemory empty : out std_logic; almost_empty : out std_logic; full : out std_logic; - almost_full : out std_logic; - fillcnt : out std_logic_vector(g_addresswidth downto 0); + fillcnt : out std_logic_vector(g_addresswidth - 1 downto 0); inword_freq : out std_logic_vector(31 downto 0); outword_freq : out std_logic_vector(31 downto 0) ); @@ -77,7 +76,7 @@ component ReadoutController signal empty : std_logic; signal almost_empty : std_logic; signal full : std_logic; - signal fillcnt : std_logic_vector(c_addresswidth downto 0); + signal fillcnt : std_logic_vector(c_addresswidth - 1 downto 0); signal inword_freq : std_logic_vector(31 downto 0); signal outword_freq : std_logic_vector(31 downto 0); signal start : std_logic := '0'; @@ -90,7 +89,7 @@ component ReadoutController signal data_out_ctrl : std_logic_vector(c_datawidth - 1 downto 0); begin - + memory : entity work.CircularMemory generic map( g_datawidth => c_datawidth, @@ -109,12 +108,11 @@ begin empty => empty, almost_empty => almost_empty, full => full, - almost_full => open, fillcnt => fillcnt, inword_freq => inword_freq, outword_freq => outword_freq ); - + controller : entity work.ReadoutController generic map( g_datawidth => c_datawidth, @@ -137,7 +135,7 @@ begin data_valid => data_valid, data_out => data_out_ctrl ); - + clk_gen : process is begin clk <= '1'; @@ -145,7 +143,7 @@ begin clk <= '0'; wait for c_clk_period/2; end process clk_gen; - + stimulus : process is begin wait for 100 ns; @@ -154,7 +152,7 @@ begin offset <= std_logic_vector(to_unsigned(10, c_addresswidth)); writes_after_trig <= std_logic_vector(to_unsigned(4, c_addresswidth)); wait for c_clk_period/2; - + wait for c_clk_period; --try reading from empty circular memory start <= '1'; @@ -224,6 +222,6 @@ begin start <= '0'; wait; end process stimulus; - - -end architecture sim; \ No newline at end of file + + +end architecture sim; diff --git a/mupix/Mupix8/trb3_periph.prj b/mupix/Mupix8/trb3_periph.prj index b1bb8bf..c9f2dca 100644 --- a/mupix/Mupix8/trb3_periph.prj +++ b/mupix/Mupix8/trb3_periph.prj @@ -146,7 +146,9 @@ add_file -vhdl -lib "work" "../../base/cores/pll_in200_out100.vhd" add_file -vhdl -lib "work" "cores/serdes_fifo.vhd" add_file -vhdl -lib "work" "cores/fifo_sim.vhd" add_file -vhdl -lib "work" "cores/RAM_DP_4096_32.vhd" +add_file -vhdl -lib "work" "cores/RAM_DP_8192_32.vhd" add_file -vhdl -lib "work" "cores/FIFO_40_512.vhd" +add_file -vhdl -lib "work" "cores/FIFO_32_512.vhd" add_file -vhdl -lib "work" "cores/PLL/mupix_pll_main_40.vhd" add_file -vhdl -lib "work" "cores/PLL/mupix_pll_main_60.vhd" add_file -vhdl -lib "work" "cores/PLL/mupix_pll_main_80.vhd" @@ -195,6 +197,7 @@ add_file -vhdl -lib "work" "sources/Datapath/DataMux.vhd" add_file -vhdl -lib "work" "sources/Datapath/DataWidthConversion.vhd" add_file -vhdl -lib "work" "sources/Datapath/MuPixUnpacker.vhd" add_file -vhdl -lib "work" "sources/Datapath/LinkSynchronizer.vhd" +add_file -vhdl -lib "work" "sources/Datapath/DataFilter.vhd" add_file -vhdl -lib "work" "sources/Simulation/DatasourceSelector.vhd" add_file -vhdl -lib "work" "sources/Simulation/FrameGeneratorMux.vhd" -- 2.43.0