controller: done, untested

parent 8b4fd4d7
...@@ -43,54 +43,58 @@ entity tdc is ...@@ -43,54 +43,58 @@ entity tdc is
g_FTIMER_WIDTH : positive := 10 g_FTIMER_WIDTH : positive := 10
); );
port( port(
clk_i : in std_logic; clk_i : in std_logic;
reset_i : in std_logic; reset_i : in std_logic;
ready_o : out std_logic; ready_o : out std_logic;
-- Coarse counter control. -- Coarse counter control.
cc_rst_i : in std_logic; cc_rst_i : in std_logic;
cc_cy_o : out std_logic; cc_cy_o : out std_logic;
-- Per-channel deskew inputs. -- Per-channel deskew inputs.
deskew_i : in std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0); deskew_i : in std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- Per-channel signal inputs. -- Per-channel signal inputs.
signal_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0); signal_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
calib_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0); calib_i : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
-- Per-channel detection outputs. -- Per-channel detection outputs.
detect_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0); detect_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
polarity_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0); polarity_o : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
raw_o : out std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0); raw_o : out std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0);
fp_o : out std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0) fp_o : out std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
-- Debug interface. -- Debug interface.
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic
-- TODO -- TODO
); );
end entity; end entity;
architecture rtl of tdc is architecture rtl of tdc is
signal cs_next : std_logic; signal cs_next : std_logic;
signal cs_last : std_logic; signal cs_last : std_logic;
signal calib_sel : std_logic; signal calib_sel : std_logic;
signal lut_a : std_logic_vector(g_RAW_COUNT-1 downto 0); signal lut_a : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut_we : std_logic; signal lut_we : std_logic;
signal lut_d_w : std_logic_vector(g_FP_COUNT-1 downto 0); signal lut_d_w : std_logic_vector(g_FP_COUNT-1 downto 0);
signal lut_d_r : std_logic_vector(g_FP_COUNT-1 downto 0); signal lut_d_r : std_logic_vector(g_FP_COUNT-1 downto 0);
signal c_detect : std_logic; signal c_detect : std_logic;
signal c_raw : std_logic_vector(g_RAW_COUNT-1 downto 0); signal c_raw : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_a : std_logic_vector(g_RAW_COUNT-1 downto 0); signal his_a : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_we : std_logic; signal his_we : std_logic;
signal his_d_w : std_logic_vector(g_FP_COUNT-1 downto 0); signal his_d_w : std_logic_vector(g_FP_COUNT-1 downto 0);
signal his_d_r : std_logic_vector(g_FP_COUNT-1 downto 0); signal his_d_r : std_logic_vector(g_FP_COUNT-1 downto 0);
signal oc_start : std_logic; signal oc_start : std_logic;
signal oc_ready : std_logic; signal oc_ready : std_logic;
signal oc_freq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0); signal oc_freq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal oc_store : std_logic; signal oc_store : std_logic;
signal oc_sfreq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0); signal oc_sfreq : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal freeze_ack : std_logic;
begin begin
cmp_channelbank: tdc_channelbank cmp_channelbank: tdc_channelbank
generic map( generic map(
...@@ -104,42 +108,42 @@ begin ...@@ -104,42 +108,42 @@ begin
g_FTIMER_WIDTH => g_FTIMER_WIDTH g_FTIMER_WIDTH => g_FTIMER_WIDTH
) )
port map( port map(
clk_i => clk_i, clk_i => clk_i,
reset_i => reset_i, reset_i => reset_i,
cc_rst_i => cc_rst_i, cc_rst_i => cc_rst_i,
cc_cy_o => cc_cy_o, cc_cy_o => cc_cy_o,
next_i => cs_next, next_i => cs_next,
last_o => cs_last, last_o => cs_last,
calib_sel_i => calib_sel, calib_sel_i => calib_sel,
deskew_i => deskew_i, deskew_i => deskew_i,
signal_i => signal_i, signal_i => signal_i,
calib_i => calib_i, calib_i => calib_i,
detect_o => detect_o, detect_o => detect_o,
polarity_o => polarity_o, polarity_o => polarity_o,
raw_o => raw_o, raw_o => raw_o,
fp_o => fp_o, fp_o => fp_o,
lut_a_i => lut_a, lut_a_i => lut_a,
lut_we_i => lut_we, lut_we_i => lut_we,
lut_d_i => lut_d_w, lut_d_i => lut_d_w,
lut_d_o => lut_d_r, lut_d_o => lut_d_r,
c_detect_o => c_detect, c_detect_o => c_detect,
c_raw_o => c_raw, c_raw_o => c_raw,
his_a_i => his_a, his_a_i => his_a,
his_we_i => his_we, his_we_i => his_we,
his_d_i => his_d_w, his_d_i => his_d_w,
his_d_o => his_d_r, his_d_o => his_d_r,
oc_start_i => oc_start, oc_start_i => oc_start,
oc_ready_o => oc_ready, oc_ready_o => oc_ready,
oc_freq_o => oc_freq, oc_freq_o => oc_freq,
oc_store_i => oc_store, oc_store_i => oc_store,
oc_sfreq_o => oc_sfreq oc_sfreq_o => oc_sfreq
); );
cmp_controller: tdc_controller cmp_controller: tdc_controller
...@@ -172,6 +176,10 @@ begin ...@@ -172,6 +176,10 @@ begin
oc_ready_i => oc_ready, oc_ready_i => oc_ready,
oc_freq_i => oc_freq, oc_freq_i => oc_freq,
oc_store_o => oc_store, oc_store_o => oc_store,
oc_sfreq_i => oc_sfreq oc_sfreq_i => oc_sfreq,
freeze_req_i => freeze_req_i,
freeze_ack_o => freeze_ack
); );
freeze_ack_o <= freeze_ack;
end architecture; end architecture;
...@@ -31,30 +31,33 @@ entity tdc_controller is ...@@ -31,30 +31,33 @@ entity tdc_controller is
g_FCOUNTER_WIDTH : positive g_FCOUNTER_WIDTH : positive
); );
port( port(
clk_i : in std_logic; clk_i : in std_logic;
reset_i : in std_logic; reset_i : in std_logic;
ready_o : out std_logic; ready_o : out std_logic;
next_o : out std_logic; next_o : out std_logic;
last_i : in std_logic; last_i : in std_logic;
calib_sel_o : out std_logic; calib_sel_o : out std_logic;
lut_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0); lut_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_o : out std_logic; lut_we_o : out std_logic;
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0); lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
c_detect_i : in std_logic; c_detect_i : in std_logic;
c_raw_i : in std_logic_vector(g_RAW_COUNT-1 downto 0); c_raw_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0); his_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
his_we_o : out std_logic; his_we_o : out std_logic;
his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0); his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
his_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0); his_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
oc_start_o : out std_logic; oc_start_o : out std_logic;
oc_ready_i : in std_logic; oc_ready_i : in std_logic;
oc_freq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0); oc_freq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_store_o : out std_logic; oc_store_o : out std_logic;
oc_sfreq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0) oc_sfreq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic
); );
end entity; end entity;
...@@ -73,11 +76,25 @@ signal ha_inc : std_logic; ...@@ -73,11 +76,25 @@ signal ha_inc : std_logic;
signal ha_last : std_logic; signal ha_last : std_logic;
signal ha_sel : std_logic; signal ha_sel : std_logic;
signal acc : std_logic_vector(g_FP_COUNT-1 downto 0);
signal acc_reset : std_logic;
signal acc_en : std_logic;
signal mul : std_logic_vector(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto 0);
signal mul_d1 : std_logic_vector(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto 0);
signal div_start : std_logic;
signal div_ready : std_logic;
signal div_quotient : std_logic_vector(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto 0);
signal div_qsat : std_logic_vector(g_FP_COUNT-1 downto 0);
type t_state is ( type t_state is (
-- startup calibration -- startup calibration
SC_NEWCHANNEL, SC_CLEARHIST, SC_READ, SC_UPDATE, SC_STOREF0, SC_NEWCHANNEL, SC_CLEARHIST, SC_READ, SC_UPDATE, SC_STOREF0,
-- online calibration -- online calibration
OC_STARTM, OC_WAITM, OC_NEXTCHANNEL OC_STARTM, OC_WAITM, OC_WAITMUL1, OC_WAITMUL2, OC_STARTDIV, OC_WAITDIV, OC_WRITELUT, OC_NEXTCHANNEL,
-- freeze state (transfer control to debug interface)
FREEZE
); );
signal state: t_state; signal state: t_state;
...@@ -125,6 +142,61 @@ begin ...@@ -125,6 +142,61 @@ begin
his_d_o <= (his_d_o'range => '0') when (ha_sel = '1') his_d_o <= (his_d_o'range => '0') when (ha_sel = '1')
else std_logic_vector(unsigned(his_d_i) + 1); else std_logic_vector(unsigned(his_d_i) + 1);
-- accumulator
process(clk_i)
begin
if rising_edge(clk_i) then
if acc_reset = '1' then
acc <= (acc'range => '0');
elsif acc_en = '1' then
acc <= std_logic_vector(unsigned(acc) + unsigned(his_d_i));
end if;
end if;
end process;
-- multiplier
process(clk_i)
begin
if rising_edge(clk_i) then
mul <= std_logic_vector(unsigned(acc) * unsigned(oc_sfreq_i));
mul_d1 <= mul;
end if;
end process;
-- divider
cmp_divider: tdc_divider
generic map(
g_WIDTH => g_FP_COUNT+g_FCOUNTER_WIDTH
)
port map(
clk_i => clk_i,
reset_i => reset_i,
start_i => div_start,
dividend_i => mul_d1,
divisor_i(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto g_FCOUNTER_WIDTH)
=> (others => '0'),
divisor_i(g_FCOUNTER_WIDTH-1 downto 0)
=> oc_freq_i,
ready_o => div_ready,
quotient_o => div_quotient,
remainder_o => open
);
process(div_quotient)
begin
if div_quotient(g_FP_COUNT+g_FCOUNTER_WIDTH-1 downto g_FP_COUNT)
= (g_FCOUNTER_WIDTH-1 downto 0 => '0') then
div_qsat <= div_quotient(g_FP_COUNT-1 downto 0);
else -- saturate
div_qsat <= (div_qsat'range => '1');
end if;
end process;
-- generate LUT address and write data
lut_a_o <= std_logic_vector(unsigned(ha_count) + 1);
lut_d_o <= div_qsat;
-- main FSM -- main FSM
process(clk_i) process(clk_i)
begin begin
...@@ -162,10 +234,35 @@ begin ...@@ -162,10 +234,35 @@ begin
state <= OC_WAITM; state <= OC_WAITM;
when OC_WAITM => when OC_WAITM =>
if oc_ready_i = '1' then if oc_ready_i = '1' then
state <= OC_WAITMUL1;
end if;
when OC_WAITMUL1 =>
state <= OC_WAITMUL2;
when OC_WAITMUL2 =>
state <= OC_STARTDIV;
when OC_STARTDIV =>
state <= OC_WAITDIV;
when OC_WAITDIV =>
if div_ready = '1' then
state <= OC_WRITELUT;
end if;
when OC_WRITELUT =>
if ha_last = '1' then
state <= OC_NEXTCHANNEL; state <= OC_NEXTCHANNEL;
else
state <= OC_WAITMUL1;
end if; end if;
when OC_NEXTCHANNEL => when OC_NEXTCHANNEL =>
state <= OC_STARTM; if freeze_req_i = '1' then
state <= FREEZE;
else
state <= OC_STARTM;
end if;
when FREEZE =>
if freeze_req_i = '0' then
state <= OC_STARTM;
end if;
end case; end case;
end if; end if;
end if; end if;
...@@ -182,18 +279,25 @@ begin ...@@ -182,18 +279,25 @@ begin
ha_inc <= '0'; ha_inc <= '0';
ha_sel <= '0'; ha_sel <= '0';
acc_reset <= '0';
acc_en <= '0';
div_start <= '0';
next_o <= '0'; next_o <= '0';
calib_sel_o <= '0'; calib_sel_o <= '0';
lut_we_o <= '0'; lut_we_o <= '0';
his_we_o <= '0'; his_we_o <= '0';
oc_start_o <= '0'; oc_start_o <= '0';
oc_store_o <= '0'; oc_store_o <= '0';
freeze_ack_o <= '0';
case state is case state is
when SC_NEWCHANNEL => when SC_NEWCHANNEL =>
hc_reset <= '1'; hc_reset <= '1';
ha_reset <= '1'; ha_reset <= '1';
when SC_CLEARHIST => when SC_CLEARHIST =>
calib_sel_o <= '1';
ha_inc <= '1'; ha_inc <= '1';
ha_sel <= '1'; ha_sel <= '1';
his_we_o <= '1'; his_we_o <= '1';
...@@ -214,13 +318,30 @@ begin ...@@ -214,13 +318,30 @@ begin
when OC_STARTM => when OC_STARTM =>
oc_start_o <= '1'; oc_start_o <= '1';
ha_reset <= '1';
acc_reset <= '1';
when OC_WAITM => when OC_WAITM =>
null; null;
when OC_WAITMUL1 =>
null;
when OC_WAITMUL2 =>
null;
when OC_STARTDIV =>
div_start <= '1';
when OC_WAITDIV =>
null;
when OC_WRITELUT =>
lut_we_o <= '1';
acc_en <= '1';
ha_inc <= '1';
when OC_NEXTCHANNEL => when OC_NEXTCHANNEL =>
next_o <= '1'; next_o <= '1';
if last_i = '1' then if last_i = '1' then
ready_p <= '1'; ready_p <= '1';
end if; end if;
when FREEZE =>
freeze_ack_o <= '1';
end case; end case;
end process; end process;
end architecture; end architecture;
...@@ -29,30 +29,33 @@ component tdc_controller is ...@@ -29,30 +29,33 @@ component tdc_controller is
g_FCOUNTER_WIDTH : positive g_FCOUNTER_WIDTH : positive
); );
port( port(
clk_i : in std_logic; clk_i : in std_logic;
reset_i : in std_logic; reset_i : in std_logic;
ready_o : out std_logic; ready_o : out std_logic;
next_o : out std_logic; next_o : out std_logic;
last_i : in std_logic; last_i : in std_logic;
calib_sel_o : out std_logic; calib_sel_o : out std_logic;
lut_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0); lut_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
lut_we_o : out std_logic; lut_we_o : out std_logic;
lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0); lut_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
c_detect_i : in std_logic; c_detect_i : in std_logic;
c_raw_i : in std_logic_vector(g_RAW_COUNT-1 downto 0); c_raw_i : in std_logic_vector(g_RAW_COUNT-1 downto 0);
his_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0); his_a_o : out std_logic_vector(g_RAW_COUNT-1 downto 0);
his_we_o : out std_logic; his_we_o : out std_logic;
his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0); his_d_o : out std_logic_vector(g_FP_COUNT-1 downto 0);
his_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0); his_d_i : in std_logic_vector(g_FP_COUNT-1 downto 0);
oc_start_o : out std_logic; oc_start_o : out std_logic;
oc_ready_i : in std_logic; oc_ready_i : in std_logic;
oc_freq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0); oc_freq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
oc_store_o : out std_logic; oc_store_o : out std_logic;
oc_sfreq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0) oc_sfreq_i : in std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
freeze_req_i : in std_logic;
freeze_ack_o : out std_logic
); );
end component; end component;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment