From 8ed5963b9b7afd60c9b0a9dff4ffdefef3c10140 Mon Sep 17 00:00:00 2001 From: Chaoqun Liang Date: Wed, 10 Apr 2024 08:50:50 +0200 Subject: [PATCH 1/4] ethernet integration --- Bender.yml | 2 +- hw/carfield.sv | 93 +++++++++------------------- hw/carfield_pkg.sv | 1 + hw/cheshire_wrap.sv | 28 +++++++++ sw/tests/bare-metal/hostd/ethernet.c | 58 +++++++++++++++++ target/sim/src/carfield_fix.sv | 39 ++++++++---- 6 files changed, 146 insertions(+), 75 deletions(-) create mode 100644 sw/tests/bare-metal/hostd/ethernet.c diff --git a/Bender.yml b/Bender.yml index 0d309ac4..79bd2502 100644 --- a/Bender.yml +++ b/Bender.yml @@ -13,7 +13,7 @@ package: dependencies: register_interface: { git: https://github.com/pulp-platform/register_interface.git, version: 0.4.3 } axi: { git: https://github.com/pulp-platform/axi.git, version: 0.39.1 } - cheshire: { git: https://github.com/pulp-platform/cheshire.git, rev: 6d389373df6b54c09888f89411b7e231d2430722 } # branch: astral-new + cheshire: { git: https://github.com/pulp-platform/cheshire.git, rev: 784ea210da869c0487a0d2fde728f190d9d54ef0 } # branch: cl/eth-astral hyperbus: { git: https://github.com/pulp-platform/hyperbus.git, rev: f039e601c8b6590181734e6d26ff8b77aa380412 } # branch: chi/add_fsm_with_Tcsh dyn_mem: { git: https://github.com/pulp-platform/dyn_spm.git, rev: 480590062742230dc9bd4050358a15b4747bdf34 } # branch: main safety_island: { git: https://github.com/pulp-platform/safety_island.git, rev: aaef55c798ab53560faaf451a86668fa1e6d0f3b } # branch: carfield diff --git a/hw/carfield.sv b/hw/carfield.sv index c8488cc6..1e8851b6 100644 --- a/hw/carfield.sv +++ b/hw/carfield.sv @@ -45,6 +45,10 @@ module carfield input logic alt_clk_i, // external reference clock for timers (CLINT, islands) input logic rt_clk_i, + // ethernet clock 125 MHz + input logic eth_clk_125_i, + // ethernet clock 125 MHz wtih 90 degree phase shift + input logic eth_clk_90_i, input logic pwr_on_rst_ni, @@ -109,16 +113,16 @@ module carfield input logic [ 3:0] spih_ot_sd_i, // ETHERNET interface input logic eth_rxck_i, + input logic [3:0] eth_rxd_i, input logic eth_rxctl_i, - input logic [ 3:0] eth_rxd_i, - input logic eth_md_i, output logic eth_txck_o, + output logic [3:0] eth_txd_o, output logic eth_txctl_o, - output logic [ 3:0] eth_txd_o, - output logic eth_md_o, - output logic eth_md_oe, + output logic eth_rstn_o, + input logic eth_mdio_i, + output logic eth_mdio_o, + output logic eth_mdio_oe, output logic eth_mdc_o, - output logic eth_rst_n_o, // CAN interface input logic can_rx_i, output logic can_tx_o, @@ -777,7 +781,14 @@ cheshire i_cheshire_wrap ( .rst_ni ( host_pwr_on_rst_n ), .test_mode_i , .boot_mode_i , - .rtc_i ( rt_clk_i ), + .rtc_i ( rt_clk_i ), + /* Ethernet Clock */ + // Quadrature (90deg) clk to `phy_tx_clk_i` -> disabled when + // `USE_CLK90 == FALSE` in ethernet IP. See `eth_mac_1g_rgmii_fifo`. + // In carfieldv1, USE_CLK90 == 0, hence changing the clock phase + // is left to PHY chips on the PCB. + .eth_clk_90_i ( eth_clk_90_i ), // to-do + .eth_clk_125_i ( eth_clk_125_i ), // External AXI LLC (DRAM) port .axi_llc_isolate_i ( hyper_isolate_req ), .axi_llc_isolated_o ( hyper_isolated_rsp ), @@ -878,6 +889,18 @@ cheshire i_cheshire_wrap ( .i2c_scl_o , .i2c_scl_i , .i2c_scl_en_o , + // ETHERNET interface + .eth_rxck_i , + .eth_rxd_i , + .eth_rxctl_i , + .eth_txck_o , + .eth_txd_o , + .eth_txctl_o , + .eth_rstn_o , + .eth_mdio_i , + .eth_mdio_o , + .eth_mdio_oe , + .eth_mdc_o , // SPI host interface .spih_sck_o , .spih_sck_en_o , @@ -2046,62 +2069,6 @@ if (CarfieldIslandsCfg.ethernet.enable) begin : gen_ethernet .cycl_count_o ( ) ); - // Ethernet IP - eth_rgmii #( - .AXI_ADDR_WIDTH ( Cfg.AddrWidth ), - .AXI_DATA_WIDTH ( Cfg.AxiDataWidth ), - .AXI_ID_WIDTH ( AxiSlvIdWidth ), - .AXI_USER_WIDTH ( Cfg.AxiUserWidth ) - ) i_eth_rgmii ( - .clk_i ( eth_mdio_clk ), - /* Clock 200MHz */ - // Only used with FPGA mapping for genesysII - // in IDELAYCTRL cell's ref clk (see IP) - .clk_200MHz_i ( '0 ), - .rst_ni ( periph_rst_n ), - /* Ethernet Clock */ - // Quadrature (90deg) clk to `phy_tx_clk_i` -> disabled when - // `USE_CLK90 == FALSE` in ethernet IP. See `eth_mac_1g_rgmii_fifo`. - // In carfieldv1, USE_CLK90 == 0, hence changing the clock phase - // is left to PHY chips on the PCB. - .eth_clk_i ( '0 ), - - .ethernet ( axi_ethernet ), - - .eth_rxck ( eth_rxck_i ), - .eth_rxctl ( eth_rxctl_i ), - .eth_rxd ( eth_rxd_i ), - - .eth_txck ( eth_txck_o ), - .eth_txctl ( eth_txctl_o ), - .eth_txd ( eth_txd_o ), - - .eth_rst_n ( eth_rst_n_o ), - .phy_tx_clk_i ( eth_rgmii_phy_clk0 ), // in phase (0deg) clk - - // MDIO - .eth_mdio_i ( eth_md_i ), - .eth_mdio_o ( eth_md_o ), - .eth_mdio_oe_o ( eth_md_oe ), - .eth_mdc_o ( eth_mdc_o ), - - .eth_irq ( car_eth_intr ) - ); - -end else begin : gen_no_ethernet - - assign ethernet_slave_isolated = '0; - assign car_eth_intr = '0; - assign eth_md_o = '0; - assign eth_md_oe = '0; - assign eth_mdc_o = '0; - assign eth_rst_n_o = '0; - assign eth_txck_o = '0; - assign eth_txctl_o = '0; - assign eth_txd_o = '0; - -end - // APB peripherals // Periph Clock Domain // axi_cdc -> axi_amos -> axi_cut -> axi_to_axilite -> axilite_to_apb -> periph devices diff --git a/hw/carfield_pkg.sv b/hw/carfield_pkg.sv index f3fd6fe9..65ac857e 100644 --- a/hw/carfield_pkg.sv +++ b/hw/carfield_pkg.sv @@ -579,6 +579,7 @@ localparam cheshire_cfg_t CarfieldCfgDefault = '{ SpiHost : 1, Gpio : 1, Dma : 1, + Ethernet : 1 SerialLink : 1, Vga : 0, AxiRt : 1, diff --git a/hw/cheshire_wrap.sv b/hw/cheshire_wrap.sv index eb3e822b..8223cd30 100644 --- a/hw/cheshire_wrap.sv +++ b/hw/cheshire_wrap.sv @@ -115,6 +115,8 @@ module cheshire_wrap input logic test_mode_i, input logic [1:0] boot_mode_i, input logic rtc_i , + input logic eth_clk_90_i, + input logic eth_clk_125_i, // External AXI LLC (DRAM) port input logic axi_llc_isolate_i, output logic axi_llc_isolated_o, @@ -217,6 +219,18 @@ module cheshire_wrap output logic i2c_scl_o, input logic i2c_scl_i, output logic i2c_scl_en_o, + // ETHERNET interface + input logic eth_rxck_i, + input logic [3:0] eth_rxd_i, + input logic eth_rxctl_i, + output logic eth_txck_o, + output logic [3:0] eth_txd_o, + output logic eth_txctl_o, + output logic eth_rstn_o, + input logic eth_mdio_i, + output logic eth_mdio_o, + output logic eth_mdio_oe, + output logic eth_mdc_o, // SPI host interface output logic spih_sck_o, output logic spih_sck_en_o, @@ -287,6 +301,8 @@ cheshire_soc #( .test_mode_i, .boot_mode_i, .rtc_i , + .eth_clk_125 ( eth_clk_125_i ), + .eth_clk_90 ( eth_clk_90_i ), // External AXI LLC (DRAM) port .axi_llc_mst_req_o ( axi_llc_mst_req ), .axi_llc_mst_rsp_i ( axi_llc_mst_rsp ), @@ -333,6 +349,18 @@ cheshire_soc #( .i2c_scl_o , .i2c_scl_i , .i2c_scl_en_o, + // ETHERNET interface + .eth_rxck_i , + .eth_rxd_i , + .eth_rxctl_i, + .eth_txck_o , + .eth_txd_o , + .eth_txctl_o, + .eth_rstn_o , + .eth_mdio_i , + .eth_mdio_o , + .eth_mdio_oe, + .eth_mdc_o , // SPI host interface .spih_sck_o , .spih_sck_en_o, diff --git a/sw/tests/bare-metal/hostd/ethernet.c b/sw/tests/bare-metal/hostd/ethernet.c new file mode 100644 index 00000000..dd8a1cd3 --- /dev/null +++ b/sw/tests/bare-metal/hostd/ethernet.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include "util.h" + +#define ETH_BASE 0x0300c000 + +#define MACLO_OFFSET 0x0 +#define MACHI_OFFSET 0x4 + +#define IDMA_SRC_ADDR_OFFSET 0x10 +#define IDMA_DST_ADDR_OFFSET 0x14 +#define IDMA_LENGTH_OFFSET 0x18 +#define IDMA_SRC_PROTO_OFFSET 0x1c +#define IDMA_DST_PROTO_OFFSET 0x20 +#define IDMA_REQ_VALID_OFFSET 0x38 +#define IDMA_REQ_READY_OFFSET 0x3c +#define IDMA_RSP_READY_OFFSET 0x40 +#define IDMA_RSP_VALID_OFFSET 0x44 + +int main(void) { + + volatile uint64_t data_to_write[8] = { + 0x1032207098001032, + 0x3210E20020709800, + 0x1716151413121110, + 0x2726252423222120, + 0x3736353433323130, + 0x4746454443424140, + 0x5756555453525150, + 0x6766656463626160 + }; + + // load data into mem + for (int i = 0; i < 8; ++i) { + + volatile uint64_t *tx_addr = (volatile uint64_t*)(0x14000000 + i * sizeof(uint64_t)); + *tx_addr = data_to_write[i]; + } + + *reg32(ETH_BASE, MACLO_OFFSET) = 0x98001032; + *reg32(ETH_BASE, MACHI_OFFSET) = 0x00012070; + + *reg32(ETH_BASE, IDMA_SRC_ADDR_OFFSET)= 0x14000000; + *reg32(ETH_BASE, IDMA_DST_ADDR_OFFSET)= 0x0; + *reg32(ETH_BASE, IDMA_LENGTH_OFFSET) = 0x40; + *reg32(ETH_BASE, IDMA_SRC_PROTO_OFFSET) = 0x0; + *reg32(ETH_BASE, IDMA_DST_PROTO_OFFSET) = 0x5; + + + *reg32(ETH_BASE, IDMA_REQ_VALID_OFFSET) = 0x1; + *reg32(ETH_BASE, IDMA_REQ_VALID_OFFSET) = 0x0; + *reg32(ETH_BASE, IDMA_RSP_READY_OFFSET) = 0x1; + + // can leave rsp_ready high + return 0; + +} diff --git a/target/sim/src/carfield_fix.sv b/target/sim/src/carfield_fix.sv index 10b7f543..6632a5a4 100644 --- a/target/sim/src/carfield_fix.sv +++ b/target/sim/src/carfield_fix.sv @@ -88,6 +88,20 @@ module carfield_soc_fixture; logic i2c_scl_i; logic i2c_scl_en; + logic eth_clk_125; + logic eth_clk_90; + logic eth_rxck; + logic [3:0] eth_rxd; + logic eth_rxctl; + logic eth_txck; + logic [3:0] eth_txd; + logic eth_txctl; + logic eth_rstn; + logic eth_mdio_i; + logic eth_mdio_o; + logic eth_mdio_en; + logic eth_mdc; + logic spih_sck_o; logic spih_sck_en; logic [SpihNumCs-1:0] spih_csb_o; @@ -140,6 +154,8 @@ module carfield_soc_fixture; .periph_clk_i ( clk ), .alt_clk_i ( clk ), .rt_clk_i ( rtc ), + .eth_clk_125_i ( eth_clk_125 ), + .eth_clk_90_i ( eth_clk_90 ), .pwr_on_rst_ni ( rst_n ), .test_mode_i ( test_mode ), .boot_mode_i ( boot_mode ), @@ -187,17 +203,18 @@ module carfield_soc_fixture; .spih_ot_sd_o ( spi_secd_sd_o ), .spih_ot_sd_en_o ( spi_secd_sd_en ), .spih_ot_sd_i ( spi_secd_sd_i ), - .eth_rxck_i ( '0 ), - .eth_rxctl_i ( '0 ), - .eth_rxd_i ( '0 ), - .eth_md_i ( '0 ), - .eth_txck_o ( /* Currently unconnected, tie to 0 */ ), - .eth_txctl_o ( /* Currently unconnected, tie to 0 */ ), - .eth_txd_o ( /* Currently unconnected, tie to 0 */ ), - .eth_md_o ( /* Currently unconnected, tie to 0 */ ), - .eth_md_oe ( /* Currently unconnected, tie to 0 */ ), - .eth_mdc_o ( /* Currently unconnected, tie to 0 */ ), - .eth_rst_n_o ( /* Currently unconnected, tie to 0 */ ), + .eth_clk_90_i + .eth_rxck_i ( eth_rxck ), + .eth_rxctl_i ( eth_rxctl ), + .eth_rxd_i ( eth_rxd ), + .eth_txck_o ( eth_txck ), + .eth_txctl_o ( eth_txctl ), + .eth_txd_o ( eth_txd ), + .eth_mdio_i ( eth_mdio_i ), + .eth_mdio_o ( eth_mdio_o ), + .eth_mdio_oe ( eth_mdio_en ), + .eth_mdc_o ( eth_mdc ), + .eth_rstn_o ( eth_rstn ), .can_rx_i ( '0 ), .can_tx_o ( ), .gpio_i ( '0 ), From ff9b16b480c956df19481bb5ec8fb19cebf937ed Mon Sep 17 00:00:00 2001 From: Chaoqun Liang Date: Wed, 17 Apr 2024 09:14:57 +0200 Subject: [PATCH 2/4] ethernet integration --- Bender.local | 2 +- Bender.lock | 42 +++- Bender.yml | 6 +- bender-common.mk | 3 +- carfield.mk | 6 +- hw/carfield.sv | 348 ++++++++++++++++----------- hw/carfield_pkg.sv | 14 +- sw/tests/bare-metal/hostd/ethernet.c | 85 +++++-- target/sim/src/carfield_fix.sv | 3 +- 9 files changed, 315 insertions(+), 194 deletions(-) diff --git a/Bender.local b/Bender.local index 60faa3bd..9cfc2d6b 100644 --- a/Bender.local +++ b/Bender.local @@ -10,7 +10,7 @@ overrides: hci: { git: "https://github.com/pulp-platform/hci.git" , rev: v1.1 } tech_cells_generic: { git: "https://github.com/pulp-platform/tech_cells_generic.git" , version: =0.2.13 } riscv-dbg: { git: "https://github.com/pulp-platform/riscv-dbg.git" , version: =0.8.0 } - idma: { git: "https://github.com/pulp-platform/idma.git" , version: 0.5.1 } + idma: { git: "https://github.com/pulp-platform/idma.git" , version: 0.6.0 } hier-icache: { git: "https://github.com/pulp-platform/hier-icache.git" , rev: 2886cb2a46cea3e2bd2d979b505d88fadfbe150c } # branch: astral scm: { git: "https://github.com/pulp-platform/scm.git" , rev: 74426dee36f28ae1c02f7635cf844a0156145320 } cluster_interconnect: { git: "https://github.com/pulp-platform/cluster_interconnect.git", rev: 89e1019d64a86425211be6200770576cbdf3e8b3 } # branch: assertion-fix diff --git a/Bender.lock b/Bender.lock index 59057e67..cbf427e3 100644 --- a/Bender.lock +++ b/Bender.lock @@ -90,6 +90,13 @@ packages: Git: https://github.com/pulp-platform/axi_slice.git dependencies: - common_cells + axi_stream: + revision: 54891ff40455ca94a37641b9da4604647878cc07 + version: 0.1.1 + source: + Git: git@github.com:pulp-platform/axi_stream.git + dependencies: + - common_cells axi_vga: revision: 3718b9930f94a9eaad8ee50b4bccc71df0403084 version: 0.1.3 @@ -106,7 +113,7 @@ packages: Git: https://github.com/AlSaqr-platform/can_bus.git dependencies: [] cheshire: - revision: 6d389373df6b54c09888f89411b7e231d2430722 + revision: f0c18fcf46473cb611642a3ed6334ca6d84b421e version: null source: Git: https://github.com/pulp-platform/cheshire.git @@ -122,6 +129,7 @@ packages: - common_cells - common_verification - cva6 + - ethernet - idma - irq_router - opentitan_peripherals @@ -162,8 +170,8 @@ packages: dependencies: - hci common_cells: - revision: ad22699793d98ef714f120c6268fe92d096a61e1 - version: 1.33.1 + revision: 7773d971b9d7bef7f5f6a2ef36ee1e4d02cefcd3 + version: 1.34.0 source: Git: https://github.com/pulp-platform/common_cells.git dependencies: @@ -208,6 +216,18 @@ packages: - redundancy_cells - register_interface - tech_cells_generic + ethernet: + revision: ca7feb6e5722aaec7bdb6d71d4cfddfe58f18afd + version: null + source: + Git: https://github.com/pulp-platform/pulp-ethernet.git + dependencies: + - axi + - axi_stream + - common_cells + - common_verification + - idma + - register_interface event_unit_flex: revision: 28e0499374117c7b0ef4c6ad81b60d7526af886f version: null @@ -259,8 +279,8 @@ packages: dependencies: - tech_cells_generic hwpe-stream: - revision: bcb4435f802add732f557dc7fa1c6b5dd8854458 - version: 1.7.1 + revision: 65c99a4a2f37a79acee800ab0151f67dfb1edef1 + version: 1.8.0 source: Git: https://github.com/pulp-platform/hwpe-stream.git dependencies: @@ -289,14 +309,16 @@ packages: Git: https://github.com/pulp-platform/icache-intc.git dependencies: [] idma: - revision: ca1b28816a3706be0bf9ce01378246d5346384f0 - version: 0.5.1 + revision: d6245c8bf8faa7a4d44325d6584387170413d53d + version: 0.6.0 source: Git: https://github.com/pulp-platform/idma.git dependencies: - axi + - axi_stream - common_cells - common_verification + - obi - register_interface irq_router: revision: d1d31350b24f3965b3a51e1bc96c71eb34e94db3 @@ -364,13 +386,17 @@ packages: dependencies: - axi_slice pulp-ethernet: - revision: bdc8031ab270a49da28df269266ce9ab9a133636 + revision: ca7feb6e5722aaec7bdb6d71d4cfddfe58f18afd version: null source: Git: https://github.com/pulp-platform/pulp-ethernet.git dependencies: - axi + - axi_stream + - common_cells - common_verification + - idma + - register_interface pulp_cluster: revision: 3cd3e83fdd7a791e8ae54aef39423004581c8a48 version: null diff --git a/Bender.yml b/Bender.yml index 79bd2502..9ab8a609 100644 --- a/Bender.yml +++ b/Bender.yml @@ -13,7 +13,7 @@ package: dependencies: register_interface: { git: https://github.com/pulp-platform/register_interface.git, version: 0.4.3 } axi: { git: https://github.com/pulp-platform/axi.git, version: 0.39.1 } - cheshire: { git: https://github.com/pulp-platform/cheshire.git, rev: 784ea210da869c0487a0d2fde728f190d9d54ef0 } # branch: cl/eth-astral + cheshire: { git: https://github.com/pulp-platform/cheshire.git, rev: f0c18fcf46473cb611642a3ed6334ca6d84b421e } # branch: cl/eth-astral hyperbus: { git: https://github.com/pulp-platform/hyperbus.git, rev: f039e601c8b6590181734e6d26ff8b77aa380412 } # branch: chi/add_fsm_with_Tcsh dyn_mem: { git: https://github.com/pulp-platform/dyn_spm.git, rev: 480590062742230dc9bd4050358a15b4747bdf34 } # branch: main safety_island: { git: https://github.com/pulp-platform/safety_island.git, rev: aaef55c798ab53560faaf451a86668fa1e6d0f3b } # branch: carfield @@ -26,7 +26,7 @@ dependencies: can_bus: { git: https://github.com/AlSaqr-platform/can_bus.git, rev: 0ec0bf8b7dab6d5e4b3f7ec58338a8efee066379 } # branch: pulp spatz: { git: https://github.com/pulp-platform/spatz.git, rev: 98de97f24fe42675c9b4a8cc08354a03af57400a } # branch: yt/astral common_cells: { git: https://github.com/pulp-platform/common_cells.git, version: 1.31.1 } - pulp-ethernet: { git: https://github.com/pulp-platform/pulp-ethernet.git, rev: bdc8031ab270a49da28df269266ce9ab9a133636 } # branch: carfield + pulp-ethernet: { git: https://github.com/pulp-platform/pulp-ethernet.git, rev: ca7feb6e5722aaec7bdb6d71d4cfddfe58f18afd } # branch: cl/eth_idma riscv-dbg: { git: https://github.com/pulp-platform/riscv-dbg.git, version: =0.8.0 } workspace: @@ -75,7 +75,7 @@ sources: # package. Files in level 1 only depend on files in level 0, files in level 2 on files in # levels 1 and 0, etc. Files within a level are ordered alphabetically. # Level 0 - - hw/carfield_pkg.sv + - hw/carfield_pkg.sv - hw/regs/carfield_reg_pkg.sv - hw/regs/carfield_reg_top.sv # Level 1 diff --git a/bender-common.mk b/bender-common.mk index 4e5ba36f..c05bb3bf 100644 --- a/bender-common.mk +++ b/bender-common.mk @@ -16,7 +16,8 @@ common_targs += -t integer_cluster common_targs += -t cv32e40p_use_ff_regfile common_targs += -t scm_use_fpga_scm common_targs += -t cv64a6_imafdcsclic_sv39 -common_targs += -t rtl +common_targs += -t rtl +common_targs += -t snitch_cluster # Carfield config target. common_targs += -t $(CARFIELD_CONFIG) diff --git a/carfield.mk b/carfield.mk index 8052c62a..b6414030 100644 --- a/carfield.mk +++ b/carfield.mk @@ -166,7 +166,7 @@ chs-sw-build: chs-sw-all .PHONY: car-sw-build ## Builds carfield application SW and specific libraries. It links against `libcheshire.a`. -car-sw-build: chs-sw-build safed-sw-build pulpd-sw-build car-sw-all +car-sw-build: chs-sw-build pulpd-sw-build car-sw-all #safed-sw-build .PHONY: safed-sw-init pulpd-sw-init ## Clone safe domain's SW stack in the dedicated repository. @@ -214,7 +214,7 @@ pulpd-sw-build: pulpd-sw-init ## Initialize Carfield HW. This step takes care of the generation of the missing hardware or the ## update of default HW configurations in some of the domains. See the two prerequisite's comment ## for more information. -car-hw-init: spatzd-hw-init chs-hw-init secd-hw-init +car-hw-init: spatzd-hw-init chs-hw-init #Build OpenTitan's debug rom with support for coreid != 0x0 secd-hw-init: @@ -289,7 +289,7 @@ include $(CAR_SIM_DIR)/sim.mk .PHONY: car-init-all ## Shortcut to initialize carfield with all the targets described above. -car-init-all: car-checkout car-hw-init car-sim-init safed-sw-init pulpd-sw-init mibench +car-init-all: car-checkout car-hw-init car-sim-init pulpd-sw-init mibench #safed-sw-init ## Initialize Carfield and build SW .PHONY: car-all diff --git a/hw/carfield.sv b/hw/carfield.sv index 1e8851b6..189042db 100644 --- a/hw/carfield.sv +++ b/hw/carfield.sv @@ -45,7 +45,7 @@ module carfield input logic alt_clk_i, // external reference clock for timers (CLINT, islands) input logic rt_clk_i, - // ethernet clock 125 MHz + // ethernet clock 125 MHz input logic eth_clk_125_i, // ethernet clock 125 MHz wtih 90 degree phase shift input logic eth_clk_90_i, @@ -781,12 +781,12 @@ cheshire i_cheshire_wrap ( .rst_ni ( host_pwr_on_rst_n ), .test_mode_i , .boot_mode_i , - .rtc_i ( rt_clk_i ), - /* Ethernet Clock */ - // Quadrature (90deg) clk to `phy_tx_clk_i` -> disabled when - // `USE_CLK90 == FALSE` in ethernet IP. See `eth_mac_1g_rgmii_fifo`. - // In carfieldv1, USE_CLK90 == 0, hence changing the clock phase - // is left to PHY chips on the PCB. + .rtc_i ( rt_clk_i ), + + + + + .eth_clk_90_i ( eth_clk_90_i ), // to-do .eth_clk_125_i ( eth_clk_125_i ), // External AXI LLC (DRAM) port @@ -889,7 +889,7 @@ cheshire i_cheshire_wrap ( .i2c_scl_o , .i2c_scl_i , .i2c_scl_en_o , - // ETHERNET interface + // ETHERNET interface .eth_rxck_i , .eth_rxd_i , .eth_rxctl_i , @@ -1931,143 +1931,199 @@ logic ethernet_slave_isolated; carfield_axi_slv_req_t axi_ethernet_req; carfield_axi_slv_rsp_t axi_ethernet_rsp; -if (CarfieldIslandsCfg.ethernet.enable) begin : gen_ethernet - assign ethernet_slave_isolated = slave_isolated[EthernetSlvIdx]; - assign slave_isolated[EthernetSlvIdx] = slave_isolated_rsp[EthernetSlvIdx]; - assign slave_isolate_req[EthernetSlvIdx] = car_regs_reg2hw.periph_isolate.q; - axi_cdc_dst #( - .LogDepth ( LogDepth ), - .SyncStages ( SyncStages ), - .aw_chan_t ( carfield_axi_slv_aw_chan_t ), - .w_chan_t ( carfield_axi_slv_w_chan_t ), - .b_chan_t ( carfield_axi_slv_b_chan_t ), - .ar_chan_t ( carfield_axi_slv_ar_chan_t ), - .r_chan_t ( carfield_axi_slv_r_chan_t ), - .axi_req_t ( carfield_axi_slv_req_t ), - .axi_resp_t ( carfield_axi_slv_rsp_t ) - ) i_ethernet_cdc_dst ( - .async_data_slave_aw_data_i ( axi_slv_ext_aw_data [EthernetSlvIdx] ), - .async_data_slave_aw_wptr_i ( axi_slv_ext_aw_wptr [EthernetSlvIdx] ), - .async_data_slave_aw_rptr_o ( axi_slv_ext_aw_rptr [EthernetSlvIdx] ), - .async_data_slave_w_data_i ( axi_slv_ext_w_data [EthernetSlvIdx] ), - .async_data_slave_w_wptr_i ( axi_slv_ext_w_wptr [EthernetSlvIdx] ), - .async_data_slave_w_rptr_o ( axi_slv_ext_w_rptr [EthernetSlvIdx] ), - .async_data_slave_b_data_o ( axi_slv_ext_b_data [EthernetSlvIdx] ), - .async_data_slave_b_wptr_o ( axi_slv_ext_b_wptr [EthernetSlvIdx] ), - .async_data_slave_b_rptr_i ( axi_slv_ext_b_rptr [EthernetSlvIdx] ), - .async_data_slave_ar_data_i ( axi_slv_ext_ar_data [EthernetSlvIdx] ), - .async_data_slave_ar_wptr_i ( axi_slv_ext_ar_wptr [EthernetSlvIdx] ), - .async_data_slave_ar_rptr_o ( axi_slv_ext_ar_rptr [EthernetSlvIdx] ), - .async_data_slave_r_data_o ( axi_slv_ext_r_data [EthernetSlvIdx] ), - .async_data_slave_r_wptr_o ( axi_slv_ext_r_wptr [EthernetSlvIdx] ), - .async_data_slave_r_rptr_i ( axi_slv_ext_r_rptr [EthernetSlvIdx] ), - .dst_clk_i ( periph_clk ), - .dst_rst_ni ( periph_rst_n ), - .dst_req_o ( axi_ethernet_req ), - .dst_resp_i ( axi_ethernet_rsp ) - ); - - AXI_BUS #( - .AXI_ADDR_WIDTH( Cfg.AddrWidth ), - .AXI_DATA_WIDTH( Cfg.AxiDataWidth ), - .AXI_ID_WIDTH ( AxiSlvIdWidth ), - .AXI_USER_WIDTH( Cfg.AxiUserWidth ) - ) axi_ethernet (); - - `AXI_ASSIGN_FROM_REQ(axi_ethernet, axi_ethernet_req); - `AXI_ASSIGN_TO_RESP(axi_ethernet_rsp, axi_ethernet); - - // The Ethernet RGMII interfaces mandates a clock of 125MHz (in 1GBit mode) for both TX and RX - // clocks. We generate a 125MHz clock starting from the `periph_clk`. The (integer) division value - // is SW-programmable. - localparam int unsigned EthRgmiiPhyClkDivWidth = 20; - // We assume a peripheral clock of 250MHz to get the 125MHz clock for the RGMII interface. Hence, - // the default division value after PoR is 250/125. - localparam int unsigned EthRgmiiPhyClkDivDefaultValue = 2; - logic [EthRgmiiPhyClkDivWidth-1:0] eth_rgmii_phy_clk_div_value; - logic eth_rgmii_phy_clk_div_value_valid; - logic eth_rgmii_phy_clk_div_value_ready; - logic eth_rgmii_phy_clk0; - - // The register file does not support back pressure directly. I.e the hardware side cannot tell - // the regfile that a reg value cannot be written at the moment. This is a problem since the clk - // divider input of the clk_int_div module will stall the transaction until it is safe to change - // the clock division factor. The stream_deposit module converts between these two protocols - // (write-pulse only protocol <-> ready-valid protocol). See the documentation in the header of - // the module for more details. - lossy_valid_to_stream #( - .DATA_WIDTH(EthRgmiiPhyClkDivWidth) - ) i_eth_rgmii_phy_clk_div_config_decouple ( - .clk_i ( periph_clk ), - .rst_ni ( periph_rst_n ), - .valid_i ( car_regs_reg2hw.eth_rgmii_phy_clk_div_value.qe ), - .data_i ( car_regs_reg2hw.eth_rgmii_phy_clk_div_value.q ), - .valid_o ( eth_rgmii_phy_clk_div_value_valid ), - .ready_i ( eth_rgmii_phy_clk_div_value_ready ), - .data_o ( eth_rgmii_phy_clk_div_value ), - .busy_o ( ) - ); - - (* no_ungroup *) - (* no_boundary_optimization *) - clk_int_div #( - .DIV_VALUE_WIDTH ( EthRgmiiPhyClkDivWidth ), - .DEFAULT_DIV_VALUE ( EthRgmiiPhyClkDivDefaultValue ), - .ENABLE_CLOCK_IN_RESET ( 0 ) - ) i_eth_rgmii_phy_clk_int_div ( - .clk_i ( periph_clk ), - .rst_ni ( periph_rst_n ), - .en_i ( car_regs_reg2hw.eth_rgmii_phy_clk_div_en.q ), - .test_mode_en_i ( test_mode_i ), - .div_i ( car_regs_reg2hw.eth_rgmii_phy_clk_div_value.q ), - .div_valid_i ( eth_rgmii_phy_clk_div_value_valid ), - .div_ready_o ( eth_rgmii_phy_clk_div_value_ready ), - .clk_o ( eth_rgmii_phy_clk0 ), - .cycl_count_o ( ) - ); - - - // The Ethernet MDIO interfaces mandates a clock of 2.5MHz. We generate a 2.5MHz clock starting from - // the `periph_clk`. The (integer) division value is SW-programmable. - localparam int unsigned EthMdioClkDivWidth = 20; - // We assume a default peripheral clock of 250 MHz to get the 2.5MHz required for the MDIO - // interface. Hence, the default division value after PoR is 250/2.5 - localparam int unsigned EthMdioClkDivDefaultValue = 100; - logic [EthRgmiiPhyClkDivWidth-1:0] eth_mdio_clk_div_value; - logic eth_mdio_clk_div_value_valid; - logic eth_mdio_clk_div_value_ready; - logic eth_mdio_clk; - - lossy_valid_to_stream #( - .DATA_WIDTH(EthMdioClkDivWidth) - ) i_eth_mdio_clk_div_config_decouple ( - .clk_i ( periph_clk ), - .rst_ni ( periph_rst_n ), - .valid_i ( car_regs_reg2hw.eth_mdio_clk_div_value.qe ), - .data_i ( car_regs_reg2hw.eth_mdio_clk_div_value.q ), - .valid_o ( eth_mdio_clk_div_value_valid ), - .ready_i ( eth_mdio_clk_div_value_ready ), - .data_o ( eth_mdio_clk_div_value ), - .busy_o ( ) - ); - - (* no_ungroup *) - (* no_boundary_optimization *) - clk_int_div #( - .DIV_VALUE_WIDTH ( EthMdioClkDivWidth ), - .DEFAULT_DIV_VALUE ( EthMdioClkDivDefaultValue ), - .ENABLE_CLOCK_IN_RESET ( 0 ) - ) i_eth_mdio_clk_int_div ( - .clk_i ( periph_clk ), - .rst_ni ( periph_rst_n ), - .en_i ( car_regs_reg2hw.eth_mdio_clk_div_en.q ), - .test_mode_en_i ( test_mode_i ), - .div_i ( car_regs_reg2hw.eth_mdio_clk_div_value.q ), - .div_valid_i ( eth_mdio_clk_div_value_valid ), - .div_ready_o ( eth_mdio_clk_div_value_ready ), - .clk_o ( eth_mdio_clk ), - .cycl_count_o ( ) - ); +// if (CarfieldIslandsCfg.ethernet.enable) begin : gen_ethernet +// assign ethernet_slave_isolated = slave_isolated[EthernetSlvIdx]; +// assign slave_isolated[EthernetSlvIdx] = slave_isolated_rsp[EthernetSlvIdx]; +// assign slave_isolate_req[EthernetSlvIdx] = car_regs_reg2hw.periph_isolate.q; +// axi_cdc_dst #( +// .LogDepth ( LogDepth ), +// .SyncStages ( SyncStages ), +// .aw_chan_t ( carfield_axi_slv_aw_chan_t ), +// .w_chan_t ( carfield_axi_slv_w_chan_t ), +// .b_chan_t ( carfield_axi_slv_b_chan_t ), +// .ar_chan_t ( carfield_axi_slv_ar_chan_t ), +// .r_chan_t ( carfield_axi_slv_r_chan_t ), +// .axi_req_t ( carfield_axi_slv_req_t ), +// .axi_resp_t ( carfield_axi_slv_rsp_t ) +// ) i_ethernet_cdc_dst ( +// .async_data_slave_aw_data_i ( axi_slv_ext_aw_data [EthernetSlvIdx] ), +// .async_data_slave_aw_wptr_i ( axi_slv_ext_aw_wptr [EthernetSlvIdx] ), +// .async_data_slave_aw_rptr_o ( axi_slv_ext_aw_rptr [EthernetSlvIdx] ), +// .async_data_slave_w_data_i ( axi_slv_ext_w_data [EthernetSlvIdx] ), +// .async_data_slave_w_wptr_i ( axi_slv_ext_w_wptr [EthernetSlvIdx] ), +// .async_data_slave_w_rptr_o ( axi_slv_ext_w_rptr [EthernetSlvIdx] ), +// .async_data_slave_b_data_o ( axi_slv_ext_b_data [EthernetSlvIdx] ), +// .async_data_slave_b_wptr_o ( axi_slv_ext_b_wptr [EthernetSlvIdx] ), +// .async_data_slave_b_rptr_i ( axi_slv_ext_b_rptr [EthernetSlvIdx] ), +// .async_data_slave_ar_data_i ( axi_slv_ext_ar_data [EthernetSlvIdx] ), +// .async_data_slave_ar_wptr_i ( axi_slv_ext_ar_wptr [EthernetSlvIdx] ), +// .async_data_slave_ar_rptr_o ( axi_slv_ext_ar_rptr [EthernetSlvIdx] ), +// .async_data_slave_r_data_o ( axi_slv_ext_r_data [EthernetSlvIdx] ), +// .async_data_slave_r_wptr_o ( axi_slv_ext_r_wptr [EthernetSlvIdx] ), +// .async_data_slave_r_rptr_i ( axi_slv_ext_r_rptr [EthernetSlvIdx] ), +// .dst_clk_i ( periph_clk ), +// .dst_rst_ni ( periph_rst_n ), +// .dst_req_o ( axi_ethernet_req ), +// .dst_resp_i ( axi_ethernet_rsp ) +// ); + +// AXI_BUS #( +// .AXI_ADDR_WIDTH( Cfg.AddrWidth ), +// .AXI_DATA_WIDTH( Cfg.AxiDataWidth ), +// .AXI_ID_WIDTH ( AxiSlvIdWidth ), +// .AXI_USER_WIDTH( Cfg.AxiUserWidth ) +// ) axi_ethernet (); + +// `AXI_ASSIGN_FROM_REQ(axi_ethernet, axi_ethernet_req); +// `AXI_ASSIGN_TO_RESP(axi_ethernet_rsp, axi_ethernet); + +// // The Ethernet RGMII interfaces mandates a clock of 125MHz (in 1GBit mode) for both TX and RX +// // clocks. We generate a 125MHz clock starting from the `periph_clk`. The (integer) division value +// // is SW-programmable. +// localparam int unsigned EthRgmiiPhyClkDivWidth = 20; +// // We assume a peripheral clock of 250MHz to get the 125MHz clock for the RGMII interface. Hence, +// // the default division value after PoR is 250/125. +// localparam int unsigned EthRgmiiPhyClkDivDefaultValue = 2; +// logic [EthRgmiiPhyClkDivWidth-1:0] eth_rgmii_phy_clk_div_value; +// logic eth_rgmii_phy_clk_div_value_valid; +// logic eth_rgmii_phy_clk_div_value_ready; +// logic eth_rgmii_phy_clk0; + +// // The register file does not support back pressure directly. I.e the hardware side cannot tell +// // the regfile that a reg value cannot be written at the moment. This is a problem since the clk +// // divider input of the clk_int_div module will stall the transaction until it is safe to change +// // the clock division factor. The stream_deposit module converts between these two protocols +// // (write-pulse only protocol <-> ready-valid protocol). See the documentation in the header of +// // the module for more details. +// lossy_valid_to_stream #( +// .DATA_WIDTH(EthRgmiiPhyClkDivWidth) +// ) i_eth_rgmii_phy_clk_div_config_decouple ( +// .clk_i ( periph_clk ), +// .rst_ni ( periph_rst_n ), +// .valid_i ( car_regs_reg2hw.eth_rgmii_phy_clk_div_value.qe ), +// .data_i ( car_regs_reg2hw.eth_rgmii_phy_clk_div_value.q ), +// .valid_o ( eth_rgmii_phy_clk_div_value_valid ), +// .ready_i ( eth_rgmii_phy_clk_div_value_ready ), +// .data_o ( eth_rgmii_phy_clk_div_value ), +// .busy_o ( ) +// ); + +// (* no_ungroup *) +// (* no_boundary_optimization *) +// clk_int_div #( +// .DIV_VALUE_WIDTH ( EthRgmiiPhyClkDivWidth ), +// .DEFAULT_DIV_VALUE ( EthRgmiiPhyClkDivDefaultValue ), +// .ENABLE_CLOCK_IN_RESET ( 0 ) +// ) i_eth_rgmii_phy_clk_int_div ( +// .clk_i ( periph_clk ), +// .rst_ni ( periph_rst_n ), +// .en_i ( car_regs_reg2hw.eth_rgmii_phy_clk_div_en.q ), +// .test_mode_en_i ( test_mode_i ), +// .div_i ( car_regs_reg2hw.eth_rgmii_phy_clk_div_value.q ), +// .div_valid_i ( eth_rgmii_phy_clk_div_value_valid ), +// .div_ready_o ( eth_rgmii_phy_clk_div_value_ready ), +// .clk_o ( eth_rgmii_phy_clk0 ), +// .cycl_count_o ( ) +// ); + + +// // The Ethernet MDIO interfaces mandates a clock of 2.5MHz. We generate a 2.5MHz clock starting from +// // the `periph_clk`. The (integer) division value is SW-programmable. +// localparam int unsigned EthMdioClkDivWidth = 20; +// // We assume a default peripheral clock of 250 MHz to get the 2.5MHz required for the MDIO +// // interface. Hence, the default division value after PoR is 250/2.5 +// localparam int unsigned EthMdioClkDivDefaultValue = 100; +// logic [EthRgmiiPhyClkDivWidth-1:0] eth_mdio_clk_div_value; +// logic eth_mdio_clk_div_value_valid; +// logic eth_mdio_clk_div_value_ready; +// logic eth_mdio_clk; + +// lossy_valid_to_stream #( +// .DATA_WIDTH(EthMdioClkDivWidth) +// ) i_eth_mdio_clk_div_config_decouple ( +// .clk_i ( periph_clk ), +// .rst_ni ( periph_rst_n ), +// .valid_i ( car_regs_reg2hw.eth_mdio_clk_div_value.qe ), +// .data_i ( car_regs_reg2hw.eth_mdio_clk_div_value.q ), +// .valid_o ( eth_mdio_clk_div_value_valid ), +// .ready_i ( eth_mdio_clk_div_value_ready ), +// .data_o ( eth_mdio_clk_div_value ), +// .busy_o ( ) +// ); + +// (* no_ungroup *) +// (* no_boundary_optimization *) +// clk_int_div #( +// .DIV_VALUE_WIDTH ( EthMdioClkDivWidth ), +// .DEFAULT_DIV_VALUE ( EthMdioClkDivDefaultValue ), +// .ENABLE_CLOCK_IN_RESET ( 0 ) +// ) i_eth_mdio_clk_int_div ( +// .clk_i ( periph_clk ), +// .rst_ni ( periph_rst_n ), +// .en_i ( car_regs_reg2hw.eth_mdio_clk_div_en.q ), +// .test_mode_en_i ( test_mode_i ), +// .div_i ( car_regs_reg2hw.eth_mdio_clk_div_value.q ), +// .div_valid_i ( eth_mdio_clk_div_value_valid ), +// .div_ready_o ( eth_mdio_clk_div_value_ready ), +// .clk_o ( eth_mdio_clk ), +// .cycl_count_o ( ) +// ); + +// // Ethernet IP +// eth_rgmii #( +// .AXI_ADDR_WIDTH ( Cfg.AddrWidth ), +// .AXI_DATA_WIDTH ( Cfg.AxiDataWidth ), +// .AXI_ID_WIDTH ( AxiSlvIdWidth ), +// .AXI_USER_WIDTH ( Cfg.AxiUserWidth ) +// ) i_eth_rgmii ( +// .clk_i ( eth_mdio_clk ), +// /* Clock 200MHz */ +// // Only used with FPGA mapping for genesysII +// // in IDELAYCTRL cell's ref clk (see IP) +// .clk_200MHz_i ( '0 ), +// .rst_ni ( periph_rst_n ), +// /* Ethernet Clock */ +// // Quadrature (90deg) clk to `phy_tx_clk_i` -> disabled when +// // `USE_CLK90 == FALSE` in ethernet IP. See `eth_mac_1g_rgmii_fifo`. +// // In carfieldv1, USE_CLK90 == 0, hence changing the clock phase +// // is left to PHY chips on the PCB. +// .eth_clk_i ( '0 ), + +// .ethernet ( axi_ethernet ), + +// .eth_rxck ( eth_rxck_i ), +// .eth_rxctl ( eth_rxctl_i ), +// .eth_rxd ( eth_rxd_i ), + +// .eth_txck ( eth_txck_o ), +// .eth_txctl ( eth_txctl_o ), +// .eth_txd ( eth_txd_o ), + +// .eth_rst_n ( eth_rst_n_o ), +// .phy_tx_clk_i ( eth_rgmii_phy_clk0 ), // in phase (0deg) clk + +// // MDIO +// .eth_mdio_i ( eth_md_i ), +// .eth_mdio_o ( eth_md_o ), +// .eth_mdio_oe_o ( eth_md_oe ), +// .eth_mdc_o ( eth_mdc_o ), + +// .eth_irq ( car_eth_intr ) +// ); + +// end else begin : gen_no_ethernet + +// assign ethernet_slave_isolated = '0; +// assign car_eth_intr = '0; +// assign eth_md_o = '0; +// assign eth_md_oe = '0; +// assign eth_mdc_o = '0; +// assign eth_rst_n_o = '0; +// assign eth_txck_o = '0; +// assign eth_txctl_o = '0; +// assign eth_txd_o = '0; + +// end // APB peripherals // Periph Clock Domain @@ -2468,4 +2524,4 @@ end else begin: gen_no_periph assign car_regs_hw2reg.periph_isolate_status.d = '0; assign car_regs_hw2reg.periph_isolate_status.de = '0; end -endmodule +endmodule \ No newline at end of file diff --git a/hw/carfield_pkg.sv b/hw/carfield_pkg.sv index 65ac857e..d2aebf2d 100644 --- a/hw/carfield_pkg.sv +++ b/hw/carfield_pkg.sv @@ -317,14 +317,14 @@ function automatic int unsigned gen_carfield_domains(islands_cfg_t island_cfg); endfunction localparam islands_cfg_t CarfieldIslandsCfg = '{ - l2_port0: '{L2Port0Enable, L2Port0Base, L2Port0Size}, - l2_port1: '{L2Port1Enable, L2Port1Base, L2Port1Size}, - safed: '{SafetyIslandEnable, SafetyIslandBase, SafetyIslandSize}, + l2_port0: '{0, L2Port0Base, L2Port0Size}, + l2_port1: '{0, L2Port1Base, L2Port1Size}, + safed: '{0, SafetyIslandBase, SafetyIslandSize}, ethernet: '{EthernetEnable, EthernetBase, EthernetSize}, periph: '{PeriphEnable, PeriphBase, PeriphSize}, - spatz: '{SpatzClusterEnable, SpatzClusterBase, SpatzClusterSize}, + spatz: '{0, SpatzClusterBase, SpatzClusterSize}, pulp: '{PulpClusterEnable, PulpClusterBase, PulpClusterSize}, - secured: '{SecurityIslandEnable, SecurityIslandBase, SecurityIslandSize}, + secured: '{0, SecurityIslandBase, SecurityIslandSize}, mbox: '{MailboxEnable, MailboxBase, MailboxSize} }; @@ -578,8 +578,8 @@ localparam cheshire_cfg_t CarfieldCfgDefault = '{ I2c : 1, SpiHost : 1, Gpio : 1, - Dma : 1, - Ethernet : 1 + Dma : 0, // to do + Ethernet : 1, SerialLink : 1, Vga : 0, AxiRt : 1, diff --git a/sw/tests/bare-metal/hostd/ethernet.c b/sw/tests/bare-metal/hostd/ethernet.c index dd8a1cd3..39a7d44e 100644 --- a/sw/tests/bare-metal/hostd/ethernet.c +++ b/sw/tests/bare-metal/hostd/ethernet.c @@ -1,25 +1,44 @@ #include #include #include +#include "printf.h" #include "util.h" -#define ETH_BASE 0x0300c000 +#define ETH_BASE 0x0300c000 #define MACLO_OFFSET 0x0 #define MACHI_OFFSET 0x4 +#define IRQ_OFFSET 0x10 +#define IDMA_SRC_ADDR_OFFSET 0x14 +#define IDMA_DST_ADDR_OFFSET 0x18 +#define IDMA_LENGTH_OFFSET 0x1c +#define IDMA_SRC_PROTO_OFFSET 0x20 +#define IDMA_DST_PROTO_OFFSET 0x24 +#define IDMA_REQ_VALID_OFFSET 0x3c +#define IDMA_REQ_READY_OFFSET 0x40 +#define IDMA_RSP_READY_OFFSET 0x44 +#define IDMA_RSP_VALID_OFFSET 0x48 + +#define PLIC_BASE 0x04000000 +#define RV_PLIC_PRIO19_REG_OFFSET 0x4c +#define RV_PLIC_IE0_0_REG_OFFSET 0x2000 +#define RV_PLIC_IE0_0_E_19_BIT 19 + +#define RV_PLIC_IP_0_OFFSET 0x1000 + +#define PRINTF_ON + +int main(void) { + + #ifdef PRINTF_ON + printf ("Start test Ethernet...\n\r"); + #endif + + *reg32(PLIC_BASE, RV_PLIC_PRIO19_REG_OFFSET) = 1; + *reg32(PLIC_BASE, RV_PLIC_IE0_0_REG_OFFSET) |= (1 << (RV_PLIC_IE0_0_E_19_BIT)); // Enable interrupt number ; + + int irq_flag = 0; -#define IDMA_SRC_ADDR_OFFSET 0x10 -#define IDMA_DST_ADDR_OFFSET 0x14 -#define IDMA_LENGTH_OFFSET 0x18 -#define IDMA_SRC_PROTO_OFFSET 0x1c -#define IDMA_DST_PROTO_OFFSET 0x20 -#define IDMA_REQ_VALID_OFFSET 0x38 -#define IDMA_REQ_READY_OFFSET 0x3c -#define IDMA_RSP_READY_OFFSET 0x40 -#define IDMA_RSP_VALID_OFFSET 0x44 - -int main(void) { - volatile uint64_t data_to_write[8] = { 0x1032207098001032, 0x3210E20020709800, @@ -29,30 +48,48 @@ int main(void) { 0x4746454443424140, 0x5756555453525150, 0x6766656463626160 - }; + }; // load data into mem for (int i = 0; i < 8; ++i) { - volatile uint64_t *tx_addr = (volatile uint64_t*)(0x14000000 + i * sizeof(uint64_t)); *tx_addr = data_to_write[i]; } + + *reg32(ETH_BASE, MACLO_OFFSET) = 0x98001032; + *reg32(ETH_BASE, MACHI_OFFSET) = 0x00012070; - *reg32(ETH_BASE, MACLO_OFFSET) = 0x98001032; - *reg32(ETH_BASE, MACHI_OFFSET) = 0x00012070; - - *reg32(ETH_BASE, IDMA_SRC_ADDR_OFFSET)= 0x14000000; - *reg32(ETH_BASE, IDMA_DST_ADDR_OFFSET)= 0x0; - *reg32(ETH_BASE, IDMA_LENGTH_OFFSET) = 0x40; + *reg32(ETH_BASE, IDMA_SRC_ADDR_OFFSET) = 0x14000000; + *reg32(ETH_BASE, IDMA_DST_ADDR_OFFSET) = 0x0; + *reg32(ETH_BASE, IDMA_LENGTH_OFFSET) = 0x40; *reg32(ETH_BASE, IDMA_SRC_PROTO_OFFSET) = 0x0; *reg32(ETH_BASE, IDMA_DST_PROTO_OFFSET) = 0x5; - *reg32(ETH_BASE, IDMA_REQ_VALID_OFFSET) = 0x1; *reg32(ETH_BASE, IDMA_REQ_VALID_OFFSET) = 0x0; *reg32(ETH_BASE, IDMA_RSP_READY_OFFSET) = 0x1; + + irq_flag = 1; + + while (!(*reg32(PLIC_BASE, RV_PLIC_IP_0_OFFSET)) & (1 << RV_PLIC_IE0_0_E_19_BIT) ); - // can leave rsp_ready high - return 0; + irq_flag = 0; + // RX test, needs sim mem + // while (!(*reg32(PLIC_BASE, RV_PLIC_IP_0_OFFSET)) & (1 << RV_PLIC_IE0_0_E_19_BIT) ); + + // *reg32(ETH_BASE, IDMA_SRC_ADDR_OFFSET) = 0x0; + // *reg32(ETH_BASE, IDMA_DST_ADDR_OFFSET) = 0x14000000; + // *reg32(ETH_BASE, IDMA_LENGTH_OFFSET) = 0x40; + // *reg32(ETH_BASE, IDMA_SRC_PROTO_OFFSET) = 0x5; + // *reg32(ETH_BASE, IDMA_DST_PROTO_OFFSET) = 0x0; + + // *reg32(ETH_BASE, IDMA_REQ_VALID_OFFSET) = 0x1; + // *reg32(ETH_BASE, IDMA_REQ_VALID_OFFSET) = 0x0; + // *reg32(ETH_BASE, IDMA_RSP_READY_OFFSET) = 0x1; + + printf ("Ethernet test pass...\n\r"); + + return 0; } + diff --git a/target/sim/src/carfield_fix.sv b/target/sim/src/carfield_fix.sv index 6632a5a4..261389af 100644 --- a/target/sim/src/carfield_fix.sv +++ b/target/sim/src/carfield_fix.sv @@ -203,7 +203,6 @@ module carfield_soc_fixture; .spih_ot_sd_o ( spi_secd_sd_o ), .spih_ot_sd_en_o ( spi_secd_sd_en ), .spih_ot_sd_i ( spi_secd_sd_i ), - .eth_clk_90_i .eth_rxck_i ( eth_rxck ), .eth_rxctl_i ( eth_rxctl ), .eth_rxd_i ( eth_rxd ), @@ -304,6 +303,8 @@ module carfield_soc_fixture; wire [SpihNumCs-1:0] spih_csb; wire [ 3:0] spih_sd; + wire eth_mdio; + // I/O to INOUT behavioral conversion for cheshire's peripherals that require it vip_cheshire_soc_tristate chs_vip_tristate (.*); From 07550ed8ffc59ad1e7b6d8aa25f7af2a856e0831 Mon Sep 17 00:00:00 2001 From: Chaoqun Liang Date: Wed, 17 Apr 2024 19:33:54 +0200 Subject: [PATCH 3/4] ethernet --- hw/carfield.sv | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/hw/carfield.sv b/hw/carfield.sv index 189042db..b50d7c12 100644 --- a/hw/carfield.sv +++ b/hw/carfield.sv @@ -782,11 +782,6 @@ cheshire i_cheshire_wrap ( .test_mode_i , .boot_mode_i , .rtc_i ( rt_clk_i ), - - - - - .eth_clk_90_i ( eth_clk_90_i ), // to-do .eth_clk_125_i ( eth_clk_125_i ), // External AXI LLC (DRAM) port @@ -1927,9 +1922,9 @@ mailbox_unit #( // Carfield peripherals // Ethernet // Peripheral Clock Domain -logic ethernet_slave_isolated; -carfield_axi_slv_req_t axi_ethernet_req; -carfield_axi_slv_rsp_t axi_ethernet_rsp; +// logic ethernet_slave_isolated; +// carfield_axi_slv_req_t axi_ethernet_req; +// carfield_axi_slv_rsp_t axi_ethernet_rsp; // if (CarfieldIslandsCfg.ethernet.enable) begin : gen_ethernet // assign ethernet_slave_isolated = slave_isolated[EthernetSlvIdx]; @@ -2134,8 +2129,7 @@ if (CarfieldIslandsCfg.periph.enable) begin: gen_periph // Handle with care... assign slave_isolate_req[PeriphsSlvIdx] = car_regs_reg2hw.periph_isolate.q; assign slave_isolated[PeriphsSlvIdx] = slave_isolated_rsp[PeriphsSlvIdx]; assign car_regs_hw2reg.periph_isolate_status.d = slave_isolated[PeriphsSlvIdx] | - hyper_isolated_rsp | - ethernet_slave_isolated; + hyper_isolated_rsp; assign car_regs_hw2reg.periph_isolate_status.de = 1'b1; carfield_axi_slv_req_t axi_d64_a48_peripherals_req; From 049b6aaf43cbdbaa2384e92d8d7058388140ef3b Mon Sep 17 00:00:00 2001 From: Chaoqun Liang Date: Fri, 26 Apr 2024 08:58:28 +0200 Subject: [PATCH 4/4] ethernet in cheshire --- sw/tests/bare-metal/hostd/ethernet.c | 5 ++++- target/sim/src/carfield_fix.sv | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sw/tests/bare-metal/hostd/ethernet.c b/sw/tests/bare-metal/hostd/ethernet.c index 39a7d44e..8a2ca2e6 100644 --- a/sw/tests/bare-metal/hostd/ethernet.c +++ b/sw/tests/bare-metal/hostd/ethernet.c @@ -28,8 +28,11 @@ #define PRINTF_ON + int main(void) { + if (hart_id() != 0) wfi(); + #ifdef PRINTF_ON printf ("Start test Ethernet...\n\r"); #endif @@ -57,7 +60,7 @@ int main(void) { } *reg32(ETH_BASE, MACLO_OFFSET) = 0x98001032; - *reg32(ETH_BASE, MACHI_OFFSET) = 0x00012070; + *reg32(ETH_BASE, MACHI_OFFSET) = 0x00002070; *reg32(ETH_BASE, IDMA_SRC_ADDR_OFFSET) = 0x14000000; *reg32(ETH_BASE, IDMA_DST_ADDR_OFFSET) = 0x0; diff --git a/target/sim/src/carfield_fix.sv b/target/sim/src/carfield_fix.sv index 261389af..8297a387 100644 --- a/target/sim/src/carfield_fix.sv +++ b/target/sim/src/carfield_fix.sv @@ -34,7 +34,7 @@ module carfield_soc_fixture; localparam cheshire_cfg_t DutCfg = carfield_pkg::CarfieldCfgDefault; `CHESHIRE_TYPEDEF_ALL(, DutCfg) - localparam time ClkPeriodSys = 10ns; + localparam time ClkPeriodSys = 5ns; // 10ns localparam time ClkPeriodJtag = 40ns; localparam time ClkPeriodRtc = 1000ns; // 1MHz RTC clock. Note: needs to equal // `DutCfg.RTCFreq` for successful autonomous boot