OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/sim
    from Rev 39 to Rev 40
    Reverse comparison

Rev 39 → Rev 40

/ghdl/ghdl_sim.sh
81,4 → 81,4
 
# Run simulation
ghdl -e --work=neorv32 neorv32_tb
ghdl -r --work=neorv32 neorv32_tb --max-stack-alloc=1048576 --ieee-asserts=disable --assert-level=error $SIM_CONFIG
ghdl -r --work=neorv32 neorv32_tb --max-stack-alloc=0 --ieee-asserts=disable --assert-level=error $SIM_CONFIG
/rtl_modules/neorv32_imem.vhd
0,0 → 1,107
-- #################################################################################################
-- # << NEORV32 - Processor-internal instruction memory (IMEM) >> #
-- # ********************************************************************************************* #
-- # This version is intended for SIMULATION ONLY! #
-- # It only allows an implementation as ROM and is initialized using "application_init_image". #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
use neorv32.neorv32_application_image.all; -- this file is generated by the image generator
 
entity neorv32_imem is
generic (
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes
IMEM_AS_ROM : boolean := false; -- implement IMEM as read-only memory?
BOOTLOADER_USE : boolean := true -- implement and use bootloader?
);
port (
clk_i : in std_ulogic; -- global clock line
rden_i : in std_ulogic; -- read enable
wren_i : in std_ulogic; -- write enable
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable
addr_i : in std_ulogic_vector(31 downto 0); -- address
data_i : in std_ulogic_vector(31 downto 0); -- data in
data_o : out std_ulogic_vector(31 downto 0); -- data out
ack_o : out std_ulogic -- transfer acknowledge
);
end neorv32_imem;
 
architecture neorv32_imem_rtl of neorv32_imem is
 
-- IO space: module base address --
constant hi_abb_c : natural := 31; -- high address boundary bit
constant lo_abb_c : natural := index_size_f(IMEM_SIZE); -- low address boundary bit
 
-- local signals --
signal acc_en : std_ulogic;
signal rdata : std_ulogic_vector(31 downto 0);
signal rden : std_ulogic;
signal addr : std_ulogic_vector(index_size_f(IMEM_SIZE/4)-1 downto 0);
 
begin
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not (IMEM_AS_ROM = false) report "NEORV32 PROCESSOR CONFIG ERROR! IMEM has to be configured as ROM." severity error;
 
 
-- Access Control -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = IMEM_BASE(hi_abb_c downto lo_abb_c)) else '0';
addr <= addr_i(index_size_f(IMEM_SIZE/4)+1 downto 2); -- word aligned
 
 
-- Memory Access --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
imem_file_access: process(clk_i)
begin
if rising_edge(clk_i) then
rden <= acc_en and rden_i;
ack_o <= acc_en and rden_i;
if (acc_en = '1') then -- reduce switching activity when not accessed
rdata <= application_init_image(to_integer(unsigned(addr)));
end if;
end if;
end process imem_file_access;
 
-- output gate --
data_o <= rdata when (rden = '1') else (others => '0');
 
 
end neorv32_imem_rtl;
/vivado/neorv32_tb_behav.wcfg
12,15 → 12,15
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="1325333fs"></ZoomStartTime>
<ZoomEndTime time="1342434fs"></ZoomEndTime>
<Cursor1Time time="1349733fs"></Cursor1Time>
<ZoomStartTime time="0fs"></ZoomStartTime>
<ZoomEndTime time="1111160fs"></ZoomEndTime>
<Cursor1Time time="15000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="203"></NameColumnWidth>
<ValueColumnWidth column_width="103"></ValueColumnWidth>
<ValueColumnWidth column_width="95"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="111" />
<WVObjectSize size="121" />
<wvobject type="divider" fp_name="divider273">
<obj_property name="label">CPU: Control.FETCH</obj_property>
<obj_property name="DisplayName">label</obj_property>
114,8 → 114,8
<obj_property name="ObjectShortName">be_store_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ctrl_o" type="array">
<obj_property name="ElementShortName">ctrl_o[62:0]</obj_property>
<obj_property name="ObjectShortName">ctrl_o[62:0]</obj_property>
<obj_property name="ElementShortName">ctrl_o[61:0]</obj_property>
<obj_property name="ObjectShortName">ctrl_o[61:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ci_instr32" type="array">
<obj_property name="ElementShortName">ci_instr32[31:0]</obj_property>
145,100 → 145,6
<obj_property name="ElementShortName">execute_engine</obj_property>
<obj_property name="ObjectShortName">execute_engine</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state" type="other">
<obj_property name="ElementShortName">.state</obj_property>
<obj_property name="ObjectShortName">.state</obj_property>
<obj_property name="CustomSignalColor">#FFFFFF</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state_prev" type="other">
<obj_property name="ElementShortName">.state_prev</obj_property>
<obj_property name="ObjectShortName">.state_prev</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.state_nxt" type="other">
<obj_property name="ElementShortName">.state_nxt</obj_property>
<obj_property name="ObjectShortName">.state_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg" type="array">
<obj_property name="ElementShortName">.i_reg[31:0]</obj_property>
<obj_property name="ObjectShortName">.i_reg[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg_nxt" type="array">
<obj_property name="ElementShortName">.i_reg_nxt[31:0]</obj_property>
<obj_property name="ObjectShortName">.i_reg_nxt[31:0]</obj_property>
<obj_property name="CustomSignalColor">#FFFFFF</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.i_reg_last" type="array">
<obj_property name="ElementShortName">.i_reg_last[31:0]</obj_property>
<obj_property name="ObjectShortName">.i_reg_last[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_ci" type="logic">
<obj_property name="ElementShortName">.is_ci</obj_property>
<obj_property name="ObjectShortName">.is_ci</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_ci_nxt" type="logic">
<obj_property name="ElementShortName">.is_ci_nxt</obj_property>
<obj_property name="ObjectShortName">.is_ci_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_jump" type="logic">
<obj_property name="ElementShortName">.is_jump</obj_property>
<obj_property name="ObjectShortName">.is_jump</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_jump_nxt" type="logic">
<obj_property name="ElementShortName">.is_jump_nxt</obj_property>
<obj_property name="ObjectShortName">.is_jump_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_cp_op" type="logic">
<obj_property name="ElementShortName">.is_cp_op</obj_property>
<obj_property name="ObjectShortName">.is_cp_op</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.is_cp_op_nxt" type="logic">
<obj_property name="ElementShortName">.is_cp_op_nxt</obj_property>
<obj_property name="ObjectShortName">.is_cp_op_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.branch_taken" type="logic">
<obj_property name="ElementShortName">.branch_taken</obj_property>
<obj_property name="ObjectShortName">.branch_taken</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc" type="array">
<obj_property name="ElementShortName">.pc[31:0]</obj_property>
<obj_property name="ObjectShortName">.pc[31:0]</obj_property>
<obj_property name="CustomSignalColor">#FFFFFF</obj_property>
<obj_property name="UseCustomSignalColor">true</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.pc_nxt" type="array">
<obj_property name="ElementShortName">.pc_nxt[31:0]</obj_property>
<obj_property name="ObjectShortName">.pc_nxt[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.next_pc" type="array">
<obj_property name="ElementShortName">.next_pc[31:0]</obj_property>
<obj_property name="ObjectShortName">.next_pc[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.last_pc" type="array">
<obj_property name="ElementShortName">.last_pc[31:0]</obj_property>
<obj_property name="ObjectShortName">.last_pc[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.last_pc_nxt" type="array">
<obj_property name="ElementShortName">.last_pc_nxt[31:0]</obj_property>
<obj_property name="ObjectShortName">.last_pc_nxt[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.sleep" type="logic">
<obj_property name="ElementShortName">.sleep</obj_property>
<obj_property name="ObjectShortName">.sleep</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.sleep_nxt" type="logic">
<obj_property name="ElementShortName">.sleep_nxt</obj_property>
<obj_property name="ObjectShortName">.sleep_nxt</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.if_rst" type="logic">
<obj_property name="ElementShortName">.if_rst</obj_property>
<obj_property name="ObjectShortName">.if_rst</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/execute_engine.if_rst_nxt" type="logic">
<obj_property name="ElementShortName">.if_rst_nxt</obj_property>
<obj_property name="ObjectShortName">.if_rst_nxt</obj_property>
</wvobject>
</wvobject>
<wvobject type="divider" fp_name="divider139">
<obj_property name="label">CPU: Control.ATOMICS</obj_property>
322,8 → 228,55
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp_ctrl" type="array">
<obj_property name="ElementShortName">cp_ctrl</obj_property>
<obj_property name="ObjectShortName">cp_ctrl</obj_property>
<obj_property name="isExpanded"></obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp0_start_o" type="logic">
<obj_property name="ElementShortName">cp0_start_o</obj_property>
<obj_property name="ObjectShortName">cp0_start_o</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp0_data_i" type="array">
<obj_property name="ElementShortName">cp0_data_i[31:0]</obj_property>
<obj_property name="ObjectShortName">cp0_data_i[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp0_valid_i" type="logic">
<obj_property name="ElementShortName">cp0_valid_i</obj_property>
<obj_property name="ObjectShortName">cp0_valid_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp1_start_o" type="logic">
<obj_property name="ElementShortName">cp1_start_o</obj_property>
<obj_property name="ObjectShortName">cp1_start_o</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp1_data_i" type="array">
<obj_property name="ElementShortName">cp1_data_i[31:0]</obj_property>
<obj_property name="ObjectShortName">cp1_data_i[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp1_valid_i" type="logic">
<obj_property name="ElementShortName">cp1_valid_i</obj_property>
<obj_property name="ObjectShortName">cp1_valid_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp2_start_o" type="logic">
<obj_property name="ElementShortName">cp2_start_o</obj_property>
<obj_property name="ObjectShortName">cp2_start_o</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp2_data_i" type="array">
<obj_property name="ElementShortName">cp2_data_i[31:0]</obj_property>
<obj_property name="ObjectShortName">cp2_data_i[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp2_valid_i" type="logic">
<obj_property name="ElementShortName">cp2_valid_i</obj_property>
<obj_property name="ObjectShortName">cp2_valid_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp3_start_o" type="logic">
<obj_property name="ElementShortName">cp3_start_o</obj_property>
<obj_property name="ObjectShortName">cp3_start_o</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp3_data_i" type="array">
<obj_property name="ElementShortName">cp3_data_i[31:0]</obj_property>
<obj_property name="ObjectShortName">cp3_data_i[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_alu_inst/cp3_valid_i" type="logic">
<obj_property name="ElementShortName">cp3_valid_i</obj_property>
<obj_property name="ObjectShortName">cp3_valid_i</obj_property>
</wvobject>
<wvobject type="divider" fp_name="divider367">
<obj_property name="label">CPU: BUS_UNIT</obj_property>
<obj_property name="DisplayName">label</obj_property>
398,14 → 351,6
<obj_property name="ElementShortName">PMP_USE</obj_property>
<obj_property name="ObjectShortName">PMP_USE</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/PMP_NUM_REGIONS" type="other">
<obj_property name="ElementShortName">PMP_NUM_REGIONS</obj_property>
<obj_property name="ObjectShortName">PMP_NUM_REGIONS</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/PMP_GRANULARITY" type="other">
<obj_property name="ElementShortName">PMP_GRANULARITY</obj_property>
<obj_property name="ObjectShortName">PMP_GRANULARITY</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/pmp" type="array">
<obj_property name="ElementShortName">pmp</obj_property>
<obj_property name="ObjectShortName">pmp</obj_property>
/README.md
0,0 → 1,17
## Simulation Source Folder
 
### [`ghdl`](https://github.com/stnolting/neorv32/tree/master/sim/ghdl)
 
This folder contains a script for simulating the processor using GHDL.
 
### [`rtl_modules`](https://github.com/stnolting/neorv32/tree/master/sim/rtl_modules)
 
This folder provides additional/alternative simulation components. The the comments in the according files for more information.
 
### [`vivado`](https://github.com/stnolting/neorv32/tree/master/sim/vivado)
 
This folder provides an example waveform configuration (for Xilinx ISIM simulator) for the default testbench.
 
### [`neorv32_tb.vhd`](https://github.com/stnolting/neorv32/tree/master/sim/neorv32_tb.vhd)
 
Default testbench for the NEORV32 Processor.
/neorv32_tb.vhd
1,16 → 1,8
-- #################################################################################################
-- # << NEORV32 - Default Testbench >> #
-- # ********************************************************************************************* #
-- # This testbench provides a virtual UART receiver connected to the processor's uart_txd_o #
-- # signal. The received chars are shown in the simulator console and also written to a file #
-- # ("neorv32.testbench_uart.out"). #
-- # #
-- # Furthermore, this testbench provides two external memories (ext_mem_a and ext_mem_b) coupled #
-- # via Wishbone. ext_mem_a is initialized with the application_init_image and can be used as #
-- # external boot memory (external IMEM). #
-- # ext_mem_b is a small uninitialized memory that can be uased as external memory-mapped IO. #
-- # #
-- # Use the "User Configuration" section to configure the testbench according to your need. #
-- # See NEORV32 data sheet (docs/NEORV32.pdf) for more information. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
70,15 → 62,18
-- simulated external Wishbone memory A (can be used as external IMEM) --
constant ext_mem_a_base_addr_c : std_ulogic_vector(31 downto 0) := x"00000000"; -- wishbone memory base address (external IMEM base)
constant ext_mem_a_size_c : natural := imem_size_c; -- wishbone memory size in bytes
constant ext_mem_a_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initiali delay
constant ext_mem_a_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- simulated external Wishbone memory B (can be used as external DMEM) --
constant ext_mem_b_base_addr_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- wishbone memory base address (external DMEM base)
constant ext_mem_b_size_c : natural := dmem_size_c; -- wishbone memory size in bytes
constant ext_mem_b_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initiali delay
constant ext_mem_b_latency_c : natural := 8; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- simulated external Wishbone memory C (can be used as external IO) --
constant ext_mem_c_base_addr_c : std_ulogic_vector(31 downto 0) := x"F0000000"; -- wishbone memory base address (default begin of EXTERNAL IO area)
constant ext_mem_c_size_c : natural := 64; -- wishbone memory size in bytes
constant ext_mem_c_latency_c : natural := 3; -- latency in clock cycles (min 1, max 255), plus 1 cycle initiali delay
constant ext_mem_c_latency_c : natural := 3; -- latency in clock cycles (min 1, max 255), plus 1 cycle initial delay
-- machine interrupt triggers --
constant msi_trigger_c : std_ulogic_vector(31 downto 0) := x"FF000000"; -- machine software interrupt
constant mei_trigger_c : std_ulogic_vector(31 downto 0) := x"FF000004"; -- machine external interrupt
-- -------------------------------------------------------------------------------------------
 
-- internals - hands off! --
108,8 → 103,11
signal twi_scl, twi_sda : std_logic;
 
-- spi --
signal spi_data : std_logic;
signal spi_data : std_ulogic;
 
-- irq --
signal msi_ring, mei_ring : std_ulogic;
 
-- Wishbone bus --
type wishbone_t is record
addr : std_ulogic_vector(31 downto 0); -- address
124,7 → 122,7
tag : std_ulogic_vector(2 downto 0); -- tag
lock : std_ulogic; -- locked/exclusive bus access
end record;
signal wb_cpu, wb_mem_a, wb_mem_b, wb_mem_c : wishbone_t;
signal wb_cpu, wb_mem_a, wb_mem_b, wb_mem_c, wb_msi, wb_mei : wishbone_t;
 
-- Wishbone memories --
type ext_mem_a_ram_t is array (0 to ext_mem_a_size_c/4-1) of std_ulogic_vector(31 downto 0);
139,7 → 137,11
begin
mem_v := (others => (others => '0'));
for i in 0 to init'length-1 loop -- init only in range of source data array
if (xbus_big_endian_c = true) then
mem_v(i) := init(i);
else
mem_v(i) := bswap32_f(init(i));
end if;
end loop; -- i
return mem_v;
end function init_wbmem;
186,8 → 188,6
FAST_SHIFT_EN => false, -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE => true, -- implement PMP?
PMP_NUM_REGIONS => 4, -- number of regions (max 16)
PMP_GRANULARITY => 14, -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE => int_imem_c , -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => imem_size_c, -- size of processor-internal instruction memory in bytes
244,10 → 244,12
twi_scl_io => twi_scl, -- twi serial clock line
-- PWM --
pwm_o => open, -- pwm channels
-- system time input from external MTIME (available if IO_MTIME_USE = false) --
mtime_i => (others => '0'), -- current system time
-- Interrupts --
mtime_irq_i => '0', -- machine software interrupt, available if IO_MTIME_USE = false
msw_irq_i => '0', -- machine software interrupt
mext_irq_i => '0' -- machine external interrupt
msw_irq_i => msi_ring, -- machine software interrupt
mext_irq_i => mei_ring -- machine external interrupt
);
 
-- TWI termination (pull-ups) --
334,15 → 336,33
wb_mem_c.cyc <= wb_cpu.cyc;
wb_mem_c.lock <= wb_cpu.lock;
 
wb_msi.addr <= wb_cpu.addr;
wb_msi.wdata <= wb_cpu.wdata;
wb_msi.we <= wb_cpu.we;
wb_msi.sel <= wb_cpu.sel;
wb_msi.tag <= wb_cpu.tag;
wb_msi.cyc <= wb_cpu.cyc;
wb_msi.lock <= wb_cpu.lock;
 
wb_mei.addr <= wb_cpu.addr;
wb_mei.wdata <= wb_cpu.wdata;
wb_mei.we <= wb_cpu.we;
wb_mei.sel <= wb_cpu.sel;
wb_mei.tag <= wb_cpu.tag;
wb_mei.cyc <= wb_cpu.cyc;
wb_mei.lock <= wb_cpu.lock;
 
-- CPU read-back signals (no mux here since peripherals have "output gates") --
wb_cpu.rdata <= wb_mem_a.rdata or wb_mem_b.rdata or wb_mem_c.rdata;
wb_cpu.ack <= wb_mem_a.ack or wb_mem_b.ack or wb_mem_c.ack;
wb_cpu.err <= wb_mem_a.err or wb_mem_b.err or wb_mem_c.err;
wb_cpu.rdata <= wb_mem_a.rdata or wb_mem_b.rdata or wb_mem_c.rdata or wb_mei.rdata or wb_msi.rdata;
wb_cpu.ack <= wb_mem_a.ack or wb_mem_b.ack or wb_mem_c.ack or wb_mei.ack or wb_msi.ack;
wb_cpu.err <= wb_mem_a.err or wb_mem_b.err or wb_mem_c.err or wb_mei.err or wb_msi.err;
 
-- peripheral select via STROBE signal --
wb_mem_a.stb <= wb_cpu.stb when (wb_cpu.addr >= ext_mem_a_base_addr_c) and (wb_cpu.addr < std_ulogic_vector(unsigned(ext_mem_a_base_addr_c) + ext_mem_a_size_c)) else '0';
wb_mem_b.stb <= wb_cpu.stb when (wb_cpu.addr >= ext_mem_b_base_addr_c) and (wb_cpu.addr < std_ulogic_vector(unsigned(ext_mem_b_base_addr_c) + ext_mem_b_size_c)) else '0';
wb_mem_c.stb <= wb_cpu.stb when (wb_cpu.addr >= ext_mem_c_base_addr_c) and (wb_cpu.addr < std_ulogic_vector(unsigned(ext_mem_c_base_addr_c) + ext_mem_c_size_c)) else '0';
wb_msi.stb <= wb_cpu.stb when (wb_cpu.addr = msi_trigger_c) else '0';
wb_mei.stb <= wb_cpu.stb when (wb_cpu.addr = mei_trigger_c) else '0';
 
 
-- Wishbone Memory A (simulated external IMEM) --------------------------------------------
467,4 → 487,34
end process ext_mem_c_access;
 
 
-- Wishbone IRQ Triggers ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ext_irq_trigger: process(clk_gen)
begin
if rising_edge(clk_gen) then
-- default --
msi_ring <= '0';
wb_msi.rdata <= (others => '0');
wb_msi.ack <= '0';
wb_msi.err <= '0';
mei_ring <= '0';
wb_mei.rdata <= (others => '0');
wb_mei.ack <= '0';
wb_mei.err <= '0';
 
-- machine software interrupt --
if ((wb_msi.cyc and wb_msi.stb and wb_msi.we) = '1') then
msi_ring <= '1';
wb_msi.ack <= '1';
end if;
 
-- machine external interrupt --
if ((wb_mei.cyc and wb_mei.stb and wb_mei.we) = '1') then
mei_ring <= '1';
wb_mei.ack <= '1';
end if;
end if;
end process ext_irq_trigger;
 
 
end neorv32_tb_rtl;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.