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
--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;
fifo_1 : entity work.STD_FIFO
generic map(
DATA_WIDTH => c_fifo_word_width,
- FIFO_DEPTH => 32
+ FIFO_DEPTH => 128
)
port map(
CLK => CLK,
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
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;
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
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;
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
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;
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";
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
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;