Compare commits
No commits in common. "7497f1f6bb9281312cf9aefbbaac16b2db40b88d" and "3ecc6a4ed15de48726aaf2e36e6d734f5f97e8e6" have entirely different histories.
7497f1f6bb
...
3ecc6a4ed1
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,6 +4,3 @@
|
|||||||
[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
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<com.sigasi.hdt.shared.librarymapping.model:LibraryMappings xmlns:com.sigasi.hdt.shared.librarymapping.model="com.sigasi.hdt.vhdl.scoping.librarymapping" Version="2">
|
|
||||||
<Mappings Location="hdl/bench" Library="bench"/>
|
|
||||||
<Mappings Location="hdl/design" Library="design"/>
|
|
||||||
<Mappings Location="hdl/device_models" Library="device_models"/>
|
|
||||||
<Mappings Location="hdl/generics" Library="generics"/>
|
|
||||||
<Mappings Location="Common Libraries/IEEE" Library="ieee"/>
|
|
||||||
<Mappings Location="Common Libraries/IEEE Synopsys" Library="ieee"/>
|
|
||||||
<Mappings Location="hdl/neorv32/rtl/core" Library="neorv32"/>
|
|
||||||
<Mappings Location="Common Libraries" Library="not mapped"/>
|
|
||||||
<Mappings Location="diamond" Library="not mapped"/>
|
|
||||||
<Mappings Location="hdl" Library="not mapped"/>
|
|
||||||
<Mappings Location="Common Libraries/STD" Library="std"/>
|
|
||||||
<Mappings Location="hdl/trashernet/trashernet" Library="trashernet"/>
|
|
||||||
<Mappings Location="" Library="work"/>
|
|
||||||
</com.sigasi.hdt.shared.librarymapping.model:LibraryMappings>
|
|
@ -1,46 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>trashernet_soc</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>com.sigasi.hdt.vhdl.ui.vhdlNature</nature>
|
|
||||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
|
||||||
<nature>com.sigasi.hdt.verilog.ui.verilogNature</nature>
|
|
||||||
</natures>
|
|
||||||
<linkedResources>
|
|
||||||
<link>
|
|
||||||
<name>Common Libraries</name>
|
|
||||||
<type>2</type>
|
|
||||||
<locationURI>virtual:/virtual</locationURI>
|
|
||||||
</link>
|
|
||||||
<link>
|
|
||||||
<name>Common Libraries/DRAG_REUSABLE_LIBRARIES_HERE.txt</name>
|
|
||||||
<type>1</type>
|
|
||||||
<locationURI>sigasiresource:/vhdl/readme.txt</locationURI>
|
|
||||||
</link>
|
|
||||||
<link>
|
|
||||||
<name>Common Libraries/IEEE</name>
|
|
||||||
<type>2</type>
|
|
||||||
<locationURI>sigasiresource:/vhdl/2008/IEEE</locationURI>
|
|
||||||
</link>
|
|
||||||
<link>
|
|
||||||
<name>Common Libraries/IEEE Synopsys</name>
|
|
||||||
<type>2</type>
|
|
||||||
<locationURI>sigasiresource:/vhdl/2008/IEEE%20Synopsys</locationURI>
|
|
||||||
</link>
|
|
||||||
<link>
|
|
||||||
<name>Common Libraries/STD</name>
|
|
||||||
<type>2</type>
|
|
||||||
<locationURI>sigasiresource:/vhdl/2008/STD</locationURI>
|
|
||||||
</link>
|
|
||||||
</linkedResources>
|
|
||||||
</projectDescription>
|
|
@ -1 +0,0 @@
|
|||||||
<project>=2008
|
|
@ -73,7 +73,7 @@ begin
|
|||||||
|
|
||||||
top_inst : entity design.top
|
top_inst : entity design.top
|
||||||
port map(
|
port map(
|
||||||
clk_in => clk,
|
clk_50m => clk,
|
||||||
uart_tx => uart_txd,
|
uart_tx => uart_txd,
|
||||||
uart_rx => uart_rxd,
|
uart_rx => uart_rxd,
|
||||||
eth_rx_p => rx_p,
|
eth_rx_p => rx_p,
|
||||||
|
@ -1,239 +0,0 @@
|
|||||||
-- -------------------------------------------------------------------------- --
|
|
||||||
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
|
||||||
-- -------------------------------------------------------------------------- --
|
|
||||||
-- VUnit test bench for the aps6404l Wishbone IF
|
|
||||||
-- -------------------------------------------------------------------------- --
|
|
||||||
-- 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;
|
|
||||||
use std.textio.all;
|
|
||||||
|
|
||||||
library design;
|
|
||||||
use design.all;
|
|
||||||
|
|
||||||
library generics;
|
|
||||||
use generics.wishbone_pkg.all;
|
|
||||||
|
|
||||||
library device_models;
|
|
||||||
use device_models.all;
|
|
||||||
|
|
||||||
library vunit_lib;
|
|
||||||
context vunit_lib.vunit_context;
|
|
||||||
|
|
||||||
library osvvm;
|
|
||||||
context osvvm.osvvmContext;
|
|
||||||
use osvvm.ScoreboardPkg_slv.all;
|
|
||||||
|
|
||||||
entity bench_top_neorv32_wb is
|
|
||||||
generic(
|
|
||||||
runner_cfg : string := runner_cfg_default
|
|
||||||
);
|
|
||||||
end entity bench_top_neorv32_wb;
|
|
||||||
|
|
||||||
architecture RTL of bench_top_neorv32_wb is
|
|
||||||
constant UART_BAUD : integer := 250000;
|
|
||||||
signal clk_in : std_logic;
|
|
||||||
signal uart_tx : std_logic;
|
|
||||||
signal uart_rx : std_logic;
|
|
||||||
signal eth_rx_p : std_logic;
|
|
||||||
signal eth_tx_p : std_logic_vector(3 downto 0);
|
|
||||||
signal eth_tx_n : std_logic_vector(3 downto 0);
|
|
||||||
signal eth_led_green_n : std_logic;
|
|
||||||
signal eth_led_orange_n : std_logic;
|
|
||||||
signal led_user : std_logic;
|
|
||||||
signal psram_ce_n : std_logic;
|
|
||||||
signal psram_sclk : std_logic;
|
|
||||||
signal psram_sio : std_logic_vector(3 downto 0);
|
|
||||||
signal flash_ce_n : std_logic;
|
|
||||||
signal flash_sclk : std_logic;
|
|
||||||
signal flash_sio : std_logic_vector(3 downto 0);
|
|
||||||
signal pmod : std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
signal SB : ScoreboardIDType;
|
|
||||||
|
|
||||||
begin
|
|
||||||
top_inst : entity design.top
|
|
||||||
generic map(
|
|
||||||
F_IN => 50000000,
|
|
||||||
F_CLK => 25000000,
|
|
||||||
F_CLK_PHY => 50000000,
|
|
||||||
UART_BAUD => UART_BAUD,
|
|
||||||
CPU => "neorv32"
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => clk_in,
|
|
||||||
uart_tx => uart_tx,
|
|
||||||
uart_rx => uart_rx,
|
|
||||||
eth_rx_p => eth_rx_p,
|
|
||||||
eth_tx_p => eth_tx_p,
|
|
||||||
eth_tx_n => eth_tx_n,
|
|
||||||
eth_led_green_n => eth_led_green_n,
|
|
||||||
eth_led_orange_n => eth_led_orange_n,
|
|
||||||
led_user => led_user,
|
|
||||||
psram_ce_n => psram_ce_n,
|
|
||||||
psram_sclk => psram_sclk,
|
|
||||||
psram_sio => psram_sio,
|
|
||||||
flash_ce_n => flash_ce_n,
|
|
||||||
flash_sclk => flash_sclk,
|
|
||||||
flash_sio => flash_sio,
|
|
||||||
pmod => pmod
|
|
||||||
);
|
|
||||||
|
|
||||||
aps6404l_inst : entity device_models.aps6404l
|
|
||||||
generic map(
|
|
||||||
LOG_EN => false
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ce_n => psram_ce_n,
|
|
||||||
sclk => psram_sclk,
|
|
||||||
sio => psram_sio
|
|
||||||
);
|
|
||||||
|
|
||||||
uart_decoder : process is
|
|
||||||
constant DELAY : time := (1 sec / UART_BAUD);
|
|
||||||
variable d : std_logic_vector(7 downto 0);
|
|
||||||
begin
|
|
||||||
wait until falling_edge(uart_tx);
|
|
||||||
wait for 0.5 * DELAY;
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
wait for DELAY;
|
|
||||||
d(i) := uart_tx;
|
|
||||||
end loop;
|
|
||||||
wait for 1.0 * DELAY;
|
|
||||||
Check(SB, d);
|
|
||||||
end process uart_decoder;
|
|
||||||
|
|
||||||
test : process is
|
|
||||||
procedure uart_tx(d : std_logic_vector(7 downto 0)) is
|
|
||||||
constant DELAY : time := (1 sec / UART_BAUD);
|
|
||||||
begin
|
|
||||||
uart_rx <= '0';
|
|
||||||
wait for DELAY;
|
|
||||||
for i in d'low to d'high loop
|
|
||||||
uart_rx <= d(i);
|
|
||||||
wait for DELAY;
|
|
||||||
end loop;
|
|
||||||
uart_rx <= '1';
|
|
||||||
wait for DELAY;
|
|
||||||
end procedure uart_tx;
|
|
||||||
|
|
||||||
begin
|
|
||||||
test_runner_setup(runner, runner_cfg);
|
|
||||||
|
|
||||||
SB <= NewID("UART RX");
|
|
||||||
|
|
||||||
report "Waiting for internal reset to be complete...";
|
|
||||||
wait for 10 us;
|
|
||||||
report "Starting tests...";
|
|
||||||
|
|
||||||
while test_suite loop
|
|
||||||
if run("bootloader") then
|
|
||||||
uart_rx <= '1';
|
|
||||||
wait for (1 sec / UART_BAUD) * 10;
|
|
||||||
|
|
||||||
report ("Writing ABCD+jalr0 to RAM...");
|
|
||||||
-- WRITE
|
|
||||||
uart_tx(x"01");
|
|
||||||
|
|
||||||
-- to RAM
|
|
||||||
uart_tx(x"40");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
|
|
||||||
-- 8 bytes
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"08");
|
|
||||||
|
|
||||||
-- with this data ("ABCD", jalr zero)
|
|
||||||
uart_tx(x"41");
|
|
||||||
uart_tx(x"42");
|
|
||||||
uart_tx(x"43");
|
|
||||||
uart_tx(x"44");
|
|
||||||
uart_tx(x"e7");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
|
|
||||||
report ("Reading back from RAM...");
|
|
||||||
-- READ
|
|
||||||
uart_tx(x"02");
|
|
||||||
|
|
||||||
-- from RAM
|
|
||||||
uart_tx(x"40");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
|
|
||||||
-- 4 bytes ("ABCD")
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"04");
|
|
||||||
|
|
||||||
Push(SB, x"41");
|
|
||||||
Push(SB, x"42");
|
|
||||||
Push(SB, x"43");
|
|
||||||
Push(SB, x"44");
|
|
||||||
|
|
||||||
wait for (1 sec / UART_BAUD) * 10 * 5;
|
|
||||||
|
|
||||||
report ("Jumping to RAM+4...");
|
|
||||||
-- JUMP
|
|
||||||
uart_tx(x"03");
|
|
||||||
|
|
||||||
-- to RAM (+4, jalr zero)
|
|
||||||
uart_tx(x"40");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"04");
|
|
||||||
|
|
||||||
-- The program will jump back to the loader, so we should be able to read again
|
|
||||||
wait for 100 us;
|
|
||||||
|
|
||||||
report ("Reading from RAM again...");
|
|
||||||
-- READ
|
|
||||||
uart_tx(x"02");
|
|
||||||
|
|
||||||
-- from RAM
|
|
||||||
uart_tx(x"40");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
|
|
||||||
-- 4 bytes
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"00");
|
|
||||||
uart_tx(x"04");
|
|
||||||
|
|
||||||
Push(SB, x"41");
|
|
||||||
Push(SB, x"42");
|
|
||||||
Push(SB, x"43");
|
|
||||||
Push(SB, x"44");
|
|
||||||
wait for (1 sec / UART_BAUD) * 10 * 5;
|
|
||||||
|
|
||||||
assert ScoreboardEmpty(SB) report "UART RX Scoreboard not empty at end of test!" severity error;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
test_runner_cleanup(runner);
|
|
||||||
end process test;
|
|
||||||
|
|
||||||
test_runner_watchdog(runner, 50 ms);
|
|
||||||
|
|
||||||
clock_driver : process
|
|
||||||
constant period : time := 20 ns;
|
|
||||||
begin
|
|
||||||
clk_in <= '0';
|
|
||||||
wait for period / 2;
|
|
||||||
clk_in <= '1';
|
|
||||||
wait for period - (period / 2);
|
|
||||||
end process clock_driver;
|
|
||||||
end architecture RTL;
|
|
@ -1,170 +0,0 @@
|
|||||||
-- -------------------------------------------------------------------------- --
|
|
||||||
-- 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;
|
|
@ -1,7 +1,7 @@
|
|||||||
-- -------------------------------------------------------------------------- --
|
-- -------------------------------------------------------------------------- --
|
||||||
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
-- TRASHERNET SoC - A Trashy Ethernet SoC for FPGAs --
|
||||||
-- -------------------------------------------------------------------------- --
|
-- -------------------------------------------------------------------------- --
|
||||||
-- Servant-compatible RAM, rewritten in VHDL
|
-- TODO
|
||||||
-- -------------------------------------------------------------------------- --
|
-- -------------------------------------------------------------------------- --
|
||||||
-- Author : Markus Koch <markus@notsyncing.net>
|
-- Author : Markus Koch <markus@notsyncing.net>
|
||||||
-- Contributors : None
|
-- Contributors : None
|
||||||
@ -11,7 +11,6 @@
|
|||||||
library ieee;
|
library ieee;
|
||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
||||||
use std.textio.all;
|
|
||||||
|
|
||||||
library generics;
|
library generics;
|
||||||
use generics.wishbone_pkg.all;
|
use generics.wishbone_pkg.all;
|
||||||
@ -32,31 +31,48 @@ entity servant_ram_vhdl is
|
|||||||
end entity servant_ram_vhdl;
|
end entity servant_ram_vhdl;
|
||||||
|
|
||||||
architecture rtl of servant_ram_vhdl is
|
architecture rtl of servant_ram_vhdl is
|
||||||
type mem_t is array (0 to 2 ** adr_width - 1) of std_logic_vector(wb_i.dat'range);
|
component servant_ram
|
||||||
|
generic(
|
||||||
|
depth : integer;
|
||||||
|
aw : integer;
|
||||||
|
memfile : string
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
i_wb_clk : in std_logic;
|
||||||
|
i_wb_rst : in std_logic;
|
||||||
|
i_wb_adr : in std_logic_vector;
|
||||||
|
i_wb_dat : in std_logic_vector;
|
||||||
|
i_wb_sel : in std_logic_vector;
|
||||||
|
i_wb_we : in std_logic;
|
||||||
|
i_wb_cyc : in std_logic;
|
||||||
|
o_wb_rdt : out std_logic_vector;
|
||||||
|
o_wb_ack : out std_logic
|
||||||
|
);
|
||||||
|
end component servant_ram;
|
||||||
|
|
||||||
impure function init_ram_hex return mem_t is
|
|
||||||
file text_file : text open read_mode is memfile;
|
|
||||||
variable text_line : line;
|
|
||||||
variable ram_content : mem_t := (others => (others => '0'));
|
|
||||||
begin
|
|
||||||
for i in 0 to 2 ** adr_width - 1 loop
|
|
||||||
exit when endfile(text_file);
|
|
||||||
readline(text_file, text_line);
|
|
||||||
hread(text_line, ram_content(i));
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
return ram_content;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
signal mem : mem_t := init_ram_hex;
|
|
||||||
signal mem_address : integer range mem'range;
|
|
||||||
begin
|
begin
|
||||||
|
servant_ram_inst : component servant_ram
|
||||||
|
generic map(
|
||||||
|
depth => 2 ** adr_width,
|
||||||
|
aw => adr_width,
|
||||||
|
memfile => memfile
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
i_wb_clk => clk,
|
||||||
|
i_wb_rst => clr,
|
||||||
|
i_wb_adr => wb_i.adr(adr_width - 1 downto 2),
|
||||||
|
i_wb_dat => wb_i.dat,
|
||||||
|
i_wb_sel => wb_i.sel,
|
||||||
|
i_wb_we => wb_i.we,
|
||||||
|
i_wb_cyc => wb_i.cyc and wb_i.stb,
|
||||||
|
o_wb_rdt => wb_o.dat,
|
||||||
|
o_wb_ack => wb_o.ack
|
||||||
|
);
|
||||||
|
|
||||||
wb_o.rty <= '0';
|
wb_o.rty <= '0';
|
||||||
wb_o.err <= '0';
|
wb_o.err <= '0';
|
||||||
wb_o.stall <= '0';
|
wb_o.stall <= '0';
|
||||||
|
|
||||||
mem_address <= to_integer(unsigned(wb_i.adr(adr_width - 1 + 2 downto 2)));
|
|
||||||
|
|
||||||
rowarn : process(clk) is
|
rowarn : process(clk) is
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
@ -71,24 +87,4 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end process rowarn;
|
end process rowarn;
|
||||||
|
|
||||||
mem_p : process(clk) is
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
wb_o.dat <= mem(mem_address);
|
|
||||||
wb_o.ack <= wb_i.stb;
|
|
||||||
if (wb_i.we) then
|
|
||||||
wb_o.dat <= (others => '-');
|
|
||||||
for i in wb_i.sel'range loop
|
|
||||||
if wb_i.sel(i) then
|
|
||||||
mem(mem_address)((i + 1) * 8 - 1 downto (i * 8)) <= wb_i.dat((i + 1) * 8 - 1 downto (i * 8));
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
if clr then
|
|
||||||
wb_o.dat <= (others => '-');
|
|
||||||
wb_o.ack <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process mem_p;
|
|
||||||
end architecture rtl;
|
end architecture rtl;
|
||||||
|
@ -23,8 +23,7 @@ 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
|
||||||
@ -81,16 +80,16 @@ architecture rtl of top is
|
|||||||
-- Wishbone interconnect (master)
|
-- Wishbone interconnect (master)
|
||||||
signal wbi_masters_o : wishbone_slave_in_vector(0 downto 0);
|
signal wbi_masters_o : wishbone_slave_in_vector(0 downto 0);
|
||||||
signal wbi_masters_i : wishbone_slave_out_vector(wbi_masters_o'range);
|
signal wbi_masters_i : wishbone_slave_out_vector(wbi_masters_o'range);
|
||||||
alias wbi_o is wbi_masters_o(0);
|
alias wbi_o is wbi_masters_o(0);
|
||||||
alias wbi_i is wbi_masters_i(0);
|
alias wbi_i is wbi_masters_i(0);
|
||||||
|
|
||||||
-- Wishbone interconnect (slave)
|
-- Wishbone interconnect (slave)
|
||||||
signal wbi_slaves_o : wishbone_master_in_vector(1 downto 0);
|
signal wbi_slaves_o : wishbone_master_in_vector(1 downto 0);
|
||||||
signal wbi_slaves_i : wishbone_master_out_vector(wbi_slaves_o'range);
|
signal wbi_slaves_i : wishbone_master_out_vector(wbi_slaves_o'range);
|
||||||
alias wbi_rom_o is wbi_slaves_o(0);
|
alias wbi_rom_o is wbi_slaves_o(0);
|
||||||
alias wbi_rom_i is wbi_slaves_i(0);
|
alias wbi_rom_i is wbi_slaves_i(0);
|
||||||
alias wbi_ram_o is wbi_slaves_o(1);
|
alias wbi_ram_o is wbi_slaves_o(1);
|
||||||
alias wbi_ram_i is wbi_slaves_i(1);
|
alias wbi_ram_i is wbi_slaves_i(1);
|
||||||
|
|
||||||
-- Slave address map
|
-- Slave address map
|
||||||
constant wishbone_instruction_addresses : wishbone_address_vector := (
|
constant wishbone_instruction_addresses : wishbone_address_vector := (
|
||||||
@ -106,20 +105,20 @@ architecture rtl of top is
|
|||||||
-- Wishbone interconnect (master)
|
-- Wishbone interconnect (master)
|
||||||
signal wbd_masters_o : wishbone_slave_in_vector(0 downto 0);
|
signal wbd_masters_o : wishbone_slave_in_vector(0 downto 0);
|
||||||
signal wbd_masters_i : wishbone_slave_out_vector(wbd_masters_o'range);
|
signal wbd_masters_i : wishbone_slave_out_vector(wbd_masters_o'range);
|
||||||
alias wbd_o is wbd_masters_o(0);
|
alias wbd_o is wbd_masters_o(0);
|
||||||
alias wbd_i is wbd_masters_i(0);
|
alias wbd_i is wbd_masters_i(0);
|
||||||
|
|
||||||
-- Wishbone interconnect (slave)
|
-- Wishbone interconnect (slave)
|
||||||
signal wbd_slaves_o : wishbone_master_in_vector(3 downto 0);
|
signal wbd_slaves_o : wishbone_master_in_vector(3 downto 0);
|
||||||
signal wbd_slaves_i : wishbone_master_out_vector(wbd_slaves_o'range);
|
signal wbd_slaves_i : wishbone_master_out_vector(wbd_slaves_o'range);
|
||||||
alias wb_ram_o is wbd_slaves_o(0);
|
alias wb_ram_o is wbd_slaves_o(0);
|
||||||
alias wb_ram_i is wbd_slaves_i(0);
|
alias wb_ram_i is wbd_slaves_i(0);
|
||||||
alias wb_timer_o is wbd_slaves_o(1);
|
alias wb_timer_o is wbd_slaves_o(1);
|
||||||
alias wb_timer_i is wbd_slaves_i(1);
|
alias wb_timer_i is wbd_slaves_i(1);
|
||||||
alias wb_uart_o is wbd_slaves_o(2);
|
alias wb_uart_o is wbd_slaves_o(2);
|
||||||
alias wb_uart_i is wbd_slaves_i(2);
|
alias wb_uart_i is wbd_slaves_i(2);
|
||||||
alias wb_eth_o is wbd_slaves_o(3);
|
alias wb_eth_o is wbd_slaves_o(3);
|
||||||
alias wb_eth_i is wbd_slaves_i(3);
|
alias wb_eth_i is wbd_slaves_i(3);
|
||||||
|
|
||||||
-- Slave address map
|
-- Slave address map
|
||||||
constant wishbone_data_addresses : wishbone_address_vector := (
|
constant wishbone_data_addresses : wishbone_address_vector := (
|
||||||
@ -202,38 +201,16 @@ 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,
|
clr => clr,
|
||||||
clr => clr,
|
wbi_o => wbi_o,
|
||||||
wbi_o => wbi_o,
|
wbi_i => wbi_i,
|
||||||
wbi_i => wbi_i,
|
wbd_o => wbd_o,
|
||||||
wbd_o => wbd_o,
|
wbd_i => wbd_i,
|
||||||
wbd_i => wbd_i,
|
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(
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Subproject commit fd79163eb2d49cc57a9d91061a9fd4f6cdc94644
|
|
@ -14,7 +14,6 @@ libraries = {
|
|||||||
"device_models",
|
"device_models",
|
||||||
"generics",
|
"generics",
|
||||||
"serv",
|
"serv",
|
||||||
"neorv32",
|
|
||||||
"trashernet"
|
"trashernet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,9 +38,6 @@ 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,7 +13,6 @@ libraries = {
|
|||||||
"device_models",
|
"device_models",
|
||||||
"generics",
|
"generics",
|
||||||
"serv",
|
"serv",
|
||||||
"neorv32",
|
|
||||||
"trashernet"
|
"trashernet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,9 +37,6 @@ 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…
Reference in New Issue
Block a user