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 36 to Rev 38
    Reverse comparison

Rev 36 → Rev 38

/vivado/neorv32_tb_behav.wcfg
12,15 → 12,15
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="953250fs"></ZoomStartTime>
<ZoomEndTime time="1057351fs"></ZoomEndTime>
<Cursor1Time time="997350fs"></Cursor1Time>
<ZoomStartTime time="5295000fs"></ZoomStartTime>
<ZoomEndTime time="5412501fs"></ZoomEndTime>
<Cursor1Time time="5715000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="203"></NameColumnWidth>
<ValueColumnWidth column_width="78"></ValueColumnWidth>
<ValueColumnWidth column_width="111"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="111" />
<WVObjectSize size="108" />
<wvobject type="divider" fp_name="divider273">
<obj_property name="label">CPU: Control.FETCH</obj_property>
<obj_property name="DisplayName">label</obj_property>
70,56 → 70,6
<obj_property name="ElementShortName">ipb</obj_property>
<obj_property name="ObjectShortName">ipb</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.wdata" type="array">
<obj_property name="ElementShortName">.wdata[33:0]</obj_property>
<obj_property name="ObjectShortName">.wdata[33:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.we" type="logic">
<obj_property name="ElementShortName">.we</obj_property>
<obj_property name="ObjectShortName">.we</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.free" type="logic">
<obj_property name="ElementShortName">.free</obj_property>
<obj_property name="ObjectShortName">.free</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.clear" type="logic">
<obj_property name="ElementShortName">.clear</obj_property>
<obj_property name="ObjectShortName">.clear</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.rdata" type="array">
<obj_property name="ElementShortName">.rdata[33:0]</obj_property>
<obj_property name="ObjectShortName">.rdata[33: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/ipb.re" type="logic">
<obj_property name="ElementShortName">.re</obj_property>
<obj_property name="ObjectShortName">.re</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.avail" type="logic">
<obj_property name="ElementShortName">.avail</obj_property>
<obj_property name="ObjectShortName">.avail</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.w_pnt" type="array">
<obj_property name="ElementShortName">.w_pnt[1:0]</obj_property>
<obj_property name="ObjectShortName">.w_pnt[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.r_pnt" type="array">
<obj_property name="ElementShortName">.r_pnt[1:0]</obj_property>
<obj_property name="ObjectShortName">.r_pnt[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.empty" type="logic">
<obj_property name="ElementShortName">.empty</obj_property>
<obj_property name="ObjectShortName">.empty</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.full" type="logic">
<obj_property name="ElementShortName">.full</obj_property>
<obj_property name="ObjectShortName">.full</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/ipb.data" type="array">
<obj_property name="ElementShortName">.data[0:1][33:0]</obj_property>
<obj_property name="ObjectShortName">.data[0:1][33:0]</obj_property>
</wvobject>
</wvobject>
<wvobject type="divider" fp_name="divider273">
<obj_property name="label">CPU: Control.ISSUE</obj_property>
142,45 → 92,6
<obj_property name="ElementShortName">ci_illegal</obj_property>
<obj_property name="ObjectShortName">ci_illegal</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/i_buf" type="array">
<obj_property name="ElementShortName">i_buf</obj_property>
<obj_property name="ObjectShortName">i_buf</obj_property>
<obj_property name="isExpanded"></obj_property>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/i_buf.wdata" type="array">
<obj_property name="ElementShortName">.wdata[35:0]</obj_property>
<obj_property name="ObjectShortName">.wdata[35:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/i_buf.rdata" type="array">
<obj_property name="ElementShortName">.rdata[35:0]</obj_property>
<obj_property name="ObjectShortName">.rdata[35:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/i_buf.status" type="logic">
<obj_property name="ElementShortName">.status</obj_property>
<obj_property name="ObjectShortName">.status</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/i_buf.clear" type="logic">
<obj_property name="ElementShortName">.clear</obj_property>
<obj_property name="ObjectShortName">.clear</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/i_buf.we" type="logic">
<obj_property name="ElementShortName">.we</obj_property>
<obj_property name="ObjectShortName">.we</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/i_buf.re" type="logic">
<obj_property name="ElementShortName">.re</obj_property>
<obj_property name="ObjectShortName">.re</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/i_buf.free" type="logic">
<obj_property name="ElementShortName">.free</obj_property>
<obj_property name="ObjectShortName">.free</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_control_inst/i_buf.avail" type="logic">
<obj_property name="ElementShortName">.avail</obj_property>
<obj_property name="ObjectShortName">.avail</obj_property>
</wvobject>
</wvobject>
<wvobject type="divider" fp_name="divider273">
<obj_property name="label">CPU: Control.EXECUTE</obj_property>
<obj_property name="DisplayName">label</obj_property>
206,8 → 117,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[45:0]</obj_property>
<obj_property name="ObjectShortName">ctrl_o[45:0]</obj_property>
<obj_property name="ElementShortName">ctrl_o[59:0]</obj_property>
<obj_property name="ObjectShortName">ctrl_o[59: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>
261,6 → 172,10
<obj_property name="ElementShortName">.i_reg_nxt[31:0]</obj_property>
<obj_property name="ObjectShortName">.i_reg_nxt[31:0]</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>
292,12 → 207,12
<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>
<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.next_pc" type="array">
<obj_property name="ElementShortName">.next_pc[31:0]</obj_property>
406,10 → 321,6
<obj_property name="label">CPU: BUS_UNIT</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/rstn_i" type="logic">
<obj_property name="ElementShortName">rstn_i</obj_property>
<obj_property name="ObjectShortName">rstn_i</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/clk_i" type="logic">
<obj_property name="ElementShortName">clk_i</obj_property>
<obj_property name="ObjectShortName">clk_i</obj_property>
500,10 → 411,6
<obj_property name="ElementShortName">pmp_ctrl_i[0:7][7:0]</obj_property>
<obj_property name="ObjectShortName">pmp_ctrl_i[0:7][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/priv_mode_i" type="array">
<obj_property name="ElementShortName">priv_mode_i[1:0]</obj_property>
<obj_property name="ObjectShortName">priv_mode_i[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cpu_inst/neorv32_cpu_bus_inst/if_pmp_fault" type="logic">
<obj_property name="ElementShortName">if_pmp_fault</obj_property>
<obj_property name="ObjectShortName">if_pmp_fault</obj_property>
584,6 → 491,10
<obj_property name="label">EXT_MEM Interface</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_wishbone_inst_true/neorv32_wishbone_inst/ctrl" type="array">
<obj_property name="ElementShortName">ctrl</obj_property>
<obj_property name="ObjectShortName">ctrl</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/wb_adr_o" type="array">
<obj_property name="ElementShortName">wb_adr_o[31:0]</obj_property>
<obj_property name="ObjectShortName">wb_adr_o[31:0]</obj_property>
629,23 → 540,20
<obj_property name="ObjectShortName">fencei_o</obj_property>
</wvobject>
<wvobject type="divider" fp_name="divider238">
<obj_property name="label">IO: CFU</obj_property>
<obj_property name="label">Testbench memory busses</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cfu_inst_true/neorv32_cfu_inst/wr_en" type="logic">
<obj_property name="ElementShortName">wr_en</obj_property>
<obj_property name="ObjectShortName">wr_en</obj_property>
<wvobject fp_name="/neorv32_tb/wb_cpu" type="array">
<obj_property name="ElementShortName">wb_cpu</obj_property>
<obj_property name="ObjectShortName">wb_cpu</obj_property>
<obj_property name="isExpanded"></obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cfu_inst_true/neorv32_cfu_inst/rd_en" type="logic">
<obj_property name="ElementShortName">rd_en</obj_property>
<obj_property name="ObjectShortName">rd_en</obj_property>
<wvobject fp_name="/neorv32_tb/wb_mem_a" type="array">
<obj_property name="ElementShortName">wb_mem_a</obj_property>
<obj_property name="ObjectShortName">wb_mem_a</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cfu_inst_true/neorv32_cfu_inst/cfu_reg_in" type="array">
<obj_property name="ElementShortName">cfu_reg_in[0:3][31:0]</obj_property>
<obj_property name="ObjectShortName">cfu_reg_in[0:3][31:0]</obj_property>
<wvobject fp_name="/neorv32_tb/wb_mem_b" type="array">
<obj_property name="ElementShortName">wb_mem_b</obj_property>
<obj_property name="ObjectShortName">wb_mem_b</obj_property>
</wvobject>
<wvobject fp_name="/neorv32_tb/neorv32_top_inst/neorv32_cfu_inst_true/neorv32_cfu_inst/cfu_reg_out" type="array">
<obj_property name="ElementShortName">cfu_reg_out[0:3][31:0]</obj_property>
<obj_property name="ObjectShortName">cfu_reg_out[0:3][31:0]</obj_property>
</wvobject>
</wave_config>
/neorv32_tb.vhd
3,9 → 3,14
-- # ********************************************************************************************* #
-- # 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"). Futhermore, this testbench provides a simple RAM connected #
-- # to the external Wishbone bus. The testbench configures the processor with all optional #
-- # elements enabled by default. #
-- # ("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. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
55,22 → 60,31
 
-- User Configuration ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant t_clock_c : time := 10 ns; -- main clock period
constant f_clock_c : real := 100000000.0; -- main clock in Hz
constant f_clock_nat_c : natural := 100000000; -- main clock in Hz
constant baud_rate_c : real := 19200.0; -- standard UART baudrate
--
constant wb_mem_base_addr_c : std_ulogic_vector(31 downto 0) := x"F0000000"; -- wishbone memory base address
constant wb_mem_size_c : natural := 256; -- wishbone memory size in bytes
constant wb_mem_latency_c : natural := 8; -- latency in clock cycles (min 1)
-- general --
constant boot_external_c : boolean := false; -- false: boot from proc-internal IMEM, true: boot from (initialized) simulated ext. mem A
constant imem_size_c : natural := 16*1024; -- size in bytes of processor-internal IMEM / external mem A
constant f_clock_c : natural := 100000000; -- main clock in Hz
-- UART --
constant baud_rate_c : natural := 19200; -- standard UART baudrate
-- 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 (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
-- simulated external Wishbone memory B (can be used as external IO) --
constant ext_mem_b_base_addr_c : std_ulogic_vector(31 downto 0) := x"F0000000"; -- wishbone memory base address (default begin of EXTERNAL IO area)
constant ext_mem_b_size_c : natural := 64; -- wishbone memory size in bytes
constant ext_mem_b_latency_c : natural := 3; -- latency in clock cycles (min 1, max 255), plus 1 cycle initiali delay
-- -------------------------------------------------------------------------------------------
 
-- internals - hands off! --
constant boot_imem_c : boolean := not boot_external_c;
 
-- text.io --
file file_uart_tx_out : text open write_mode is "neorv32.testbench_uart.out";
 
-- internal configuration --
constant baud_val_c : real := f_clock_c / baud_rate_c;
constant f_clk_c : natural := natural(f_clock_c);
constant baud_val_c : real := real(f_clock_c) / real(baud_rate_c);
constant t_clock_c : time := (1 sec) / f_clock_c;
 
-- generators --
signal clk_gen, rst_gen : std_ulogic := '0';
105,16 → 119,17
err : std_ulogic; -- transfer error
tag : std_ulogic_vector(2 downto 0); -- tag
end record;
signal wb_cpu : wishbone_t;
signal wb_cpu, wb_mem_a, wb_mem_b : wishbone_t;
 
-- Wishbone memory --
type wb_mem_ram_t is array (0 to wb_mem_size_c/4-1) of std_ulogic_vector(31 downto 0);
type wb_mem_read_latency_t is array (0 to wb_mem_latency_c-1) of std_ulogic_vector(31 downto 0);
-- 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);
type ext_mem_b_ram_t is array (0 to ext_mem_b_size_c/4-1) of std_ulogic_vector(31 downto 0);
type ext_mem_read_latency_t is array (0 to 255) of std_ulogic_vector(31 downto 0);
 
-- init function --
-- impure function: returns NOT the same result every time it is evaluated with the same arguments since the source file might have changed
impure function init_wbmem(init : application_init_image_t) return wb_mem_ram_t is
variable mem_v : wb_mem_ram_t;
impure function init_wbmem(init : application_init_image_t) return ext_mem_a_ram_t is
variable mem_v : ext_mem_a_ram_t;
begin
mem_v := (others => (others => '0'));
for i in 0 to init'length-1 loop -- init only in range of source data array
123,25 → 138,16
return mem_v;
end function init_wbmem;
 
-- ---------------------------------------------- --
-- How to simulate a boot from an external memory --
-- ---------------------------------------------- --
-- The simulated Wishbone memory can be initialized with the compiled application init.
-- 1. Uncomment the init_wbmem function below; this will initialize the simulated wishbone memory with the neorv32_application_image.vhd image
-- 2. Increase the wb_mem_size_c constant above to (at least) the size of the application image (like 16kB -> 16*1024)
-- 3. Disable the processor-internal IMEM in the processor instantiation below (MEM_INT_IMEM_USE => false)
-- 4. Set the Wishbone memory base address wb_mem_base_addr_c (above) to zero (constant wb_mem_base_addr_c : std_ulogic_vector(31 downto 0) := x"00000000";)
-- 5. Simulate!
-- external memory components --
signal ext_ram_a : ext_mem_a_ram_t := init_wbmem(application_init_image); -- initialized, used to simulate external instruction boot memory
signal ext_ram_b : ext_mem_b_ram_t; -- uninitialized, used to simulate external IO
 
signal wb_ram : wb_mem_ram_t;-- := init_wbmem(application_init_image); -- uncomment if you want to init the WB ram with app image
 
type wb_mem_t is record
rdata : wb_mem_read_latency_t;
type ext_mem_t is record
rdata : ext_mem_read_latency_t;
acc_en : std_ulogic;
ack : std_ulogic_vector(wb_mem_latency_c-1 downto 0);
rb_en : std_ulogic_vector(wb_mem_latency_c-1 downto 0);
ack : std_ulogic_vector(ext_mem_a_latency_c-1 downto 0);
end record;
signal wb_mem : wb_mem_t;
signal ext_mem_a, ext_mem_b : ext_mem_t;
 
begin
 
156,7 → 162,7
neorv32_top_inst: neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => f_clock_nat_c, -- clock frequency of clk_i in Hz
CLOCK_FREQUENCY => f_clock_c, -- clock frequency of clk_i in Hz
BOOTLOADER_USE => false, -- implement processor-internal bootloader?
USER_CODE => x"12345678", -- custom user code
HW_THREAD_ID => x"00000000", -- hardware thread id (hartid)
175,8 → 181,8
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 => true, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => 16*1024, -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_USE => boot_imem_c, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => imem_size_c, -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_ROM => false, -- implement processor-internal instruction memory as ROM
-- Internal Data memory --
MEM_INT_DMEM_USE => true, -- implement processor-internal data memory
259,7 → 265,7
uart_rx_busy <= '1';
end if;
else
if (uart_rx_baud_cnt = 0.0) then
if (uart_rx_baud_cnt <= 0.0) then
if (uart_rx_bitcnt = 1) then
uart_rx_baud_cnt <= round(0.5 * baud_val_c);
else
292,42 → 298,110
end process uart_rx_console;
 
 
-- Wishbone Memory (simulated external memory) --------------------------------------------
-- Wishbone Fabric ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
wb_mem_ram_access: process(clk_gen)
-- CPU broadcast signals --
wb_mem_a.addr <= wb_cpu.addr;
wb_mem_b.addr <= wb_cpu.addr;
wb_mem_a.wdata <= wb_cpu.wdata;
wb_mem_b.wdata <= wb_cpu.wdata;
wb_mem_a.we <= wb_cpu.we;
wb_mem_b.we <= wb_cpu.we;
wb_mem_a.sel <= wb_cpu.sel;
wb_mem_b.sel <= wb_cpu.sel;
wb_mem_a.tag <= wb_cpu.tag;
wb_mem_b.tag <= wb_cpu.tag;
wb_mem_a.cyc <= wb_cpu.cyc;
wb_mem_b.cyc <= wb_cpu.cyc;
-- CPU read-back signals (no mux here since peripherals have "output gates") --
wb_cpu.rdata <= wb_mem_a.rdata or wb_mem_b.rdata;
wb_cpu.ack <= wb_mem_a.ack or wb_mem_b.ack;
wb_cpu.err <= wb_mem_a.err or wb_mem_b.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';
 
 
-- Wishbone Memory A (simulated external memory) ------------------------------------------
-- -------------------------------------------------------------------------------------------
ext_mem_a_access: process(clk_gen)
begin
if rising_edge(clk_gen) then
-- control --
wb_mem.rb_en(0) <= wb_cpu.cyc and wb_cpu.stb and wb_mem.acc_en and (not wb_cpu.we); -- read-back control
wb_mem.ack(0) <= wb_cpu.cyc and wb_cpu.stb and wb_mem.acc_en; -- wishbone acknowledge
ext_mem_a.ack(0) <= wb_mem_a.cyc and wb_mem_a.stb; -- wishbone acknowledge
 
-- write access --
if ((wb_cpu.cyc and wb_cpu.stb and wb_mem.acc_en and wb_cpu.we) = '1') then -- valid write access
if ((wb_mem_a.cyc and wb_mem_a.stb and wb_mem_a.we) = '1') then -- valid write access
for i in 0 to 3 loop
if (wb_cpu.sel(i) = '1') then
wb_ram(to_integer(unsigned(wb_cpu.addr(index_size_f(wb_mem_size_c/4)+1 downto 2))))(7+i*8 downto 0+i*8) <= wb_cpu.wdata(7+i*8 downto 0+i*8);
if (wb_mem_a.sel(i) = '1') then
ext_ram_a(to_integer(unsigned(wb_mem_a.addr(index_size_f(ext_mem_a_size_c/4)+1 downto 2))))(7+i*8 downto 0+i*8) <= wb_mem_a.wdata(7+i*8 downto 0+i*8);
end if;
end loop; -- i
end if;
 
-- read access --
wb_mem.rdata(0) <= wb_ram(to_integer(unsigned(wb_cpu.addr(index_size_f(wb_mem_size_c/4)+1 downto 2)))); -- word aligned
ext_mem_a.rdata(0) <= ext_ram_a(to_integer(unsigned(wb_mem_a.addr(index_size_f(ext_mem_a_size_c/4)+1 downto 2)))); -- word aligned
-- virtual read and ack latency --
if (wb_mem_latency_c > 1) then
for i in 1 to wb_mem_latency_c-1 loop
wb_mem.rdata(i) <= wb_mem.rdata(i-1);
wb_mem.rb_en(i) <= wb_mem.rb_en(i-1) and wb_cpu.cyc;
wb_mem.ack(i) <= wb_mem.ack(i-1) and wb_cpu.cyc;
if (ext_mem_a_latency_c > 1) then
for i in 1 to ext_mem_a_latency_c-1 loop
ext_mem_a.rdata(i) <= ext_mem_a.rdata(i-1);
ext_mem_a.ack(i) <= ext_mem_a.ack(i-1) and wb_mem_a.cyc;
end loop;
end if;
 
-- bus output register --
wb_mem_a.err <= '0';
if (ext_mem_a.ack(ext_mem_a_latency_c-1) = '1') and (wb_mem_b.cyc = '1') then
wb_mem_a.rdata <= ext_mem_a.rdata(ext_mem_a_latency_c-1);
wb_mem_a.ack <= '1';
else
wb_mem_a.rdata <= (others => '0');
wb_mem_a.ack <= '0';
end if;
end if;
end process wb_mem_ram_access;
end process ext_mem_a_access;
 
-- wishbone memory access? --
wb_mem.acc_en <= '1' when (wb_cpu.addr >= wb_mem_base_addr_c) and (wb_cpu.addr < std_ulogic_vector(unsigned(wb_mem_base_addr_c) + wb_mem_size_c)) else '0';
 
-- output to cpu --
wb_cpu.rdata <= wb_mem.rdata(wb_mem_latency_c-1) when (wb_mem.rb_en(wb_mem_latency_c-1) = '1') else (others=> '0'); -- data output gate
wb_cpu.ack <= wb_mem.ack(wb_mem_latency_c-1);
wb_cpu.err <= '0';
-- Wishbone Memory B (simulated external memory) ------------------------------------------
-- -------------------------------------------------------------------------------------------
ext_mem_b_access: process(clk_gen)
begin
if rising_edge(clk_gen) then
-- control --
ext_mem_b.ack(0) <= wb_mem_b.cyc and wb_mem_b.stb; -- wishbone acknowledge
 
-- write access --
if ((wb_mem_b.cyc and wb_mem_b.stb and wb_mem_b.we) = '1') then -- valid write access
for i in 0 to 3 loop
if (wb_mem_b.sel(i) = '1') then
ext_ram_b(to_integer(unsigned(wb_mem_b.addr(index_size_f(ext_mem_b_size_c/4)+1 downto 2))))(7+i*8 downto 0+i*8) <= wb_mem_b.wdata(7+i*8 downto 0+i*8);
end if;
end loop; -- i
end if;
 
-- read access --
ext_mem_b.rdata(0) <= ext_ram_b(to_integer(unsigned(wb_mem_b.addr(index_size_f(ext_mem_b_size_c/4)+1 downto 2)))); -- word aligned
-- virtual read and ack latency --
if (ext_mem_b_latency_c > 1) then
for i in 1 to ext_mem_b_latency_c-1 loop
ext_mem_b.rdata(i) <= ext_mem_b.rdata(i-1);
ext_mem_b.ack(i) <= ext_mem_b.ack(i-1) and wb_mem_b.cyc;
end loop;
end if;
 
-- bus output register --
wb_mem_b.err <= '0';
if (ext_mem_b.ack(ext_mem_b_latency_c-1) = '1') and (wb_mem_b.cyc = '1') then
wb_mem_b.rdata <= ext_mem_b.rdata(ext_mem_b_latency_c-1);
wb_mem_b.ack <= '1';
else
wb_mem_b.rdata <= (others => '0');
wb_mem_b.ack <= '0';
end if;
end if;
end process ext_mem_b_access;
 
 
end neorv32_tb_rtl;

powered by: WebSVN 2.1.0

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