Line 74... |
Line 74... |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
|
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
|
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
|
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64)
|
CPU_IPB_ENTRIES : natural := 2; -- entries is instruction prefetch buffer, has to be a power of 2
|
CPU_IPB_ENTRIES : natural := 2; -- entries is instruction prefetch buffer, has to be a power of 2
|
|
|
-- Physical Memory Protection (PMP) --
|
-- Physical Memory Protection (PMP) --
|
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64)
|
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..16)
|
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
|
PMP_MIN_GRANULARITY : natural := 4; -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
|
|
|
-- Hardware Performance Monitors (HPM) --
|
-- Hardware Performance Monitors (HPM) --
|
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
|
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29)
|
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
|
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64)
|
|
|
Line 278... |
Line 278... |
we : std_ulogic; -- write enable
|
we : std_ulogic; -- write enable
|
re : std_ulogic; -- read enable
|
re : std_ulogic; -- read enable
|
ack : std_ulogic; -- bus transfer acknowledge
|
ack : std_ulogic; -- bus transfer acknowledge
|
err : std_ulogic; -- bus transfer error
|
err : std_ulogic; -- bus transfer error
|
fence : std_ulogic; -- fence(i) instruction executed
|
fence : std_ulogic; -- fence(i) instruction executed
|
priv : std_ulogic_vector(1 downto 0); -- current privilege level
|
priv : std_ulogic; -- current privilege level
|
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
|
src : std_ulogic; -- access source (1=instruction fetch, 0=data access)
|
lock : std_ulogic; -- exclusive access request
|
lock : std_ulogic; -- exclusive access request
|
end record;
|
end record;
|
signal cpu_i, i_cache, cpu_d, p_bus : bus_interface_t;
|
signal cpu_i, i_cache, cpu_d, p_bus : bus_interface_t;
|
|
|
Line 435... |
Line 435... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
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 <= '-';
|
clk_div <= (others => '0'); -- reset required
|
|
clk_div_ff <= (others => '-');
|
clk_div_ff <= (others => '-');
|
clk_gen <= (others => '-');
|
clk_div <= (others => '0'); -- reset required
|
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);
|
-- actual clock generator --
|
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);
|
end if;
|
end if;
|
|
end if;
|
|
end process clock_generator;
|
|
|
-- clock enables: rising edge detectors --
|
-- clock enables: rising edge detectors --
|
clk_div_ff <= clk_div;
|
|
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
|
clk_gen(clk_div4_c) <= clk_div(1) and (not clk_div_ff(1)); -- CLK/4
|
clk_gen(clk_div4_c) <= clk_div(1) and (not clk_div_ff(1)); -- CLK/4
|
clk_gen(clk_div8_c) <= clk_div(2) and (not clk_div_ff(2)); -- CLK/8
|
clk_gen(clk_div8_c) <= clk_div(2) and (not clk_div_ff(2)); -- CLK/8
|
clk_gen(clk_div64_c) <= clk_div(5) and (not clk_div_ff(5)); -- CLK/64
|
clk_gen(clk_div64_c) <= clk_div(5) and (not clk_div_ff(5)); -- CLK/64
|
clk_gen(clk_div128_c) <= clk_div(6) and (not clk_div_ff(6)); -- CLK/128
|
clk_gen(clk_div128_c) <= clk_div(6) and (not clk_div_ff(6)); -- CLK/128
|
clk_gen(clk_div1024_c) <= clk_div(9) and (not clk_div_ff(9)); -- CLK/1024
|
clk_gen(clk_div1024_c) <= clk_div(9) and (not clk_div_ff(9)); -- CLK/1024
|
clk_gen(clk_div2048_c) <= clk_div(10) and (not clk_div_ff(10)); -- CLK/2048
|
clk_gen(clk_div2048_c) <= clk_div(10) and (not clk_div_ff(10)); -- CLK/2048
|
clk_gen(clk_div4096_c) <= clk_div(11) and (not clk_div_ff(11)); -- CLK/4096
|
clk_gen(clk_div4096_c) <= clk_div(11) and (not clk_div_ff(11)); -- CLK/4096
|
end if;
|
|
end process clock_generator;
|
|
|
|
-- fresh clocks anyone? --
|
-- fresh clocks anyone? --
|
clk_gen_en(0) <= wdt_cg_en;
|
clk_gen_en(0) <= wdt_cg_en;
|
clk_gen_en(1) <= uart0_cg_en;
|
clk_gen_en(1) <= uart0_cg_en;
|
clk_gen_en(2) <= uart1_cg_en;
|
clk_gen_en(2) <= uart1_cg_en;
|
Line 499... |
Line 498... |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
|
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
|
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
|
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
|
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
|
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64)
|
CPU_IPB_ENTRIES => CPU_IPB_ENTRIES, -- entries is instruction prefetch buffer, has to be a power of 2
|
CPU_IPB_ENTRIES => CPU_IPB_ENTRIES, -- entries is instruction prefetch buffer, has to be a power of 2
|
-- Physical Memory Protection (PMP) --
|
-- Physical Memory Protection (PMP) --
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..16)
|
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes
|
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 4 bytes
|
-- Hardware Performance Monitors (HPM) --
|
-- Hardware Performance Monitors (HPM) --
|
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
|
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29)
|
HPM_CNT_WIDTH => HPM_CNT_WIDTH -- total size of HPM counters (0..64)
|
HPM_CNT_WIDTH => HPM_CNT_WIDTH -- total size of HPM counters (0..64)
|
)
|
)
|
port map (
|
port map (
|
Line 590... |
Line 589... |
port map (
|
port map (
|
-- global control --
|
-- global control --
|
clk_i => clk_i, -- global clock, rising edge
|
clk_i => clk_i, -- global clock, rising edge
|
rstn_i => sys_rstn, -- global reset, low-active, async
|
rstn_i => sys_rstn, -- global reset, low-active, async
|
clear_i => cpu_i.fence, -- cache clear
|
clear_i => cpu_i.fence, -- cache clear
|
|
miss_o => open, -- cache miss
|
-- host controller interface --
|
-- host controller interface --
|
host_addr_i => cpu_i.addr, -- bus access address
|
host_addr_i => cpu_i.addr, -- bus access address
|
host_rdata_o => cpu_i.rdata, -- bus read data
|
host_rdata_o => cpu_i.rdata, -- bus read data
|
host_wdata_i => cpu_i.wdata, -- bus write data
|
host_wdata_i => cpu_i.wdata, -- bus write data
|
host_ben_i => cpu_i.ben, -- byte enable
|
host_ben_i => cpu_i.ben, -- byte enable
|
Line 942... |
Line 942... |
|
|
|
|
-- 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 and (not p_bus.src); -- PMA: no_execute for IO region
|
io_rden <= io_acc and p_bus.re;
|
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 <= io_acc and p_bus.we and and_reduce_f(p_bus.ben); -- only full-word write accesses are allowed (reduces HW complexity)
|
|
|
|
|
-- Custom Functions Subsystem (CFS) -------------------------------------------------------
|
-- Custom Functions Subsystem (CFS) -------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
Line 962... |
Line 962... |
-- host access --
|
-- host access --
|
clk_i => clk_i, -- global clock line
|
clk_i => clk_i, -- global clock line
|
rstn_i => sys_rstn, -- global reset line, low-active, use as async
|
rstn_i => sys_rstn, -- global reset line, low-active, use as async
|
addr_i => p_bus.addr, -- address
|
addr_i => p_bus.addr, -- address
|
rden_i => io_rden, -- read enable
|
rden_i => io_rden, -- read enable
|
wren_i => io_wren, -- byte write enable
|
wren_i => io_wren, -- word write enable
|
data_i => p_bus.wdata, -- data in
|
data_i => p_bus.wdata, -- data in
|
data_o => resp_bus(RESP_CFS).rdata, -- data out
|
data_o => resp_bus(RESP_CFS).rdata, -- data out
|
ack_o => resp_bus(RESP_CFS).ack, -- transfer acknowledge
|
ack_o => resp_bus(RESP_CFS).ack, -- transfer acknowledge
|
err_o => resp_bus(RESP_CFS).err, -- access error
|
err_o => resp_bus(RESP_CFS).err, -- access error
|
-- clock generator --
|
-- clock generator --
|
Line 1498... |
Line 1498... |
generic map (
|
generic map (
|
-- General --
|
-- General --
|
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
|
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
|
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader?
|
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader?
|
-- Physical memory protection (PMP) --
|
-- Physical memory protection (PMP) --
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64)
|
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..16)
|
-- internal Instruction memory --
|
-- internal Instruction memory --
|
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
|
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory
|
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
|
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
|
-- Internal Data memory --
|
-- Internal Data memory --
|
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
|
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory
|