Line 72... |
Line 72... |
constant ctrl_en_c : natural := 0; -- r/w: timer enable
|
constant ctrl_en_c : natural := 0; -- r/w: timer enable
|
constant ctrl_prsc0_c : natural := 1; -- r/w: clock prescaler select bit 0
|
constant ctrl_prsc0_c : natural := 1; -- r/w: clock prescaler select bit 0
|
constant ctrl_prsc1_c : natural := 2; -- r/w: clock prescaler select bit 1
|
constant ctrl_prsc1_c : natural := 2; -- r/w: clock prescaler select bit 1
|
constant ctrl_prsc2_c : natural := 3; -- r/w: clock prescaler select bit 2
|
constant ctrl_prsc2_c : natural := 3; -- r/w: clock prescaler select bit 2
|
constant ctrl_mode_c : natural := 4; -- r/w: mode (0=single-shot, 1=continuous)
|
constant ctrl_mode_c : natural := 4; -- r/w: mode (0=single-shot, 1=continuous)
|
constant ctrl_alarm_c : natural := 5; -- r/c: alarm flag (interrupt), cleared by writing zero
|
|
--
|
--
|
signal ctrl : std_ulogic_vector(4 downto 0);
|
signal ctrl : std_ulogic_vector(4 downto 0);
|
|
|
-- access control --
|
-- access control --
|
signal acc_en : std_ulogic; -- module access enable
|
signal acc_en : std_ulogic; -- module access enable
|
Line 94... |
Line 93... |
match : std_ulogic; -- count == thres
|
match : std_ulogic; -- count == thres
|
cnt_we : std_ulogic; -- write access to count
|
cnt_we : std_ulogic; -- write access to count
|
end record;
|
end record;
|
signal timer : timer_t;
|
signal timer : timer_t;
|
|
|
-- interrupt generator --
|
-- interrupt detector --
|
type irq_t is record
|
signal irq_detect : std_ulogic_vector(1 downto 0);
|
pending : std_ulogic; -- pending interrupt request
|
|
detect : std_ulogic_vector(1 downto 0); -- rising-edge detector
|
|
clearn : std_ulogic; -- clear/ack IRQ request, active-low
|
|
end record;
|
|
signal irq : irq_t;
|
|
|
|
begin
|
begin
|
|
|
-- Access Control -------------------------------------------------------------------------
|
-- Access Control -------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
Line 121... |
Line 115... |
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
-- bus access acknowledge --
|
-- bus access acknowledge --
|
ack_o <= rden or wren;
|
ack_o <= rden or wren;
|
|
|
-- write access --
|
-- write access --
|
irq.clearn <= '1';
|
|
timer.cnt_we <= '0';
|
timer.cnt_we <= '0';
|
if (wren = '1') then
|
if (wren = '1') then
|
if (addr = gptmr_ctrl_addr_c) then -- control register
|
if (addr = gptmr_ctrl_addr_c) then -- control register
|
ctrl(ctrl_en_c) <= data_i(ctrl_en_c);
|
ctrl(ctrl_en_c) <= data_i(ctrl_en_c);
|
ctrl(ctrl_prsc0_c) <= data_i(ctrl_prsc0_c);
|
ctrl(ctrl_prsc0_c) <= data_i(ctrl_prsc0_c);
|
ctrl(ctrl_prsc1_c) <= data_i(ctrl_prsc1_c);
|
ctrl(ctrl_prsc1_c) <= data_i(ctrl_prsc1_c);
|
ctrl(ctrl_prsc2_c) <= data_i(ctrl_prsc2_c);
|
ctrl(ctrl_prsc2_c) <= data_i(ctrl_prsc2_c);
|
ctrl(ctrl_mode_c) <= data_i(ctrl_mode_c);
|
ctrl(ctrl_mode_c) <= data_i(ctrl_mode_c);
|
irq.clearn <= data_i(ctrl_alarm_c);
|
|
end if;
|
end if;
|
if (addr = gptmr_thres_addr_c) then -- threshold register
|
if (addr = gptmr_thres_addr_c) then -- threshold register
|
timer.thres <= data_i;
|
timer.thres <= data_i;
|
end if;
|
end if;
|
if (addr = gptmr_count_addr_c) then -- counter register
|
if (addr = gptmr_count_addr_c) then -- counter register
|
Line 150... |
Line 142... |
data_o(ctrl_en_c) <= ctrl(ctrl_en_c);
|
data_o(ctrl_en_c) <= ctrl(ctrl_en_c);
|
data_o(ctrl_prsc0_c) <= ctrl(ctrl_prsc0_c);
|
data_o(ctrl_prsc0_c) <= ctrl(ctrl_prsc0_c);
|
data_o(ctrl_prsc1_c) <= ctrl(ctrl_prsc1_c);
|
data_o(ctrl_prsc1_c) <= ctrl(ctrl_prsc1_c);
|
data_o(ctrl_prsc2_c) <= ctrl(ctrl_prsc2_c);
|
data_o(ctrl_prsc2_c) <= ctrl(ctrl_prsc2_c);
|
data_o(ctrl_mode_c) <= ctrl(ctrl_mode_c);
|
data_o(ctrl_mode_c) <= ctrl(ctrl_mode_c);
|
data_o(ctrl_alarm_c) <= irq.pending;
|
|
when "01" => -- threshold register
|
when "01" => -- threshold register
|
data_o <= timer.thres;
|
data_o <= timer.thres;
|
when others => -- counter register
|
when others => -- counter register
|
data_o <= timer.count;
|
data_o <= timer.count;
|
end case;
|
end case;
|
Line 196... |
Line 187... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
irq_generator: process(clk_i)
|
irq_generator: process(clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
if (ctrl(ctrl_en_c) = '0') then
|
if (ctrl(ctrl_en_c) = '0') then
|
irq.detect <= "00";
|
irq_detect <= "00";
|
irq.pending <= '0';
|
|
else
|
else
|
irq.detect <= irq.detect(0) & timer.match;
|
irq_detect <= irq_detect(0) & timer.match;
|
if (irq.detect = "01") then -- rising edge
|
|
irq.pending <= '1';
|
|
elsif (irq.clearn = '0') then
|
|
irq.pending <= '0';
|
|
end if;
|
|
end if;
|
end if;
|
end if;
|
end if;
|
end process irq_generator;
|
end process irq_generator;
|
|
|
-- IRQ request to CPU --
|
-- IRQ request to CPU --
|
irq_o <= irq.pending;
|
irq_o <= '1' when (irq_detect = "01") else '0';
|
|
|
|
|
end neorv32_gptmr_rtl;
|
end neorv32_gptmr_rtl;
|
|
|
No newline at end of file
|
No newline at end of file
|