From 5cc41fbdeb30387b89a4d184c645cbeda9740348 Mon Sep 17 00:00:00 2001 From: "sem24h18 Fabian Hauser (fhauser)" <146116057+fhaus1@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:46:03 +0100 Subject: [PATCH] new_usb added (empty shell) --- Bender.yml | 1 + hw/cheshire_pkg.sv | 1 + hw/cheshire_soc.sv | 87 +++++++++++++++++++++++++++-------- hw/newusb/new_usb_ohci.sv | 96 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 20 deletions(-) create mode 100644 hw/newusb/new_usb_ohci.sv diff --git a/Bender.yml b/Bender.yml index 87112e93..2ffb1f36 100644 --- a/Bender.yml +++ b/Bender.yml @@ -44,6 +44,7 @@ sources: - hw/regs/cheshire_reg_top.sv - hw/newusb_regs/newusb_reg_pkg.sv - hw/newusb_regs/newusb_reg_top.sv + - hw/newusb/new_usb_ohci.sv - hw/cheshire_pkg.sv - hw/cheshire_soc.sv diff --git a/hw/cheshire_pkg.sv b/hw/cheshire_pkg.sv index ad4b0c72..8132f79c 100644 --- a/hw/cheshire_pkg.sv +++ b/hw/cheshire_pkg.sv @@ -32,6 +32,7 @@ package cheshire_pkg; localparam int unsigned SlinkMaxClkDiv = 1 << serial_link_single_channel_reg_pkg::Log2MaxClkDiv; localparam int unsigned ClintNumCores = clint_reg_pkg::NumCores; localparam int unsigned UsbNumPorts = spinal_usb_ohci_pkg::NumPhyPorts; + localparam int unsigned NewUsbNumPorts = new_usb_ohci_pkg::NumPhyPorts; // Default JTAG ID code type typedef struct packed { diff --git a/hw/cheshire_soc.sv b/hw/cheshire_soc.sv index 41782a79..947aa062 100644 --- a/hw/cheshire_soc.sv +++ b/hw/cheshire_soc.sv @@ -1718,36 +1718,83 @@ module cheshire_soc import cheshire_pkg::*; #( /////////////// // New USB // /////////////// - + if (Cfg.NewUsb) begin : gen_new_usb + // TODO: USB has no internal error handling, so it should have a bus error unit. - newusb_reg_top #( - .reg_req_t ( reg_req_t ), - .reg_rsp_t ( reg_rsp_t ) - ) i_regs ( - .clk_i, - .rst_ni, - .reg_req_i ( reg_out_req[RegOut.new_usb] ), - .reg_rsp_o ( reg_out_rsp[RegOut.new_usb] ), - .reg2hw ( /* NC */ ), - .hw2reg ( '0 ), - .devmode_i ( 1'b1 ) + new_usb_ohci #( + .AxiMaxReads ( Cfg.UsbDmaMaxReads ), + .AxiAddrWidth ( Cfg.AddrWidth ), + .AxiDataWidth ( Cfg.AxiDataWidth ), + .AxiIdWidth ( Cfg.AxiMstIdWidth ), + .AxiUserWidth ( Cfg.AxiUserWidth ), + .AxiId ( '0 ), + .AxiUser ( Cfg.AxiUserDefault ), + .AxiAddrDomain ( Cfg.UsbAddrDomain ), + .AxiAddrMask ( Cfg.UsbAddrMask ), + .reg_req_t ( reg_req_t ), + .reg_rsp_t ( reg_rsp_t ), + .axi_req_t ( axi_mst_req_t ), + .axi_rsp_t ( axi_mst_rsp_t ) + ) i_new_usb_ohci ( + .soc_clk_i ( clk_i ), + .soc_rst_ni ( rst_ni ), + .ctrl_req_i ( reg_out_req[RegOut.new_usb] ), + .ctrl_rsp_o ( reg_out_rsp[RegOut.new_usb] ), + .dma_req_o ( axi_in_req[AxiIn.new_usb] ), + .dma_rsp_i ( axi_in_rsp[AxiIn.new_usb] ), + .intr_o ( intr.intn.usb ), + .phy_clk_i ( usb_clk_i ), + .phy_rst_ni ( usb_rst_ni ), + .phy_dm_i ( usb_dm_i ), + .phy_dm_o ( usb_dm_o ), + .phy_dm_oe_o ( usb_dm_oe_o ), + .phy_dp_i ( usb_dp_i ), + .phy_dp_o ( usb_dp_o ), + .phy_dp_oe_o ( usb_dp_oe_o ) ); - // DMA port tied-off - assign axi_in_req[AxiIn.new_usb] = '0; - - // IRQ tied-off - assign intr.intn.new_usb = '0; + end else begin : gen_no_usb - end else begin : gen_no_new_usb + assign usb_dm_o = '0; + assign usb_dm_oe_o = '0; + assign usb_dp_o = '0; + assign usb_dp_oe_o = '0; - // tie-off other signals (USB PHY, IRQs) - assign intr.intn.new_usb = '0; + assign intr.intn.new_usb = 0; end + //if (Cfg.NewUsb) begin : gen_new_usb +// +// + // newusb_reg_top #( + // .reg_req_t ( reg_req_t ), + // .reg_rsp_t ( reg_rsp_t ) + // ) i_regs ( + // .clk_i, + // .rst_ni, + // .reg_req_i ( reg_out_req[RegOut.new_usb] ), //SW HCD + // .reg_rsp_o ( reg_out_rsp[RegOut.new_usb] ), //SW HCD + // .reg2hw ( /* NC */ ), //HW HC + // .hw2reg ( '0 ), //HW HC + // .devmode_i ( 1'b1 ) + // ); +// + // // DMA port tied-off + // assign axi_in_req[AxiIn.new_usb] = '0; +// + // // IRQ tied-off + // assign intr.intn.new_usb = '0; +// + //end else begin : gen_no_new_usb +// + // // tie-off other signals (USB PHY, IRQs) + // assign intr.intn.new_usb = '0; +// + //end + ////////////////// // Assertions // ////////////////// diff --git a/hw/newusb/new_usb_ohci.sv b/hw/newusb/new_usb_ohci.sv new file mode 100644 index 00000000..436550b7 --- /dev/null +++ b/hw/newusb/new_usb_ohci.sv @@ -0,0 +1,96 @@ +// Copyright 2024 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +// Fabian Hauser + +/// Main module for the direct SystemVerilog New USB OHCI, configured for AXI4 buses. +/// The config port is adapted to 32b Regbus, the DMA port to parametric AXI4. +/// The IOs are bundled into PULP structs and arrays to simplify connection. + + +// Changes inside this package need to be confirmed with a make hw-all, +// because the package values need to influence the configuration inside newusb_regs.hjson. +package new_usb_ohci_pkg; + //Supports between 1-15 ports + localparam int unsigned NumPhyPorts = 8; + //To Do: Overcurrent protection global/individual + // 0: off + // 1: global + // 2: individual + //To Do: Power switching protection global/individual + // 0: off + // 1: global + // 2: individual + //To Do: Fifodepth + //To Do: Usb Dmalength + //To Do: Beats per Dmalength + //To Do: words per Beat +endpackage + +module new_usb_ohci import new_usb_ohci_pkg::*; #( + /// DMA manager port parameters + parameter int unsigned AxiMaxReads = 0, + parameter int unsigned AxiAddrWidth = 0, + parameter int unsigned AxiDataWidth = 0, + parameter int unsigned AxiIdWidth = 0, + parameter int unsigned AxiUserWidth = 0, + /// The current controller can only address a 32b address space. + /// This parameter can statically add a domain and mask for the lower bits. + parameter logic [AxiAddrWidth-1:0] AxiAddrDomain = '0, + parameter logic [AxiAddrWidth-1:0] AxiAddrMask = 'hFFFF_FFFF, + /// Default User and ID presented on DMA manager AR, AW, W channels. + /// In most systems, these can or should be left at '0. + parameter logic [AxiIdWidth-1:0] AxiId = '0, + parameter logic [AxiUserWidth-1:0] AxiUser = '0, + /// SoC interface types + parameter type reg_req_t = logic, + parameter type reg_rsp_t = logic, + parameter type axi_req_t = logic, + parameter type axi_rsp_t = logic +) ( + /// SoC clock and reset + input logic soc_clk_i, + input logic soc_rst_ni, + /// Control subordinate port + input reg_req_t ctrl_req_i, + output reg_rsp_t ctrl_rsp_o, + /// DMA manager port + output axi_req_t dma_req_o, + input axi_rsp_t dma_rsp_i, + /// Interrupt + output logic intr_o, + /// PHY clock and reset + input logic phy_clk_i, + input logic phy_rst_ni, + /// PHY IO + input logic [NumPhyPorts-1:0] phy_dm_i, + output logic [NumPhyPorts-1:0] phy_dm_o, + output logic [NumPhyPorts-1:0] phy_dm_oe_o, + input logic [NumPhyPorts-1:0] phy_dp_i, + output logic [NumPhyPorts-1:0] phy_dp_o, + output logic [NumPhyPorts-1:0] phy_dp_oe_o +); + +newusb_reg_top #( + .reg_req_t ( reg_req_t ), + .reg_rsp_t ( reg_rsp_t ) +) i_regs ( + .clk_i ( soc_clk_i ), + .rst_ni ( soc_rst_ni ), + .reg_req_i ( ctrl_req_i ), //SW HCD + .reg_rsp_o ( ctrl_rsp_o ), //SW HCD + .reg2hw ( /* NC */ ), //HW HC + .hw2reg ( '0 ), //HW HC + .devmode_i ( 1'b1 ) +); + + assign dma_req_o = '0; + // IRQ tied-off + assign intr_o = '0; + + // assign usb_dm_o = '0; + // assign usb_dm_oe_o = '0; + // assign usb_dp_o = '0; + // assign usb_dp_oe_o = '0; +endmodule