------------------------------------------------------------------
--- 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;
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
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));
--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
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
--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;
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
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
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
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,
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);
-- 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");
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;
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;
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);
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');
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 =>
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;
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;
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
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;
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;
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;
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,
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);
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;
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');
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;
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);
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';
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;
)
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,
)
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,
)
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,
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,
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;
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
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)
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,
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;
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';
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';
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;
entity CircularMemoryTest is
end entity CircularMemoryTest;
-
+
architecture sim of CircularMemoryTest is
-
+
component CircularMemory
generic(
g_datawidth : integer := 32;
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;
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';
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,
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';
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;
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);
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';
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;
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)
);
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';
signal data_out_ctrl : std_logic_vector(c_datawidth - 1 downto 0);
begin
-
+
memory : entity work.CircularMemory
generic map(
g_datawidth => c_datawidth,
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,
data_valid => data_valid,
data_out => data_out_ctrl
);
-
+
clk_gen : process is
begin
clk <= '1';
clk <= '0';
wait for c_clk_period/2;
end process clk_gen;
-
+
stimulus : process is
begin
wait for 100 ns;
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';
start <= '0';
wait;
end process stimulus;
-
-
-end architecture sim;
\ No newline at end of file
+
+
+end architecture sim;
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"
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"