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; |