Skip to content

Commit

Permalink
PandaBrick quDIS Interface - Initial commit
Browse files Browse the repository at this point in the history
Remove Aux IO Board and replace it with HSSL quDIS Interface.

- Hardware supports 2 x 3 axis quDIS Interferometer units.
  • Loading branch information
1 parent e296941 commit 0db195e
Show file tree
Hide file tree
Showing 7 changed files with 606 additions and 112 deletions.
139 changes: 139 additions & 0 deletions modules/qudis/hdl/hssl_axis_decoder.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
----------------------------------------------------------------------------------
--
-- Single Axis quDIS HSSL Decoder.
--
-- G.Francis, August 2024.
--
--
-- quDIS Settings:
--
-- Timings below are for 32 bits (for PandABrick)
--
-- quDIS absolute maximum update rate is about 25kHz...
--
-- Example quDIS Daisy Settings (frequencies approximate):
--
-- 25kHz : Clock: 1uS, Gap: 8, Average 80nS.
--
-- 10kHz : Clock: 2uS, Gap: 18, Average 160nS.
--
-- Slowest mode is Clock 2.48uS, Gap 63, which gives 4.24kHz.
--
--
----------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity hssl_axis_decoder is
generic (
DATA_LEN : natural := 32
);
Port (

clk_i : in std_logic; -- 125MHz Clock

clk_bit_i : in std_logic; -- HSSL Interface
data_bit_i : in std_logic;

hssl_val_o : out std_logic_vector(DATA_LEN-1 downto 0); -- Position Output
health_bit_o : out std_logic

);
end hssl_axis_decoder;


architecture arch_hssl of hssl_axis_decoder is


signal clk_bit : std_logic := '0';
signal clk_bit_b : std_logic := '0';
signal clk_prev : std_logic := '0';

signal rx_shift_reg : std_logic_vector(DATA_LEN-1 downto 0);

signal health_bit : std_logic := '0';

signal clk_timer : unsigned(15 downto 0);
signal bit_count : unsigned(5 downto 0);
signal threshold : unsigned(15 downto 0);



begin


-- Synchronize the hssl clock input
process (clk_i) is
begin
if rising_edge(clk_i) then
clk_bit <= clk_bit_b;
clk_bit_b <= clk_bit_i;
end if;
end process;



-- Decoder State Machine
process (clk_i) is

variable timeout : natural := 0;

begin
if rising_edge(clk_i) then

if clk_bit /= clk_prev then -- Clock bit has changed...

if clk_bit = '1' then -- rising edge...

if clk_timer > threshold then -- If finished,

if bit_count = DATA_LEN then
hssl_val_o <= rx_shift_reg; -- output value,
health_bit <= '1'; -- and flag good data.
else
health_bit <= '0'; -- or flag bad data if the bit count is wrong.
end if;

bit_count <= (others => '0'); -- reset bit counter

end if;

else -- falling edge...

rx_shift_reg <= rx_shift_reg(rx_shift_reg'high-1 downto 0) & data_bit_i; -- sample bit,
bit_count <= bit_count + 1; -- increment bit counter
threshold <= clk_timer + clk_timer/2; -- Set threshold to 1.5 * (measured clock-low width)
clk_timer <= (others => '0'); -- and reset clk-low width counter.

end if;

timeout := 0;

else

if clk_bit = '0' then
clk_timer <= clk_timer + 1; -- Clock bit has not changed (and is low), so increment timer.
end if;

end if;

clk_prev <= clk_bit; -- (store new clock level)


if timeout > 1250000 then -- 10mS timeout on clock bit input.
health_bit_o <= '0';
else
health_bit_o <= health_bit;
timeout := timeout + 1;
end if;

end if;

end process;



end arch_hssl;
114 changes: 114 additions & 0 deletions modules/qudis/hdl/qudis.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
----------------------------------------------------------------------------------
--
-- 3-Axis quDIS Interferometer decoder
--
-- G.Francis, August 2024.
--
----------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.top_defines.all;
use work.addr_defines.all;


entity qudis is
Port (

clk_i : in std_logic;
reset_i : in std_logic;
bit_bus_i : in bit_bus_t;
pos_bus_i : in pos_bus_t;

-- HSSL Hardware Interface
hssl_clk_pins : in std_logic_vector(3 downto 1);
hssl_data_pins : in std_logic_vector(3 downto 1);

-- Output Positions
pos_1_o : out std_logic_vector(31 downto 0);
pos_2_o : out std_logic_vector(31 downto 0);
pos_3_o : out std_logic_vector(31 downto 0);

-- Internal read interface
read_strobe_i : in std_logic;
read_address_i : in std_logic_vector(BLK_AW-1 downto 0);
read_data_o : out std_logic_vector(31 downto 0);
read_ack_o : out std_logic;

-- Internal write interface
write_strobe_i : in std_logic;
write_address_i : in std_logic_vector(BLK_AW-1 downto 0);
write_data_i : in std_logic_vector(31 downto 0);
write_ack_o : out std_logic

);
end qudis;


architecture arch_qudis of qudis is

signal hssl_positions : std32_array(3 downto 1);
signal health_bits : std_logic_vector(3 downto 1);
signal health : std_logic_vector(31 downto 0);

begin


-- Generate the Decoders...
GEN_DECODERS:
for axis_num in 1 to 3 generate

hssl_axis_decoder_inst : entity work.hssl_axis_decoder
port map (
clk_i => clk_i,
clk_bit_i => hssl_clk_pins(axis_num),
data_bit_i => hssl_data_pins(axis_num),
hssl_val_o => hssl_positions(axis_num),
health_bit_o => health_bits(axis_num)
);

end generate GEN_DECODERS;


-- Output positions...
pos_1_o <= hssl_positions(1);
pos_2_o <= hssl_positions(2);
pos_3_o <= hssl_positions(3);


-- Health word (bits are 1 for good)...
health(0) <= not health_bits(1);
health(1) <= not health_bits(2);
health(2) <= not health_bits(3);
health(31 downto 3) <= ( others => '0' );



qudis_ctrl_inst : entity work.qudis_ctrl
port map (
-- Clock and Reset
clk_i => clk_i,
reset_i => reset_i,
bit_bus_i => bit_bus_i,
pos_bus_i => pos_bus_i,

-- Block Parameters
HEALTH => health,

-- Memory Bus Interface
read_strobe_i => read_strobe_i,
read_address_i => read_address_i,
read_data_o => read_data_o,
read_ack_o => read_ack_o,

write_strobe_i => write_strobe_i,
write_address_i => write_address_i,
write_data_i => write_data_i,
write_ack_o => write_ack_o
);


end arch_qudis;
Loading

0 comments on commit 0db195e

Please sign in to comment.