Skip to content

Commit

Permalink
[sim] rework default testbench (#1119)
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting authored Dec 14, 2024
2 parents 64d7699 + 9114f10 commit 79e9df2
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 82 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 12.12.2024 | 1.10.7.2 | add external memory configuration/initialization options to testbench | [#1119](https://github.com/stnolting/neorv32/pull/1119) |
| 11.12.2024 | 1.10.7.1 | :test_tube: shrink bootloader's minimal ISA (`rv32e`) and RAM (256 bytes) requirements | [#1118](https://github.com/stnolting/neorv32/pull/1118) |
| 10.12.2024 | [**:rocket:1.10.7**](https://github.com/stnolting/neorv32/releases/tag/v1.10.7) | **New release** | |
| 03.12.2024 | 1.10.6.9 | :sparkles: add ONEWIRE command and data FIFO; :warning: rework ONEWIRE interface register layout; :bug: fix regression: busy flag was stuck at zero | [#1113](https://github.com/stnolting/neorv32/pull/1113) |
Expand Down
13 changes: 12 additions & 1 deletion rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ package neorv32_package is

-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100701"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100702"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width

Expand Down Expand Up @@ -194,6 +194,17 @@ package neorv32_package is
cyc : std_ulogic; -- valid cycle
end record;

-- source (request) termination --
constant xbus_req_terminate_c : xbus_req_t := (
addr => (others => '0'),
data => (others => '0'),
tag => (others => '0'),
we => '0',
sel => (others => '0'),
stb => '0',
cyc => '0'
);

-- xbus response --
type xbus_rsp_t is record
data : std_ulogic_vector(31 downto 0); -- read data, valid if ack=1
Expand Down
123 changes: 77 additions & 46 deletions sim/neorv32_tb.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ use neorv32.neorv32_package.all;

entity neorv32_tb is
generic (
-- processor --
CLOCK_FREQUENCY : natural := 100_000_000; -- clock frequency of clk_i in Hz
BOOT_MODE_SELECT : natural range 0 to 2 := 2; -- boot from pre-initialized IMEM
BOOT_ADDR_CUSTOM : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CPU boot address (if boot_config = 1)
RISCV_ISA_C : boolean := false; -- implement compressed extension
RISCV_ISA_E : boolean := false; -- implement embedded RF extension
RISCV_ISA_M : boolean := true; -- implement mul/div extension
Expand Down Expand Up @@ -54,7 +56,17 @@ entity neorv32_tb is
ICACHE_BLOCK_SIZE : natural range 4 to 2**16 := 32; -- i-cache: block size in bytes (min 4), has to be a power of 2
DCACHE_EN : boolean := true; -- implement data cache
DCACHE_NUM_BLOCKS : natural range 1 to 256 := 32; -- d-cache: number of blocks (min 1), has to be a power of 2
DCACHE_BLOCK_SIZE : natural range 4 to 2**16 := 32 -- d-cache: block size in bytes (min 4), has to be a power of 2
DCACHE_BLOCK_SIZE : natural range 4 to 2**16 := 32; -- d-cache: block size in bytes (min 4), has to be a power of 2
-- external memory A --
EXT_MEM_A_EN : boolean := false; -- enable memory
EXT_MEM_A_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- base address, has to be word-aligned
EXT_MEM_A_SIZE : natural := 64; -- memory size in bytes, min 4
EXT_MEM_A_FILE : string := ""; -- memory initialization file (plain HEX), no initialization if empty
-- external memory B --
EXT_MEM_B_EN : boolean := false; -- enable memory
EXT_MEM_B_BASE : std_ulogic_vector(31 downto 0) := x"80000000"; -- base address, has to be word-aligned
EXT_MEM_B_SIZE : natural := 64; -- memory size in bytes, min 4
EXT_MEM_B_FILE : string := "" -- memory initialization file (plain HEX), no initialization if empty
);
end neorv32_tb;

Expand All @@ -79,8 +91,8 @@ architecture neorv32_tb_rtl of neorv32_tb is
signal slink_tx, slink_rx : slink_t;

-- XBUS (Wishbone b4) bus --
signal xbus_core_req, xbus_imem_req, xbus_dmem_req, xbus_mmio_req, xbus_trig_req : xbus_req_t;
signal xbus_core_rsp, xbus_imem_rsp, xbus_dmem_rsp, xbus_mmio_rsp, xbus_trig_rsp : xbus_rsp_t;
signal xbus_core_req, xbus_ext_mem_a_req, xbus_ext_mem_b_req, xbus_mmio_req, xbus_trig_req : xbus_req_t;
signal xbus_core_rsp, xbus_ext_mem_a_rsp, xbus_ext_mem_b_rsp, xbus_mmio_rsp, xbus_trig_rsp : xbus_rsp_t;

begin

Expand All @@ -102,7 +114,7 @@ begin
JEDEC_ID => "00000000000",
-- Boot Configuration --
BOOT_MODE_SELECT => BOOT_MODE_SELECT,
BOOT_ADDR_CUSTOM => x"00000000",
BOOT_ADDR_CUSTOM => BOOT_ADDR_CUSTOM,
-- On-Chip Debugger (OCD) --
OCD_EN => true,
OCD_AUTHENTICATION => true,
Expand Down Expand Up @@ -142,7 +154,7 @@ begin
HPM_NUM_CNTS => 12,
HPM_CNT_WIDTH => 40,
-- Internal Instruction memory --
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN ,
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN,
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE,
-- Internal Data memory --
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN,
Expand Down Expand Up @@ -352,9 +364,9 @@ begin
-- -------------------------------------------------------------------------------------------
sim_rx_uart0: entity work.sim_uart_rx
generic map (
name => "uart0",
fclk => real(CLOCK_FREQUENCY),
baud => real(19200)
NAME => "uart0",
FCLK => real(CLOCK_FREQUENCY),
BAUD => real(19200)
)
port map (
clk => clk_gen,
Expand All @@ -363,9 +375,9 @@ begin

sim_rx_uart1: entity work.sim_uart_rx
generic map (
name => "uart1",
fclk => real(CLOCK_FREQUENCY),
baud => real(19200)
NAME => "uart1",
FCLK => real(CLOCK_FREQUENCY),
BAUD => real(19200)
)
port map (
clk => clk_gen,
Expand All @@ -378,59 +390,78 @@ begin
xbus_interconnect: entity work.xbus_gateway
generic map (
-- device address size in bytes and base address --
DEV_0_SIZE => MEM_INT_IMEM_SIZE, DEV_0_BASE => mem_imem_base_c,
DEV_1_SIZE => MEM_INT_DMEM_SIZE, DEV_1_BASE => mem_dmem_base_c,
DEV_2_SIZE => 64, DEV_2_BASE => x"F0000000",
DEV_3_SIZE => 4, DEV_3_BASE => x"FF000000"
DEV_0_EN => EXT_MEM_A_EN, DEV_0_SIZE => EXT_MEM_A_SIZE, DEV_0_BASE => EXT_MEM_A_BASE,
DEV_1_EN => EXT_MEM_B_EN, DEV_1_SIZE => EXT_MEM_B_SIZE, DEV_1_BASE => EXT_MEM_B_BASE,
DEV_2_EN => true, DEV_2_SIZE => 64, DEV_2_BASE => x"F0000000",
DEV_3_EN => true, DEV_3_SIZE => 4, DEV_3_BASE => x"FF000000"
)
port map (
-- host port --
host_req_i => xbus_core_req,
host_rsp_o => xbus_core_rsp,
-- device ports --
dev_0_req_o => xbus_imem_req, dev_0_rsp_i => xbus_imem_rsp,
dev_1_req_o => xbus_dmem_req, dev_1_rsp_i => xbus_dmem_rsp,
dev_2_req_o => xbus_mmio_req, dev_2_rsp_i => xbus_mmio_rsp,
dev_3_req_o => xbus_trig_req, dev_3_rsp_i => xbus_trig_rsp
dev_0_req_o => xbus_ext_mem_a_req, dev_0_rsp_i => xbus_ext_mem_a_rsp,
dev_1_req_o => xbus_ext_mem_b_req, dev_1_rsp_i => xbus_ext_mem_b_rsp,
dev_2_req_o => xbus_mmio_req, dev_2_rsp_i => xbus_mmio_rsp,
dev_3_req_o => xbus_trig_req, dev_3_rsp_i => xbus_trig_rsp
);


-- XBUS: Instruction Memory ---------------------------------------------------------------
-- XBUS: External Memory A ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
xbus_imem: entity work.xbus_memory
generic map (
MEM_SIZE => MEM_INT_IMEM_SIZE,
MEM_LATE => 1
)
port map (
clk_i => clk_gen,
rstn_i => rst_gen,
xbus_req_i => xbus_imem_req,
xbus_rsp_o => xbus_imem_rsp
);


-- XBUS: Data Memory ----------------------------------------------------------------------
xbus_external_memory_a_enable:
if EXT_MEM_A_EN generate
xbus_external_memory_a: entity work.xbus_memory
generic map (
MEM_SIZE => EXT_MEM_A_SIZE,
MEM_LATE => 1,
MEM_FILE => EXT_MEM_A_FILE
)
port map (
clk_i => clk_gen,
rstn_i => rst_gen,
xbus_req_i => xbus_ext_mem_a_req,
xbus_rsp_o => xbus_ext_mem_a_rsp
);
end generate;

xbus_external_memory_a_disable:
if not EXT_MEM_A_EN generate
xbus_ext_mem_a_rsp <= xbus_rsp_terminate_c;
end generate;


-- XBUS: External Memory B ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
xbus_dmem: entity work.xbus_memory
generic map (
MEM_SIZE => MEM_INT_DMEM_SIZE,
MEM_LATE => 1
)
port map (
clk_i => clk_gen,
rstn_i => rst_gen,
xbus_req_i => xbus_dmem_req,
xbus_rsp_o => xbus_dmem_rsp
);
xbus_external_memory_b_enable:
if EXT_MEM_B_EN generate
xbus_external_memory_b: entity work.xbus_memory
generic map (
MEM_SIZE => EXT_MEM_B_SIZE,
MEM_LATE => 1,
MEM_FILE => EXT_MEM_B_FILE
)
port map (
clk_i => clk_gen,
rstn_i => rst_gen,
xbus_req_i => xbus_ext_mem_b_req,
xbus_rsp_o => xbus_ext_mem_b_rsp
);
end generate;

xbus_external_memory_b_disable:
if not EXT_MEM_B_EN generate
xbus_ext_mem_b_rsp <= xbus_rsp_terminate_c;
end generate;


-- XBUS: Memory-Mapped IO -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
xbus_mmio: entity work.xbus_memory
generic map (
MEM_SIZE => 64,
MEM_LATE => 32
MEM_LATE => 32,
MEM_FILE => "" -- no initialization
)
port map (
clk_i => clk_gen,
Expand Down
14 changes: 7 additions & 7 deletions sim/sim_uart_rx.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use std.textio.all;

entity sim_uart_rx is
generic (
name : string; -- receiver name (for log file)
fclk : real; -- clock speed of clk_i in Hz
baud : real -- baud rate
NAME : string; -- receiver name (for log file)
FCLK : real; -- clock speed of clk_i in Hz
BAUD : real -- baud rate
);
port (
clk : in std_ulogic; -- global clock
Expand All @@ -33,8 +33,8 @@ architecture sim_uart_rx_rtl of sim_uart_rx is
signal sreg : std_ulogic_vector(8 downto 0) := (others => '0');
signal baudcnt : real;
signal bitcnt : natural;
constant baud_val_c : real := fclk / baud;
file file_out : text open write_mode is "neorv32_tb." & name & "_rx.out";
constant baud_val_c : real := FCLK / BAUD;
file file_out : text open write_mode is "neorv32_tb." & NAME & "_rx.out";

begin

Expand Down Expand Up @@ -67,9 +67,9 @@ begin
c := to_integer(unsigned(sreg(8 downto 1)));

if (c < 32) or (c > 32+95) then -- non-printable character?
report name & ".rx: (" & integer'image(c) & ")";
report NAME & ".rx: (" & integer'image(c) & ")";
else
report name & ".rx: " & character'val(c);
report NAME & ".rx: " & character'val(c);
end if;

if (c = 10) then -- LF line break
Expand Down
25 changes: 15 additions & 10 deletions sim/xbus_gateway.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ use neorv32.neorv32_package.all;

entity xbus_gateway is
generic (
-- device address size in bytes and base address --
DEV_0_SIZE : natural := 0; DEV_0_BASE : std_ulogic_vector(31 downto 0) := (others => '0');
DEV_1_SIZE : natural := 0; DEV_1_BASE : std_ulogic_vector(31 downto 0) := (others => '0');
DEV_2_SIZE : natural := 0; DEV_2_BASE : std_ulogic_vector(31 downto 0) := (others => '0');
DEV_3_SIZE : natural := 0; DEV_3_BASE : std_ulogic_vector(31 downto 0) := (others => '0')
-- device enable, address size in bytes and base address (word-aligned) --
DEV_0_EN : boolean := false; DEV_0_SIZE : natural := 0; DEV_0_BASE : std_ulogic_vector(31 downto 0) := (others => '0');
DEV_1_EN : boolean := false; DEV_1_SIZE : natural := 0; DEV_1_BASE : std_ulogic_vector(31 downto 0) := (others => '0');
DEV_2_EN : boolean := false; DEV_2_SIZE : natural := 0; DEV_2_BASE : std_ulogic_vector(31 downto 0) := (others => '0');
DEV_3_EN : boolean := false; DEV_3_SIZE : natural := 0; DEV_3_BASE : std_ulogic_vector(31 downto 0) := (others => '0')
);
port (
-- host port --
Expand All @@ -41,8 +41,10 @@ architecture xbus_gateway_rtl of xbus_gateway is
constant num_devs_c : natural := 4; -- number of device ports

-- list of device base address and address size --
type dev_en_list_t is array (0 to num_devs_c-1) of boolean;
type dev_base_list_t is array (0 to num_devs_c-1) of std_ulogic_vector(31 downto 0);
type dev_size_list_t is array (0 to num_devs_c-1) of natural;
constant dev_en_list_c : dev_en_list_t := (DEV_0_EN, DEV_1_EN, DEV_2_EN, DEV_3_EN);
constant dev_base_list_c : dev_base_list_t := (DEV_0_BASE, DEV_1_BASE, DEV_2_BASE, DEV_3_BASE);
constant dev_size_list_c : dev_size_list_t := (DEV_0_SIZE, DEV_1_SIZE, DEV_2_SIZE, DEV_3_SIZE);

Expand All @@ -66,7 +68,7 @@ begin
-- device select --
acc_en_gen:
for i in 0 to num_devs_c-1 generate
acc_en(i) <= '1' when (dev_size_list_c(i) > 0) and
acc_en(i) <= '1' when (dev_size_list_c(i) > 0) and dev_en_list_c(i) and
(unsigned(host_req_i.addr) >= unsigned(dev_base_list_c(i))) and
(unsigned(host_req_i.addr) < (unsigned(dev_base_list_c(i)) + dev_size_list_c(i))) else '0';
end generate;
Expand All @@ -76,9 +78,12 @@ begin
for i in 0 to num_devs_c-1 generate
bus_request: process(host_req_i, acc_en)
begin
dev_req(i) <= host_req_i;
dev_req(i).cyc <= host_req_i.cyc and acc_en(i);
dev_req(i).stb <= host_req_i.stb and acc_en(i);
dev_req(i) <= xbus_req_terminate_c; -- default: disabled
if dev_en_list_c(i) then
dev_req(i) <= host_req_i;
dev_req(i).cyc <= host_req_i.cyc and acc_en(i);
dev_req(i).stb <= host_req_i.stb and acc_en(i);
end if;
end process bus_request;
end generate;

Expand All @@ -90,7 +95,7 @@ begin
tmp_v.ack := '0';
tmp_v.err := '0';
for i in 0 to num_devs_c-1 loop -- OR all enabled response buses
if (acc_en(i) = '1') then
if (acc_en(i) = '1') and dev_en_list_c(i) then
tmp_v.data := tmp_v.data or dev_rsp(i).data;
tmp_v.ack := tmp_v.ack or dev_rsp(i).ack;
tmp_v.err := tmp_v.err or dev_rsp(i).err;
Expand Down
Loading

0 comments on commit 79e9df2

Please sign in to comment.