fpga: Add NEORV32 as alternative CPU core
This commit is contained in:
		
							parent
							
								
									bb7b2a7a10
								
							
						
					
					
						commit
						ba299e537b
					
				
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							@ -4,3 +4,6 @@
 | 
				
			|||||||
[submodule "fpga/hdl/trashernet"]
 | 
					[submodule "fpga/hdl/trashernet"]
 | 
				
			||||||
	path = fpga/hdl/trashernet
 | 
						path = fpga/hdl/trashernet
 | 
				
			||||||
	url = https://git.notsyncing.net/fpga/trashernet.git
 | 
						url = https://git.notsyncing.net/fpga/trashernet.git
 | 
				
			||||||
 | 
					[submodule "fpga/hdl/neorv32"]
 | 
				
			||||||
 | 
						path = fpga/hdl/neorv32
 | 
				
			||||||
 | 
						url = https://github.com/stnolting/neorv32.git
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										170
									
								
								fpga/hdl/design/neorv32_top.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								fpga/hdl/design/neorv32_top.vhd
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,170 @@
 | 
				
			|||||||
 | 
					-- -------------------------------------------------------------------------- --
 | 
				
			||||||
 | 
					--              TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs              --
 | 
				
			||||||
 | 
					-- -------------------------------------------------------------------------- --
 | 
				
			||||||
 | 
					-- Wrapper for NEORV32
 | 
				
			||||||
 | 
					-- -------------------------------------------------------------------------- --
 | 
				
			||||||
 | 
					-- Author       : Markus Koch <markus@notsyncing.net>
 | 
				
			||||||
 | 
					-- Contributors : None
 | 
				
			||||||
 | 
					-- License      : Mozilla Public License (MPL) Version 2
 | 
				
			||||||
 | 
					-- -------------------------------------------------------------------------- --
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					library ieee;
 | 
				
			||||||
 | 
					use ieee.std_logic_1164.all;
 | 
				
			||||||
 | 
					use ieee.numeric_std.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					library generics;
 | 
				
			||||||
 | 
					use generics.wishbone_pkg.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					library neorv32;
 | 
				
			||||||
 | 
					use neorv32.neorv32_package.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					entity neorv32_top_vhdl is
 | 
				
			||||||
 | 
						port(
 | 
				
			||||||
 | 
							clk       : in  std_logic;      -- CPU and bus clock
 | 
				
			||||||
 | 
							clr       : in  std_logic;      -- Synchronous clear (CPU reset)
 | 
				
			||||||
 | 
							wbi_o     : out wishbone_master_out; -- Instruction Wishbone bus (out)
 | 
				
			||||||
 | 
							wbi_i     : in  wishbone_master_in; -- Instruction Wishbone bus (in)
 | 
				
			||||||
 | 
							wbd_o     : out wishbone_master_out; -- Data Wishbone bus (out)
 | 
				
			||||||
 | 
							wbd_i     : in  wishbone_master_in; -- Data Wishbone bus (in)
 | 
				
			||||||
 | 
							irq_timer : in  std_logic       -- System timer interrupt
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					end entity neorv32_top_vhdl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					architecture rtl of neorv32_top_vhdl is
 | 
				
			||||||
 | 
						signal ibus_req_o : bus_req_t;
 | 
				
			||||||
 | 
						signal ibus_rsp_i : bus_rsp_t;
 | 
				
			||||||
 | 
						signal dbus_req_o : bus_req_t;
 | 
				
			||||||
 | 
						signal dbus_rsp_i : bus_rsp_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						signal wbi_rsp_latched : std_logic;
 | 
				
			||||||
 | 
						signal wbd_rsp_latched : std_logic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						signal ibus_req_mask : std_logic;
 | 
				
			||||||
 | 
						signal ibus_rsp_mask : std_logic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						signal dbus_req_mask : std_logic;
 | 
				
			||||||
 | 
						signal dbus_rsp_mask : std_logic;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						neorv32_cpu_inst : entity neorv32.neorv32_cpu
 | 
				
			||||||
 | 
							generic map(
 | 
				
			||||||
 | 
								HART_ID                    => x"00000000",
 | 
				
			||||||
 | 
								VENDOR_ID                  => x"00000000",
 | 
				
			||||||
 | 
								CPU_BOOT_ADDR              => x"00000000",
 | 
				
			||||||
 | 
								CPU_DEBUG_PARK_ADDR        => x"00000000",
 | 
				
			||||||
 | 
								CPU_DEBUG_EXC_ADDR         => x"00000000",
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_A      => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_B      => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_C      => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_E      => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_M      => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_U      => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zbkx   => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zfinx  => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zicntr => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zicond => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zihpm  => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zknd   => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zkne   => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zknh   => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zmmul  => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Zxcfu  => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Sdext  => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Sdtrig => false,
 | 
				
			||||||
 | 
								CPU_EXTENSION_RISCV_Smpmp  => false,
 | 
				
			||||||
 | 
								FAST_MUL_EN                => false,
 | 
				
			||||||
 | 
								FAST_SHIFT_EN              => false,
 | 
				
			||||||
 | 
								REGFILE_HW_RST             => true,
 | 
				
			||||||
 | 
								PMP_NUM_REGIONS            => 0,
 | 
				
			||||||
 | 
								PMP_MIN_GRANULARITY        => 0,
 | 
				
			||||||
 | 
								PMP_TOR_MODE_EN            => false,
 | 
				
			||||||
 | 
								PMP_NAP_MODE_EN            => false,
 | 
				
			||||||
 | 
								HPM_NUM_CNTS               => 0,
 | 
				
			||||||
 | 
								HPM_CNT_WIDTH              => 0
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							port map(
 | 
				
			||||||
 | 
								clk_i      => clk,
 | 
				
			||||||
 | 
								clk_aux_i  => clk,
 | 
				
			||||||
 | 
								rstn_i     => not clr,
 | 
				
			||||||
 | 
								sleep_o    => open,
 | 
				
			||||||
 | 
								debug_o    => open,
 | 
				
			||||||
 | 
								msi_i      => '0',
 | 
				
			||||||
 | 
								mei_i      => '0',
 | 
				
			||||||
 | 
								mti_i      => irq_timer,
 | 
				
			||||||
 | 
								firq_i     => x"0000",
 | 
				
			||||||
 | 
								dbi_i      => '0',
 | 
				
			||||||
 | 
								ibus_req_o => ibus_req_o,
 | 
				
			||||||
 | 
								ibus_rsp_i => ibus_rsp_i,
 | 
				
			||||||
 | 
								dbus_req_o => dbus_req_o,
 | 
				
			||||||
 | 
								dbus_rsp_i => dbus_rsp_i
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Instruction bus
 | 
				
			||||||
 | 
						wbi_o.adr       <= wishbone_address(ibus_req_o.addr);
 | 
				
			||||||
 | 
						wbi_o.dat       <= wishbone_data(ibus_req_o.data);
 | 
				
			||||||
 | 
						wbi_o.sel       <= wishbone_byte_select(ibus_req_o.ben);
 | 
				
			||||||
 | 
						wbi_o.we        <= ibus_req_o.rw; -- TODO: We should also buffer this like we do stb, but in the current version the CPU holds it for us, so :shrug:
 | 
				
			||||||
 | 
						wbi_o.cyc       <= wbi_o.stb;
 | 
				
			||||||
 | 
						ibus_rsp_i.data <= std_ulogic_vector(wbi_i.dat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wbi_o.stb      <= ibus_req_mask;
 | 
				
			||||||
 | 
						ibus_rsp_i.ack <= wbi_i.ack and not (ibus_rsp_mask);
 | 
				
			||||||
 | 
						ibus_rsp_i.err <= (wbi_i.err or wbi_i.rty) and not (ibus_rsp_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wb2bus_i : process(clk) is
 | 
				
			||||||
 | 
						begin
 | 
				
			||||||
 | 
							if rising_edge(clk) then
 | 
				
			||||||
 | 
								if ibus_req_o.stb then
 | 
				
			||||||
 | 
									ibus_req_mask <= '1';
 | 
				
			||||||
 | 
									assert ibus_req_o.rvso = '0' report "Error: IBus RVSO not implemented but requested!" severity FAILURE;
 | 
				
			||||||
 | 
								end if;
 | 
				
			||||||
 | 
								if (wbi_i.ack or wbi_i.err or wbi_i.rty) and not ibus_req_o.stb then
 | 
				
			||||||
 | 
									ibus_req_mask <= '0';
 | 
				
			||||||
 | 
									ibus_rsp_mask <= '1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									ibus_rsp_mask <= '0';
 | 
				
			||||||
 | 
								end if;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if clr then
 | 
				
			||||||
 | 
									ibus_req_mask <= '0';
 | 
				
			||||||
 | 
									ibus_rsp_mask <= '0';
 | 
				
			||||||
 | 
								end if;
 | 
				
			||||||
 | 
							end if;
 | 
				
			||||||
 | 
						end process wb2bus_i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Data bus
 | 
				
			||||||
 | 
						wbd_o.adr       <= wishbone_address(dbus_req_o.addr);
 | 
				
			||||||
 | 
						wbd_o.dat       <= wishbone_data(dbus_req_o.data);
 | 
				
			||||||
 | 
						wbd_o.sel       <= wishbone_byte_select(dbus_req_o.ben);
 | 
				
			||||||
 | 
						wbd_o.we        <= dbus_req_o.rw;
 | 
				
			||||||
 | 
						wbd_o.cyc       <= wbd_o.stb;
 | 
				
			||||||
 | 
						dbus_rsp_i.data <= std_ulogic_vector(wbd_i.dat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wbd_o.stb      <= dbus_req_mask;
 | 
				
			||||||
 | 
						dbus_rsp_i.ack <= wbd_i.ack and not (dbus_rsp_mask);
 | 
				
			||||||
 | 
						dbus_rsp_i.err <= (wbd_i.err or wbd_i.rty) and not (dbus_rsp_mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wb2bus_d : process(clk) is
 | 
				
			||||||
 | 
						begin
 | 
				
			||||||
 | 
							if rising_edge(clk) then
 | 
				
			||||||
 | 
								if dbus_req_o.stb then
 | 
				
			||||||
 | 
									dbus_req_mask <= '1';
 | 
				
			||||||
 | 
									assert dbus_req_o.rvso = '0' report "Error: dbus RVSO not implemented but requested!" severity FAILURE;
 | 
				
			||||||
 | 
								end if;
 | 
				
			||||||
 | 
								if (wbd_i.ack or wbd_i.err or wbd_i.rty) and not dbus_req_o.stb then
 | 
				
			||||||
 | 
									dbus_req_mask <= '0';
 | 
				
			||||||
 | 
									dbus_rsp_mask <= '1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									dbus_rsp_mask <= '0';
 | 
				
			||||||
 | 
								end if;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if clr then
 | 
				
			||||||
 | 
									dbus_req_mask <= '0';
 | 
				
			||||||
 | 
									dbus_rsp_mask <= '0';
 | 
				
			||||||
 | 
								end if;
 | 
				
			||||||
 | 
							end if;
 | 
				
			||||||
 | 
						end process wb2bus_d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end architecture rtl;
 | 
				
			||||||
@ -23,7 +23,8 @@ entity top is
 | 
				
			|||||||
		F_IN      : integer := 50000000;
 | 
							F_IN      : integer := 50000000;
 | 
				
			||||||
		F_CLK     : integer := 25000000;
 | 
							F_CLK     : integer := 25000000;
 | 
				
			||||||
		F_CLK_PHY : integer := 50000000;
 | 
							F_CLK_PHY : integer := 50000000;
 | 
				
			||||||
		UART_BAUD : integer := 250000
 | 
							UART_BAUD : integer := 250000;
 | 
				
			||||||
 | 
							CPU       : string  := "serv"
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
	port(
 | 
						port(
 | 
				
			||||||
		clk_in           : in    std_logic; -- System clock
 | 
							clk_in           : in    std_logic; -- System clock
 | 
				
			||||||
@ -201,6 +202,7 @@ begin
 | 
				
			|||||||
		end if;
 | 
							end if;
 | 
				
			||||||
	end process por;
 | 
						end process por;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cpu_sel : if CPU = "serv" generate
 | 
				
			||||||
		serv_top_vhdl_inst : entity work.serv_top_vhdl
 | 
							serv_top_vhdl_inst : entity work.serv_top_vhdl
 | 
				
			||||||
			port map(
 | 
								port map(
 | 
				
			||||||
				clk       => clk,
 | 
									clk       => clk,
 | 
				
			||||||
@ -212,6 +214,27 @@ begin
 | 
				
			|||||||
				irq_timer => irq_timer
 | 
									irq_timer => irq_timer
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						elsif CPU = "neorv32" generate
 | 
				
			||||||
 | 
							neorv32_top_vhdl_inst : entity work.neorv32_top_vhdl
 | 
				
			||||||
 | 
								port map(
 | 
				
			||||||
 | 
									clk       => clk,
 | 
				
			||||||
 | 
									clr       => clr,
 | 
				
			||||||
 | 
									wbi_o     => wbi_o,
 | 
				
			||||||
 | 
									wbi_i     => wbi_i,
 | 
				
			||||||
 | 
									wbd_o     => wbd_o,
 | 
				
			||||||
 | 
									wbd_i     => wbd_i,
 | 
				
			||||||
 | 
									irq_timer => irq_timer
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						else generate
 | 
				
			||||||
 | 
							cpu_sel_err_p : process is
 | 
				
			||||||
 | 
							begin
 | 
				
			||||||
 | 
								report "ERROR: Selected invalid CPU" severity FAILURE;
 | 
				
			||||||
 | 
								wait;
 | 
				
			||||||
 | 
							end process cpu_sel_err_p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						end generate cpu_sel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	servant_rom_vhdl_inst : entity work.servant_ram_vhdl
 | 
						servant_rom_vhdl_inst : entity work.servant_ram_vhdl
 | 
				
			||||||
		generic map(
 | 
							generic map(
 | 
				
			||||||
			memfile   => "../sw/bootrom/bootrom.vhex",
 | 
								memfile   => "../sw/bootrom/bootrom.vhex",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								fpga/hdl/neorv32
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								fpga/hdl/neorv32
									
									
									
									
									
										Submodule
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					Subproject commit fd79163eb2d49cc57a9d91061a9fd4f6cdc94644
 | 
				
			||||||
@ -14,6 +14,7 @@ libraries = {
 | 
				
			|||||||
		"device_models",
 | 
							"device_models",
 | 
				
			||||||
		"generics",
 | 
							"generics",
 | 
				
			||||||
		"serv",
 | 
							"serv",
 | 
				
			||||||
 | 
							"neorv32",
 | 
				
			||||||
		"trashernet"
 | 
							"trashernet"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -38,6 +39,9 @@ for base_path in libraries:
 | 
				
			|||||||
			if library_name == "trashernet": # Special case: Trashernet submodule
 | 
								if library_name == "trashernet": # Special case: Trashernet submodule
 | 
				
			||||||
				path = os.path.join(base_path, "hdl", library_name, library_name, "*.vhd")
 | 
									path = os.path.join(base_path, "hdl", library_name, library_name, "*.vhd")
 | 
				
			||||||
				libs[library_name].add_source_files(path)
 | 
									libs[library_name].add_source_files(path)
 | 
				
			||||||
 | 
								elif library_name == "neorv32": # Special case: NEORV32 submodule
 | 
				
			||||||
 | 
									path = os.path.join(base_path, "hdl", library_name, "rtl", "core", "*.vhd")
 | 
				
			||||||
 | 
									libs[library_name].add_source_files(path)
 | 
				
			||||||
			elif library_name == "serv": # Special case: SERV submodule
 | 
								elif library_name == "serv": # Special case: SERV submodule
 | 
				
			||||||
				print("Skipping SERV. It's Verilog.")
 | 
									print("Skipping SERV. It's Verilog.")
 | 
				
			||||||
			else: # Normal lib
 | 
								else: # Normal lib
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@ libraries = {
 | 
				
			|||||||
		"device_models",
 | 
							"device_models",
 | 
				
			||||||
		"generics",
 | 
							"generics",
 | 
				
			||||||
		"serv",
 | 
							"serv",
 | 
				
			||||||
 | 
							"neorv32",
 | 
				
			||||||
		"trashernet"
 | 
							"trashernet"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -37,6 +38,9 @@ for base_path in libraries:
 | 
				
			|||||||
			if library_name == "trashernet": # Special case: Trashernet submodule
 | 
								if library_name == "trashernet": # Special case: Trashernet submodule
 | 
				
			||||||
				path = os.path.join(base_path, "hdl", library_name, library_name, "*.vhd")
 | 
									path = os.path.join(base_path, "hdl", library_name, library_name, "*.vhd")
 | 
				
			||||||
				libs[library_name].add_source_files(path)
 | 
									libs[library_name].add_source_files(path)
 | 
				
			||||||
 | 
								elif library_name == "neorv32": # Special case: NEORV32 submodule
 | 
				
			||||||
 | 
									path = os.path.join(base_path, "hdl", library_name, "rtl", "core", "*.vhd")
 | 
				
			||||||
 | 
									libs[library_name].add_source_files(path)
 | 
				
			||||||
			elif library_name == "serv": # Special case: SERV submodule
 | 
								elif library_name == "serv": # Special case: SERV submodule
 | 
				
			||||||
				print("Skipping SERV. It's Verilog.")
 | 
									print("Skipping SERV. It's Verilog.")
 | 
				
			||||||
			else: # Normal lib
 | 
								else: # Normal lib
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user