From 4d3e4dd9315f5f9583d0b006d64612559140d9bb Mon Sep 17 00:00:00 2001 From: daniel-k Date: Tue, 9 Jan 2018 10:20:46 +0100 Subject: [PATCH] ips: make irqs a list --- fpga/etc/fpga.json | 12 +++++------ fpga/include/villas/fpga/ip.hpp | 19 +++++++++++------ fpga/lib/ip.cpp | 36 ++++++++++++++++++++++++++------- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/fpga/etc/fpga.json b/fpga/etc/fpga.json index b1cbb50ea..aaac01297 100644 --- a/fpga/etc/fpga.json +++ b/fpga/etc/fpga.json @@ -33,12 +33,12 @@ "timer_0": { "vlnv": "xilinx.com:ip:axi_timer:2.0", "baseaddr": 16384, - "irq": "axi_pcie_intc_0:0" + "irqs": [ "axi_pcie_intc_0:0" ] }, "dma_0": { "vlnv": "xilinx.com:ip:axi_dma:7.1", "baseaddr": 12288, - "irq": "axi_pcie_intc_0:3" + "irqs": [ "axi_pcie_intc_0:3" ] }, "axi_pcie_intc_0": { "vlnv": "acs.eonerc.rwth-aachen.de:user:axi_pcie_intc:1.0", @@ -51,7 +51,7 @@ "master": [ { "num": 0, "other": "switch_0:6" } ], "slave": [ { "num": 0, "other": "switch_0:6" } ] }, - "irq": "axi_pcie_intc_0:3" + "irqs": [ "axi_pcie_intc_0:3" ] }, "fifo_mm_s_0": { "vlnv": "xilinx.com:ip:axi_fifo_mm_s:4.1", @@ -61,7 +61,7 @@ "master": [ { "num": 0, "other": "switch_0:2" } ], "slave": [ { "num": 0, "other": "switch_0:2" } ] }, - "irq": "axi_pcie_intc_0:2" + "irqs": [ "axi_pcie_intc_0:2" ] }, "rtds_axis_0": { "vlnv": "acs.eonerc.rwth-aachen.de:user:rtds_axis:1.0", @@ -70,7 +70,7 @@ "master": [ { "num": 0, "other": "switch_0:0" } ], "slave": [ { "num": 0, "other": "switch_0:0" } ] }, - "irq": "axi_pcie_intc_0:5" + "irqs": [ "axi_pcie_intc_0:5", "axi_pcie_intc_0:6" ] }, "hls_dft_0": { "vlnv": "acs.eonerc.rwth-aachen.de:hls:hls_dft:1.0", @@ -79,7 +79,7 @@ "master": [ { "num": 0, "other": "switch_0:5" } ], "slave": [ { "num": 0, "other": "switch_0:5" } ] }, - "irq": "axi_pcie_intc_0:1", + "irqs": [ "axi_pcie_intc_0:1" ], "period": 400, "harmonics": [ 0, diff --git a/fpga/include/villas/fpga/ip.hpp b/fpga/include/villas/fpga/ip.hpp index d265ecc50..a9cef05a9 100644 --- a/fpga/include/villas/fpga/ip.hpp +++ b/fpga/include/villas/fpga/ip.hpp @@ -75,7 +75,7 @@ public: friend IpCoreFactory; - IpCore() : card(nullptr), baseaddr(0), irq(-1) {} + IpCore() : card(nullptr), baseaddr(0) {} virtual ~IpCore() {} // IPs can implement this interface @@ -105,14 +105,21 @@ protected: uintptr_t getBaseaddr() const; + struct IrqPort { + int num; + std::string controllerName; + std::string description; + }; + protected: // populated by FpgaIpFactory - PCIeCard* card; /**< FPGA card this IP is instantiated on */ - IpIdentifier id; /**< VLNV and name defined in JSON config */ - uintptr_t baseaddr; /**< The baseadress of this FPGA IP component */ - int irq; /**< The interrupt number of the FPGA IP component. */ + PCIeCard* card; ///< FPGA card this IP is instantiated on + IpIdentifier id; ///< VLNV and name defined in JSON config + uintptr_t baseaddr; ///< The baseadress of this IP component + std::map irqs; ///< Interrupts of this IP component - std::map dependencies; +private: + std::map dependencies; ///< dependencies on other IPs }; diff --git a/fpga/lib/ip.cpp b/fpga/lib/ip.cpp index 6e5e4cb51..e84c7cb0e 100644 --- a/fpga/lib/ip.cpp +++ b/fpga/lib/ip.cpp @@ -226,17 +226,39 @@ IpCoreFactory::make(PCIeCard* card, json_t *json_ips) ip->card = card; ip->id = id; - // extract some optional properties - int ret = json_unpack(json_ip, "{ s?: i, s?: i }", - "baseaddr", &ip->baseaddr, // required - "irq", &ip->irq); // optional - - if(ret != 0) { - cpp_warn << "Problem while parsing JSON for IP " + // extract base address if it has one + if(json_unpack(json_ip, "{ s?: i }", "baseaddr", &ip->baseaddr) != 0) { + cpp_warn << "Problem while parsing base address of IP " << TXT_BOLD(ipName); continue; } + json_t* json_irqs = json_object_get(json_ip, "irqs"); + if(json_is_array(json_irqs)) { + size_t index; + json_t* json_irq; + json_array_foreach(json_irqs, index, json_irq) { + const char* irq = json_string_value(json_irq); + auto tokens = utils::tokenize(irq, ":"); + if(tokens.size() != 2) { + cpp_warn << "Cannot parse IRQ '" << irq << "' of" + << TXT_BOLD(ipName); + continue; + } + + int num; + try { + num = std::stoi(tokens[1]); + } catch(const std::invalid_argument&) { + cpp_warn << "IRQ number is not an integer: '" << irq << "'"; + continue; + } + + ip->irqs[index] = {num, tokens[0]}; + } + } + + bool dependenciesOk = true; for(auto& [depName, depVlnv] : ipCoreFactory->getDependencies()) { // lookup dependency IP core in list of already initialized IPs