From 2d1de981a46eeb6e728bb0484fcb78b9323beed1 Mon Sep 17 00:00:00 2001 From: Tobias Weber Date: Wed, 1 Aug 2018 13:35:15 +0200 Subject: [PATCH] modifications to fast pixel slow control. --- mupix/Mupix8/sources/MupixBoard.vhd | 9 +- mupix/Mupix8/sources/PixelControl.vhd | 125 ++++++++++++++------------ mupix/Mupix8/tb/MupixShiftReg.vhd | 2 +- mupix/Mupix8/tb/PixCtrlTest.vhd | 35 ++++++-- 4 files changed, 102 insertions(+), 69 deletions(-) diff --git a/mupix/Mupix8/sources/MupixBoard.vhd b/mupix/Mupix8/sources/MupixBoard.vhd index 3de7ed7..1b5a60b 100644 --- a/mupix/Mupix8/sources/MupixBoard.vhd +++ b/mupix/Mupix8/sources/MupixBoard.vhd @@ -167,8 +167,9 @@ architecture Behavioral of MupixBoard8 is SLV_UNKNOWN_ADDR_OUT : out std_logic); end component PixelControl; - constant fpga_clk_speed : integer := 1e8; --100 MHz - constant mupix_spi_clk_speed : integer := 5e4; --50 kHz + constant fpga_clk_speed : integer := 1e8; -- 100 MHz + constant mupix_spi_clk_speed : integer := 4e5; -- 400 kHz + constant board_spi_clk_speed : integer := 5e4; -- 50 kHz signal mupixslctrl_i : MupixSlowControl; component MupixBoardDAC is @@ -470,6 +471,10 @@ begin -- Behavioral boardcontrol_1 : entity work.MupixBoardDAC + generic map( + fpga_clock_speed => fpga_clk_speed, + spi_clock_speed => board_spi_clk_speed + ) port map( clk => clk, reset => reset, diff --git a/mupix/Mupix8/sources/PixelControl.vhd b/mupix/Mupix8/sources/PixelControl.vhd index 47a21f9..c7529b1 100644 --- a/mupix/Mupix8/sources/PixelControl.vhd +++ b/mupix/Mupix8/sources/PixelControl.vhd @@ -12,7 +12,7 @@ entity PixelControl is generic( fpga_clk_speed : integer := 1e8; spi_clk_speed : integer := 1e4; - config_bits : integer := 8096 + config_bits : integer := 2998 ); port ( clk : in std_logic; --clock @@ -95,13 +95,14 @@ architecture Behavioral of PixelControl is --send single configuration bit signal start_send, sending : std_logic; signal reset_bitcounter : std_logic; - type t_send_bits_fsm is (idle, sendbit1, sendbit2, done); + type t_send_bits_fsm is (idle, din, clk1high, clk1low, clk2high, clk2low); signal send_bits_fsm : t_send_bits_fsm := idle; --configuration state machine - type t_config_fsm is (idle, config, readfifo, waitfifo, load); - signal config_fsm : t_config_fsm := idle; + type t_config_fsm is (idle, config, readfifo, waitfifo); + signal config_fsm : t_config_fsm := idle; + signal config_busy : std_logic := '0'; --readback of configuration data constant c_config_words_max : integer := config_bits/32 + 1; @@ -138,7 +139,7 @@ begin -- Behavioral fifo_1 : entity work.STD_FIFO generic map( DATA_WIDTH => c_fifo_word_width, - FIFO_DEPTH => 32 + FIFO_DEPTH => 128 ) port map( CLK => CLK, @@ -215,18 +216,18 @@ begin -- Behavioral mupix_clk1_edge <= mupix_clk1_edge(0) & mupix_ctrl_reg.clk1; mupix_load_edge <= mupix_load_edge(0) & mupix_ctrl_reg.load; if mupix_clk1_edge = "01" then -- use rising edge of clk1 as sampling point for mupix_dout and crc sums - readback_shift_reg <= readback_shift_reg(30 downto 0) & ctrl_dout; + readback_shift_reg <= readback_shift_reg(30 downto 0) & not ctrl_dout; readback_cnt_i <= readback_cnt_i + 1; - data_from_mupix_i <= ctrl_dout; --CRC checksum + data_from_mupix_i <= not ctrl_dout; --CRC checksum enable_crc_from_mupix <= '1'; data_in_crc_to_mupix <= mupix_ctrl_reg.sin; enable_crc_to_mupix <= '1'; readback_wr_addr <= readback_wr_addr_new; end if; if readback_cnt_i = 32 or mupix_load_edge = "01" then - readback_cnt_i <= 0; - readback_mem_wren_i <= '1'; - readback_data_in <= readback_shift_reg; + readback_cnt_i <= 0; + readback_mem_wren_i <= '1'; + readback_data_in <= readback_shift_reg; if to_integer(unsigned(readback_wr_addr_new)) < c_config_words_max - 1 then readback_wr_addr_new <= std_logic_vector(unsigned(readback_wr_addr_new) + 1); else @@ -248,51 +249,69 @@ begin -- Behavioral mupix_ctrl_i.sin <= '0'; sending <= '0'; else + mupix_ctrl_i.clk1 <= '0'; + mupix_ctrl_i.clk2 <= '0'; + mupix_ctrl_i.sin <= '0'; case send_bits_fsm is when idle => - bitcouner_word <= 31; - sending <= '0'; - clk_div_cnt <= 0; - send_bits_fsm <= idle; - mupix_ctrl_i.clk1 <= '0'; - mupix_ctrl_i.clk2 <= '0'; - mupix_ctrl_i.sin <= '0'; + bitcouner_word <= 0; + sending <= '0'; + clk_div_cnt <= 0; + send_bits_fsm <= idle; if start_send = '1' then sending <= '1'; - send_bits_fsm <= sendbit1; + send_bits_fsm <= din; end if; if reset_bitcounter = '1' then bitcounter <= (others => '0'); end if; - when sendbit1 => - clk_div_cnt <= clk_div_cnt + 1; - send_bits_fsm <= sendbit1; + when din => + mupix_ctrl_i.sin <= DataOut(bitcouner_word); + if clk_div_cnt = c_clk_div_max - 1 then + clk_div_cnt <= 0; + send_bits_fsm <= clk1high; + else + clk_div_cnt <= clk_div_cnt + 1; + end if; + when clk1high => + mupix_ctrl_i.sin <= DataOut(bitcouner_word); + mupix_ctrl_i.clk1 <= '1'; + if clk_div_cnt = c_clk_div_max - 1 then + clk_div_cnt <= 0; + send_bits_fsm <= clk1low; + bitcounter <= bitcounter + 1; + else + clk_div_cnt <= clk_div_cnt + 1; + end if; + when clk1low => mupix_ctrl_i.sin <= DataOut(bitcouner_word); - if clk_div_cnt = (c_clk_div_max - 1)/2 then - send_bits_fsm <= sendbit2; - mupix_ctrl_i.clk1 <= '1'; -- clocking - mupix_ctrl_i.clk2 <= '0'; - bitcounter <= bitcounter + 1; + if clk_div_cnt = c_clk_div_max - 1 then + clk_div_cnt <= 0; + send_bits_fsm <= clk2high; + else + clk_div_cnt <= clk_div_cnt + 1; + end if; + when clk2high => + mupix_ctrl_i.sin <= DataOut(bitcouner_word); + mupix_ctrl_i.clk2 <= '1'; + if clk_div_cnt = c_clk_div_max - 1 then + clk_div_cnt <= 0; + send_bits_fsm <= clk2low; + else + clk_div_cnt <= clk_div_cnt + 1; end if; - when sendbit2 => - clk_div_cnt <= clk_div_cnt + 1; - send_bits_fsm <= sendbit2; + when clk2low => + mupix_ctrl_i.sin <= DataOut(bitcouner_word); if clk_div_cnt = c_clk_div_max - 1 then - mupix_ctrl_i.clk1 <= '0'; - mupix_ctrl_i.clk2 <= '1'; - clk_div_cnt <= 0; - if bitcouner_word = 0 or bitcounter = bitstosend then - send_bits_fsm <= done; + clk_div_cnt <= 0; + if bitcouner_word = 31 or bitcounter = bitstosend then + send_bits_fsm <= idle; else - send_bits_fsm <= sendbit1; - bitcouner_word <= bitcouner_word -1; + send_bits_fsm <= din; + bitcouner_word <= bitcouner_word + 1; end if; - end if; - when done => -- - clk_div_cnt <= clk_div_cnt + 1; - send_bits_fsm <= done; - if clk_div_cnt = (c_clk_div_max - 1)/2 then - send_bits_fsm <= idle; -- just hold clk2 high long enough before going back to idle + else + clk_div_cnt <= clk_div_cnt + 1; end if; end case; end if; @@ -302,21 +321,21 @@ begin -- Behavioral configure_proc : process(clk) is - variable hold_load_counter : integer range 0 to 7; begin if rising_edge(clk) then if reset = '1' then mupix_ctrl_i.load <= '0'; config_fsm <= idle; - hold_load_counter := 0; + config_busy <= '0'; else mupix_ctrl_i.load <= '0'; ReadEn <= '0'; start_send <= '0'; reset_bitcounter <= '0'; + config_busy <= '1'; case config_fsm is when idle => - hold_load_counter := 0; + config_busy <= '0'; if Empty = '0' then config_fsm <= readfifo; else @@ -340,18 +359,10 @@ begin -- Behavioral if bitcounter < bitstosend then -- everything send or read other fifo word config_fsm <= readfifo; else - config_fsm <= load; + config_fsm <= idle; + reset_bitcounter <= '1'; end if; end if; - when load => -- load from shift register - hold_load_counter := hold_load_counter + 1; - mupix_ctrl_i.load <= '1'; - config_fsm <= load; - if hold_load_counter = 7 then - mupix_ctrl_i.load <= '0'; - reset_bitcounter <= '1'; - config_fsm <= idle; - end if; end case; end if; end if; @@ -409,7 +420,7 @@ begin -- Behavioral slv_ack_out <= '1'; reset_readback_i <= '1'; when x"0085" => - slv_ack_out <= '1'; + slv_ack_out <= '1'; if to_integer(unsigned(slv_data_in)) < c_config_words_max then readback_rd_addr <= slv_data_in(c_ram_address_width - 1 downto 0); else @@ -428,7 +439,7 @@ begin -- Behavioral SLV_DATA_OUT(10 downto 0) <= crc_out_crc_from_mupix & crc_out_crc_to_mupix & crc_correct; SLV_ACK_OUT <= '1'; when x"0082" => - SLV_DATA_OUT(1 downto 0) <= Empty & Full; + SLV_DATA_OUT(2 downto 0) <= config_busy & Empty & Full; SLV_ACK_OUT <= '1'; when x"0083" => SLV_DATA_OUT(0) <= mupix_ctrl_ext.sin; diff --git a/mupix/Mupix8/tb/MupixShiftReg.vhd b/mupix/Mupix8/tb/MupixShiftReg.vhd index b0e4426..e4c004d 100644 --- a/mupix/Mupix8/tb/MupixShiftReg.vhd +++ b/mupix/Mupix8/tb/MupixShiftReg.vhd @@ -38,7 +38,7 @@ begin end if; end process; - sout <= pixeldac_shift_reg(pixeldac_shift_length - 1) after delay; + sout <= not pixeldac_shift_reg(pixeldac_shift_length - 1) after delay; end architecture RTL; diff --git a/mupix/Mupix8/tb/PixCtrlTest.vhd b/mupix/Mupix8/tb/PixCtrlTest.vhd index 59edd1b..e08dc1b 100644 --- a/mupix/Mupix8/tb/PixCtrlTest.vhd +++ b/mupix/Mupix8/tb/PixCtrlTest.vhd @@ -93,17 +93,27 @@ architecture simulation of PixCtrlTest is constant sin : in std_logic; constant clk_period : in time := 10 ns) is begin -- procedure WriteMupixSlow + -- bit in slv_write_in <= '1'; slv_addr_in <= x"0083"; slv_data_in(4 downto 0) <= "1000" & sin; wait for clk_period; slv_write_in <= '0'; wait for 100 ns; + -- clk1 high slv_write_in <= '1'; slv_addr_in <= x"0083"; slv_data_in(4 downto 0) <= "1001" & sin; wait for clk_period; slv_write_in <= '0'; + --clk1 low + wait for 100 ns; + slv_write_in <= '1'; + slv_addr_in <= x"0083"; + slv_data_in(4 downto 0) <= "1000" & sin; + wait for clk_period; + slv_write_in <= '0'; + --clk2 high wait for 100 ns; slv_write_in <= '1'; slv_addr_in <= x"0083"; @@ -111,14 +121,21 @@ architecture simulation of PixCtrlTest is wait for clk_period; slv_write_in <= '0'; wait for 100 ns; + -- clk2 low slv_write_in <= '1'; slv_addr_in <= x"0083"; - slv_data_in(4 downto 0) <= "1000" & "0"; + slv_data_in(4 downto 0) <= "1000" & sin; + wait for clk_period; + slv_write_in <= '0'; + -- write zero + wait for 100 ns; + slv_write_in <= '1'; + slv_data_in(4 downto 0) <= "1000" & '0'; + slv_addr_in <= x"0083"; wait for clk_period; slv_write_in <= '0'; slv_data_in <= (others => '0'); slv_addr_in <= (others => '0'); - wait for clk_period; end procedure WriteMupixSlow; begin @@ -189,17 +206,17 @@ begin TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000005", x"0085"); --test programming with data from FIFO via FPGA state machine TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0000", x"0083"); - TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"AAAAAAAA", x"0080"); - TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"BBBBBBBB", x"0080"); + TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"55555555", x"0080"); --reverse of AAAAAAAA + TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"DDDDDDDD", x"0080"); --reverse of BBBBBBBB wait for 3*c_time_per_word; - TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"CCCC0000", x"0080"); + TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00003333", x"0080"); --reverse of CCCC0000 --test of crc checksum computation - wait for 1.5*c_time_per_word; + wait for 10*c_time_per_word; TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0060", x"0083"); TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, std_logic_vector(to_unsigned(c_shiftregister_length, 16)) & x"0000", x"0083"); - TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"AAAAAAAA", x"0080"); - TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"BBBBBBBB", x"0080"); - TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"CCCC0000", x"0080"); + TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"55555555", x"0080"); + TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"DDDDDDDD", x"0080"); + TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00003333", x"0080"); wait; end process stimulus_gen; -- 2.43.0