Line 244... |
Line 244... |
|
|
-- helpers --
|
-- helpers --
|
constant io_slink_en_c : boolean := boolean(SLINK_NUM_RX > 0) or boolean(SLINK_NUM_TX > 0); -- implement slink at all?
|
constant io_slink_en_c : boolean := boolean(SLINK_NUM_RX > 0) or boolean(SLINK_NUM_TX > 0); -- implement slink at all?
|
|
|
-- reset generator --
|
-- reset generator --
|
signal rstn_gen : std_ulogic_vector(7 downto 0) := (others => '0'); -- initialize (=reset) via bitstream (for FPGAs only)
|
signal ext_rstn_sync : std_ulogic_vector(3 downto 0) := (others => '0'); -- initialize (=reset) via bitstream (for FPGAs only)
|
signal ext_rstn : std_ulogic;
|
signal ext_rstn : std_ulogic;
|
signal sys_rstn : std_ulogic;
|
signal sys_rstn : std_ulogic;
|
signal wdt_rstn : std_ulogic;
|
signal wdt_rstn : std_ulogic;
|
|
|
-- clock generator --
|
-- clock generator --
|
Line 415... |
Line 415... |
-- Reset Generator ------------------------------------------------------------------------
|
-- Reset Generator ------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
reset_generator: process(rstn_i, clk_i)
|
reset_generator: process(rstn_i, clk_i)
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
rstn_gen <= (others => '0');
|
ext_rstn_sync <= (others => '0');
|
|
ext_rstn <= '0';
|
sys_rstn <= '0';
|
sys_rstn <= '0';
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
-- keep internal reset active for at least <rstn_gen'size> clock cycles --
|
-- keep internal reset active for at least <ext_rstn_sync'size> clock cycles --
|
rstn_gen <= rstn_gen(rstn_gen'left-1 downto 0) & '1';
|
ext_rstn_sync <= ext_rstn_sync(ext_rstn_sync'left-1 downto 0) & '1';
|
|
-- beautified external reset signal --
|
|
if (and_reduce_f(ext_rstn_sync) = '1') then
|
|
ext_rstn <= '1';
|
|
else
|
|
ext_rstn <= '0';
|
|
end if;
|
-- system reset: can also be triggered by watchdog and debug module --
|
-- system reset: can also be triggered by watchdog and debug module --
|
sys_rstn <= ext_rstn and wdt_rstn and dci_ndmrstn;
|
sys_rstn <= ext_rstn and wdt_rstn and dci_ndmrstn;
|
end if;
|
end if;
|
end process reset_generator;
|
end process reset_generator;
|
|
|
-- beautified external reset signal --
|
|
ext_rstn <= rstn_gen(rstn_gen'left);
|
|
|
|
|
|
-- Clock Generator ------------------------------------------------------------------------
|
-- Clock Generator ------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
clock_generator: process(sys_rstn, clk_i)
|
clock_generator: process(sys_rstn, clk_i)
|
begin
|
begin
|
if (sys_rstn = '0') then
|
if (sys_rstn = '0') then
|
clk_gen_en_ff <= '-';
|
clk_gen_en_ff <= '0';
|
clk_div_ff <= (others => '-');
|
clk_div <= (others => '0');
|
clk_div <= (others => '0'); -- reset required
|
clk_div_ff <= (others => '0');
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
clk_gen_en_ff <= or_reduce_f(clk_gen_en);
|
clk_gen_en_ff <= or_reduce_f(clk_gen_en);
|
clk_div_ff <= clk_div;
|
if (clk_gen_en_ff = '1') then
|
if (clk_gen_en_ff = '1') then -- actual clock generator
|
|
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
|
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
|
|
else
|
|
clk_div <= (others => '0');
|
end if;
|
end if;
|
|
clk_div_ff <= clk_div;
|
end if;
|
end if;
|
end process clock_generator;
|
end process clock_generator;
|
|
|
-- clock enables: rising edge detectors --
|
-- clock enables: rising edge detectors --
|
clk_gen(clk_div2_c) <= clk_div(0) and (not clk_div_ff(0)); -- CLK/2
|
clk_gen(clk_div2_c) <= clk_div(0) and (not clk_div_ff(0)); -- CLK/2
|
Line 942... |
Line 948... |
|
|
|
|
-- IO Access? -----------------------------------------------------------------------------
|
-- IO Access? -----------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
io_acc <= '1' when (p_bus.addr(data_width_c-1 downto index_size_f(io_size_c)) = io_base_c(data_width_c-1 downto index_size_f(io_size_c))) else '0';
|
io_acc <= '1' when (p_bus.addr(data_width_c-1 downto index_size_f(io_size_c)) = io_base_c(data_width_c-1 downto index_size_f(io_size_c))) else '0';
|
io_rden <= io_acc and p_bus.re;
|
io_rden <= '1' when (io_acc = '1') and (p_bus.re = '1') else '0';
|
io_wren <= io_acc and p_bus.we and and_reduce_f(p_bus.ben); -- only full-word write accesses are allowed (reduces HW complexity)
|
io_wren <= '1' when (io_acc = '1') and (p_bus.we = '1') and (p_bus.ben = "1111") else '0'; -- only full-word write accesses are allowed (reduces HW complexity)
|
|
|
|
|
-- Custom Functions Subsystem (CFS) -------------------------------------------------------
|
-- Custom Functions Subsystem (CFS) -------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
neorv32_cfs_inst_true:
|
neorv32_cfs_inst_true:
|