diff --git a/data/sonata_udp.rdl b/data/sonata_udp.rdl new file mode 100644 index 000000000..2c8c40363 --- /dev/null +++ b/data/sonata_udp.rdl @@ -0,0 +1,50 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +/* Indicates what the signal is used for. + */ +enum SigType { + None; + PadInOut; // Signal is a pad for In and Out. i.e: i2c.sda. + PadInput; // Signal is a pad for Input. i.e: uart.rx + PadOutput; // Signal is a pad for Output. i.e: uart.tx + Interrupt;// Signal is an Interrupt +}; + +/* Indicates what the signal will be used for. + */ +property sigtype { + type = SigType; + component = signal; + default = SigType::None; +}; + +enum IoCombine { + None; + Mux; + And; + Or; +}; + +/* + */ +property io_combine { + type = IoCombine; + component = signal; + default = IoCombine::None; +}; + +struct parameter { + string type_; + string name; + string value; +}; + +property xbar { + type = parameter[]; + component = addrmap|mem; + default = '{}; +}; + diff --git a/data/top.rdl b/data/top.rdl new file mode 100644 index 000000000..a87889ebf --- /dev/null +++ b/data/top.rdl @@ -0,0 +1,79 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +`include "udp.rdl" +`include "sonata_udp.rdl" +`include "../rtl/ip/system_info/data/system_info.rdl" +`include "../rtl/ip/spi/data/spi.rdl" +`include "../rtl/ip/rgbled_ctrl/data/rgbled_ctrl.rdl" +`include "../rtl/ip/pwm/data/pwm.rdl" +`include "../rtl/ip/gpio/data/gpio.rdl" +`include "../rtl/ip/usbdev/data/usbdev.rdl" +`include "../rtl/ip/i2c/data/i2c.rdl" +`include "../rtl/ip/uart/data/uart.rdl" +`include "../rtl/ip/xadc/data/xadc.rdl" +`include "../rtl/ip/rev_ctl/data/rev_ctl.rdl" +`include "../rtl/system/data/rv_plic.rdl" +`include "../rtl/system/data/pinmux.rdl" +`include "../rtl/system/data/rv_timer.rdl" + +addrmap top_sonata { + external mem sram { + mementries = 0x20000; memwidth=8; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + } SRAM @ 0x00100000; + + external mem hyperram { + mementries = 0x100000; memwidth=8; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + } HYPERRAM @ 0x40000000; + + external mem rev_tag { + mementries = 0x800; memwidth=8; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + } REV_TAG @ 0x30000000; + + gpio GPIO[6] @ 0x80000000 += 0x40; + + pwm PWM[1] @ 0x80001000 += 0x1000; + + pinmux PINMUX @ 0x80005000; + + rgbled_ctrl RGBLED_CTRL @ 0x80009000; + + rev_ctl HW_REV @ 0x8000A000; + + xadc XADC @ 0x8000B000; + + system_info SYSTEM_INFO @ 0x8000C000; + + rv_timer TIMER @ 0x80040000; + + uart uart[3] @ 0x80100000 += 0x1000; + + i2c I2C[2] @ 0x80200000 += 0x1000; + + spi SPI_LCD @ 0x80300000; + + spi SPI_ETHMAC @ 0x80301000; + + spi SPI[3] @ 0x80302000 += 0x1000; + + usbdev USBDEV @ 0x80400000; + + // This block is overaligned to 0x0800_0000 bytes since OpenTitan RV_PLIC block expects it. + rv_plic RV_PLIC @ 0x88000000; + + external mem dgb_dev { + mementries = 0x1000; memwidth=8; + xbar = '{ parameter'{ type_: "bool", name: "pipeline", value: "true" }}; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + } DBG_DEV @ 0xB0000000; +}; + diff --git a/data/top_config.toml b/data/top_config.toml index d86e8d42d..d9eb40ba0 100644 --- a/data/top_config.toml +++ b/data/top_config.toml @@ -1,59 +1,3 @@ -[[blocks]] -name = "gpio" -instances = 5 # RPi, Ard, Pmod0, Pmod1, PmodC -ios = [ - { - name = "ios", - type = "inout", - combine = "mux", - length = 32 - }, -] -memory_start = 0x80000040 -memory_size = 0x00000040 - -[[blocks]] -name = "pwm" -instances = 1 -ios = [{ name = "out", type = "output", length = 7 }] -memory_start = 0x80001000 -memory_size = 0x00001000 -xbar = { pipeline = "true", req_fifo_pass = "false", rsp_fifo_pass = "false" } - -[[blocks]] -name = "uart" -instances = 3 -ios = [ - { name = "rx", type = "input", default = 1 }, - { name = "tx", type = "output" }, -] -memory_start = 0x80100000 -memory_size = 0x00001000 -xbar = { pipeline = "true", req_fifo_pass = "false", rsp_fifo_pass = "false" } - -[[blocks]] -name = "i2c" -instances = 2 -ios = [ - { name = "scl", type = "inout", combine = "and" }, - { name = "sda", type = "inout", combine = "and" }, -] -memory_start = 0x80200000 -memory_size = 0x00001000 -xbar = { pipeline = "true", req_fifo_pass = "false", rsp_fifo_pass = "false" } - -[[blocks]] -name = "spi" -instances = 3 -ios = [ - { name = "cipo", type = "input", default = 0 }, - { name = "copi", type = "output" }, - { name = "sclk", type = "output" }, - { name = "cs", type = "output", length = 4 }, -] -memory_start = 0x80302000 -memory_size = 0x00001000 - # UARTS [[pins]] name = "ser0_tx" diff --git a/data/udp.rdl b/data/udp.rdl new file mode 100644 index 000000000..723507fed --- /dev/null +++ b/data/udp.rdl @@ -0,0 +1,119 @@ +/* Copyright lowRISC contributors (OpenTitan project). + * Licensed under the Apache License, Version 2.0; see LICENSE for details. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * 4-bits boolean values + */ +enum MultiBitBool4 { + True = 0x6; + False = 0x9; +}; + +/** + * 8-bits boolean values + */ +enum MultiBitBool8 { + True = 0x96; + False = 0x69; +}; + +/** + * 12-bits boolean values + */ +enum MultiBitBool12 { + True = 0x696; + False = 0x969; +}; + +/** + * 16-bits boolean values + */ +enum MultiBitBool16 { + True = 0x9696; + False = 0x6969; +}; + +/** + * 20-bits boolean values + */ +enum MultiBitBool20 { + True = 0x69696; + False = 0x96969; +}; + +/** + * 24-bits boolean values + */ +enum MultiBitBool24 { + True = 0x969696; + False = 0x696969; +}; + +/** + * 28-bits boolean values + */ +enum MultiBitBool28 { + True = 0x6969696; + False = 0x9696969; +}; + +/** + * 32-bits boolean values + */ +enum MultiBitBool32 { + True = 0x96969696; + False = 0x69696969; +}; + +/** + * true if hardware uses `re` signal, which is latched signal of software read pulse. + * The standard SystemRDL property `swacc` cannot be used here because `swacc = hwre | swmod`. + */ +property hwre { + type = boolean; + component = reg; + default = false; +}; + +/* If it is true, the register will be implemented using the prim_subreg_shadow module. + * Shadow registers are a mechanism to guard sensitive registers against this specific + * type of attack. They come at a cost of increased area, and a modified SW interaction. + */ +property shadowed { + type = boolean; + component = reg; + default = false; +}; + +/* Indicates the register must cross to a different clock domain before use. + * The value shown here should correspond to one of the module’s clocks. + */ +property async_clk { + type = boolean; + component = reg; + default = false; +}; + +property clk_input { + type = string[]; + component = addrmap|regfile|reg|mem; + default = '{}; +}; + +/* If true, integrity bits are passed through directly from the memory. + */ +property integrity_bypass { + type = boolean; + component = mem; + default = false; +}; + +property rst_input { + type = string[]; + component = addrmap|regfile|reg|mem; + default = '{}; +}; + + diff --git a/data/xbar_main.hjson b/data/xbar_main.hjson index a2c0f1dc5..243701f75 100644 --- a/data/xbar_main.hjson +++ b/data/xbar_main.hjson @@ -31,308 +31,377 @@ xbar: false, pipeline: true, }, - { name: "sram", // Internal memory - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x00100000", - size_byte: "0x00020000", - }], - }, - { name: "hyperram", // HyperRAM memory - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x40000000", - size_byte: "0x00100000", - }], - }, - { name: "rev_tag", // Revocation tag memory - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x30000000", - size_byte: "0x00000800", - }], - }, - { name: "gpio", // General purpose input and output - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - base_addr: "0x80000000", - size_byte: "0x00001000", - }], - pipeline: true, - }, - { name: "pinmux", // Pin multiplexer - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - base_addr: "0x80005000", - size_byte: "0x00001000", - }], - pipeline: true, - }, - { name: "rgbled_ctrl", // RGB LED Controller - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - base_addr: "0x80009000", - size_byte: "0x00001000", - }], - pipeline: true, - }, - { name: "hw_rev", // Hardware revoker control register - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x8000A000", - size_byte: "0x00001000", - }], - }, - { name: "xadc", // XADC - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - base_addr: "0x8000B000", - size_byte: "0x00001000", - }], - pipeline: true, - }, - { name: "system_info", // System information - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x8000C000", - size_byte: "0x00001000", - }], - }, - { name: "timer", // Interrupt timer - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80040000", - size_byte: "0x00010000", - }], - }, - { name: "spi_lcd", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80300000", - size_byte: "0x00001000", - }], - }, - { name: "spi_ethmac", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80301000", - size_byte: "0x00001000", - }], - }, - { name: "pwm0", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80001000", - size_byte: "0x1000", - }], - pipeline: true, - req_fifo_pass: false, - rsp_fifo_pass: false, - }, - { name: "uart0", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80100000", - size_byte: "0x1000", - }], - pipeline: true, - req_fifo_pass: false, - rsp_fifo_pass: false, - }, - { name: "uart1", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80101000", - size_byte: "0x1000", - }], - pipeline: true, - req_fifo_pass: false, - rsp_fifo_pass: false, - }, - { name: "uart2", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80102000", - size_byte: "0x1000", - }], - pipeline: true, - req_fifo_pass: false, - rsp_fifo_pass: false, - }, - { name: "i2c0", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80200000", - size_byte: "0x1000", - }], - pipeline: true, - req_fifo_pass: false, - rsp_fifo_pass: false, - }, - { name: "i2c1", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80201000", - size_byte: "0x1000", - }], - pipeline: true, - req_fifo_pass: false, - rsp_fifo_pass: false, - }, - { name: "spi0", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80302000", - size_byte: "0x1000", - }], - }, - { name: "spi1", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80303000", - size_byte: "0x1000", - }], - }, - { name: "spi2", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80304000", - size_byte: "0x1000", - }], - }, - { name: "usbdev", // USB device - type: "device", - clock: "clk_usb_i", - reset: "rst_usb_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80400000", - size_byte: "0x00001000", - }], - }, - { name: "dbg_dev", // Debug module fetch interface - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - pipeline: true, - addr_range: [{ - base_addr: "0xB0000000", - size_byte: "0x00001000", - }], - }, - { name: "rv_plic", // RISC-V platform interrupt controller - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - // This block is overaligned to 0x0800_0000 bytes since OpenTitan RV_PLIC block expects it. - base_addr: "0x88000000", - size_byte: "0x08000000", - }], - pipeline: true, - }, + { name: "sram", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x00100000", + size_byte: "0x00020000", + }], + }, + { name: "rev_tag", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x30000000", + size_byte: "0x00000800", + }], + }, + { name: "hyperram", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x40000000", + size_byte: "0x00100000", + }], + }, + { name: "gpio0", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80000000", + size_byte: "0x00000040", + }], + }, + { name: "gpio1", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80000040", + size_byte: "0x00000040", + }], + }, + { name: "gpio2", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80000080", + size_byte: "0x00000040", + }], + }, + { name: "gpio3", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x800000C0", + size_byte: "0x00000040", + }], + }, + { name: "gpio4", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80000100", + size_byte: "0x00000040", + }], + }, + { name: "gpio5", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80000140", + size_byte: "0x00000040", + }], + }, + { name: "pwm", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80001000", + size_byte: "0x00001000", + }], + }, + { name: "pinmux", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80005000", + size_byte: "0x00001000", + }], + }, + { name: "rgbled_ctrl", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80009000", + size_byte: "0x00000010", + }], + }, + { name: "hw_rev", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x8000A000", + size_byte: "0x00000020", + }], + }, + { name: "xadc", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x8000B000", + size_byte: "0x00000080", + }], + }, + { name: "system_info", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x8000C000", + size_byte: "0x00000020", + }], + }, + { name: "timer", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80040000", + size_byte: "0x00010000", + }], + }, + { name: "uart0", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80100000", + size_byte: "0x00001000", + }], + }, + { name: "uart1", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80101000", + size_byte: "0x00001000", + }], + }, + { name: "uart2", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80102000", + size_byte: "0x00001000", + }], + }, + { name: "i2c0", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80200000", + size_byte: "0x00001000", + }], + }, + { name: "i2c1", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80201000", + size_byte: "0x00001000", + }], + }, + { name: "spi_lcd", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80300000", + size_byte: "0x00000040", + }], + }, + { name: "spi_ethmac", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80301000", + size_byte: "0x00000040", + }], + }, + { name: "spi0", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80302000", + size_byte: "0x00001000", + }], + }, + { name: "spi1", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80303000", + size_byte: "0x00001000", + }], + }, + { name: "spi2", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80304000", + size_byte: "0x00001000", + }], + }, + { name: "usbdev", + type: "device", + clock: "clk_usb_i", + reset: "rst_usb_ni", + xbar: false, + addr_range: [{ + base_addr: "0x80400000", + size_byte: "0x00001000", + }], + }, + { name: "rv_plic", + type: "device", + pipeline: true, + req_fifo_pass: false, + rsp_fifo_pass: false, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0x88000000", + size_byte: "0x08000000", + }], + }, + { name: "dbg_dev", + type: "device", + pipeline: true, + clock: "clk_sys_i", + reset: "rst_sys_ni", + xbar: false, + addr_range: [{ + base_addr: "0xB0000000", + size_byte: "0x00001000", + }], + }, ], connections: { ibex_lsu: [ - "sram", - "hyperram", - "rev_tag", - "dbg_dev", - "gpio", - "pinmux", - "system_info", - "rgbled_ctrl", - "hw_rev", - "xadc", - "timer", - "spi_lcd", - "spi_ethmac", - "pwm0", - "uart0", - "uart1", - "uart2", - "i2c0", - "i2c1", - "spi0", - "spi1", - "spi2", - "usbdev", - "rv_plic", + "sram", + "rev_tag", + "hyperram", + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "pwm", + "pinmux", + "rgbled_ctrl", + "hw_rev", + "xadc", + "system_info", + "timer", + "uart0", + "uart1", + "uart2", + "i2c0", + "i2c1", + "spi_lcd", + "spi_ethmac", + "spi0", + "spi1", + "spi2", + "usbdev", + "rv_plic", + "dbg_dev", ], dbg_host: [ "sram", @@ -341,3 +410,5 @@ ], }, } + + diff --git a/data/xbar_main.hjson.tpl b/data/xbar_main.hjson.tpl index 896b6311f..876a4421b 100644 --- a/data/xbar_main.hjson.tpl +++ b/data/xbar_main.hjson.tpl @@ -31,217 +31,29 @@ xbar: false, pipeline: true, }, - { name: "sram", // Internal memory - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x00100000", - size_byte: "0x00020000", - }], - }, - { name: "hyperram", // HyperRAM memory - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x40000000", - size_byte: "0x00100000", - }], - }, - { name: "rev_tag", // Revocation tag memory - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x30000000", - size_byte: "0x00000800", - }], - }, - { name: "gpio", // General purpose input and output - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - base_addr: "0x80000000", - size_byte: "0x00001000", - }], - pipeline: true, - }, - { name: "pinmux", // Pin multiplexer - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - base_addr: "0x80005000", - size_byte: "0x00001000", - }], - pipeline: true, - }, - { name: "rgbled_ctrl", // RGB LED Controller - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - base_addr: "0x80009000", - size_byte: "0x00001000", - }], - pipeline: true, - }, - { name: "hw_rev", // Hardware revoker control register - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x8000A000", - size_byte: "0x00001000", - }], - }, - { name: "xadc", // XADC - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - base_addr: "0x8000B000", - size_byte: "0x00001000", - }], - pipeline: true, - }, - { name: "system_info", // System information - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x8000C000", - size_byte: "0x00001000", - }], - }, - { name: "timer", // Interrupt timer - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80040000", - size_byte: "0x00010000", - }], - }, - { name: "spi_lcd", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80300000", - size_byte: "0x00001000", - }], - }, - { name: "spi_ethmac", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80301000", - size_byte: "0x00001000", - }], - }, - % for block in config.blocks: - % if not block.name == "gpio": - % for i in range(block.instances): - { name: "${f"{block.name}{i}"}", - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - addr_range: [{ - base_addr: "${hex(block.memory_start + i * block.memory_size)}", - size_byte: "${hex(block.memory_size)}", - }], - % for (setting, value) in block.xbar.items(): - ${setting}: ${value}, - % endfor - }, - % endfor - % endif +% for block in config.blocks: + % for i in range(block.instances): + { name: "${block.name}${f"{i}" if block.instances > 1 else "" }", + type: "device", + % for (setting, value) in block.xbar.items(): + ${setting}: ${value}, % endfor - { name: "usbdev", // USB device - type: "device", - clock: "clk_usb_i", - reset: "rst_usb_ni", - xbar: false, - addr_range: [{ - base_addr: "0x80400000", - size_byte: "0x00001000", - }], - }, - { name: "dbg_dev", // Debug module fetch interface - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - xbar: false, - pipeline: true, - addr_range: [{ - base_addr: "0xB0000000", - size_byte: "0x00001000", - }], - }, - { name: "rv_plic", // RISC-V platform interrupt controller - type: "device", - clock: "clk_sys_i", - reset: "rst_sys_ni", - req_fifo_pass: false, - rsp_fifo_pass: false, - xbar: false, - addr_range: [{ - // This block is overaligned to 0x0800_0000 bytes since OpenTitan RV_PLIC block expects it. - base_addr: "0x88000000", - size_byte: "0x08000000", - }], - pipeline: true, - }, + xbar: false, + addr_range: [{ + base_addr: "${"0x%08X" % (block.memory_start + i * block.memory_size)}", + size_byte: "${"0x%08X" % (block.memory_size)}", + }], + }, + % endfor +% endfor ], connections: { ibex_lsu: [ - "sram", - "hyperram", - "rev_tag", - "dbg_dev", - "gpio", - "pinmux", - "system_info", - "rgbled_ctrl", - "hw_rev", - "xadc", - "timer", - "spi_lcd", - "spi_ethmac", - % for block in config.blocks: - % if not block.name == "gpio": - % for i in range(block.instances): - "${f"{block.name}{i}"}", - % endfor - % endif - % endfor - "usbdev", - "rv_plic", +% for block in config.blocks: + % for i in range(block.instances): + "${block.name}${f"{i}" if block.instances > 1 else "" }", + % endfor +% endfor ], dbg_host: [ "sram", @@ -250,3 +62,5 @@ ], }, } + + diff --git a/doc/ip/pinmux/README.md b/doc/ip/pinmux/README.md index 398e8183f..063fad4d0 100644 --- a/doc/ip/pinmux/README.md +++ b/doc/ip/pinmux/README.md @@ -166,9 +166,9 @@ Besides the output pin selectors, there are also selectors for which pin should | 0x83d | `gpio_4_ios_3` | 0, `pmodc_4` | | 0x83e | `gpio_4_ios_4` | 0, `pmodc_5` | | 0x83f | `gpio_4_ios_5` | 0, `pmodc_6` | -| 0x840 | `uart_0_rx` | 1, `ser0_rx` | -| 0x841 | `uart_1_rx` | 1, `ser1_rx`, `rph_rxd0`, `ah_tmpio0`, `mb8`, `pmod0_3` | -| 0x842 | `uart_2_rx` | 1, `ser1_rx`, `rs232_rx`, `rs485_rx`, `pmod1_3` | +| 0x840 | `uart_0_rx` | 0, `ser0_rx` | +| 0x841 | `uart_1_rx` | 0, `ser1_rx`, `rph_rxd0`, `ah_tmpio0`, `mb8`, `pmod0_3` | +| 0x842 | `uart_2_rx` | 0, `ser1_rx`, `rs232_rx`, `rs485_rx`, `pmod1_3` | | 0x843 | `spi_0_cipo` | 0, `appspi_d1`, `microsd_dat0` | | 0x844 | `spi_1_cipo` | 0, `rph_g9`, `ah_tmpio12`, `pmod0_3` | | 0x845 | `spi_2_cipo` | 0, `rph_g19`, `mb3`, `pmod1_3` | diff --git a/pyproject.toml b/pyproject.toml index 595ff8d01..de19eaf7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,7 @@ dependencies = [ "tabulate>=0.9.0,<0.10", "setuptools>=80.9.0", "packaging>=25.0", + "rdl2ot>=0.3.0", ] [tool.setuptools] diff --git a/rtl/bus/sonata_xbar_main.sv b/rtl/bus/sonata_xbar_main.sv index 8746c1de8..5828cec8c 100644 --- a/rtl/bus/sonata_xbar_main.sv +++ b/rtl/bus/sonata_xbar_main.sv @@ -23,42 +23,42 @@ module sonata_xbar_main // Device interfaces output tlul_pkg::tl_h2d_t tl_sram_o, input tlul_pkg::tl_d2h_t tl_sram_i, - output tlul_pkg::tl_h2d_t tl_hyperram_o, - input tlul_pkg::tl_d2h_t tl_hyperram_i, output tlul_pkg::tl_h2d_t tl_rev_tag_o, input tlul_pkg::tl_d2h_t tl_rev_tag_i, - output tlul_pkg::tl_h2d_t tl_gpio_o, - input tlul_pkg::tl_d2h_t tl_gpio_i, + output tlul_pkg::tl_h2d_t tl_hyperram_o, + input tlul_pkg::tl_d2h_t tl_hyperram_i, + output tlul_pkg::tl_h2d_t tl_gpio_o[GPIO_NUM], + input tlul_pkg::tl_d2h_t tl_gpio_i[GPIO_NUM], + output tlul_pkg::tl_h2d_t tl_pwm_o, + input tlul_pkg::tl_d2h_t tl_pwm_i, output tlul_pkg::tl_h2d_t tl_pinmux_o, input tlul_pkg::tl_d2h_t tl_pinmux_i, - output tlul_pkg::tl_h2d_t tl_system_info_o, - input tlul_pkg::tl_d2h_t tl_system_info_i, output tlul_pkg::tl_h2d_t tl_rgbled_ctrl_o, input tlul_pkg::tl_d2h_t tl_rgbled_ctrl_i, output tlul_pkg::tl_h2d_t tl_hw_rev_o, input tlul_pkg::tl_d2h_t tl_hw_rev_i, output tlul_pkg::tl_h2d_t tl_xadc_o, input tlul_pkg::tl_d2h_t tl_xadc_i, + output tlul_pkg::tl_h2d_t tl_system_info_o, + input tlul_pkg::tl_d2h_t tl_system_info_i, output tlul_pkg::tl_h2d_t tl_timer_o, input tlul_pkg::tl_d2h_t tl_timer_i, - output tlul_pkg::tl_h2d_t tl_spi_lcd_o, - input tlul_pkg::tl_d2h_t tl_spi_lcd_i, - output tlul_pkg::tl_h2d_t tl_spi_ethmac_o, - input tlul_pkg::tl_d2h_t tl_spi_ethmac_i, - output tlul_pkg::tl_h2d_t tl_pwm_o[PWM_NUM], - input tlul_pkg::tl_d2h_t tl_pwm_i[PWM_NUM], output tlul_pkg::tl_h2d_t tl_uart_o[UART_NUM], input tlul_pkg::tl_d2h_t tl_uart_i[UART_NUM], output tlul_pkg::tl_h2d_t tl_i2c_o[I2C_NUM], input tlul_pkg::tl_d2h_t tl_i2c_i[I2C_NUM], + output tlul_pkg::tl_h2d_t tl_spi_lcd_o, + input tlul_pkg::tl_d2h_t tl_spi_lcd_i, + output tlul_pkg::tl_h2d_t tl_spi_ethmac_o, + input tlul_pkg::tl_d2h_t tl_spi_ethmac_i, output tlul_pkg::tl_h2d_t tl_spi_o[SPI_NUM], input tlul_pkg::tl_d2h_t tl_spi_i[SPI_NUM], output tlul_pkg::tl_h2d_t tl_usbdev_o, input tlul_pkg::tl_d2h_t tl_usbdev_i, - output tlul_pkg::tl_h2d_t tl_dbg_dev_o, - input tlul_pkg::tl_d2h_t tl_dbg_dev_i, output tlul_pkg::tl_h2d_t tl_rv_plic_o, - input tlul_pkg::tl_d2h_t tl_rv_plic_i + input tlul_pkg::tl_d2h_t tl_rv_plic_i, + output tlul_pkg::tl_h2d_t tl_dbg_dev_o, + input tlul_pkg::tl_d2h_t tl_dbg_dev_i ); xbar_main xbar ( @@ -77,30 +77,36 @@ module sonata_xbar_main // Device interfaces. .tl_sram_o (tl_sram_o), .tl_sram_i (tl_sram_i), - .tl_hyperram_o (tl_hyperram_o), - .tl_hyperram_i (tl_hyperram_i), - .tl_rev_tag_o (tl_rev_tag_o), - .tl_rev_tag_i (tl_rev_tag_i), - .tl_gpio_o (tl_gpio_o), - .tl_gpio_i (tl_gpio_i), - .tl_pinmux_o (tl_pinmux_o), - .tl_pinmux_i (tl_pinmux_i), - .tl_system_info_o (tl_system_info_o), - .tl_system_info_i (tl_system_info_i), - .tl_rgbled_ctrl_o (tl_rgbled_ctrl_o), - .tl_rgbled_ctrl_i (tl_rgbled_ctrl_i), - .tl_hw_rev_o (tl_hw_rev_o), - .tl_hw_rev_i (tl_hw_rev_i), + .tl_rev_tag_o (tl_rev_tag_o), + .tl_rev_tag_i (tl_rev_tag_i), + .tl_hyperram_o (tl_hyperram_o), + .tl_hyperram_i (tl_hyperram_i), + .tl_gpio0_o (tl_gpio_o[0]), + .tl_gpio0_i (tl_gpio_i[0]), + .tl_gpio1_o (tl_gpio_o[1]), + .tl_gpio1_i (tl_gpio_i[1]), + .tl_gpio2_o (tl_gpio_o[2]), + .tl_gpio2_i (tl_gpio_i[2]), + .tl_gpio3_o (tl_gpio_o[3]), + .tl_gpio3_i (tl_gpio_i[3]), + .tl_gpio4_o (tl_gpio_o[4]), + .tl_gpio4_i (tl_gpio_i[4]), + .tl_gpio5_o (tl_gpio_o[5]), + .tl_gpio5_i (tl_gpio_i[5]), + .tl_pwm_o (tl_pwm_o), + .tl_pwm_i (tl_pwm_i), + .tl_pinmux_o (tl_pinmux_o), + .tl_pinmux_i (tl_pinmux_i), + .tl_rgbled_ctrl_o (tl_rgbled_ctrl_o), + .tl_rgbled_ctrl_i (tl_rgbled_ctrl_i), + .tl_hw_rev_o (tl_hw_rev_o), + .tl_hw_rev_i (tl_hw_rev_i), .tl_xadc_o (tl_xadc_o), .tl_xadc_i (tl_xadc_i), - .tl_timer_o (tl_timer_o), - .tl_timer_i (tl_timer_i), - .tl_spi_lcd_i (tl_spi_lcd_i), - .tl_spi_lcd_o (tl_spi_lcd_o), - .tl_spi_ethmac_i (tl_spi_ethmac_i), - .tl_spi_ethmac_o (tl_spi_ethmac_o), - .tl_pwm0_o (tl_pwm_o[0]), - .tl_pwm0_i (tl_pwm_i[0]), + .tl_system_info_o (tl_system_info_o), + .tl_system_info_i (tl_system_info_i), + .tl_timer_o (tl_timer_o), + .tl_timer_i (tl_timer_i), .tl_uart0_o (tl_uart_o[0]), .tl_uart0_i (tl_uart_i[0]), .tl_uart1_o (tl_uart_o[1]), @@ -111,18 +117,22 @@ module sonata_xbar_main .tl_i2c0_i (tl_i2c_i[0]), .tl_i2c1_o (tl_i2c_o[1]), .tl_i2c1_i (tl_i2c_i[1]), + .tl_spi_lcd_o (tl_spi_lcd_o), + .tl_spi_lcd_i (tl_spi_lcd_i), + .tl_spi_ethmac_o (tl_spi_ethmac_o), + .tl_spi_ethmac_i (tl_spi_ethmac_i), .tl_spi0_o (tl_spi_o[0]), .tl_spi0_i (tl_spi_i[0]), .tl_spi1_o (tl_spi_o[1]), .tl_spi1_i (tl_spi_i[1]), .tl_spi2_o (tl_spi_o[2]), .tl_spi2_i (tl_spi_i[2]), - .tl_usbdev_o (tl_usbdev_o), - .tl_usbdev_i (tl_usbdev_i), - .tl_dbg_dev_o (tl_dbg_dev_o), - .tl_dbg_dev_i (tl_dbg_dev_i), - .tl_rv_plic_o (tl_rv_plic_o), - .tl_rv_plic_i (tl_rv_plic_i), + .tl_usbdev_o (tl_usbdev_o), + .tl_usbdev_i (tl_usbdev_i), + .tl_rv_plic_o (tl_rv_plic_o), + .tl_rv_plic_i (tl_rv_plic_i), + .tl_dbg_dev_o (tl_dbg_dev_o), + .tl_dbg_dev_i (tl_dbg_dev_i), .scanmode_i (prim_mubi_pkg::MuBi4False) ); diff --git a/rtl/bus/tl_main_pkg.sv b/rtl/bus/tl_main_pkg.sv index 2371e71eb..04558967e 100644 --- a/rtl/bus/tl_main_pkg.sv +++ b/rtl/bus/tl_main_pkg.sv @@ -7,83 +7,98 @@ package tl_main_pkg; localparam logic [31:0] ADDR_SPACE_SRAM = 32'h 00100000; - localparam logic [31:0] ADDR_SPACE_HYPERRAM = 32'h 40000000; localparam logic [31:0] ADDR_SPACE_REV_TAG = 32'h 30000000; - localparam logic [31:0] ADDR_SPACE_GPIO = 32'h 80000000; + localparam logic [31:0] ADDR_SPACE_HYPERRAM = 32'h 40000000; + localparam logic [31:0] ADDR_SPACE_GPIO0 = 32'h 80000000; + localparam logic [31:0] ADDR_SPACE_GPIO1 = 32'h 80000040; + localparam logic [31:0] ADDR_SPACE_GPIO2 = 32'h 80000080; + localparam logic [31:0] ADDR_SPACE_GPIO3 = 32'h 800000c0; + localparam logic [31:0] ADDR_SPACE_GPIO4 = 32'h 80000100; + localparam logic [31:0] ADDR_SPACE_GPIO5 = 32'h 80000140; + localparam logic [31:0] ADDR_SPACE_PWM = 32'h 80001000; localparam logic [31:0] ADDR_SPACE_PINMUX = 32'h 80005000; localparam logic [31:0] ADDR_SPACE_RGBLED_CTRL = 32'h 80009000; localparam logic [31:0] ADDR_SPACE_HW_REV = 32'h 8000a000; localparam logic [31:0] ADDR_SPACE_XADC = 32'h 8000b000; localparam logic [31:0] ADDR_SPACE_SYSTEM_INFO = 32'h 8000c000; localparam logic [31:0] ADDR_SPACE_TIMER = 32'h 80040000; - localparam logic [31:0] ADDR_SPACE_SPI_LCD = 32'h 80300000; - localparam logic [31:0] ADDR_SPACE_SPI_ETHMAC = 32'h 80301000; - localparam logic [31:0] ADDR_SPACE_PWM0 = 32'h 80001000; localparam logic [31:0] ADDR_SPACE_UART0 = 32'h 80100000; localparam logic [31:0] ADDR_SPACE_UART1 = 32'h 80101000; localparam logic [31:0] ADDR_SPACE_UART2 = 32'h 80102000; localparam logic [31:0] ADDR_SPACE_I2C0 = 32'h 80200000; localparam logic [31:0] ADDR_SPACE_I2C1 = 32'h 80201000; + localparam logic [31:0] ADDR_SPACE_SPI_LCD = 32'h 80300000; + localparam logic [31:0] ADDR_SPACE_SPI_ETHMAC = 32'h 80301000; localparam logic [31:0] ADDR_SPACE_SPI0 = 32'h 80302000; localparam logic [31:0] ADDR_SPACE_SPI1 = 32'h 80303000; localparam logic [31:0] ADDR_SPACE_SPI2 = 32'h 80304000; localparam logic [31:0] ADDR_SPACE_USBDEV = 32'h 80400000; - localparam logic [31:0] ADDR_SPACE_DBG_DEV = 32'h b0000000; localparam logic [31:0] ADDR_SPACE_RV_PLIC = 32'h 88000000; + localparam logic [31:0] ADDR_SPACE_DBG_DEV = 32'h b0000000; localparam logic [31:0] ADDR_MASK_SRAM = 32'h 0001ffff; - localparam logic [31:0] ADDR_MASK_HYPERRAM = 32'h 000fffff; localparam logic [31:0] ADDR_MASK_REV_TAG = 32'h 000007ff; - localparam logic [31:0] ADDR_MASK_GPIO = 32'h 00000fff; + localparam logic [31:0] ADDR_MASK_HYPERRAM = 32'h 000fffff; + localparam logic [31:0] ADDR_MASK_GPIO0 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_GPIO1 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_GPIO2 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_GPIO3 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_GPIO4 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_GPIO5 = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_PWM = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_PINMUX = 32'h 00000fff; - localparam logic [31:0] ADDR_MASK_RGBLED_CTRL = 32'h 00000fff; - localparam logic [31:0] ADDR_MASK_HW_REV = 32'h 00000fff; - localparam logic [31:0] ADDR_MASK_XADC = 32'h 00000fff; - localparam logic [31:0] ADDR_MASK_SYSTEM_INFO = 32'h 00000fff; + localparam logic [31:0] ADDR_MASK_RGBLED_CTRL = 32'h 0000000f; + localparam logic [31:0] ADDR_MASK_HW_REV = 32'h 0000001f; + localparam logic [31:0] ADDR_MASK_XADC = 32'h 0000007f; + localparam logic [31:0] ADDR_MASK_SYSTEM_INFO = 32'h 0000001f; localparam logic [31:0] ADDR_MASK_TIMER = 32'h 0000ffff; - localparam logic [31:0] ADDR_MASK_SPI_LCD = 32'h 00000fff; - localparam logic [31:0] ADDR_MASK_SPI_ETHMAC = 32'h 00000fff; - localparam logic [31:0] ADDR_MASK_PWM0 = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_UART0 = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_UART1 = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_UART2 = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_I2C0 = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_I2C1 = 32'h 00000fff; + localparam logic [31:0] ADDR_MASK_SPI_LCD = 32'h 0000003f; + localparam logic [31:0] ADDR_MASK_SPI_ETHMAC = 32'h 0000003f; localparam logic [31:0] ADDR_MASK_SPI0 = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_SPI1 = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_SPI2 = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_USBDEV = 32'h 00000fff; - localparam logic [31:0] ADDR_MASK_DBG_DEV = 32'h 00000fff; localparam logic [31:0] ADDR_MASK_RV_PLIC = 32'h 07ffffff; + localparam logic [31:0] ADDR_MASK_DBG_DEV = 32'h 00000fff; localparam int N_HOST = 2; - localparam int N_DEVICE = 24; + localparam int N_DEVICE = 29; typedef enum int { TlSram = 0, - TlHyperram = 1, - TlRevTag = 2, - TlGpio = 3, - TlPinmux = 4, - TlRgbledCtrl = 5, - TlHwRev = 6, - TlXadc = 7, - TlSystemInfo = 8, - TlTimer = 9, - TlSpiLcd = 10, - TlSpiEthmac = 11, - TlPwm0 = 12, - TlUart0 = 13, - TlUart1 = 14, - TlUart2 = 15, - TlI2C0 = 16, - TlI2C1 = 17, - TlSpi0 = 18, - TlSpi1 = 19, - TlSpi2 = 20, - TlUsbdev = 21, - TlDbgDev = 22, - TlRvPlic = 23 + TlRevTag = 1, + TlHyperram = 2, + TlGpio0 = 3, + TlGpio1 = 4, + TlGpio2 = 5, + TlGpio3 = 6, + TlGpio4 = 7, + TlGpio5 = 8, + TlPwm = 9, + TlPinmux = 10, + TlRgbledCtrl = 11, + TlHwRev = 12, + TlXadc = 13, + TlSystemInfo = 14, + TlTimer = 15, + TlUart0 = 16, + TlUart1 = 17, + TlUart2 = 18, + TlI2C0 = 19, + TlI2C1 = 20, + TlSpiLcd = 21, + TlSpiEthmac = 22, + TlSpi0 = 23, + TlSpi1 = 24, + TlSpi2 = 25, + TlUsbdev = 26, + TlRvPlic = 27, + TlDbgDev = 28 } tl_device_e; typedef enum int { diff --git a/rtl/bus/xbar_main.sv b/rtl/bus/xbar_main.sv index 0292d2030..2dac9d870 100644 --- a/rtl/bus/xbar_main.sv +++ b/rtl/bus/xbar_main.sv @@ -7,42 +7,47 @@ // // Interconnect // ibex_lsu -// -> s1n_26 -// -> sm1_27 +// -> s1n_31 +// -> sm1_32 // -> sram -// -> sm1_28 -// -> hyperram // -> rev_tag -// -> dbg_dev -// -> gpio +// -> sm1_33 +// -> hyperram +// -> gpio0 +// -> gpio1 +// -> gpio2 +// -> gpio3 +// -> gpio4 +// -> gpio5 +// -> pwm // -> pinmux -// -> sm1_29 -// -> system_info // -> rgbled_ctrl // -> hw_rev // -> xadc +// -> sm1_34 +// -> system_info // -> timer -// -> spi_lcd -// -> spi_ethmac -// -> pwm0 // -> uart0 // -> uart1 // -> uart2 // -> i2c0 // -> i2c1 +// -> spi_lcd +// -> spi_ethmac // -> spi0 // -> spi1 // -> spi2 -// -> asf_30 +// -> asf_35 // -> usbdev // -> rv_plic +// -> dbg_dev // dbg_host -// -> s1n_31 -// -> sm1_27 +// -> s1n_36 +// -> sm1_32 // -> sram -// -> sm1_28 +// -> sm1_33 // -> hyperram -// -> sm1_29 +// -> sm1_34 // -> system_info module xbar_main ( @@ -60,12 +65,24 @@ module xbar_main ( // Device interfaces output tlul_pkg::tl_h2d_t tl_sram_o, input tlul_pkg::tl_d2h_t tl_sram_i, - output tlul_pkg::tl_h2d_t tl_hyperram_o, - input tlul_pkg::tl_d2h_t tl_hyperram_i, output tlul_pkg::tl_h2d_t tl_rev_tag_o, input tlul_pkg::tl_d2h_t tl_rev_tag_i, - output tlul_pkg::tl_h2d_t tl_gpio_o, - input tlul_pkg::tl_d2h_t tl_gpio_i, + output tlul_pkg::tl_h2d_t tl_hyperram_o, + input tlul_pkg::tl_d2h_t tl_hyperram_i, + output tlul_pkg::tl_h2d_t tl_gpio0_o, + input tlul_pkg::tl_d2h_t tl_gpio0_i, + output tlul_pkg::tl_h2d_t tl_gpio1_o, + input tlul_pkg::tl_d2h_t tl_gpio1_i, + output tlul_pkg::tl_h2d_t tl_gpio2_o, + input tlul_pkg::tl_d2h_t tl_gpio2_i, + output tlul_pkg::tl_h2d_t tl_gpio3_o, + input tlul_pkg::tl_d2h_t tl_gpio3_i, + output tlul_pkg::tl_h2d_t tl_gpio4_o, + input tlul_pkg::tl_d2h_t tl_gpio4_i, + output tlul_pkg::tl_h2d_t tl_gpio5_o, + input tlul_pkg::tl_d2h_t tl_gpio5_i, + output tlul_pkg::tl_h2d_t tl_pwm_o, + input tlul_pkg::tl_d2h_t tl_pwm_i, output tlul_pkg::tl_h2d_t tl_pinmux_o, input tlul_pkg::tl_d2h_t tl_pinmux_i, output tlul_pkg::tl_h2d_t tl_rgbled_ctrl_o, @@ -78,12 +95,6 @@ module xbar_main ( input tlul_pkg::tl_d2h_t tl_system_info_i, output tlul_pkg::tl_h2d_t tl_timer_o, input tlul_pkg::tl_d2h_t tl_timer_i, - output tlul_pkg::tl_h2d_t tl_spi_lcd_o, - input tlul_pkg::tl_d2h_t tl_spi_lcd_i, - output tlul_pkg::tl_h2d_t tl_spi_ethmac_o, - input tlul_pkg::tl_d2h_t tl_spi_ethmac_i, - output tlul_pkg::tl_h2d_t tl_pwm0_o, - input tlul_pkg::tl_d2h_t tl_pwm0_i, output tlul_pkg::tl_h2d_t tl_uart0_o, input tlul_pkg::tl_d2h_t tl_uart0_i, output tlul_pkg::tl_h2d_t tl_uart1_o, @@ -94,6 +105,10 @@ module xbar_main ( input tlul_pkg::tl_d2h_t tl_i2c0_i, output tlul_pkg::tl_h2d_t tl_i2c1_o, input tlul_pkg::tl_d2h_t tl_i2c1_i, + output tlul_pkg::tl_h2d_t tl_spi_lcd_o, + input tlul_pkg::tl_d2h_t tl_spi_lcd_i, + output tlul_pkg::tl_h2d_t tl_spi_ethmac_o, + input tlul_pkg::tl_d2h_t tl_spi_ethmac_i, output tlul_pkg::tl_h2d_t tl_spi0_o, input tlul_pkg::tl_d2h_t tl_spi0_i, output tlul_pkg::tl_h2d_t tl_spi1_o, @@ -102,10 +117,10 @@ module xbar_main ( input tlul_pkg::tl_d2h_t tl_spi2_i, output tlul_pkg::tl_h2d_t tl_usbdev_o, input tlul_pkg::tl_d2h_t tl_usbdev_i, - output tlul_pkg::tl_h2d_t tl_dbg_dev_o, - input tlul_pkg::tl_d2h_t tl_dbg_dev_i, output tlul_pkg::tl_h2d_t tl_rv_plic_o, input tlul_pkg::tl_d2h_t tl_rv_plic_i, + output tlul_pkg::tl_h2d_t tl_dbg_dev_o, + input tlul_pkg::tl_d2h_t tl_dbg_dev_i, input prim_mubi_pkg::mubi4_t scanmode_i ); @@ -118,268 +133,303 @@ module xbar_main ( logic unused_scanmode; assign unused_scanmode = ^scanmode_i; - tl_h2d_t tl_s1n_26_us_h2d ; - tl_d2h_t tl_s1n_26_us_d2h ; + tl_h2d_t tl_s1n_31_us_h2d ; + tl_d2h_t tl_s1n_31_us_d2h ; - tl_h2d_t tl_s1n_26_ds_h2d [24]; - tl_d2h_t tl_s1n_26_ds_d2h [24]; + tl_h2d_t tl_s1n_31_ds_h2d [29]; + tl_d2h_t tl_s1n_31_ds_d2h [29]; // Create steering signal - logic [4:0] dev_sel_s1n_26; + logic [4:0] dev_sel_s1n_31; - tl_h2d_t tl_sm1_27_us_h2d [2]; - tl_d2h_t tl_sm1_27_us_d2h [2]; + tl_h2d_t tl_sm1_32_us_h2d [2]; + tl_d2h_t tl_sm1_32_us_d2h [2]; - tl_h2d_t tl_sm1_27_ds_h2d ; - tl_d2h_t tl_sm1_27_ds_d2h ; + tl_h2d_t tl_sm1_32_ds_h2d ; + tl_d2h_t tl_sm1_32_ds_d2h ; - tl_h2d_t tl_sm1_28_us_h2d [2]; - tl_d2h_t tl_sm1_28_us_d2h [2]; + tl_h2d_t tl_sm1_33_us_h2d [2]; + tl_d2h_t tl_sm1_33_us_d2h [2]; - tl_h2d_t tl_sm1_28_ds_h2d ; - tl_d2h_t tl_sm1_28_ds_d2h ; + tl_h2d_t tl_sm1_33_ds_h2d ; + tl_d2h_t tl_sm1_33_ds_d2h ; - tl_h2d_t tl_sm1_29_us_h2d [2]; - tl_d2h_t tl_sm1_29_us_d2h [2]; + tl_h2d_t tl_sm1_34_us_h2d [2]; + tl_d2h_t tl_sm1_34_us_d2h [2]; - tl_h2d_t tl_sm1_29_ds_h2d ; - tl_d2h_t tl_sm1_29_ds_d2h ; + tl_h2d_t tl_sm1_34_ds_h2d ; + tl_d2h_t tl_sm1_34_ds_d2h ; - tl_h2d_t tl_asf_30_us_h2d ; - tl_d2h_t tl_asf_30_us_d2h ; - tl_h2d_t tl_asf_30_ds_h2d ; - tl_d2h_t tl_asf_30_ds_d2h ; + tl_h2d_t tl_asf_35_us_h2d ; + tl_d2h_t tl_asf_35_us_d2h ; + tl_h2d_t tl_asf_35_ds_h2d ; + tl_d2h_t tl_asf_35_ds_d2h ; - tl_h2d_t tl_s1n_31_us_h2d ; - tl_d2h_t tl_s1n_31_us_d2h ; + tl_h2d_t tl_s1n_36_us_h2d ; + tl_d2h_t tl_s1n_36_us_d2h ; - tl_h2d_t tl_s1n_31_ds_h2d [3]; - tl_d2h_t tl_s1n_31_ds_d2h [3]; + tl_h2d_t tl_s1n_36_ds_h2d [3]; + tl_d2h_t tl_s1n_36_ds_d2h [3]; // Create steering signal - logic [1:0] dev_sel_s1n_31; + logic [1:0] dev_sel_s1n_36; + + assign tl_sm1_32_us_h2d[0] = tl_s1n_31_ds_h2d[0]; + assign tl_s1n_31_ds_d2h[0] = tl_sm1_32_us_d2h[0]; - assign tl_sm1_27_us_h2d[0] = tl_s1n_26_ds_h2d[0]; - assign tl_s1n_26_ds_d2h[0] = tl_sm1_27_us_d2h[0]; + assign tl_rev_tag_o = tl_s1n_31_ds_h2d[1]; + assign tl_s1n_31_ds_d2h[1] = tl_rev_tag_i; - assign tl_sm1_28_us_h2d[0] = tl_s1n_26_ds_h2d[1]; - assign tl_s1n_26_ds_d2h[1] = tl_sm1_28_us_d2h[0]; + assign tl_sm1_33_us_h2d[0] = tl_s1n_31_ds_h2d[2]; + assign tl_s1n_31_ds_d2h[2] = tl_sm1_33_us_d2h[0]; - assign tl_rev_tag_o = tl_s1n_26_ds_h2d[2]; - assign tl_s1n_26_ds_d2h[2] = tl_rev_tag_i; + assign tl_gpio0_o = tl_s1n_31_ds_h2d[3]; + assign tl_s1n_31_ds_d2h[3] = tl_gpio0_i; - assign tl_dbg_dev_o = tl_s1n_26_ds_h2d[3]; - assign tl_s1n_26_ds_d2h[3] = tl_dbg_dev_i; + assign tl_gpio1_o = tl_s1n_31_ds_h2d[4]; + assign tl_s1n_31_ds_d2h[4] = tl_gpio1_i; - assign tl_gpio_o = tl_s1n_26_ds_h2d[4]; - assign tl_s1n_26_ds_d2h[4] = tl_gpio_i; + assign tl_gpio2_o = tl_s1n_31_ds_h2d[5]; + assign tl_s1n_31_ds_d2h[5] = tl_gpio2_i; - assign tl_pinmux_o = tl_s1n_26_ds_h2d[5]; - assign tl_s1n_26_ds_d2h[5] = tl_pinmux_i; + assign tl_gpio3_o = tl_s1n_31_ds_h2d[6]; + assign tl_s1n_31_ds_d2h[6] = tl_gpio3_i; - assign tl_sm1_29_us_h2d[0] = tl_s1n_26_ds_h2d[6]; - assign tl_s1n_26_ds_d2h[6] = tl_sm1_29_us_d2h[0]; + assign tl_gpio4_o = tl_s1n_31_ds_h2d[7]; + assign tl_s1n_31_ds_d2h[7] = tl_gpio4_i; - assign tl_rgbled_ctrl_o = tl_s1n_26_ds_h2d[7]; - assign tl_s1n_26_ds_d2h[7] = tl_rgbled_ctrl_i; + assign tl_gpio5_o = tl_s1n_31_ds_h2d[8]; + assign tl_s1n_31_ds_d2h[8] = tl_gpio5_i; - assign tl_hw_rev_o = tl_s1n_26_ds_h2d[8]; - assign tl_s1n_26_ds_d2h[8] = tl_hw_rev_i; + assign tl_pwm_o = tl_s1n_31_ds_h2d[9]; + assign tl_s1n_31_ds_d2h[9] = tl_pwm_i; - assign tl_xadc_o = tl_s1n_26_ds_h2d[9]; - assign tl_s1n_26_ds_d2h[9] = tl_xadc_i; + assign tl_pinmux_o = tl_s1n_31_ds_h2d[10]; + assign tl_s1n_31_ds_d2h[10] = tl_pinmux_i; - assign tl_timer_o = tl_s1n_26_ds_h2d[10]; - assign tl_s1n_26_ds_d2h[10] = tl_timer_i; + assign tl_rgbled_ctrl_o = tl_s1n_31_ds_h2d[11]; + assign tl_s1n_31_ds_d2h[11] = tl_rgbled_ctrl_i; - assign tl_spi_lcd_o = tl_s1n_26_ds_h2d[11]; - assign tl_s1n_26_ds_d2h[11] = tl_spi_lcd_i; + assign tl_hw_rev_o = tl_s1n_31_ds_h2d[12]; + assign tl_s1n_31_ds_d2h[12] = tl_hw_rev_i; - assign tl_spi_ethmac_o = tl_s1n_26_ds_h2d[12]; - assign tl_s1n_26_ds_d2h[12] = tl_spi_ethmac_i; + assign tl_xadc_o = tl_s1n_31_ds_h2d[13]; + assign tl_s1n_31_ds_d2h[13] = tl_xadc_i; - assign tl_pwm0_o = tl_s1n_26_ds_h2d[13]; - assign tl_s1n_26_ds_d2h[13] = tl_pwm0_i; + assign tl_sm1_34_us_h2d[0] = tl_s1n_31_ds_h2d[14]; + assign tl_s1n_31_ds_d2h[14] = tl_sm1_34_us_d2h[0]; - assign tl_uart0_o = tl_s1n_26_ds_h2d[14]; - assign tl_s1n_26_ds_d2h[14] = tl_uart0_i; + assign tl_timer_o = tl_s1n_31_ds_h2d[15]; + assign tl_s1n_31_ds_d2h[15] = tl_timer_i; - assign tl_uart1_o = tl_s1n_26_ds_h2d[15]; - assign tl_s1n_26_ds_d2h[15] = tl_uart1_i; + assign tl_uart0_o = tl_s1n_31_ds_h2d[16]; + assign tl_s1n_31_ds_d2h[16] = tl_uart0_i; - assign tl_uart2_o = tl_s1n_26_ds_h2d[16]; - assign tl_s1n_26_ds_d2h[16] = tl_uart2_i; + assign tl_uart1_o = tl_s1n_31_ds_h2d[17]; + assign tl_s1n_31_ds_d2h[17] = tl_uart1_i; - assign tl_i2c0_o = tl_s1n_26_ds_h2d[17]; - assign tl_s1n_26_ds_d2h[17] = tl_i2c0_i; + assign tl_uart2_o = tl_s1n_31_ds_h2d[18]; + assign tl_s1n_31_ds_d2h[18] = tl_uart2_i; - assign tl_i2c1_o = tl_s1n_26_ds_h2d[18]; - assign tl_s1n_26_ds_d2h[18] = tl_i2c1_i; + assign tl_i2c0_o = tl_s1n_31_ds_h2d[19]; + assign tl_s1n_31_ds_d2h[19] = tl_i2c0_i; - assign tl_spi0_o = tl_s1n_26_ds_h2d[19]; - assign tl_s1n_26_ds_d2h[19] = tl_spi0_i; + assign tl_i2c1_o = tl_s1n_31_ds_h2d[20]; + assign tl_s1n_31_ds_d2h[20] = tl_i2c1_i; - assign tl_spi1_o = tl_s1n_26_ds_h2d[20]; - assign tl_s1n_26_ds_d2h[20] = tl_spi1_i; + assign tl_spi_lcd_o = tl_s1n_31_ds_h2d[21]; + assign tl_s1n_31_ds_d2h[21] = tl_spi_lcd_i; - assign tl_spi2_o = tl_s1n_26_ds_h2d[21]; - assign tl_s1n_26_ds_d2h[21] = tl_spi2_i; + assign tl_spi_ethmac_o = tl_s1n_31_ds_h2d[22]; + assign tl_s1n_31_ds_d2h[22] = tl_spi_ethmac_i; - assign tl_asf_30_us_h2d = tl_s1n_26_ds_h2d[22]; - assign tl_s1n_26_ds_d2h[22] = tl_asf_30_us_d2h; + assign tl_spi0_o = tl_s1n_31_ds_h2d[23]; + assign tl_s1n_31_ds_d2h[23] = tl_spi0_i; - assign tl_rv_plic_o = tl_s1n_26_ds_h2d[23]; - assign tl_s1n_26_ds_d2h[23] = tl_rv_plic_i; + assign tl_spi1_o = tl_s1n_31_ds_h2d[24]; + assign tl_s1n_31_ds_d2h[24] = tl_spi1_i; - assign tl_sm1_27_us_h2d[1] = tl_s1n_31_ds_h2d[0]; - assign tl_s1n_31_ds_d2h[0] = tl_sm1_27_us_d2h[1]; + assign tl_spi2_o = tl_s1n_31_ds_h2d[25]; + assign tl_s1n_31_ds_d2h[25] = tl_spi2_i; - assign tl_sm1_28_us_h2d[1] = tl_s1n_31_ds_h2d[1]; - assign tl_s1n_31_ds_d2h[1] = tl_sm1_28_us_d2h[1]; + assign tl_asf_35_us_h2d = tl_s1n_31_ds_h2d[26]; + assign tl_s1n_31_ds_d2h[26] = tl_asf_35_us_d2h; - assign tl_sm1_29_us_h2d[1] = tl_s1n_31_ds_h2d[2]; - assign tl_s1n_31_ds_d2h[2] = tl_sm1_29_us_d2h[1]; + assign tl_rv_plic_o = tl_s1n_31_ds_h2d[27]; + assign tl_s1n_31_ds_d2h[27] = tl_rv_plic_i; - assign tl_s1n_26_us_h2d = tl_ibex_lsu_i; - assign tl_ibex_lsu_o = tl_s1n_26_us_d2h; + assign tl_dbg_dev_o = tl_s1n_31_ds_h2d[28]; + assign tl_s1n_31_ds_d2h[28] = tl_dbg_dev_i; - assign tl_sram_o = tl_sm1_27_ds_h2d; - assign tl_sm1_27_ds_d2h = tl_sram_i; + assign tl_sm1_32_us_h2d[1] = tl_s1n_36_ds_h2d[0]; + assign tl_s1n_36_ds_d2h[0] = tl_sm1_32_us_d2h[1]; - assign tl_hyperram_o = tl_sm1_28_ds_h2d; - assign tl_sm1_28_ds_d2h = tl_hyperram_i; + assign tl_sm1_33_us_h2d[1] = tl_s1n_36_ds_h2d[1]; + assign tl_s1n_36_ds_d2h[1] = tl_sm1_33_us_d2h[1]; - assign tl_system_info_o = tl_sm1_29_ds_h2d; - assign tl_sm1_29_ds_d2h = tl_system_info_i; + assign tl_sm1_34_us_h2d[1] = tl_s1n_36_ds_h2d[2]; + assign tl_s1n_36_ds_d2h[2] = tl_sm1_34_us_d2h[1]; - assign tl_usbdev_o = tl_asf_30_ds_h2d; - assign tl_asf_30_ds_d2h = tl_usbdev_i; + assign tl_s1n_31_us_h2d = tl_ibex_lsu_i; + assign tl_ibex_lsu_o = tl_s1n_31_us_d2h; - assign tl_s1n_31_us_h2d = tl_dbg_host_i; - assign tl_dbg_host_o = tl_s1n_31_us_d2h; + assign tl_sram_o = tl_sm1_32_ds_h2d; + assign tl_sm1_32_ds_d2h = tl_sram_i; + + assign tl_hyperram_o = tl_sm1_33_ds_h2d; + assign tl_sm1_33_ds_d2h = tl_hyperram_i; + + assign tl_system_info_o = tl_sm1_34_ds_h2d; + assign tl_sm1_34_ds_d2h = tl_system_info_i; + + assign tl_usbdev_o = tl_asf_35_ds_h2d; + assign tl_asf_35_ds_d2h = tl_usbdev_i; + + assign tl_s1n_36_us_h2d = tl_dbg_host_i; + assign tl_dbg_host_o = tl_s1n_36_us_d2h; always_comb begin // default steering to generate error response if address is not within the range - dev_sel_s1n_26 = 5'd24; - if ((tl_s1n_26_us_h2d.a_address & + dev_sel_s1n_31 = 5'd29; + if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_SRAM)) == ADDR_SPACE_SRAM) begin - dev_sel_s1n_26 = 5'd0; + dev_sel_s1n_31 = 5'd0; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_REV_TAG)) == ADDR_SPACE_REV_TAG) begin + dev_sel_s1n_31 = 5'd1; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_HYPERRAM)) == ADDR_SPACE_HYPERRAM) begin - dev_sel_s1n_26 = 5'd1; + dev_sel_s1n_31 = 5'd2; - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_REV_TAG)) == ADDR_SPACE_REV_TAG) begin - dev_sel_s1n_26 = 5'd2; + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO0)) == ADDR_SPACE_GPIO0) begin + dev_sel_s1n_31 = 5'd3; - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_DBG_DEV)) == ADDR_SPACE_DBG_DEV) begin - dev_sel_s1n_26 = 5'd3; + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO1)) == ADDR_SPACE_GPIO1) begin + dev_sel_s1n_31 = 5'd4; - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_GPIO)) == ADDR_SPACE_GPIO) begin - dev_sel_s1n_26 = 5'd4; + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO2)) == ADDR_SPACE_GPIO2) begin + dev_sel_s1n_31 = 5'd5; - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_PINMUX)) == ADDR_SPACE_PINMUX) begin - dev_sel_s1n_26 = 5'd5; + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO3)) == ADDR_SPACE_GPIO3) begin + dev_sel_s1n_31 = 5'd6; - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_SYSTEM_INFO)) == ADDR_SPACE_SYSTEM_INFO) begin - dev_sel_s1n_26 = 5'd6; + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO4)) == ADDR_SPACE_GPIO4) begin + dev_sel_s1n_31 = 5'd7; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO5)) == ADDR_SPACE_GPIO5) begin + dev_sel_s1n_31 = 5'd8; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_PWM)) == ADDR_SPACE_PWM) begin + dev_sel_s1n_31 = 5'd9; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_PINMUX)) == ADDR_SPACE_PINMUX) begin + dev_sel_s1n_31 = 5'd10; + + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_RGBLED_CTRL)) == ADDR_SPACE_RGBLED_CTRL) begin - dev_sel_s1n_26 = 5'd7; + dev_sel_s1n_31 = 5'd11; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_HW_REV)) == ADDR_SPACE_HW_REV) begin - dev_sel_s1n_26 = 5'd8; + dev_sel_s1n_31 = 5'd12; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_XADC)) == ADDR_SPACE_XADC) begin - dev_sel_s1n_26 = 5'd9; - - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_TIMER)) == ADDR_SPACE_TIMER) begin - dev_sel_s1n_26 = 5'd10; - - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_SPI_LCD)) == ADDR_SPACE_SPI_LCD) begin - dev_sel_s1n_26 = 5'd11; + dev_sel_s1n_31 = 5'd13; - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_SPI_ETHMAC)) == ADDR_SPACE_SPI_ETHMAC) begin - dev_sel_s1n_26 = 5'd12; + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_SYSTEM_INFO)) == ADDR_SPACE_SYSTEM_INFO) begin + dev_sel_s1n_31 = 5'd14; - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_PWM0)) == ADDR_SPACE_PWM0) begin - dev_sel_s1n_26 = 5'd13; + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_TIMER)) == ADDR_SPACE_TIMER) begin + dev_sel_s1n_31 = 5'd15; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_UART0)) == ADDR_SPACE_UART0) begin - dev_sel_s1n_26 = 5'd14; + dev_sel_s1n_31 = 5'd16; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_UART1)) == ADDR_SPACE_UART1) begin - dev_sel_s1n_26 = 5'd15; + dev_sel_s1n_31 = 5'd17; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_UART2)) == ADDR_SPACE_UART2) begin - dev_sel_s1n_26 = 5'd16; + dev_sel_s1n_31 = 5'd18; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_I2C0)) == ADDR_SPACE_I2C0) begin - dev_sel_s1n_26 = 5'd17; + dev_sel_s1n_31 = 5'd19; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_I2C1)) == ADDR_SPACE_I2C1) begin - dev_sel_s1n_26 = 5'd18; + dev_sel_s1n_31 = 5'd20; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_SPI_LCD)) == ADDR_SPACE_SPI_LCD) begin + dev_sel_s1n_31 = 5'd21; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_SPI_ETHMAC)) == ADDR_SPACE_SPI_ETHMAC) begin + dev_sel_s1n_31 = 5'd22; + + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_SPI0)) == ADDR_SPACE_SPI0) begin - dev_sel_s1n_26 = 5'd19; + dev_sel_s1n_31 = 5'd23; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_SPI1)) == ADDR_SPACE_SPI1) begin - dev_sel_s1n_26 = 5'd20; + dev_sel_s1n_31 = 5'd24; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_SPI2)) == ADDR_SPACE_SPI2) begin - dev_sel_s1n_26 = 5'd21; + dev_sel_s1n_31 = 5'd25; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_USBDEV)) == ADDR_SPACE_USBDEV) begin - dev_sel_s1n_26 = 5'd22; + dev_sel_s1n_31 = 5'd26; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_RV_PLIC)) == ADDR_SPACE_RV_PLIC) begin - dev_sel_s1n_26 = 5'd23; + dev_sel_s1n_31 = 5'd27; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_DBG_DEV)) == ADDR_SPACE_DBG_DEV) begin + dev_sel_s1n_31 = 5'd28; end end always_comb begin // default steering to generate error response if address is not within the range - dev_sel_s1n_31 = 2'd3; - if ((tl_s1n_31_us_h2d.a_address & + dev_sel_s1n_36 = 2'd3; + if ((tl_s1n_36_us_h2d.a_address & ~(ADDR_MASK_SRAM)) == ADDR_SPACE_SRAM) begin - dev_sel_s1n_31 = 2'd0; + dev_sel_s1n_36 = 2'd0; - end else if ((tl_s1n_31_us_h2d.a_address & + end else if ((tl_s1n_36_us_h2d.a_address & ~(ADDR_MASK_HYPERRAM)) == ADDR_SPACE_HYPERRAM) begin - dev_sel_s1n_31 = 2'd1; + dev_sel_s1n_36 = 2'd1; - end else if ((tl_s1n_31_us_h2d.a_address & + end else if ((tl_s1n_36_us_h2d.a_address & ~(ADDR_MASK_SYSTEM_INFO)) == ADDR_SPACE_SYSTEM_INFO) begin - dev_sel_s1n_31 = 2'd2; + dev_sel_s1n_36 = 2'd2; end end @@ -388,19 +438,19 @@ end tlul_socket_1n #( .HReqDepth (4'h0), .HRspDepth (4'h0), - .DReqPass (24'h781d47), - .DRspPass (24'h781d47), - .DReqDepth (96'h100001111110001010111000), - .DRspDepth (96'h100001111110001010111000), - .N (24) - ) u_s1n_26 ( + .DReqPass (29'h7e0d007), + .DRspPass (29'h7e0d007), + .DReqDepth (116'h11000000111110010111111111000), + .DRspDepth (116'h11000000111110010111111111000), + .N (29) + ) u_s1n_31 ( .clk_i (clk_sys_i), .rst_ni (rst_sys_ni), - .tl_h_i (tl_s1n_26_us_h2d), - .tl_h_o (tl_s1n_26_us_d2h), - .tl_d_o (tl_s1n_26_ds_h2d), - .tl_d_i (tl_s1n_26_ds_d2h), - .dev_select_i (dev_sel_s1n_26) + .tl_h_i (tl_s1n_31_us_h2d), + .tl_h_o (tl_s1n_31_us_d2h), + .tl_d_o (tl_s1n_31_ds_h2d), + .tl_d_i (tl_s1n_31_ds_d2h), + .dev_select_i (dev_sel_s1n_31) ); tlul_socket_m1 #( .HReqDepth (8'h0), @@ -408,13 +458,13 @@ end .DReqDepth (4'h0), .DRspDepth (4'h0), .M (2) - ) u_sm1_27 ( + ) u_sm1_32 ( .clk_i (clk_sys_i), .rst_ni (rst_sys_ni), - .tl_h_i (tl_sm1_27_us_h2d), - .tl_h_o (tl_sm1_27_us_d2h), - .tl_d_o (tl_sm1_27_ds_h2d), - .tl_d_i (tl_sm1_27_ds_d2h) + .tl_h_i (tl_sm1_32_us_h2d), + .tl_h_o (tl_sm1_32_us_d2h), + .tl_d_o (tl_sm1_32_ds_h2d), + .tl_d_i (tl_sm1_32_ds_d2h) ); tlul_socket_m1 #( .HReqDepth (8'h0), @@ -422,13 +472,13 @@ end .DReqDepth (4'h0), .DRspDepth (4'h0), .M (2) - ) u_sm1_28 ( + ) u_sm1_33 ( .clk_i (clk_sys_i), .rst_ni (rst_sys_ni), - .tl_h_i (tl_sm1_28_us_h2d), - .tl_h_o (tl_sm1_28_us_d2h), - .tl_d_o (tl_sm1_28_ds_h2d), - .tl_d_i (tl_sm1_28_ds_d2h) + .tl_h_i (tl_sm1_33_us_h2d), + .tl_h_o (tl_sm1_33_us_d2h), + .tl_d_o (tl_sm1_33_ds_h2d), + .tl_d_i (tl_sm1_33_ds_d2h) ); tlul_socket_m1 #( .HReqDepth (8'h0), @@ -436,26 +486,26 @@ end .DReqDepth (4'h0), .DRspDepth (4'h0), .M (2) - ) u_sm1_29 ( + ) u_sm1_34 ( .clk_i (clk_sys_i), .rst_ni (rst_sys_ni), - .tl_h_i (tl_sm1_29_us_h2d), - .tl_h_o (tl_sm1_29_us_d2h), - .tl_d_o (tl_sm1_29_ds_h2d), - .tl_d_i (tl_sm1_29_ds_d2h) + .tl_h_i (tl_sm1_34_us_h2d), + .tl_h_o (tl_sm1_34_us_d2h), + .tl_d_o (tl_sm1_34_ds_h2d), + .tl_d_i (tl_sm1_34_ds_d2h) ); tlul_fifo_async #( .ReqDepth (1), .RspDepth (1) - ) u_asf_30 ( + ) u_asf_35 ( .clk_h_i (clk_sys_i), .rst_h_ni (rst_sys_ni), .clk_d_i (clk_usb_i), .rst_d_ni (rst_usb_ni), - .tl_h_i (tl_asf_30_us_h2d), - .tl_h_o (tl_asf_30_us_d2h), - .tl_d_o (tl_asf_30_ds_h2d), - .tl_d_i (tl_asf_30_ds_d2h) + .tl_h_i (tl_asf_35_us_h2d), + .tl_h_o (tl_asf_35_us_d2h), + .tl_d_o (tl_asf_35_ds_h2d), + .tl_d_i (tl_asf_35_ds_d2h) ); tlul_socket_1n #( .HReqPass (1'b0), @@ -463,14 +513,14 @@ end .DReqDepth (12'h0), .DRspDepth (12'h0), .N (3) - ) u_s1n_31 ( + ) u_s1n_36 ( .clk_i (clk_sys_i), .rst_ni (rst_sys_ni), - .tl_h_i (tl_s1n_31_us_h2d), - .tl_h_o (tl_s1n_31_us_d2h), - .tl_d_o (tl_s1n_31_ds_h2d), - .tl_d_i (tl_s1n_31_ds_d2h), - .dev_select_i (dev_sel_s1n_31) + .tl_h_i (tl_s1n_36_us_h2d), + .tl_h_o (tl_s1n_36_us_d2h), + .tl_d_o (tl_s1n_36_ds_h2d), + .tl_d_i (tl_s1n_36_ds_d2h), + .dev_select_i (dev_sel_s1n_36) ); endmodule diff --git a/rtl/ip/gpio/data/gpio.rdl b/rtl/ip/gpio/data/gpio.rdl new file mode 100644 index 000000000..cab7504f5 --- /dev/null +++ b/rtl/ip/gpio/data/gpio.rdl @@ -0,0 +1,65 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap gpio #( + longint num_pads = 32 +){ + + xbar = '{ + parameter'{ type_: "bool", name: "pipeline", value: "true" }, + parameter'{ type_: "bool", name: "req_fifo_pass", value: "false" }, + parameter'{ type_: "bool", name: "rsp_fifo_pass", value: "false" } + }; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + // Ios pads. + signal {sigtype=SigType::PadInOut; io_combine=IoCombine::Mux; } ios[num_pads]; + // signal {sigtype=SigType::PadInOut; io_combine=IoCombine::Mux; } ios_rpi[32]; + // signal {sigtype=SigType::PadInOut; io_combine=IoCombine::Mux; } ios_arduino[32]; + // signal {sigtype=SigType::PadInOut; io_combine=IoCombine::Mux; } ios_pmod0[32]; + // signal {sigtype=SigType::PadInOut; io_combine=IoCombine::Mux; } ios_pmod1[32]; + // signal {sigtype=SigType::PadInOut; io_combine=IoCombine::Mux; } ios_pmodc[32]; + + addrmap gpio_spec_t { + reg { + field { + sw=w; + reset = 0; + desc = "Pins."; + } PINS[32] = 0; + } OUT @0x0000; + + reg { + field { + sw=r; + reset = 0; + desc = "Pins."; + } PINS[32] = 0; + } IN @0x0004; + + reg { + field { + sw=r; + reset = 0; + desc = "DBNC."; + } PINS[32] = 0; + } IN_DBNC @0x0008; + + reg { + field { + sw=rw; + reset = 0; + desc = "val"; + } PINS[32] = 0; + } OUTPUT_ENABLE @0x000c; + }; + + gpio_spec_t gpio; + // gpio_spec_t gpio_rpi; + // gpio_spec_t gpio_arduino; + // gpio_spec_t gpio_pmod[2]; + // gpio_spec_t gpio_pmodc; +}; diff --git a/rtl/ip/gpio/rtl/gpio.sv b/rtl/ip/gpio/rtl/gpio.sv index 027639437..6ec20c1fa 100644 --- a/rtl/ip/gpio/rtl/gpio.sv +++ b/rtl/ip/gpio/rtl/gpio.sv @@ -13,8 +13,8 @@ module gpio #( input logic clk_i, input logic rst_ni, - input tlul_pkg::tl_h2d_t tl_i, - output tlul_pkg::tl_d2h_t tl_o, + input tlul_pkg::tl_h2d_t tl_i[NumInstances], + output tlul_pkg::tl_d2h_t tl_o[NumInstances], input logic [GpiMaxWidth-1:0] gp_i[NumInstances], output logic [GpoMaxWidth-1:0] gp_o[NumInstances], @@ -22,31 +22,21 @@ module gpio #( output logic pcint_o[NumInstances] ); - localparam int unsigned NumBytesPerInstance = 16 * DataWidth/8; - localparam int unsigned AddrBitsPerInstance = $clog2(NumBytesPerInstance); - localparam int unsigned AddrBitsInstanceIdx = $clog2(NumInstances); - localparam int unsigned RegAddrWidth = AddrBitsInstanceIdx + AddrBitsPerInstance; - logic device_req; - logic [RegAddrWidth-1:0] device_addr; - logic device_re; // Read enable. - logic device_we; // Write enable. - logic [3:0] device_be; - logic [DataWidth-1:0] device_wdata; - logic [DataWidth-1:0] device_rdata; - - logic inst_req[NumInstances]; - logic [DataWidth-1:0] inst_rdata[NumInstances]; - - logic [AddrBitsInstanceIdx-1:0] selected_inst_idx; + for (genvar inst_idx = 0; inst_idx < NumInstances; inst_idx++) begin : gen_gpio_core + localparam int unsigned NumBytesPerInstance = 16 * DataWidth/8; + localparam int unsigned AddrBitsPerInstance = $clog2(NumBytesPerInstance); + localparam int unsigned RegAddrWidth = AddrBitsPerInstance; - assign device_req = device_re | device_we; + logic device_req; + logic [RegAddrWidth-1:0] device_addr; + logic device_re; // Read enable. + logic device_we; // Write enable. + logic [3:0] device_be; + logic [DataWidth-1:0] device_wdata; + logic [DataWidth-1:0] device_rdata; - // Route req based on the high bits of the request address - assign selected_inst_idx = device_addr[RegAddrWidth-1:AddrBitsPerInstance]; - - for (genvar inst_idx = 0; inst_idx < NumInstances; inst_idx++) begin : gen_gpio_core - assign inst_req[inst_idx] = (selected_inst_idx == inst_idx) && device_req; + assign device_req = device_re | device_we; gpio_core #( .GpiWidth ( GpiInstWidths[inst_idx] ), @@ -56,52 +46,43 @@ module gpio #( ) u_gpio_inst ( .clk_i, .rst_ni, - .device_req_i(inst_req[inst_idx]), + .device_req_i(device_req), .device_addr_i(device_addr[AddrBitsPerInstance-1:0]), .device_we_i(device_we), .device_be_i(device_be), .device_wdata_i(device_wdata), - .device_rdata_o(inst_rdata[inst_idx]), + .device_rdata_o(device_rdata), .gp_i(gp_i[inst_idx][GpiInstWidths[inst_idx]-1:0]), .gp_o(gp_o[inst_idx][GpoInstWidths[inst_idx]-1:0]), .gp_o_en(gp_o_en[inst_idx][GpoInstWidths[inst_idx]-1:0]), .pcint_o(pcint_o[inst_idx]) ); - end - - // Merge read data from all instances using a bitwise OR. - // Instance rdata outputs are all-zeroes unless they have a valid request. - always_comb begin - device_rdata = 'b0; - for (integer inst_idx = 0; inst_idx < NumInstances; inst_idx++) begin - device_rdata |= inst_rdata[inst_idx]; - end - end - - tlul_adapter_reg #( - .AccessLatency ( 0 ), - .RegAw ( RegAddrWidth ), - .RegDw ( DataWidth ) - ) gpio_device_adapter ( - .clk_i, - .rst_ni, - // TL-UL interface. - .tl_i, - .tl_o, - - // Control interface. - .en_ifetch_i (prim_mubi_pkg::MuBi4False), - .intg_error_o (), + tlul_adapter_reg #( + .AccessLatency ( 0 ), + .RegAw ( RegAddrWidth ), + .RegDw ( DataWidth ) + ) gpio_device_adapter ( + .clk_i, + .rst_ni, - // Register interface. - .re_o (device_re), - .we_o (device_we), - .addr_o (device_addr), - .wdata_o (device_wdata), - .be_o (device_be), - .busy_i (1'b0), - .rdata_i (device_rdata), - .error_i (1'b0) - ); + // TL-UL interface. + .tl_i(tl_i[inst_idx]), + .tl_o(tl_o[inst_idx]), + + // Control interface. + .en_ifetch_i (prim_mubi_pkg::MuBi4False), + .intg_error_o (), + + // Register interface. + .re_o (device_re), + .we_o (device_we), + .addr_o (device_addr), + .wdata_o (device_wdata), + .be_o (device_be), + .busy_i (1'b0), + .rdata_i (device_rdata), + .error_i (1'b0) + ); + end endmodule diff --git a/rtl/ip/i2c/data/i2c.rdl b/rtl/ip/i2c/data/i2c.rdl new file mode 100644 index 000000000..6053780aa --- /dev/null +++ b/rtl/ip/i2c/data/i2c.rdl @@ -0,0 +1,985 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap i2c #( + longint FifoDepth = 8, + longint AcqFifoDepth = 8, + longint NumAlerts = 1 +){ + xbar = '{ + parameter'{ type_: "bool", name: "pipeline", value: "true" }, + parameter'{ type_: "bool", name: "req_fifo_pass", value: "false" }, + parameter'{ type_: "bool", name: "rsp_fifo_pass", value: "false" } + }; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + signal { + desc = "Raised when Format FIFO reaches threshold"; + sigtype=SigType::Interrupt; + }format_fifo_threshold; + signal { + desc = "Raised when Receive FIFO reaches threshold"; + sigtype=SigType::Interrupt; + }receive_fifo_threshold; + signal { + desc = "Raised when Acquire FIFO reaches threshold"; + sigtype=SigType::Interrupt; + }acquire_fifo_threshold; + signal { + desc = "Raised when Receive FIFO overflows"; + sigtype=SigType::Interrupt; + }receive_fifo_overflow; + signal { + desc = "Raised when NACK is received"; + sigtype=SigType::Interrupt; + }received_nack; + signal { + desc = "Raised when SCL interference detected"; + sigtype=SigType::Interrupt; + }scl_interference; + signal { + desc = "Raised when SDA interference detected"; + sigtype=SigType::Interrupt; + }sda_interference; + signal { + desc = "Raised when stretch timeout occurs"; + sigtype=SigType::Interrupt; + }stretch_timeout; + signal { + desc = "Raised when SDA line is unstable"; + sigtype=SigType::Interrupt; + }sda_unstable; + signal { + desc = "Raised when command completes"; + sigtype=SigType::Interrupt; + }command_complete; + signal { + desc = "Raised when transmit stretch occurs"; + sigtype=SigType::Interrupt; + }transmit_stretch; + signal { + desc = "Raised when transmit FIFO reaches threshold"; + sigtype=SigType::Interrupt; + }transmit_threshold; + signal { + desc = "Raised when acquire FIFO is full"; + sigtype=SigType::Interrupt; + }acquire_fifo_full; + signal { + desc = "Raised when unexpected stop is detected"; + sigtype=SigType::Interrupt; + }unexpected_stop; + signal { + desc = "Raised when host timeout occurs"; + sigtype=SigType::Interrupt; + }host_timeout; + + // Ios pads. + signal {sigtype=SigType::PadInOut; io_combine=IoCombine::And; } scl; + signal {sigtype=SigType::PadInOut; io_combine=IoCombine::And; } sda; + + reg { + desc = "Interrupt State Register"; + field { + sw = r; + hw = rw; + reset = false; + desc = "host mode interrupt: asserted whilst the FMT FIFO level is below the low threshold. This is a level status interrupt."; + } FMT_THRESHOLD[0:0]; + field { + sw = r; + hw = rw; + reset = false; + desc = "host mode interrupt: asserted whilst the RX FIFO level is above the high threshold. This is a level status interrupt."; + } RX_THRESHOLD[1:1]; + field { + sw = r; + hw = rw; + reset = false; + desc = "target mode interrupt: asserted whilst the ACQ FIFO level is above the high threshold. This is a level status interrupt."; + } ACQ_THRESHOLD[2:2]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "host mode interrupt: raised if the RX FIFO has overflowed."; + } RX_OVERFLOW[3:3]; + field { + sw = r; + hw = rw; + reset = false; + desc = "host mode interrupt: raised if the controller FSM is halted, such as on an unexpected NACK or lost arbitration.Check !!CONTROLLER_EVENTS for the reason.The interrupt will be released when the bits in !!CONTROLLER_EVENTS are cleared."; + } CONTROLLER_HALT[4:4]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "host mode interrupt: raised if the SCL line drops early (not supported without clock synchronization)."; + } SCL_INTERFERENCE[5:5]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "host mode interrupt: raised if the SDA line goes low when host is trying to assert high"; + } SDA_INTERFERENCE[6:6]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "host mode interrupt: raised if target stretches the clock beyond the allowed timeout period"; + } STRETCH_TIMEOUT[7:7]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "host mode interrupt: raised if the target does not assert a constant value of SDA during transmission."; + } SDA_UNSTABLE[8:8]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "host and target mode interrupt.In host mode, raised if the host issues a repeated START or terminates the transaction by issuing STOP.In target mode, raised if the external host issues a STOP or repeated START."; + } CMD_COMPLETE[9:9]; + field { + sw = r; + hw = rw; + reset = false; + desc = "target mode interrupt: raised if the target is stretching clocks for a read command. This is a level status interrupt."; + } TX_STRETCH[10:10]; + field { + sw = r; + hw = rw; + reset = false; + desc = "target mode interrupt: asserted whilst the TX FIFO level is below the low threshold. This is a level status interrupt."; + } TX_THRESHOLD[11:11]; + field { + sw = r; + hw = rw; + reset = false; + desc = "target mode interrupt: raised if the target is stretching clocks due to full ACQ FIFO or zero count in !!TARGET_ACK_CTRL.NBYTES (if enabled). This is a level status interrupt."; + } ACQ_STRETCH[12:12]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "target mode interrupt: raised if STOP is received without a preceding NACK during an external host read."; + } UNEXP_STOP[13:13]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "target mode interrupt: raised if the host stops sending the clock during an ongoing transaction."; + } HOST_TIMEOUT[14:14]; + } INTR_STATE @ 0x0; + + reg { + desc = "Interrupt Enable Register"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.fmt_threshold is set."; + } FMT_THRESHOLD[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_threshold is set."; + } RX_THRESHOLD[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.acq_threshold is set."; + } ACQ_THRESHOLD[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_overflow is set."; + } RX_OVERFLOW[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.controller_halt is set."; + } CONTROLLER_HALT[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.scl_interference is set."; + } SCL_INTERFERENCE[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.sda_interference is set."; + } SDA_INTERFERENCE[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.stretch_timeout is set."; + } STRETCH_TIMEOUT[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.sda_unstable is set."; + } SDA_UNSTABLE[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.cmd_complete is set."; + } CMD_COMPLETE[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.tx_stretch is set."; + } TX_STRETCH[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.tx_threshold is set."; + } TX_THRESHOLD[11:11]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.acq_stretch is set."; + } ACQ_STRETCH[12:12]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.unexp_stop is set."; + } UNEXP_STOP[13:13]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.host_timeout is set."; + } HOST_TIMEOUT[14:14]; + } INTR_ENABLE @ 0x4; + + external reg { + desc = "Interrupt Test Register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.fmt_threshold to 1."; + } FMT_THRESHOLD[0:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_threshold to 1."; + } RX_THRESHOLD[1:1]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.acq_threshold to 1."; + } ACQ_THRESHOLD[2:2]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_overflow to 1."; + } RX_OVERFLOW[3:3]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.controller_halt to 1."; + } CONTROLLER_HALT[4:4]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.scl_interference to 1."; + } SCL_INTERFERENCE[5:5]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.sda_interference to 1."; + } SDA_INTERFERENCE[6:6]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.stretch_timeout to 1."; + } STRETCH_TIMEOUT[7:7]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.sda_unstable to 1."; + } SDA_UNSTABLE[8:8]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.cmd_complete to 1."; + } CMD_COMPLETE[9:9]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.tx_stretch to 1."; + } TX_STRETCH[10:10]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.tx_threshold to 1."; + } TX_THRESHOLD[11:11]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.acq_stretch to 1."; + } ACQ_STRETCH[12:12]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.unexp_stop to 1."; + } UNEXP_STOP[13:13]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.host_timeout to 1."; + } HOST_TIMEOUT[14:14]; + } INTR_TEST @ 0x8; + + external reg { + desc = "Alert Test Register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to trigger one alert event of this kind."; + } FATAL_FAULT[0:0]; + } ALERT_TEST @ 0xC; + + reg { + desc = "I2C Control Register"; + field { + sw = rw; + hw = r; + reset = false; + desc = "Enable Host I2C functionality"; + } ENABLEHOST[0:0]; + field { + sw = rw; + hw = r; + reset = false; + desc = "Enable Target I2C functionality"; + } ENABLETARGET[1:1]; + field { + sw = rw; + hw = r; + reset = false; + desc = "Enable I2C line loopback testIf line loopback is enabled, the internal design sees ACQ and RX data as \"1\""; + } LLPBK[2:2]; + field { + sw = rw; + hw = r; + reset = false; + desc = "Enable NACKing the address on a stretch timeout.This is a Target mode feature.If enabled (1), a stretch timeout will cause the device to NACK the address byte.If disabled (0), a stretch timeout will cause the device to ACK the address byte.SMBus requires that devices always ACK their address, even for read commands.However, non-SMBus protocols may have a different approach and can choose to NACK instead.Note that both cases handle data bytes the same way.For writes, the Target module will NACK all subsequent data bytes until it receives a Stop.For reads, the Target module will release SDA, causing 0xff to be returned for all data bytes until it receives a Stop."; + } NACK_ADDR_AFTER_TIMEOUT[3:3]; + field { + sw = rw; + hw = r; + reset = false; + desc = "Enable I2C Target ACK Control Mode.ACK Control Mode works together with !!TARGET_ACK_CTRL.NBYTES to allow software to control upper-layer protocol (N)ACKing (e.g. as in SMBus).This bit enables the mode when 1, and !!TARGET_ACK_CTRL.NBYTES limits how many bytes may be automatically ACK'd while the ACQ FIFO has space.If it is 0, the decision to ACK or NACK is made only from stretching timeouts and !!CTRL.NACK_ADDR_AFTER_TIMEOUT."; + } ACK_CTRL_EN[4:4]; + field { + sw = rw; + hw = r; + reset = false; + desc = "Enable the bus monitor in multi-controller mode.If a 0->1 transition happens while !!CTRL.ENABLEHOST and !!CTRL.ENABLETARGET are both 0, the bus monitor will enable and begin in the \"bus busy\" state.To transition to a bus free state, !!HOST_TIMEOUT_CTRL must be nonzero, so the bus monitor may count out idle cycles to confirm the freedom to transmit.In addition, the bus monitor will track whether the bus is free based on the enabled timeouts and detected Stop symbols.For multi-controller mode, ensure !!CTRL.MULTI_CONTROLLER_MONITOR_EN becomes 1 no later than !!CTRL.ENABLEHOST or !!CTRL.ENABLETARGET.This bit can be set at the same time as either or both of the other two, though.Note that if !!CTRL.MULTI_CONTROLLER_MONITOR_EN is set after !!CTRL.ENABLEHOST or !!CTRL.ENABLETARGET, the bus monitor will begin in the \"bus free\" state instead.This would violate the proper protocol for a controller to join a multi-controller environment.However, if this controller is known to be the first to join, this ordering will enable skipping the idle wait.When 0, the bus monitor will report that the bus is always free, so the controller FSM is never blocked from transmitting."; + } MULTI_CONTROLLER_MONITOR_EN[5:5]; + field { + sw = rw; + hw = r; + reset = false; + desc = "If set to 1, this bit causes a read transfer addressed to this target to set the corresponding bit in !!TARGET_EVENTS.While !!TARGET_EVENTS.TX_PENDING is 1, subsequent read transactions will stretch the clock, even if there is data in the TX FIFO.If enabled, this function allows software to confirm the data in the TX FIFO should be released for the current read.This may be useful for cases where the TX FIFO has data that does not apply to the current transfer.For example, the transaction could've targeted an alternate function via another address."; + } TX_STRETCH_CTRL_EN[6:6]; + } CTRL @ 0x10; + + external reg { + desc = "I2C Live Status Register for Host and Target modes"; + field { + sw = r; + hw = w; + desc = "Host mode FMT FIFO is full"; + } FMTFULL[0:0]; + field { + sw = r; + hw = w; + desc = "Host mode RX FIFO is full"; + } RXFULL[1:1]; + field { + sw = r; + hw = w; + reset = true; + desc = "Host mode FMT FIFO is empty"; + } FMTEMPTY[2:2]; + field { + sw = r; + hw = w; + reset = true; + desc = "Host functionality is idle. No Host transaction is in progress"; + } HOSTIDLE[3:3]; + field { + sw = r; + hw = w; + reset = true; + desc = "Target functionality is idle. No Target transaction is in progress"; + } TARGETIDLE[4:4]; + field { + sw = r; + hw = w; + reset = true; + desc = "Host mode RX FIFO is empty"; + } RXEMPTY[5:5]; + field { + sw = r; + hw = w; + desc = "Target mode TX FIFO is full"; + } TXFULL[6:6]; + field { + sw = r; + hw = w; + desc = "Target mode receive FIFO is full"; + } ACQFULL[7:7]; + field { + sw = r; + hw = w; + reset = true; + desc = "Target mode TX FIFO is empty"; + } TXEMPTY[8:8]; + field { + sw = r; + hw = w; + reset = true; + desc = "Target mode receive FIFO is empty"; + } ACQEMPTY[9:9]; + field { + sw = r; + hw = w; + desc = "Target mode stretching at (N)ACK phase due to zero count in !!TARGET_ACK_CTRL.NBYTES"; + } ACK_CTRL_STRETCH[10:10]; + } STATUS @ 0x14; + + external reg { + hwre = true; + desc = "I2C Read Data"; + field { + sw = r; + hw = rw; + } RDATA[7:0]; + } RDATA @ 0x18; + + reg { + desc = "I2C Host Format DataWrites to this register are used to define and drive Controller-Mode transactions."; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Format Byte.If no flags are set, hardware will transmit this byte directly.If READB is set, this field becomes the number of bytes hardware will automaticallyread from the bus."; + } FBYTE[7:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Issue a START condition before transmitting FBYTE."; + } START[8:8]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Issue a STOP condition after transmitting FBYTE."; + } STOP[9:9]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Transfer Direction Indicator.If unset, this write to FDATA defines a controller-transmitter operation (WRITE).A single byte of data (FBYTE) is written to the bus.If set, this write to FDATA defines a controller-receiver operation (READ).The value of FBYTE defines the number of bytes read from the bus. (256 if FBYTE==0)\"After this number of bytes are read, the final byte will be NACKed to end the transferunless RCONT is also set."; + } READB[10:10]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Do not NACK the last byte read, let the read operation continue."; + } RCONT[11:11]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "For the currrent controller-transmitter byte (WRITE), do not halt via CONTROLLER_EVENTSor assert the 'controller_halt' interrupt if the current byte is not ACK'd."; + } NAKOK[12:12]; + } FDATA @ 0x1C; + + reg { + desc = "I2C FIFO control register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "RX fifo reset. Write 1 to the register resets RX_FIFO. Read returns 0"; + } RXRST[0:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "FMT fifo reset. Write 1 to the register resets FMT_FIFO. Read returns 0"; + } FMTRST[1:1]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "ACQ FIFO reset. Write 1 to the register resets it. Read returns 0"; + } ACQRST[7:7]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "TX FIFO reset. Write 1 to the register resets it. Read returns 0"; + } TXRST[8:8]; + } FIFO_CTRL @ 0x20; + + reg { + desc = "Host mode FIFO configuration"; + field { + sw = rw; + hw = r; + reset = false; + swmod = true; + desc = "Threshold level for RX interrupts. Whilst the level of data in the RX FIFOis above this setting, the rx_threshold interrupt will be asserted."; + } RX_THRESH[11:0]; + field { + sw = rw; + hw = r; + reset = false; + swmod = true; + desc = "Threshold level for FMT interrupts. Whilst the number of used entries in theFMT FIFO is below this setting, the fmt_threshold interrupt will be asserted."; + } FMT_THRESH[27:16]; + } HOST_FIFO_CONFIG @ 0x24; + + reg { + desc = "Target mode FIFO configuration"; + field { + sw = rw; + hw = r; + reset = false; + swmod = true; + desc = "Threshold level for TX interrupts. Whilst the number of used entries in theTX FIFO is below this setting, the tx_threshold interrupt will be asserted."; + } TX_THRESH[11:0]; + field { + sw = rw; + hw = r; + reset = false; + swmod = true; + desc = "Threshold level for ACQ interrupts. Whilst the level of data in the ACQ FIFOis above this setting, the acq_threshold interrupt will be asserted."; + } ACQ_THRESH[27:16]; + } TARGET_FIFO_CONFIG @ 0x28; + + external reg { + desc = "Host mode FIFO status register"; + field { + sw = r; + hw = w; + desc = "Current fill level of FMT fifo"; + } FMTLVL[11:0]; + field { + sw = r; + hw = w; + desc = "Current fill level of RX fifo"; + } RXLVL[27:16]; + } HOST_FIFO_STATUS @ 0x2C; + + external reg { + desc = "Target mode FIFO status register"; + field { + sw = r; + hw = w; + desc = "Current fill level of TX fifo"; + } TXLVL[11:0]; + field { + sw = r; + hw = w; + desc = "Current fill level of ACQ fifo"; + } ACQLVL[27:16]; + } TARGET_FIFO_STATUS @ 0x30; + + reg { + desc = "I2C Override Control Register"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Override the SDA and SCL TX signals."; + } TXOVRDEN[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Value for SCL Override. Set to 0 to drive TX Low, and set to 1 for high-Z"; + } SCLVAL[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Value for SDA Override. Set to 0 to drive TX Low, and set to 1 for high-Z"; + } SDAVAL[2:2]; + } OVRD @ 0x34; + + external reg { + desc = "Oversampled RX values"; + field { + sw = r; + hw = w; + desc = "Last 16 oversampled values of SCL. Most recent bit is bit 0, oldest 15."; + } SCL_RX[15:0]; + field { + sw = r; + hw = w; + desc = "Last 16 oversampled values of SDA. Most recent bit is bit 16, oldest 31."; + } SDA_RX[31:16]; + } VAL @ 0x38; + + reg { + desc = "Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification).All values are expressed in units of the input clock period.These must be greater than 2 in order for the change in SCL to propagate to the input of the FSM so that acknowledgements are detected correctly."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The actual time to hold SCL high in a given pulse.This field is sized to have a range of at least Standard Mode's 4.0 us max with a core clock at 1 GHz."; + } THIGH[12:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The actual time to hold SCL low between any two SCL pulses.This field is sized to have a range of at least Standard Mode's 4.7 us max with a core clock at 1 GHz."; + } TLOW[28:16]; + } TIMING0 @ 0x3C; + + reg { + desc = "Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification).All values are expressed in units of the input clock period."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The nominal rise time to anticipate for the bus (depends on capacitance).This field is sized to have a range of at least Standard Mode's 1000 ns max with a core clock at 1 GHz."; + } T_R[9:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The nominal fall time to anticipate for the bus (influences SDA hold times).This field is sized to have a range of at least Standard Mode's 300 ns max with a core clock at 1 GHz."; + } T_F[24:16]; + } TIMING1 @ 0x40; + + reg { + desc = "Detailed I2C Timings (directly corresponding to table 10 in the I2C Specification).All values are expressed in units of the input clock period."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Actual setup time for repeated start signals.This field is sized to have a range of at least Standard Mode's 4.7 us max with a core clock at 1 GHz."; + } TSU_STA[12:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Actual hold time for start signals.This field is sized to have a range of at least Standard Mode's 4.0 us max with a core clock at 1 GHz."; + } THD_STA[28:16]; + } TIMING2 @ 0x44; + + reg { + desc = "Detailed I2C Timings (directly corresponding to table 10, in the I2C Specification).All values are expressed in units of the input clock period."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Actual setup time for data (or ack) bits.This field is sized to have a range of at least Standard Mode's 250 ns max with a core clock at 1 GHz."; + } TSU_DAT[8:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Actual hold time for data (or ack) bits.(Note, where required, the parameters TVD_DAT is taken to be THD_DAT+T_F)This field is sized to have a range that accommodates Standard Mode's 3.45 us max for TVD_DAT with a core clock at 1 GHz.However, this field is generally expected to represent a time substantially shorter than that.It should be long enough to cover the maximum round-trip latency from output pins, through pads and voltage transitions on the board, and back to the input pins, but it should not be substantially greater."; + } THD_DAT[28:16]; + } TIMING3 @ 0x48; + + reg { + desc = "Detailed I2C Timings (directly corresponding to table 10, in the I2C Specification).All values are expressed in units of the input clock period."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Actual setup time for stop signals.This field is sized to have a range of at least Standard Mode's 4.0 us max with a core clock at 1 GHz."; + } TSU_STO[12:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Actual time between each STOP signal and the following START signal.This field is sized to have a range of at least Standard Mode's 4.7 us max with a core clock at 1 GHz."; + } T_BUF[28:16]; + } TIMING4 @ 0x4C; + + reg { + desc = "I2C clock stretching and bus timeout control.This timeout must be enabled by setting !!TIMEOUT_CTRL.EN to 1, and the behavior of this feature depends on the value of !!TIMEOUT_CTRL.MODE.If the mode is \"STRETCH_TIMEOUT\", this is used in I2C controller mode to detect whether a connected target is stretching a single low time beyond the timeout value.Configured as such, this timeout is more informative and doesn't do more than assert the \"stretch_timeout\" interrupt.If the mode is \"BUS_TIMEOUT\", it is used to detect whether the clock has been held low for too long instead, inclusive of the controller's clock low time.This is useful for an SMBus context, where the VAL programmed should be tTIMEOUT:MIN."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Clock stretching timeout value (in units of input clock frequency)"; + } VAL[29:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Selects the timeout mode, between a stretch timeout and a bus timeout.Between the two modes, the primary difference is how much of the clock low period is counted.For a stretch timeout, only the time that another device holds the clock low will be counted.For a bus timeout, the entire clock low time is counted, consistent with the SMBus tTIMEOUT type.!!TIMEOUT_CTRL.EN must be 1 for either of these features to be enabled."; + } MODE[30:30]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable stretch timeout or bus timeout feature"; + } EN[31:31]; + } TIMEOUT_CTRL @ 0x50; + + reg { + desc = "I2C target address and mask pairs"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "I2C target address number 0"; + } ADDRESS0[6:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "I2C target mask number 0.At least one bit in MASK0 must be set to 1 for ADDRESS0 to be used."; + } MASK0[13:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "I2C target address number 1"; + } ADDRESS1[20:14]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "I2C target mask number 1.At least one bit in MASK1 must be set to 1 for ADDRESS1 to be used."; + } MASK1[27:21]; + } TARGET_ID @ 0x54; + + external reg { + hwre = true; + desc = "I2C target acquired data"; + field { + sw = r; + hw = rw; + desc = "Address for accepted transaction or acquired byte"; + } ABYTE[7:0]; + field { + sw = r; + hw = rw; + desc = "Indicates any control symbols associated with the ABYTE.For the STOP symbol, a stretch timeout or other unexpected events will cause a NACK_STOP to appear in the ACQ FIFO.If the ACQ FIFO doesn't have enough space to record a START and a STOP, the transaction will be dropped entirely on a stretch timeout.In that case, the START byte will not appear (neither as START nor NACK_START), but a standalone NACK_STOP may, if there was space.Software can discard any standalone NACK_STOP that appears.See the associated values for more information about the contents."; + } SIGNAL[10:8]; + } ACQDATA @ 0x58; + + reg { + desc = "I2C target transmit data"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + } TXDATA[7:0]; + } TXDATA @ 0x5C; + + reg { + desc = "I2C host clock generation timeout value (in units of input clock frequency).In an active transaction in Target-Mode, if the Controller ceases to send SCL pulsesfor this number of cycles then the \"host_timeout\" interrupt will be asserted.In multi-controller monitoring mode, !!HOST_TIMEOUT_CTRL is required to be nonzero to transition out of the initial busy state.Set this CSR to 0 to disable this behaviour."; + field { + sw = rw; + hw = r; + reset = 0x0; + } HOST_TIMEOUT_CTRL[19:0]; + } HOST_TIMEOUT_CTRL @ 0x60; + + reg { + desc = "I2C target internal stretching timeout control.When the target has stretched beyond this time it will send a NACK for incoming data bytes or release SDA for outgoing data bytes.The behavior for the address byte is configurable via !!CTRL.ACK_ADDR_AFTER_TIMEOUT.Note that the count accumulates stretching time over the course of a transaction.In other words, this is equivalent to the SMBus cumulative target clock extension time."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Clock stretching timeout value (in units of input clock frequency)"; + } VAL[30:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable timeout feature and send NACK once the timeout has been reached"; + } EN[31:31]; + } TARGET_TIMEOUT_CTRL @ 0x64; + + reg { + desc = "Number of times the I2C target has NACK'ed a new transaction since the last read of this register.Reading this register clears it.This is useful because when the ACQ FIFO is full the software know that a NACK has occurred, but without this register would not know how many transactions it missed.When it reaches its maximum value it will stay at that value."; + field { + sw = rw; + onread = rclr; + hw = rw; + reset = 0x0; + } TARGET_NACK_COUNT[7:0]; + } TARGET_NACK_COUNT @ 0x68; + + external reg { + desc = "Controls for mid-transfer (N)ACK phase handling"; + field { + sw = rw; + hw = rw; + swmod = true; + desc = "Remaining number of bytes the Target module may ACK automatically.If !!CTRL.ACK_CTRL_EN is set to 1, the Target module will stretch the clock at the (N)ACK phase of a byte if this CSR is 0, awaiting software's instructions.At the beginning of each Write transfer, this byte count is reset to 0.Writes to this CSR also are only accepted while the Target module is stretching the clock.The Target module will always ACK its address if the ACQ FIFO has space.For data bytes afterwards, it will stop at the (N)ACK phase and stretch the clock when this CSR is 0.For each data byte that is ACK'd in a transaction, the byte count will decrease by 1.Note that a full ACQ FIFO can still cause the Target module to halt at the beginning of a new byte.The ACK Control Mode provides an additional synchronization point, during the (N)ACK phase instead of after.For both cases, !!TARGET_TIMEOUT_CTRL applies, and stretching past the timeout will produce an automatic NACK.This mode can be used to implement the mid-transfer (N)ACK responses required by various SMBus protocols."; + } NBYTES[8:0]; + field { + sw = w; + hw = r; + swmod = true; + desc = "When the Target module stretches on the (N)ACK phase of a Write due to !!TARGET_ACK_CTRL.NBYTES being 0, writing a 1 here will cause it to send a NACK.If software chooses to NACK, note that the NACKing behavior is the same as if a stretch timeout occurred.The rest of the transaction will be NACK'd, including subsequent transfers.For the address byte, the (N)ACK phase of subsequent transfers will follow the behavior specified by !!CTRL.NACK_ADDR_AFTER_TIMEOUT.Automatically clears to 0."; + } NACK[31:31]; + } TARGET_ACK_CTRL @ 0x6C; + + external reg { + desc = "The data byte pending to be written to the ACQ FIFO.This CSR is only valid while the Target module is stretching in the (N)ACK phase, indicated by !!STATUS.ACK_CTRL_STRETCH .It is intended to be used with ACK Control Mode, so software may check the current byte."; + field { + sw = r; + hw = w; + } ACQ_FIFO_NEXT_DATA[7:0]; + } ACQ_FIFO_NEXT_DATA @ 0x70; + + reg { + desc = "Timeout in Host-Mode for an unhandled NACK before hardware automatically ends the transaction.(in units of input clock frequency)If an active Controller-Transmitter transfer receives a NACK from the Target, the !!CONTROLLER_EVENTS.NACK bit is set.In turn, this causes the Controller FSM to halt awaiting software intervention, and the 'controller_halt' interrupt may assert.Software must clear the !!CONTROLLER_EVENTS.NACK bit to allow the state machine to continue, typically after clearing out the FMTFIFO to start a new transfer.While halted, the active transaction is not ended (no STOP (P) condition is created), and the block asserts SCL and leaves SDA released.This timeout can be used to automatically produce a STOP condition, whether as a backstop for slow software responses (longer timeout) or as a convenience (short timeout).If the timeout expires, the Controller FSM will issue a STOP (P) condition on the bus to end the active transaction.Additionally, the !!CONTROLLER_EVENTS.UNHANDLED_NACK_TIMEOUT bit is set to alert software, and the FSM will return to the idle state and halt until the bit is cleared.The enable bit must be set for this feature to operate."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Unhandled NAK timeout value (in units of input clock frequency)"; + } VAL[30:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Timeout enable"; + } EN[31:31]; + } HOST_NACK_HANDLER_TIMEOUT @ 0x74; + + reg { + desc = "Latched events that explain why the controller halted.Any bits that are set must be written (with a 1) to clear the CONTROLLER_HALT interrupt."; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "Received an unexpected NACK"; + } NACK[0:0]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "A Host-Mode active transaction has been ended by the !!HOST_NACK_HANDLER_TIMEOUT mechanism."; + } UNHANDLED_NACK_TIMEOUT[1:1]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "A Host-Mode active transaction has terminated due to a bus timeout activated by !!TIMEOUT_CTRL."; + } BUS_TIMEOUT[2:2]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "A Host-Mode active transaction has terminated due to lost arbitration."; + } ARBITRATION_LOST[3:3]; + } CONTROLLER_EVENTS @ 0x78; + + reg { + desc = "Latched events that can cause the target module to stretch the clock at the beginning of a read transfer.These events cause TX FIFO-related stretching even when the TX FIFO has data available.Any bits that are set must be written (with a 1) to clear the tx_stretch interrupt.This CSR serves as a gate to prevent the Target module from responding to a read command with unrelated, leftover data."; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "A new Target-Mode read transfer has arrived that addressed this target.This bit is used by software to confirm the release of the contents in the TX FIFO.If the contents do not apply, software should first reset the TX FIFO, then load it with the correct data, then clear this bit.Optionally enabled by !!CTRL.TX_STRETCH_CTRL_EN."; + } TX_PENDING[0:0]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "A Target-Mode read transfer has terminated due to a bus timeout activated by !!TIMEOUT_CTRL."; + } BUS_TIMEOUT[1:1]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "A Target-Mode read transfer has terminated due to lost arbitration."; + } ARBITRATION_LOST[2:2]; + } TARGET_EVENTS @ 0x7C; + +}; diff --git a/rtl/ip/pwm/data/pwm.rdl b/rtl/ip/pwm/data/pwm.rdl new file mode 100644 index 000000000..5d2415ae8 --- /dev/null +++ b/rtl/ip/pwm/data/pwm.rdl @@ -0,0 +1,40 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap pwm { + + xbar = '{ + parameter'{ type_: "bool", name: "pipeline", value: "true" }, + parameter'{ type_: "bool", name: "req_fifo_pass", value: "false" }, + parameter'{ type_: "bool", name: "rsp_fifo_pass", value: "false" } + }; + + clk_input = '{ + "clk_sys_i" + }; + + rst_input = '{ + "rst_sys_ni" + }; + + // Ios pads. + signal {sigtype=SigType::PadOutput;} out[7]; + + reg { + field { + sw=rw; + reset = 0; + desc = "Pwm width."; + } value[32] = 0; + } WIDTH @0x00; + + reg { + field { + sw=rw; + reset = 0; + desc = "Pwm counter."; + } value[32] = 0; + } COUNTER @0x04; +}; diff --git a/rtl/ip/rev_ctl/data/rev_ctl.rdl b/rtl/ip/rev_ctl/data/rev_ctl.rdl new file mode 100644 index 000000000..26cee2be6 --- /dev/null +++ b/rtl/ip/rev_ctl/data/rev_ctl.rdl @@ -0,0 +1,77 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap rev_ctl { + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + reg { + desc = "Start address for the hardware revoker."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Start address."; + } ADDRESS[31:0]; + } START_ADDR @ 0x0; + + reg { + desc = "End address for the hardware revoker."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "End address."; + } ADDRESS[31:0]; + } END_ADDR @ 0x4; + + external reg { + desc = "Start the revocation engine."; + field { + sw = rw; + hw = rw; + reset = 0x55000000; + swmod = true; + desc = "Any value written here will start the engine, it always reads a constant value."; + } GO[31:0]; + } GO @ 0x8; + + reg { + desc = "Epoch to keep track of revocation cycles."; + field { + sw = r; + hw = rw; + reset = 0x0; + desc = "One bit indicating whether a sweep is ongoing. (0 means idle.)"; + } RUNNING[0:0]; + field { + sw = r; + hw = rw; + reset = 0x0; + desc = "Epoch counter that increases after each sweep."; + } EPOCH[31:1]; + } EPOCH @ 0xC; + + external reg { + desc = "Used to clear the interrupt and read it out if enabled."; + field { + sw = rw; + hw = rw; + swmod = true; + desc = "High when interrupt is raised and low if not. Writing anything here will clear the interrupt."; + } STATUS[0:0]; + } INTERRUPT_STATUS @ 0x10; + + reg { + desc = "Used to clear the interrupt and read it out if enabled."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "High when interrupt is enabled and low if not."; + } ENABLE[0:0]; + } INTERRUPT_ENABLE @ 0x14; + +}; diff --git a/rtl/ip/rgbled_ctrl/data/rgbled_ctrl.rdl b/rtl/ip/rgbled_ctrl/data/rgbled_ctrl.rdl new file mode 100644 index 000000000..80d254bf6 --- /dev/null +++ b/rtl/ip/rgbled_ctrl/data/rgbled_ctrl.rdl @@ -0,0 +1,90 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap rgbled_ctrl { + xbar = '{ + parameter'{ type_: "bool", name: "pipeline", value: "true" }, + parameter'{ type_: "bool", name: "req_fifo_pass", value: "false" }, + parameter'{ type_: "bool", name: "rsp_fifo_pass", value: "false" } + }; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + external reg { + desc = "RGB for first LED"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Red"; + } R[7:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Green"; + } G[15:8]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Blue"; + } B[23:16]; + } RGBLED0 @ 0x0; + + external reg { + desc = "RGB for second LED"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Red"; + } R[7:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Green"; + } G[15:8]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Blue"; + } B[23:16]; + } RGBLED1 @ 0x4; + + external reg { + desc = "Control"; + field { + sw = w; + hw = r; + swmod = true; + desc = "Write 1 to set RGB LEDs to specified colours"; + } SETRGB[0:0]; + field { + sw = w; + hw = r; + swmod = true; + desc = "Write 1 to turn off RGB LEDs. Write to Set to turn on again."; + } OFF[1:1]; + } CTRL @ 0x8; + + external reg { + desc = "Status"; + field { + sw = r; + hw = w; + desc = "When set controller is idle and new colours can be set. When clear writes to REGLED0/REGLED1/CTRL are ignored."; + } IDLE[0:0]; + } STATUS @ 0xC; + +}; diff --git a/rtl/ip/spi/data/spi.rdl b/rtl/ip/spi/data/spi.rdl new file mode 100644 index 000000000..0d72fc1d2 --- /dev/null +++ b/rtl/ip/spi/data/spi.rdl @@ -0,0 +1,323 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap spi #( + longint MaxPeripherals = 4 +){ + // Ios pads. + signal {sigtype=SigType::PadInput;} cipo; + signal {sigtype=SigType::PadOutput;} copi; + signal {sigtype=SigType::PadOutput;} sclk; + signal {sigtype=SigType::PadOutput;} cs[4]; + + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + reg { + desc = "Interrupt State Register"; + field { + sw = r; + hw = rw; + reset = false; + desc = "Receive FIFO is full"; + } RX_FULL[0:0]; + field { + sw = r; + hw = rw; + reset = false; + desc = "Receive FIFO level is at or above watermark"; + } RX_WATERMARK[1:1]; + field { + sw = r; + hw = rw; + reset = false; + desc = "Transmit FIFO is empty"; + } TX_EMPTY[2:2]; + field { + sw = r; + hw = rw; + reset = false; + desc = "Transmit FIFO level is at or below watermark"; + } TX_WATERMARK[3:3]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "On-going SPI operation has completed and the block is now idle"; + } COMPLETE[4:4]; + } INTR_STATE @ 0x0; + + reg { + desc = "Interrupt Enable Register"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_full is set."; + } RX_FULL[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_watermark is set."; + } RX_WATERMARK[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.tx_empty is set."; + } TX_EMPTY[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.tx_watermark is set."; + } TX_WATERMARK[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.complete is set."; + } COMPLETE[4:4]; + } INTR_ENABLE @ 0x4; + + external reg { + desc = "Interrupt Test Register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_full to 1."; + } RX_FULL[0:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_watermark to 1."; + } RX_WATERMARK[1:1]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.tx_empty to 1."; + } TX_EMPTY[2:2]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.tx_watermark to 1."; + } TX_WATERMARK[3:3]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.complete to 1."; + } COMPLETE[4:4]; + } INTR_TEST @ 0x8; + + reg { + desc = "Configuration register. Controls how the SPI block transmits and receives data. This register can only be modified whilst the SPI block is idle. "; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The length of a half period (i.e. positive edge to negative edge) of the SPI clock, measured in system clock cycles reduced by 1. At the standard Sonata 50 MHz system clock a value of 0 gives a 25 MHz SPI clock, a value of 1 gives a 12.5 MHz SPI clock, a value of 2 gives a 8.33 MHz SPI clock and so on."; + } HALF_CLK_PERIOD[15:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "State of the controller output line (COPI) when not transmitting."; + } COPI_IDLE[28:28]; + field { + sw = rw; + hw = r; + reset = 0x1; + desc = "When set the most significant bit (MSB) is the first bit sent and received with each byte"; + } MSB_FIRST[29:29]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The phase of the spi_clk signal. When CPHA is 0 data is sampled on the leading edge and changes on the trailing edge. The first data bit is immediately available before the first leading edge of the clock when transmission begins. When CPHA is 1 data is sampled on the trailing edge and change on the leading edge."; + } CPHA[30:30]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The polarity of the spi_clk signal. When CPOL is 0 clock is low when idle and the leading edge is positive. When CPOL is 1 clock is high when idle and the leading edge is negative"; + } CPOL[31:31]; + } CFG @ 0xC; + + reg { + desc = "Controls the operation of the SPI block. This register can only be modified whilst the SPI block is idle."; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to clear the transmit FIFO"; + } TX_CLEAR[0:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to clear the receive FIFO"; + } RX_CLEAR[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + swmod = true; + desc = "When set bytes from the transmit FIFO are sent. When clear the state of the outgoing spi_copi is undefined whilst the SPI clock is running."; + } TX_ENABLE[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + swmod = true; + desc = "When set incoming bits are written to the receive FIFO. When clear incoming bits are ignored."; + } RX_ENABLE[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + swmod = true; + desc = "The watermark level for the transmit FIFO, depending on the value the interrupt will trigger at different points: * 0 - 1 or fewer items in the FIFO * 1 - 2 or fewer items in the FIFO * 2 - 4 or fewer items in the FIFO * 3 - 8 or fewer items in the FIFO * 4 - 16 or fewer items in the FIFO"; + } TX_WATERMARK[7:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + swmod = true; + desc = "The watermark level for the receive FIFO, depending on the value the interrupt will trigger at different points: * 0 - 1 or more items in the FIFO * 1 - 2 or more items in the FIFO * 2 - 4 or more items in the FIFO * 3 - 8 or more items in the FIFO * 4 - 16 or more items in the FIFO * 5 - 32 or more items in the FIFO * 6 - 56 or more items in the FIFO"; + } RX_WATERMARK[11:8]; + field { + sw = rw; + hw = r; + reset = false; + swmod = true; + desc = "When set the CIPO line is internally connected to the COPI line, providing loopback functionality which may be useful in testing. Note that the COPI line is unaffected and still carries data so test software should normally leave the CS lines deasserted. This bit shall be changed only when the SPI core is idle."; + } INT_LOOPBACK[30:30]; + field { + sw = w; + hw = r; + reset = false; + swmod = true; + desc = "When a 1 is written to this field a reset of the controller logic is performed. This shall be used only to recover from error conditions. The TX FIFO shall be cleared before resetting the controller logic; then clear the RX FIFO after the controller reset. The bit self-clears and always reads as zero."; + } SW_RESET[31:31]; + } CONTROL @ 0x10; + + external reg { + desc = "Status information about the SPI block"; + field { + sw = r; + hw = w; + desc = "Number of items in the transmit FIFO"; + } TX_FIFO_LEVEL[7:0]; + field { + sw = r; + hw = w; + desc = "Number of items in the receive FIFO"; + } RX_FIFO_LEVEL[15:8]; + field { + sw = r; + hw = w; + desc = "When set the transmit FIFO is full and any data written to it will be ignored."; + } TX_FIFO_FULL[16:16]; + field { + sw = r; + hw = w; + desc = "When set the receive FIFO is empty and any data read from it will be undefined."; + } RX_FIFO_EMPTY[17:17]; + field { + sw = r; + hw = w; + desc = "When set the SPI block is idle and can accept a new start command."; + } IDLE[18:18]; + } STATUS @ 0x14; + + reg { + desc = "When written begins an SPI operation. Writes are ignored when the SPI block is active."; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Number of bytes to receive/transmit in the SPI operation"; + } BYTE_COUNT[10:0]; + } START @ 0x18; + + external reg { + hwre = true; + desc = "Data from the receive FIFO. When read the data is popped from the FIFO. If the FIFO is empty data read is undefined."; + field { + sw = r; + hw = rw; + desc = "Byte popped from the FIFO"; + } DATA[7:0]; + } RX_FIFO @ 0x1C; + + reg { + desc = "Bytes written here are pushed to the transmit FIFO. If the FIFO is full writes are ignored."; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Byte to push to the FIFO"; + } DATA[7:0]; + } TX_FIFO @ 0x20; + + external reg { + desc = "Returns information on the SPI controller."; + field { + sw = r; + hw = w; + desc = "Maximum number of items in the transmit FIFO."; + } TX_FIFO_DEPTH[7:0]; + field { + sw = r; + hw = w; + desc = "Maximum number of items in the receive FIFO."; + } RX_FIFO_DEPTH[15:8]; + } INFO @ 0x24; + + reg { + desc = "Specifies which peripherals are selected for transmit/receive operations. An operation may select multiple peripherals simultaneously but this functionality shall be used only for transmit operations. This register shall be changed only when the SPI controller is idle, not whilst a transmit/receive operation may be in progress."; + field { + sw = rw; + hw = r; + reset = true; + desc = "If this bit is clear the peripheral is selected for transmit/receive operations."; + } CS_0[0:0]; + field { + sw = rw; + hw = r; + reset = true; + desc = "If this bit is clear the peripheral is selected for transmit/receive operations."; + } CS_1[1:1]; + field { + sw = rw; + hw = r; + reset = true; + desc = "If this bit is clear the peripheral is selected for transmit/receive operations."; + } CS_2[2:2]; + field { + sw = rw; + hw = r; + reset = true; + desc = "If this bit is clear the peripheral is selected for transmit/receive operations."; + } CS_3[3:3]; + } CS[1] @ 0x28; + +}; diff --git a/rtl/ip/system_info/data/system_info.rdl b/rtl/ip/system_info/data/system_info.rdl new file mode 100644 index 000000000..c4cda7d19 --- /dev/null +++ b/rtl/ip/system_info/data/system_info.rdl @@ -0,0 +1,83 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap system_info { + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + external reg { + desc = "This contains the git hash of the Sonata System repository when this bitstream was generated. This is useful to determine the configuration of the RTL."; + field { + sw = r; + hw = w; + desc = "First 32-bits of the git SHA hash."; + } HASH[31:0]; + } RTL_COMMIT_HASH_0 @ 0x0; + + external reg { + desc = "Extension of the RTL_COMMIT_HASH_0 register."; + field { + sw = r; + hw = w; + desc = "Second 32-bits of the git SHA hash."; + } HASH[31:0]; + } RTL_COMMIT_HASH_1 @ 0x4; + + external reg { + desc = "This contains whether the repository was dirty when the bitstream was generated."; + field { + sw = r; + hw = w; + reset = 0x1; + desc = "One if the git repository was dirty when generating the bitstream. Zero if the git repository was clean. This should be used in combination with the RTL_COMMIT_HASH register."; + } DIRTY[0:0]; + } RTL_COMMIT_DIRTY @ 0x8; + + external reg { + desc = "Contains the system frequency."; + field { + sw = r; + hw = w; + desc = "The frequency of the system clock in Hz."; + } FREQUENCY[31:0]; + } SYSTEM_FREQUENCY @ 0xC; + + external reg { + desc = "Contains information about the GPIO blocks in Sonata."; + field { + sw = r; + hw = w; + desc = "Number of GPIO block instances."; + } INSTANCES[7:0]; + } GPIO_INFO @ 0x10; + + external reg { + desc = "Contains information about the UART blocks in Sonata."; + field { + sw = r; + hw = w; + desc = "Number of UART block instances."; + } INSTANCES[7:0]; + } UART_INFO @ 0x14; + + external reg { + desc = "Contains information about the I2C blocks in Sonata."; + field { + sw = r; + hw = w; + desc = "Number of I2C block instances."; + } INSTANCES[7:0]; + } I2C_INFO @ 0x18; + + external reg { + desc = "Contains information about the SPI blocks in Sonata."; + field { + sw = r; + hw = w; + desc = "Number of SPI block instances."; + } INSTANCES[7:0]; + } SPI_INFO @ 0x1C; + +}; diff --git a/rtl/ip/uart/data/uart.rdl b/rtl/ip/uart/data/uart.rdl new file mode 100644 index 000000000..9024a6aa7 --- /dev/null +++ b/rtl/ip/uart/data/uart.rdl @@ -0,0 +1,436 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap uart #( + longint RxFifoDepth = 8, + longint TxFifoDepth = 8, + longint NumAlerts = 1 +){ + xbar = '{ + parameter'{ type_: "bool", name: "pipeline", value: "true" }, + parameter'{ type_: "bool", name: "req_fifo_pass", value: "false" }, + parameter'{ type_: "bool", name: "rsp_fifo_pass", value: "false" } + }; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + // Interrupts + signal { desc = "Raised when TX FIFO reaches watermark"; sigtype=SigType::Interrupt;} tx_watermark; + signal { desc = "Raised when RX FIFO reaches watermark";sigtype=SigType::Interrupt;} rx_watermark; + signal { desc = "Raised when TX FIFO becomes empty";sigtype=SigType::Interrupt;} tx_empty; + signal { desc = "Raised when RX FIFO overflows";sigtype=SigType::Interrupt;} rx_overflow; + signal { desc = "Raised on RX frame error";sigtype=SigType::Interrupt;} rx_frame_err; + signal { desc = "Raised on RX break condition";sigtype=SigType::Interrupt;} rx_break_err; + signal { desc = "Raised on RX timeout";sigtype=SigType::Interrupt;} rx_timeout; + signal { desc = "Raised on RX parity error";sigtype=SigType::Interrupt;} rx_parity_err; + + // Ios pads. + signal {sigtype=SigType::PadInput;} rx; + signal {sigtype=SigType::PadOutput;} tx; + + reg { + desc = "Interrupt State Register"; + field { + sw = r; + hw = rw; + reset = true; + desc = "raised if the transmit FIFO is past the high-water mark."; + } TX_WATERMARK[0:0]; + field { + sw = r; + hw = rw; + reset = false; + desc = "raised if the receive FIFO is past the high-water mark."; + } RX_WATERMARK[1:1]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "raised if the transmit FIFO has emptied and no transmit is ongoing."; + } TX_DONE[2:2]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "raised if the receive FIFO has overflowed."; + } RX_OVERFLOW[3:3]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "raised if a framing error has been detected on receive."; + } RX_FRAME_ERR[4:4]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "raised if break condition has been detected on receive."; + } RX_BREAK_ERR[5:5]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "raised if RX FIFO has characters remaining in the FIFO without beingretrieved for the programmed time period."; + } RX_TIMEOUT[6:6]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "raised if the receiver has detected a parity error."; + } RX_PARITY_ERR[7:7]; + field { + sw = r; + hw = rw; + reset = true; + desc = "raised if the transmit FIFO is empty."; + } TX_EMPTY[8:8]; + } INTR_STATE @ 0x0; + + reg { + desc = "Interrupt Enable Register"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.tx_watermark is set."; + } TX_WATERMARK[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_watermark is set."; + } RX_WATERMARK[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.tx_done is set."; + } TX_DONE[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_overflow is set."; + } RX_OVERFLOW[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_frame_err is set."; + } RX_FRAME_ERR[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_break_err is set."; + } RX_BREAK_ERR[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_timeout is set."; + } RX_TIMEOUT[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_parity_err is set."; + } RX_PARITY_ERR[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.tx_empty is set."; + } TX_EMPTY[8:8]; + } INTR_ENABLE @ 0x4; + + external reg { + desc = "Interrupt Test Register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.tx_watermark to 1."; + } TX_WATERMARK[0:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_watermark to 1."; + } RX_WATERMARK[1:1]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.tx_done to 1."; + } TX_DONE[2:2]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_overflow to 1."; + } RX_OVERFLOW[3:3]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_frame_err to 1."; + } RX_FRAME_ERR[4:4]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_break_err to 1."; + } RX_BREAK_ERR[5:5]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_timeout to 1."; + } RX_TIMEOUT[6:6]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_parity_err to 1."; + } RX_PARITY_ERR[7:7]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.tx_empty to 1."; + } TX_EMPTY[8:8]; + } INTR_TEST @ 0x8; + + external reg { + desc = "Alert Test Register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to trigger one alert event of this kind."; + } FATAL_FAULT[0:0]; + } ALERT_TEST @ 0xC; + + reg { + desc = "UART control register"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "TX enable"; + } TX[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "RX enable"; + } RX[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "RX noise filter enable.If the noise filter is enabled, RX line goes through the 3-taprepetition code. It ignores single IP clock period noise."; + } NF[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "System loopback enable.If this bit is turned on, any outgoing bits to TX are received through RX.See Block Diagram. Note that the TX line goes 1 if System loopback is enabled."; + } SLPBK[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Line loopback enable.If this bit is turned on, incoming bits are forwarded to TX for testing purpose.See Block Diagram. Note that the internal design sees RX value as 1 always if lineloopback is enabled."; + } LLPBK[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If true, parity is enabled in both RX and TX directions."; + } PARITY_EN[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If PARITY_EN is true, this determines the type, 1 for odd parity, 0 for even."; + } PARITY_ODD[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Trigger level for RX break detection. Sets the number of charactertimes the line must be low to detect a break."; + } RXBLVL[9:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "BAUD clock rate control."; + } NCO[31:16]; + } CTRL @ 0x10; + + external reg { + hwre = true; + desc = "UART live status register"; + field { + sw = r; + hw = rw; + desc = "TX buffer is full"; + } TXFULL[0:0]; + field { + sw = r; + hw = rw; + desc = "RX buffer is full"; + } RXFULL[1:1]; + field { + sw = r; + hw = rw; + reset = true; + desc = "TX FIFO is empty"; + } TXEMPTY[2:2]; + field { + sw = r; + hw = rw; + reset = true; + desc = "TX FIFO is empty and all bits have been transmitted"; + } TXIDLE[3:3]; + field { + sw = r; + hw = rw; + reset = true; + desc = "RX is idle"; + } RXIDLE[4:4]; + field { + sw = r; + hw = rw; + reset = true; + desc = "RX FIFO is empty"; + } RXEMPTY[5:5]; + } STATUS @ 0x14; + + external reg { + hwre = true; + desc = "UART read data"; + field { + sw = r; + hw = rw; + } RDATA[7:0]; + } RDATA @ 0x18; + + reg { + desc = "UART write data"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + } WDATA[7:0]; + } WDATA @ 0x1C; + + reg { + desc = "UART FIFO control register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "RX fifo reset. Write 1 to the register resets RX_FIFO. Read returns 0"; + } RXRST[0:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "TX fifo reset. Write 1 to the register resets TX_FIFO. Read returns 0"; + } TXRST[1:1]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Trigger level for RX interrupts. If the FIFO depth is greater than or equal tothe setting, it raises rx_watermark interrupt."; + } RXILVL[4:2]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Trigger level for TX interrupts. If the FIFO depth is less than the setting, itraises tx_watermark interrupt."; + } TXILVL[7:5]; + } FIFO_CTRL @ 0x20; + + external reg { + desc = "UART FIFO status register"; + field { + sw = r; + hw = w; + desc = "Current fill level of TX fifo"; + } TXLVL[7:0]; + field { + sw = r; + hw = w; + desc = "Current fill level of RX fifo"; + } RXLVL[23:16]; + } FIFO_STATUS @ 0x24; + + reg { + desc = "TX pin override control. Gives direct SW control over TX pin state"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable TX pin override control"; + } TXEN[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Write to set the value of the TX pin"; + } TXVAL[1:1]; + } OVRD @ 0x28; + + external reg { + desc = "UART oversampled values"; + field { + sw = r; + hw = w; + desc = "Last 16 oversampled values of RX. Most recent bit is bit 0, oldest 15."; + } RX[15:0]; + } VAL @ 0x2C; + + reg { + desc = "UART RX timeout control"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "RX timeout value in UART bit times"; + } VAL[23:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable RX timeout feature"; + } EN[31:31]; + } TIMEOUT_CTRL @ 0x30; + +}; diff --git a/rtl/ip/usbdev/data/usbdev.rdl b/rtl/ip/usbdev/data/usbdev.rdl new file mode 100644 index 000000000..b40f8184b --- /dev/null +++ b/rtl/ip/usbdev/data/usbdev.rdl @@ -0,0 +1,1746 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap usbdev #( + longint NEndpoints = 12, + longint NumAlerts = 1 +){ + clk_input = '{ "clk_usb_i" }; + rst_input = '{ "rst_usb_ni" }; + + reg { + desc = "Interrupt State Register"; + field { + sw = r; + hw = rw; + reset = false; + desc = "Raised if a packet was received using an OUT or SETUP transaction.This interrupt is directly tied to whether the RX FIFO is empty, so it should be cleared only after handling the FIFO entry."; + } PKT_RECEIVED[0:0]; + field { + sw = r; + hw = rw; + reset = false; + desc = "Raised if a packet was sent as part of an IN transaction.This interrupt is directly tied to whether a sent packet has not been acknowledged in the !!in_sent register.It should be cleared only after clearing all bits in the !!in_sent register."; + } PKT_SENT[1:1]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if VBUS is lost, thus the link is disconnected."; + } DISCONNECTED[2:2]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if link is active but SOF was not received from host for 4.096 ms. The SOF should be every 1 ms."; + } HOST_LOST[3:3]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if the link is at SE0 longer than 3 us indicating a link reset (host asserts for min 10 ms, device can react after 2.5 us)."; + } LINK_RESET[4:4]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if the line has signaled J for longer than 3ms and is therefore in suspend state."; + } LINK_SUSPEND[5:5]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised when the link becomes active again after being suspended."; + } LINK_RESUME[6:6]; + field { + sw = r; + hw = rw; + reset = false; + desc = "Raised when the Available OUT Buffer FIFO is empty and the device interface is enabled.This interrupt is directly tied to the FIFO status, so the Available OUT Buffer FIFO must be provided with a free buffer before the interrupt can be cleared."; + } AV_OUT_EMPTY[7:7]; + field { + sw = r; + hw = rw; + reset = false; + desc = "Raised when the RX FIFO is full and the device interface is enabled.This interrupt is directly tied to the FIFO status, so the RX FIFO must have an entry removed before the interrupt is cleared.If the condition is not cleared, the interrupt can re-assert."; + } RX_FULL[8:8]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if a write was done to either the Available OUT Buffer FIFO or the Available SETUP Buffer FIFO when the FIFO was full."; + } AV_OVERFLOW[9:9]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if a packet to an IN endpoint started to be received but wasthen dropped due to an error. After transmitting the IN payload,the USB device expects a valid ACK handshake packet. This error israised if either the packet or CRC is invalid, leading to a NAK instead,or if a different token was received."; + } LINK_IN_ERR[10:10]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if a CRC error occurred on a received packet."; + } RX_CRC_ERR[11:11]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if an invalid Packet IDentifier (PID) was received."; + } RX_PID_ERR[12:12]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if an invalid bitstuffing was received."; + } RX_BITSTUFF_ERR[13:13]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised when the USB frame number is updated with a valid SOF."; + } FRAME[14:14]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if VBUS is applied."; + } POWERED[15:15]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = false; + desc = "Raised if a packet to an OUT endpoint started to be received but was then dropped due to an error.This error is raised if the data toggle, token, packet and/or CRC are invalid, or if the appropriate Available OUT Buffer FIFO is empty and/or the Received Buffer FIFO is full when a packet should have been received."; + } LINK_OUT_ERR[16:16]; + field { + sw = r; + hw = rw; + reset = false; + desc = "Raised when the Available SETUP Buffer FIFO is empty and the device interface is enabled.This interrupt is directly tied to the FIFO status, so the Available SETUP Buffer FIFO must be provided with a free buffer before the interrupt can be cleared."; + } AV_SETUP_EMPTY[17:17]; + } INTR_STATE @ 0x0; + + reg { + desc = "Interrupt Enable Register"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.pkt_received is set."; + } PKT_RECEIVED[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.pkt_sent is set."; + } PKT_SENT[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.disconnected is set."; + } DISCONNECTED[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.host_lost is set."; + } HOST_LOST[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.link_reset is set."; + } LINK_RESET[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.link_suspend is set."; + } LINK_SUSPEND[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.link_resume is set."; + } LINK_RESUME[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.av_out_empty is set."; + } AV_OUT_EMPTY[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_full is set."; + } RX_FULL[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.av_overflow is set."; + } AV_OVERFLOW[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.link_in_err is set."; + } LINK_IN_ERR[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_crc_err is set."; + } RX_CRC_ERR[11:11]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_pid_err is set."; + } RX_PID_ERR[12:12]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.rx_bitstuff_err is set."; + } RX_BITSTUFF_ERR[13:13]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.frame is set."; + } FRAME[14:14]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.powered is set."; + } POWERED[15:15]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.link_out_err is set."; + } LINK_OUT_ERR[16:16]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable interrupt when !!INTR_STATE.av_setup_empty is set."; + } AV_SETUP_EMPTY[17:17]; + } INTR_ENABLE @ 0x4; + + external reg { + desc = "Interrupt Test Register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.pkt_received to 1."; + } PKT_RECEIVED[0:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.pkt_sent to 1."; + } PKT_SENT[1:1]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.disconnected to 1."; + } DISCONNECTED[2:2]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.host_lost to 1."; + } HOST_LOST[3:3]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.link_reset to 1."; + } LINK_RESET[4:4]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.link_suspend to 1."; + } LINK_SUSPEND[5:5]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.link_resume to 1."; + } LINK_RESUME[6:6]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.av_out_empty to 1."; + } AV_OUT_EMPTY[7:7]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_full to 1."; + } RX_FULL[8:8]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.av_overflow to 1."; + } AV_OVERFLOW[9:9]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.link_in_err to 1."; + } LINK_IN_ERR[10:10]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_crc_err to 1."; + } RX_CRC_ERR[11:11]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_pid_err to 1."; + } RX_PID_ERR[12:12]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.rx_bitstuff_err to 1."; + } RX_BITSTUFF_ERR[13:13]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.frame to 1."; + } FRAME[14:14]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.powered to 1."; + } POWERED[15:15]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.link_out_err to 1."; + } LINK_OUT_ERR[16:16]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to force !!INTR_STATE.av_setup_empty to 1."; + } AV_SETUP_EMPTY[17:17]; + } INTR_TEST @ 0x8; + + external reg { + desc = "Alert Test Register"; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to trigger one alert event of this kind."; + } FATAL_FAULT[0:0]; + } ALERT_TEST @ 0xC; + + reg { + desc = "USB Control"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Set to connect the USB interface (i.e. assert the pullup)."; + } ENABLE[0:0]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write a 1 to this bit to instruct usbdev to jump to the LinkResuming state.The write will only have an effect when the device is in the LinkPowered state.Its intention is to handle a resume-from-suspend event after the IP has been powered down."; + } RESUME_LINK_ACTIVE[1:1]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "Device address set by host (this should be copied fromthe Set Device ID SETUP packet).This will be zeroed by the hardware when the link resets."; + } DEVICE_ADDRESS[22:16]; + } USBCTRL @ 0x10; + + external reg { + desc = "USB Status"; + field { + sw = r; + hw = w; + desc = "Frame index received from host. On an active link, this will increment every milisecond."; + } FRAME[10:0]; + field { + sw = r; + hw = w; + desc = "Start of frame not received from host for 4.096 ms and the line is active."; + } HOST_LOST[11:11]; + field { + sw = r; + hw = w; + desc = "State of USB link, decoded from line."; + } LINK_STATE[14:12]; + field { + sw = r; + hw = w; + desc = "Reflects the state of the sense pin.1 indicates that the host is providing VBUS.Note that this bit always shows the state of the actual pin and does not take account of the override control."; + } SENSE[15:15]; + field { + sw = r; + hw = w; + desc = "Number of buffers in the Available OUT Buffer FIFO.These buffers are available for receiving OUT DATA packets."; + } AV_OUT_DEPTH[19:16]; + field { + sw = r; + hw = w; + desc = "Number of buffers in the Available SETUP Buffer FIFO.These buffers are available for receiving SETUP DATA packets."; + } AV_SETUP_DEPTH[22:20]; + field { + sw = r; + hw = w; + desc = "Available OUT Buffer FIFO is full."; + } AV_OUT_FULL[23:23]; + field { + sw = r; + hw = w; + desc = "Number of buffers in the Received Buffer FIFO.These buffers have packets that have been received andshould be popped from the FIFO and processed."; + } RX_DEPTH[27:24]; + field { + sw = r; + hw = w; + desc = "Available SETUP Buffer FIFO is full."; + } AV_SETUP_FULL[30:30]; + field { + sw = r; + hw = w; + reset = true; + desc = "Received Buffer FIFO is empty."; + } RX_EMPTY[31:31]; + } USBSTAT @ 0x1C; + + external reg { + desc = "Available OUT Buffer FIFO"; + field { + sw = w; + hw = r; + swmod = true; + desc = "This field contains the buffer ID being passed to the USB receive engine.If the Available OUT Buffer FIFO is full, any write operations are discarded."; + } BUFFER[4:0]; + } AVOUTBUFFER @ 0x20; + + external reg { + desc = "Available SETUP Buffer FIFO"; + field { + sw = w; + hw = r; + swmod = true; + desc = "This field contains the buffer ID being passed to the USB receive engine.If the Available SETUP Buffer FIFO is full, any write operations are discarded."; + } BUFFER[4:0]; + } AVSETUPBUFFER @ 0x24; + + external reg { + hwre = true; + desc = "Received Buffer FIFO"; + field { + sw = r; + hw = rw; + desc = "This field contains the buffer ID that data was received into.On read the buffer ID is popped from the Received Buffer FIFO and returned to software."; + } BUFFER[4:0]; + field { + sw = r; + hw = rw; + desc = "This field contains the data length in bytes of the packet written to the buffer."; + } SIZE[14:8]; + field { + sw = r; + hw = rw; + desc = "This bit indicates if the received transaction is of type SETUP (1) or OUT (0)."; + } SETUP[19:19]; + field { + sw = r; + hw = rw; + desc = "This field contains the endpoint ID to which the packet was directed."; + } EP[23:20]; + } RXFIFO @ 0x28; + + external reg { + desc = "OUT Endpoints Data Toggles"; + field { + sw = rw; + hw = rw; + swmod = true; + desc = "Reading returns the current state of the OUT endpoint Data Toggle flags.Writing sets the Data Toggle flag for each endpoint if the corresponding mask bitin the upper half of this register is set."; + } STATUS[11:0]; + field { + sw = rw; + hw = rw; + swmod = true; + desc = "Reads as zero.When writing, a set bit will cause the Data Toggle flag of the correspondingOUT endpoint to be updated. A clear bit will leave the flag for the correspondingendpoint unchanged."; + } MASK[27:16]; + } OUT_DATA_TOGGLE @ 0x7C; + + external reg { + desc = "IN Endpoints Data Toggles"; + field { + sw = rw; + hw = rw; + swmod = true; + desc = "Reading returns the current state of the IN endpoint Data Toggle flags.Writing sets the Data Toggle flag for each endpoint if the corresponding mask bitin the upper half of this register is set."; + } STATUS[11:0]; + field { + sw = rw; + hw = rw; + swmod = true; + desc = "Reads as zero.When writing, a set bit will cause the Data Toggle flag of the correspondingIN endpoint to be updated. A clear bit will leave the flag for the correspondingendpoint unchanged."; + } MASK[27:16]; + } IN_DATA_TOGGLE @ 0x80; + + external reg { + desc = "USB PHY pins sense.This register can be used to read out the state of the USB device inputs and outputs from software.This is designed to be used for debugging purposes or during chip testing."; + field { + sw = r; + hw = w; + desc = "USB D+ input."; + } RX_DP_I[0:0]; + field { + sw = r; + hw = w; + desc = "USB D- input."; + } RX_DN_I[1:1]; + field { + sw = r; + hw = w; + desc = "USB data input from an external differential receiver, if available."; + } RX_D_I[2:2]; + field { + sw = r; + hw = w; + desc = "USB transmit D+ output (readback)."; + } TX_DP_O[8:8]; + field { + sw = r; + hw = w; + desc = "USB transmit D- output (readback)."; + } TX_DN_O[9:9]; + field { + sw = r; + hw = w; + desc = "USB transmit data value (readback)."; + } TX_D_O[10:10]; + field { + sw = r; + hw = w; + desc = "USB single-ended zero output (readback)."; + } TX_SE0_O[11:11]; + field { + sw = r; + hw = w; + desc = "USB OE output (readback)."; + } TX_OE_O[12:12]; + field { + sw = r; + hw = w; + desc = "USB power sense signal."; + } PWR_SENSE[16:16]; + } PHY_PINS_SENSE @ 0x84; + + reg { + desc = "USB PHY pins drive.This register can be used to control the USB device inputs and outputs from software.This is designed to be used for debugging purposes or during chip testing."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "USB transmit D+ output, used with dn_o."; + } DP_O[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "USB transmit D- output, used with dp_o."; + } DN_O[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "USB transmit data output, encoding K and J when se0_o is 0."; + } D_O[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "USB single-ended zero output."; + } SE0_O[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "USB OE output."; + } OE_O[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Enable differential receiver."; + } RX_ENABLE_O[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "USB D+ pullup enable output."; + } DP_PULLUP_EN_O[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "USB D- pullup enable output."; + } DN_PULLUP_EN_O[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "0: Outputs are controlled by the hardware block.1: Outputs are controlled with this register."; + } EN[16:16]; + } PHY_PINS_DRIVE @ 0x88; + + reg { + desc = "USB PHY Configuration"; + field { + sw = rw; + hw = r; + reset = false; + desc = "Detect received K and J symbols from the usb_rx_d signal, which must be driven from an external differential receiver.If 1, make use of the usb_rx_d input.If 0, the usb_rx_d input is ignored and the usb_rx_dp and usb_rx_dn pair are used to detect K and J (useful for some environments, but will be unlikely to pass full USB compliance).Regardless of the state of this field usb_rx_dp and usb_rx_dn are always used to detect SE0.This bit also feeds the rx_enable pin, activating the receiver when the device is not suspended."; + } USE_DIFF_RCVR[0:0]; + field { + sw = rw; + hw = r; + reset = false; + desc = "If 1, select the d and se0 TX interface.If 0, select the dp and dn TX interface.This directly controls the output pin of the same name.It is intended to be used to enable the use of a variety of external transceivers, to select an encoding that matches the transceiver."; + } TX_USE_D_SE0[1:1]; + field { + sw = rw; + hw = r; + reset = true; + desc = "Recognize a single SE0 bit as an end of packet, otherwise two successive bits are required."; + } EOP_SINGLE_BIT[2:2]; + field { + sw = rw; + hw = r; + reset = false; + desc = "Flip the D+/D- pins.Particularly useful if D+/D- are mapped to SBU1/SBU2 pins of USB-C."; + } PINFLIP[5:5]; + field { + sw = rw; + hw = r; + reset = false; + desc = "0: Enable reference signal generation for clock synchronization, 1: disable it by forcing the associated signals to zero."; + } USB_REF_DISABLE[6:6]; + field { + sw = rw; + hw = r; + reset = false; + desc = "Disable (0) or enable (1) oscillator test mode.If enabled, the device constantly transmits a J/K pattern, which is useful for testing the USB clock.Note that while in oscillator test mode, the device no longer receives SOFs and consequently does not generate the reference signal for clock synchronization.The clock might drift off."; + } TX_OSC_TEST_MODE[7:7]; + } PHY_CONFIG @ 0x8C; + + external reg { + desc = "USB wake module control for suspend / resume"; + async_clk = true; + field { + sw = w; + hw = r; + reset = false; + swmod = true; + desc = "Suspend request to the wake detection module.Trigger the wake detection module to begin monitoring for wake-from-suspend events.When written with a 1, the wake detection module will activate.Activation may not happen immediately, and its status can be verified by checking wake_events.module_active."; + } SUSPEND_REQ[0:0]; + field { + sw = w; + hw = r; + reset = false; + swmod = true; + desc = "Wake acknowledgement.Signal to the wake detection module that it may release control of the pull-ups back to the main block and return to an inactive state.The release back to normal state may not happen immediately.The status can be confirmed via wake_events.module_active.Note that this bit can also be used without powering down, such as when usbdev detects resume signaling before transitions to low power states have begun."; + } WAKE_ACK[1:1]; + } WAKE_CONTROL @ 0x90; + + reg { + desc = "USB wake module events and debug"; + async_clk = true; + field { + sw = r; + hw = w; + reset = false; + desc = "USB aon wake module is active, monitoring events and controlling the pull-ups."; + } MODULE_ACTIVE[0:0]; + field { + sw = r; + hw = w; + reset = false; + desc = "USB aon wake module detected VBUS was interrupted while monitoring events."; + } DISCONNECTED[8:8]; + field { + sw = r; + hw = w; + reset = false; + desc = "USB aon wake module detected a bus reset while monitoring events."; + } BUS_RESET[9:9]; + field { + sw = r; + hw = w; + reset = false; + desc = "USB aon wake module detected a non-idle bus while monitoring events."; + } BUS_NOT_IDLE[10:10]; + } WAKE_EVENTS @ 0x94; + + reg { + desc = "FIFO control register"; + field { + sw = w; + hw = r; + reset = false; + swmod = true; + desc = "Software reset of the Available OUT Buffer FIFO. This must be used only when the USB deviceis not connected to the USB."; + } AVOUT_RST[0:0]; + field { + sw = w; + hw = r; + reset = false; + swmod = true; + desc = "Software reset of the Available SETUP Buffer FIFO. This must be used only when the USB deviceis not connected to the USB."; + } AVSETUP_RST[1:1]; + field { + sw = w; + hw = r; + reset = false; + swmod = true; + desc = "Software reset the of Rx Buffer FIFO. This must be used only when the USB device is notconnected to the USB."; + } RX_RST[2:2]; + } FIFO_CTRL @ 0x98; + + external reg { + desc = "Counter for OUT side USB events."; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Number of events counted."; + } COUNT[7:0]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count the OUT transactions for which the USB device acknowledged the OUT packetand dropped it internally, which is the correct response to a packet transmittedwith an incorrect Data Toggle.The expectation is that this packet is a retry of the previous packet transmissionand that the handshake response was not received intact by the USB host, indicatingunreliable communications.Other causes of Data Toggle synchronization failure may result in data loss."; + } DATATOG_OUT[12:12]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count the SETUP/OUT packets ignored, dropped or NAKed because the RX FIFO was full.SETUP packets have been ignored, Isochronous OUT packets have been dropped, andnon-Isochronous OUT packets have been NAKed."; + } DROP_RX[13:13]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count the OUT packets that could not be accepted because there was no buffer in theAv OUT FIFO. Non-Isochronous OUT packets have been NAKed.Isochronous OUT packets were ignored."; + } DROP_AVOUT[14:14]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count the SETUP packets that were ignored because there was no buffer in theAv SETUP FIFO."; + } IGN_AVSETUP[15:15]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Set of OUT endpoints for which this counter is enabled."; + } ENDPOINTS[27:16]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to reset the counter."; + } RST[31:31]; + } COUNT_OUT @ 0x9C; + + external reg { + desc = "Counter for IN side USB events."; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Number of events counted."; + } COUNT[7:0]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count the IN transactions that were attempted when there was no packet availablein the corresponding 'configin' register(s). This is not necessarily an errorcondition, and the counter primarily offers some visibility into when the INtraffic is underusing the available bus bandwidth.It is of particular utility to Isochronous IN endpoints."; + } NODATA[13:13]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count the IN transactions rejected by the host responding with a NAK handshake."; + } NAK[14:14]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count the IN transactions for which the USB host did not respond with a handshake,and the transactions timed out. This indicates that the host did not receive itand decode it as a valid packet, suggesting that communication is unreliable.Isochronous IN transactions are excluded from this count because there is nohandshake response to Isochronous packet transfers."; + } TIMEOUT[15:15]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Set of endpoints for which this counter is enabled."; + } ENDPOINTS[27:16]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to reset the counter."; + } RST[31:31]; + } COUNT_IN @ 0xA0; + + external reg { + desc = "Count of IN transactions for which no packet data was available.This secondary register allows some partitioning of endpoints among the twocounters, for more targeted measurement, eg. endpoints may be grouped according tothe expected bandwidth usage, or Isochronous vs. non-Isochronous transfers."; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Number of IN transactions that were attempted when there was no packet availablein the corresponding 'configin' register(s)."; + } COUNT[7:0]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Set of endpoints for which this counter is enabled."; + } ENDPOINTS[27:16]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to reset the counter."; + } RST[31:31]; + } COUNT_NODATA_IN @ 0xA4; + + external reg { + desc = "Count of error conditions detected on token packets from the host."; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Number of events counted."; + } COUNT[7:0]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Number of Invalid PIDs detected on packets from the host. Invalid PIDs mayindicate very unreliable communication and/or a substantial frequency mismatchbetween the host and the device."; + } PID_INVALID[27:27]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Number of SETUP/OUT packets that were ignored, dropped or NAKed because aBit Stuffing error was detected."; + } BITSTUFF[28:28]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count SETUP/OUT DATA packets that were ignored, dropped or NAKed because aCRC16 error was detected."; + } CRC16[29:29]; + field { + sw = rw; + hw = rw; + reset = 0x0; + swmod = true; + desc = "Count CRC5 errors detected on token packets sent by the host. CRC5 errors ontoken packets received from the host indicate very unreliable communication andpossibly a substantial frequency mismatch between the host and the device."; + } CRC5[30:30]; + field { + sw = w; + hw = r; + reset = 0x0; + swmod = true; + desc = "Write 1 to reset the counter."; + } RST[31:31]; + } COUNT_ERRORS @ 0xA8; + + reg { + desc = "Enable an endpoint to respond to transactions in the downstream direction.Note that as the default endpoint, endpoint 0 must be enabled in both the IN and OUT directions before enabling the USB interface to connect."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_0[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_1[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_2[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_3[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_4[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_5[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_6[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_7[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_8[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_9[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_10[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable downstream transactions to be received on the endpoint and elicit responses.If the bit is clear, any SETUP or OUT packets sent to the endpoint will be ignored."; + } ENABLE_11[11:11]; + } EP_OUT_ENABLE[1] @ 0x14; + + reg { + desc = "Enable an endpoint to respond to transactions in the upstream direction.Note that as the default endpoint, endpoint 0 must be enabled in both the IN and OUT directions before enabling the USB interface to connect."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_0[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_1[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_2[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_3[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_4[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_5[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_6[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_7[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_8[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_9[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_10[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable upstream transactions to be received on the endpoint and elicit responses.If the bit is clear then any IN packets sent to the endpoint will be ignored."; + } ENABLE_11[11:11]; + } EP_IN_ENABLE[1] @ 0x18; + + reg { + desc = "Receive SETUP transaction enable"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_0[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_1[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_2[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_3[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_4[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_5[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_6[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_7[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_8[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_9[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_10[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "This bit must be set to enable SETUP transactions to bereceived on the endpoint. If the bit is clear then aSETUP packet will be ignored. The bit should be set forcontrol endpoints (and only control endpoints)."; + } SETUP_11[11:11]; + } RXENABLE_SETUP[1] @ 0x2C; + + reg { + desc = "Receive OUT transaction enable"; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_0[0:0]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_1[1:1]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_2[2:2]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_3[3:3]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_4[4:4]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_5[5:5]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_6[6:6]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_7[7:7]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_8[8:8]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_9[9:9]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_10[10:10]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit must be set to enable OUT transactions to be received on the endpoint.If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.Software must set this bit again to receive the next OUT transaction.Until that happens, hardware will continue to NAK any OUT transaction to this endpoint."; + } OUT_11[11:11]; + } RXENABLE_OUT[1] @ 0x30; + + reg { + desc = "Set NAK after OUT transactions"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_0[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_1[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_2[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_3[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_4[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_5[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_6[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_7[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_8[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_9[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_10[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.This bit should not be changed while the endpoint is active."; + } ENABLE_11[11:11]; + } SET_NAK_OUT[1] @ 0x34; + + reg { + desc = "IN Transaction Sent"; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_0[0:0]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_1[1:1]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_2[2:2]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_3[3:3]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_4[4:4]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_5[5:5]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_6[6:6]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_7[7:7]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_8[8:8]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_9[9:9]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_10[10:10]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit will be set when the ACK is received fromthe host to indicate successful packet deliveryas part of an IN transaction."; + } SENT_11[11:11]; + } IN_SENT[1] @ 0x38; + + reg { + desc = "OUT Endpoint STALL control"; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_0[0:0]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_1[1:1]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_2[2:2]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_3[3:3]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_4[4:4]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_5[5:5]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_6[6:6]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_7[7:7]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_8[8:8]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_9[9:9]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_10[10:10]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an OUT transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_11[11:11]; + } OUT_STALL[1] @ 0x3C; + + reg { + desc = "IN Endpoint STALL control"; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_0[0:0]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_1[1:1]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_2[2:2]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_3[3:3]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_4[4:4]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_5[5:5]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_6[6:6]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_7[7:7]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_8[8:8]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_9[9:9]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_10[10:10]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "If this bit is set then an IN transaction to this endpoint will elicit a STALL handshake, when a non-isochronous endpoint is enabled.If the configuration has both STALL and NAK enabled, the STALL handshake will take priority.Note that SETUP transactions are always either accepted or ignored.For endpoints that accept SETUP transactions, a SETUP packet will clear the STALL flag on endpoints for both the IN and OUT directions."; + } ENDPOINT_11[11:11]; + } IN_STALL[1] @ 0x40; + + reg { + desc = "Configure IN Transaction"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The buffer ID containing the data to send when an IN transaction is received on the endpoint."; + } BUFFER[4:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "The number of bytes to send from the buffer.If this is 0 then a CRC only packet is sent.If this is greater than 64 then 64 bytes are sent."; + } SIZE[14:8]; + field { + sw = rw; + onwrite = woclr; + hw = w; + reset = 0x0; + desc = "This bit indicates that the buffer is in the process of being collected by thehost. It becomes set upon the first attempt by the host to collect a buffer fromthis endpoint when the rdy bit was set.It is cleared when the packet has been collected successfully or the pendingtransaction has been canceled by the hardware through detection of alink reset or receipt of a SETUP packet."; + } SENDING[29:29]; + field { + sw = rw; + onwrite = woclr; + hw = rw; + reset = 0x0; + desc = "This bit indicates a pending transaction was canceled by the hardware.The bit is set when the rdy bit is cleared by hardware because of aSETUP packet being received or a link reset being detected.The bit remains set until cleared by being written with a 1."; + } PEND[30:30]; + field { + sw = rw; + hw = rw; + reset = 0x0; + desc = "This bit should be set to indicate the buffer is ready for sending.It will be cleared when the ACK is received indicating the host has accepted the data.This bit will also be cleared if an enabled SETUP transaction is received on the endpoint.This allows use of the IN channel for transfer of SETUP information.The original buffer must be resubmitted after the SETUP sequence is complete.A link reset also clears the bit.In either of the cases where the hardware cancels the transaction it will also set the pend bit."; + } RDY[31:31]; + } CONFIGIN[12] @ 0x44; + + reg { + desc = "OUT Endpoint isochronous setting"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_0[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_1[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_2[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_3[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_4[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_5[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_6[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_7[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_8[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_9[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_10[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be sent for an OUT transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_11[11:11]; + } OUT_ISO[1] @ 0x74; + + reg { + desc = "IN Endpoint isochronous setting"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_0[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_1[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_2[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_3[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_4[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_5[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_6[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_7[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_8[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_9[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_10[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "If this bit is set then the endpoint will be treated as an isochronous endpoint.No handshake packet will be expected for an IN transaction.Note that if a rxenable_setup is set for this endpoint's number, this bit will not take effect.Control endpoint configuration trumps isochronous endpoint configuration."; + } ISO_11[11:11]; + } IN_ISO[1] @ 0x78; + + external mem { + memwidth = 0x20; + mementries = 0x200; + sw = rw; + } BUFFER @ 0x800; + +}; diff --git a/rtl/ip/xadc/data/xadc.rdl b/rtl/ip/xadc/data/xadc.rdl new file mode 100644 index 000000000..97238665a --- /dev/null +++ b/rtl/ip/xadc/data/xadc.rdl @@ -0,0 +1,51 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap xadc { + xbar = '{ + parameter'{ type_: "bool", name: "pipeline", value: "true" }, + parameter'{ type_: "bool", name: "req_fifo_pass", value: "false" }, + parameter'{ type_: "bool", name: "rsp_fifo_pass", value: "false" } + }; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + regfile status{ + reg status_reg_t {regwidth = 8; field {sw=r;} val; }; + + status_reg_t TEMPERATURE; + status_reg_t VCCINT; + status_reg_t VCCAUX; + status_reg_t VPVN; + status_reg_t VREFP; + status_reg_t VREFN; + status_reg_t VCCBRAM; + status_reg_t SUPPY_A_OFFSET @ 0x08; + status_reg_t ADC_A_OFFSET; + status_reg_t ACD_A_GAIN ; + status_reg_t VCCPINT @ 0x0D; + status_reg_t VCCPAUX; + status_reg_t VCCO_DDR; + status_reg_t VAUXP[16]; + status_reg_t MAX_TEMP; + status_reg_t MAX_V_CCINT; + status_reg_t MAX_V_CCAUX; + status_reg_t MAX_VCCBRAM; + status_reg_t MIN_TEMP; + status_reg_t MIN_V_CCINT; + status_reg_t MIN_V_CCAUX; + status_reg_t MIN_VCCBRAM; + }; + + reg { + regwidth = 8; + field {} cfg; + } CONFIG[3] @ 0x40; + + reg { + regwidth = 8; + field {} tr; + } TEST_REG[4] @ 0x43; +}; diff --git a/rtl/system/data/pinmux.rdl b/rtl/system/data/pinmux.rdl new file mode 100644 index 000000000..58067a557 --- /dev/null +++ b/rtl/system/data/pinmux.rdl @@ -0,0 +1,179 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap pinmux { + xbar = '{ + parameter'{ type_: "bool", name: "pipeline", value: "true" }, + parameter'{ type_: "bool", name: "req_fifo_pass", value: "false" }, + parameter'{ type_: "bool", name: "rsp_fifo_pass", value: "false" } + }; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + reg mux_t { + regwidth = 8; + field { + sw = rw; + hw = rw; + } val[7:0]; + }; + + mux_t SER0_TX @ 0x000; + mux_t SER1_TX @ 0x001; + mux_t RS232_TX @ 0x002; + mux_t RS485_TX @ 0x003; + mux_t SCL0 @ 0x004; + mux_t SDA0 @ 0x005; + mux_t SCL1 @ 0x006; + mux_t SDA1 @ 0x007; + mux_t RPH_G0 @ 0x008; + mux_t RPH_G1 @ 0x009; + mux_t RPH_G2_SDA @ 0x00a; + mux_t RPH_G3_SCL @ 0x00b; + mux_t RPH_G4 @ 0x00c; + mux_t RPH_G5 @ 0x00d; + mux_t RPH_G6 @ 0x00e; + mux_t RPH_G7 @ 0x00f; + mux_t RPH_G8 @ 0x010; + mux_t RPH_G9 @ 0x011; + mux_t RPH_G10 @ 0x012; + mux_t RPH_G11 @ 0x013; + mux_t RPH_G12 @ 0x014; + mux_t RPH_G13 @ 0x015; + mux_t RPH_TXD0 @ 0x016; + mux_t RPH_RXD0 @ 0x017; + mux_t RPH_G16 @ 0x018; + mux_t RPH_G17 @ 0x019; + mux_t RPH_G18 @ 0x01a; + mux_t RPH_G19 @ 0x01b; + mux_t RPH_G20 @ 0x01c; + mux_t RPH_G21 @ 0x01d; + mux_t RPH_G22 @ 0x01e; + mux_t RPH_G23 @ 0x01f; + mux_t RPH_G24 @ 0x020; + mux_t RPH_G25 @ 0x021; + mux_t RPH_G26 @ 0x022; + mux_t RPH_G27 @ 0x023; + mux_t AH_TMPIO0 @ 0x024; + mux_t AH_TMPIO1 @ 0x025; + mux_t AH_TMPIO2 @ 0x026; + mux_t AH_TMPIO3 @ 0x027; + mux_t AH_TMPIO4 @ 0x028; + mux_t AH_TMPIO5 @ 0x029; + mux_t AH_TMPIO6 @ 0x02a; + mux_t AH_TMPIO7 @ 0x02b; + mux_t AH_TMPIO8 @ 0x02c; + mux_t AH_TMPIO9 @ 0x02d; + mux_t AH_TMPIO10 @ 0x02e; + mux_t AH_TMPIO11 @ 0x02f; + mux_t AH_TMPIO12 @ 0x030; + mux_t AH_TMPIO13 @ 0x031; + mux_t MB1 @ 0x032; + mux_t MB2 @ 0x033; + mux_t MB4 @ 0x034; + mux_t MB5 @ 0x035; + mux_t MB6 @ 0x036; + mux_t MB7 @ 0x037; + mux_t MB10 @ 0x038; + mux_t PMOD0_1 @ 0x039; + mux_t PMOD0_2 @ 0x03a; + mux_t PMOD0_3 @ 0x03b; + mux_t PMOD0_4 @ 0x03c; + mux_t PMOD0_7 @ 0x03d; + mux_t PMOD0_8 @ 0x03e; + mux_t PMOD0_9 @ 0x03f; + mux_t PMOD0_10 @ 0x040; + mux_t PMOD1_1 @ 0x041; + mux_t PMOD1_2 @ 0x042; + mux_t PMOD1_3 @ 0x043; + mux_t PMOD1_4 @ 0x044; + mux_t PMOD1_7 @ 0x045; + mux_t PMOD1_8 @ 0x046; + mux_t PMOD1_9 @ 0x047; + mux_t PMOD1_10 @ 0x048; + mux_t PMODC_1 @ 0x049; + mux_t PMODC_2 @ 0x04a; + mux_t PMODC_3 @ 0x04b; + mux_t PMODC_4 @ 0x04c; + mux_t PMODC_5 @ 0x04d; + mux_t PMODC_6 @ 0x04e; + mux_t APPSPI_D0 @ 0x04f; + mux_t APPSPI_CLK @ 0x050; + mux_t APPSPI_CS @ 0x051; + mux_t MICROSD_CMD @ 0x052; + mux_t MICROSD_CLK @ 0x053; + mux_t MICROSD_DAT3 @ 0x054; + + mux_t GPIO_0_IOS_0 @ 0x800; + mux_t GPIO_0_IOS_1 @ 0x801; + mux_t GPIO_0_IOS_2 @ 0x802; + mux_t GPIO_0_IOS_3 @ 0x803; + mux_t GPIO_0_IOS_4 @ 0x804; + mux_t GPIO_0_IOS_5 @ 0x805; + mux_t GPIO_0_IOS_6 @ 0x806; + mux_t GPIO_0_IOS_7 @ 0x807; + mux_t GPIO_0_IOS_8 @ 0x808; + mux_t GPIO_0_IOS_9 @ 0x809; + mux_t GPIO_0_IOS_10 @ 0x80a; + mux_t GPIO_0_IOS_11 @ 0x80b; + mux_t GPIO_0_IOS_12 @ 0x80c; + mux_t GPIO_0_IOS_13 @ 0x80d; + mux_t GPIO_0_IOS_14 @ 0x80e; + mux_t GPIO_0_IOS_15 @ 0x80f; + mux_t GPIO_0_IOS_16 @ 0x810; + mux_t GPIO_0_IOS_17 @ 0x811; + mux_t GPIO_0_IOS_18 @ 0x812; + mux_t GPIO_0_IOS_19 @ 0x813; + mux_t GPIO_0_IOS_20 @ 0x814; + mux_t GPIO_0_IOS_21 @ 0x815; + mux_t GPIO_0_IOS_22 @ 0x816; + mux_t GPIO_0_IOS_23 @ 0x817; + mux_t GPIO_0_IOS_24 @ 0x818; + mux_t GPIO_0_IOS_25 @ 0x819; + mux_t GPIO_0_IOS_26 @ 0x81a; + mux_t GPIO_0_IOS_27 @ 0x81b; + mux_t GPIO_1_IOS_0 @ 0x81c; + mux_t GPIO_1_IOS_1 @ 0x81d; + mux_t GPIO_1_IOS_2 @ 0x81e; + mux_t GPIO_1_IOS_3 @ 0x81f; + mux_t GPIO_1_IOS_4 @ 0x820; + mux_t GPIO_1_IOS_5 @ 0x821; + mux_t GPIO_1_IOS_6 @ 0x822; + mux_t GPIO_1_IOS_7 @ 0x823; + mux_t GPIO_1_IOS_8 @ 0x824; + mux_t GPIO_1_IOS_9 @ 0x825; + mux_t GPIO_1_IOS_10 @ 0x826; + mux_t GPIO_1_IOS_11 @ 0x827; + mux_t GPIO_1_IOS_12 @ 0x828; + mux_t GPIO_1_IOS_13 @ 0x829; + mux_t GPIO_2_IOS_0 @ 0x82a; + mux_t GPIO_2_IOS_1 @ 0x82b; + mux_t GPIO_2_IOS_2 @ 0x82c; + mux_t GPIO_2_IOS_3 @ 0x82d; + mux_t GPIO_2_IOS_4 @ 0x82e; + mux_t GPIO_2_IOS_5 @ 0x82f; + mux_t GPIO_2_IOS_6 @ 0x830; + mux_t GPIO_2_IOS_7 @ 0x831; + mux_t GPIO_3_IOS_0 @ 0x832; + mux_t GPIO_3_IOS_1 @ 0x833; + mux_t GPIO_3_IOS_2 @ 0x834; + mux_t GPIO_3_IOS_3 @ 0x835; + mux_t GPIO_3_IOS_4 @ 0x836; + mux_t GPIO_3_IOS_5 @ 0x837; + mux_t GPIO_3_IOS_6 @ 0x838; + mux_t GPIO_3_IOS_7 @ 0x839; + mux_t GPIO_4_IOS_0 @ 0x83a; + mux_t GPIO_4_IOS_1 @ 0x83b; + mux_t GPIO_4_IOS_2 @ 0x83c; + mux_t GPIO_4_IOS_3 @ 0x83d; + mux_t GPIO_4_IOS_4 @ 0x83e; + mux_t GPIO_4_IOS_5 @ 0x83f; + mux_t UART_0_RX @ 0x840; + mux_t UART_1_RX @ 0x841; + mux_t UART_2_RX @ 0x842; + mux_t SPI_0_CIPO @ 0x843; + mux_t SPI_1_CIPO @ 0x844; + mux_t SPI_2_CIPO @ 0x845; +}; diff --git a/rtl/system/data/rv_plic.rdl b/rtl/system/data/rv_plic.rdl new file mode 100644 index 000000000..89d6b36cb --- /dev/null +++ b/rtl/system/data/rv_plic.rdl @@ -0,0 +1,729 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap rv_plic #( + longint NumSrc = 32, + longint NumTarget = 1, + longint PrioWidth = 2, + longint NumAlerts = 1 +){ + xbar = '{ + parameter'{ type_: "bool", name: "pipeline", value: "true" }, + parameter'{ type_: "bool", name: "req_fifo_pass", value: "false" }, + parameter'{ type_: "bool", name: "rsp_fifo_pass", value: "false" } + }; + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + reg { + desc = "Interrupt Source 0 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO0[1:0]; + } PRIO0 @ 0x0; + + reg { + desc = "Interrupt Source 1 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO1[1:0]; + } PRIO1 @ 0x4; + + reg { + desc = "Interrupt Source 2 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO2[1:0]; + } PRIO2 @ 0x8; + + reg { + desc = "Interrupt Source 3 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO3[1:0]; + } PRIO3 @ 0xC; + + reg { + desc = "Interrupt Source 4 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO4[1:0]; + } PRIO4 @ 0x10; + + reg { + desc = "Interrupt Source 5 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO5[1:0]; + } PRIO5 @ 0x14; + + reg { + desc = "Interrupt Source 6 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO6[1:0]; + } PRIO6 @ 0x18; + + reg { + desc = "Interrupt Source 7 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO7[1:0]; + } PRIO7 @ 0x1C; + + reg { + desc = "Interrupt Source 8 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO8[1:0]; + } PRIO8 @ 0x20; + + reg { + desc = "Interrupt Source 9 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO9[1:0]; + } PRIO9 @ 0x24; + + reg { + desc = "Interrupt Source 10 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO10[1:0]; + } PRIO10 @ 0x28; + + reg { + desc = "Interrupt Source 11 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO11[1:0]; + } PRIO11 @ 0x2C; + + reg { + desc = "Interrupt Source 12 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO12[1:0]; + } PRIO12 @ 0x30; + + reg { + desc = "Interrupt Source 13 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO13[1:0]; + } PRIO13 @ 0x34; + + reg { + desc = "Interrupt Source 14 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO14[1:0]; + } PRIO14 @ 0x38; + + reg { + desc = "Interrupt Source 15 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO15[1:0]; + } PRIO15 @ 0x3C; + + reg { + desc = "Interrupt Source 16 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO16[1:0]; + } PRIO16 @ 0x40; + + reg { + desc = "Interrupt Source 17 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO17[1:0]; + } PRIO17 @ 0x44; + + reg { + desc = "Interrupt Source 18 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO18[1:0]; + } PRIO18 @ 0x48; + + reg { + desc = "Interrupt Source 19 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO19[1:0]; + } PRIO19 @ 0x4C; + + reg { + desc = "Interrupt Source 20 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO20[1:0]; + } PRIO20 @ 0x50; + + reg { + desc = "Interrupt Source 21 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO21[1:0]; + } PRIO21 @ 0x54; + + reg { + desc = "Interrupt Source 22 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO22[1:0]; + } PRIO22 @ 0x58; + + reg { + desc = "Interrupt Source 23 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO23[1:0]; + } PRIO23 @ 0x5C; + + reg { + desc = "Interrupt Source 24 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO24[1:0]; + } PRIO24 @ 0x60; + + reg { + desc = "Interrupt Source 25 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO25[1:0]; + } PRIO25 @ 0x64; + + reg { + desc = "Interrupt Source 26 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO26[1:0]; + } PRIO26 @ 0x68; + + reg { + desc = "Interrupt Source 27 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO27[1:0]; + } PRIO27 @ 0x6C; + + reg { + desc = "Interrupt Source 28 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO28[1:0]; + } PRIO28 @ 0x70; + + reg { + desc = "Interrupt Source 29 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO29[1:0]; + } PRIO29 @ 0x74; + + reg { + desc = "Interrupt Source 30 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO30[1:0]; + } PRIO30 @ 0x78; + + reg { + desc = "Interrupt Source 31 Priority"; + field { + sw = rw; + hw = r; + reset = 0x0; + } PRIO31[1:0]; + } PRIO31 @ 0x7C; + + reg { + desc = "Threshold of priority for Target 0"; + field { + sw = rw; + hw = r; + reset = 0x0; + } THRESHOLD0[1:0]; + } THRESHOLD0 @ 0x200000; + + external reg { + hwre = true; + desc = "Claim interrupt by read, complete interrupt by write for Target 0.Value read/written is interrupt ID. Reading a value of 0 means no pending interrupts."; + field { + sw = rw; + hw = rw; + swmod = true; + } CC0[4:0]; + } CC0 @ 0x200004; + + reg { + desc = "msip for Hart 0.Write 1 to here asserts software interrupt for Hart msip_o[0], write 0 to clear."; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Software Interrupt Pending register"; + } MSIP0[0:0]; + } MSIP0 @ 0x4000000; + + reg { + desc = "Interrupt Pending"; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_0[0:0]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_1[1:1]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_2[2:2]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_3[3:3]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_4[4:4]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_5[5:5]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_6[6:6]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_7[7:7]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_8[8:8]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_9[9:9]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_10[10:10]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_11[11:11]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_12[12:12]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_13[13:13]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_14[14:14]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_15[15:15]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_16[16:16]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_17[17:17]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_18[18:18]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_19[19:19]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_20[20:20]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_21[21:21]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_22[22:22]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_23[23:23]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_24[24:24]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_25[25:25]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_26[26:26]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_27[27:27]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_28[28:28]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_29[29:29]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_30[30:30]; + field { + sw = r; + hw = w; + reset = 0x0; + desc = "Interrupt Pending of Source"; + } P_31[31:31]; + } IP[1] @ 0x1000; + + reg { + desc = "Interrupt Enable for Target 0"; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_0[0:0]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_1[1:1]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_2[2:2]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_3[3:3]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_4[4:4]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_5[5:5]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_6[6:6]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_7[7:7]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_8[8:8]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_9[9:9]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_10[10:10]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_11[11:11]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_12[12:12]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_13[13:13]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_14[14:14]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_15[15:15]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_16[16:16]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_17[17:17]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_18[18:18]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_19[19:19]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_20[20:20]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_21[21:21]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_22[22:22]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_23[23:23]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_24[24:24]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_25[25:25]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_26[26:26]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_27[27:27]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_28[28:28]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_29[29:29]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_30[30:30]; + field { + sw = rw; + hw = r; + reset = 0x0; + desc = "Interrupt Enable of Source"; + } E_31[31:31]; + } IE0[1] @ 0x2000; + +}; diff --git a/rtl/system/data/rv_timer.rdl b/rtl/system/data/rv_timer.rdl new file mode 100644 index 000000000..564903629 --- /dev/null +++ b/rtl/system/data/rv_timer.rdl @@ -0,0 +1,40 @@ +/* Copyright lowRISC contributors. +* Licensed under the Apache License, Version 2.0; see LICENSE for details. +* SPDX-License-Identifier: Apache-2.0 +*/ + +addrmap rv_timer { + clk_input = '{ "clk_sys_i" }; + rst_input = '{ "rst_sys_ni" }; + + reg { + field { + desc = "mtime cmp low"; + sw = rw; + hw = rw; + } value[32]; + }MTIMECMPL @4000; + reg { + field { + desc = "mtime cmp high"; + sw = rw; + hw = rw; + } value[32]; + }MTIMECMPH; + + reg { + field { + desc = "mtime low"; + sw = rw; // read-write + hw = rw; + } VALUE[32]; + }MTIMEL @ 0xbff8; + reg { + field { + desc = "mtime high"; + sw = rw; + hw = rw; + reset = 0x00000000; + } VALUE[32]; + }MTIMEH; +}; diff --git a/rtl/system/pinmux.sv b/rtl/system/pinmux.sv index 3e11575a5..fe28c4426 100644 --- a/rtl/system/pinmux.sv +++ b/rtl/system/pinmux.sv @@ -12,36 +12,50 @@ module pinmux input logic clk_i, input logic rst_ni, + + + // GPIO IOs - output [31:0] gpio_ios_o [GPIO_NUM], - input [31:0] gpio_ios_i [GPIO_NUM], - input [31:0] gpio_ios_en_i[GPIO_NUM], + output [31:0] gpio_ios_o [5], + input [31:0] gpio_ios_i [5], + input [31:0] gpio_ios_en_i[5], // PWM IOs - input [6:0] pwm_out_i [PWM_NUM], - input [6:0] pwm_out_en_i[PWM_NUM], + input [6:0] pwm_out_i [1], + input [6:0] pwm_out_en_i[1], + + + + + + // UART IOs - output uart_rx_o[UART_NUM], - input uart_tx_i [UART_NUM], - input uart_tx_en_i[UART_NUM], + output uart_rx_o[3], + input uart_tx_i [3], + input uart_tx_en_i[3], // I2C IOs - output i2c_scl_o [I2C_NUM], - input i2c_scl_i [I2C_NUM], - input i2c_scl_en_i[I2C_NUM], - output i2c_sda_o [I2C_NUM], - input i2c_sda_i [I2C_NUM], - input i2c_sda_en_i[I2C_NUM], + output i2c_scl_o [2], + input i2c_scl_i [2], + input i2c_scl_en_i[2], + output i2c_sda_o [2], + input i2c_sda_i [2], + input i2c_sda_en_i[2], + + // SPI IOs - output spi_cipo_o[SPI_NUM], - input spi_copi_i [SPI_NUM], - input spi_copi_en_i[SPI_NUM], - input spi_sclk_i [SPI_NUM], - input spi_sclk_en_i[SPI_NUM], - input [3:0] spi_cs_i [SPI_NUM], - input [3:0] spi_cs_en_i[SPI_NUM], + output spi_cipo_o[3], + input spi_copi_i [3], + input spi_copi_en_i[3], + input spi_sclk_i [3], + input spi_sclk_en_i[3], + input [3:0] spi_cs_i [3], + input [3:0] spi_cs_en_i[3], + + + // Pin Signals input sonata_in_pins_t in_from_pins_i, @@ -6491,7 +6505,7 @@ module pinmux .clk_i, .rst_ni, .in_i({ - 1'b1, + 1'b0, in_from_pins_i[IN_PIN_SER0_RX] }), .sel_i(uart_rx_0_sel), @@ -6525,7 +6539,7 @@ module pinmux .clk_i, .rst_ni, .in_i({ - 1'b1, + 1'b0, in_from_pins_i[IN_PIN_SER1_RX], inout_from_pins_i[INOUT_PIN_RPH_RXD0], inout_from_pins_i[INOUT_PIN_AH_TMPIO0], @@ -6563,7 +6577,7 @@ module pinmux .clk_i, .rst_ni, .in_i({ - 1'b1, + 1'b0, in_from_pins_i[IN_PIN_SER1_RX], in_from_pins_i[IN_PIN_RS232_RX], in_from_pins_i[IN_PIN_RS485_RX], diff --git a/rtl/system/sonata_pkg.sv b/rtl/system/sonata_pkg.sv index d7695ee62..66ebb57c4 100644 --- a/rtl/system/sonata_pkg.sv +++ b/rtl/system/sonata_pkg.sv @@ -7,22 +7,51 @@ package sonata_pkg; // Number of Instances - localparam int unsigned GPIO_NUM = 5; + localparam int unsigned SRAM_NUM = 1; + localparam int unsigned REV_TAG_NUM = 1; + localparam int unsigned HYPERRAM_NUM = 1; + localparam int unsigned GPIO_NUM = 6; localparam int unsigned PWM_NUM = 1; + localparam int unsigned PINMUX_NUM = 1; + localparam int unsigned RGBLED_CTRL_NUM = 1; + localparam int unsigned HW_REV_NUM = 1; + localparam int unsigned XADC_NUM = 1; + localparam int unsigned SYSTEM_INFO_NUM = 1; + localparam int unsigned TIMER_NUM = 1; localparam int unsigned UART_NUM = 3; localparam int unsigned I2C_NUM = 2; + localparam int unsigned SPI_LCD_NUM = 1; + localparam int unsigned SPI_ETHMAC_NUM = 1; localparam int unsigned SPI_NUM = 3; + localparam int unsigned USBDEV_NUM = 1; + localparam int unsigned RV_PLIC_NUM = 1; + localparam int unsigned DBG_DEV_NUM = 1; // Width of block IO arrays localparam int unsigned GPIO_IOS_WIDTH = 32; localparam int unsigned PWM_OUT_WIDTH = 7; + localparam int unsigned UART_RX_WIDTH = 1; + localparam int unsigned UART_TX_WIDTH = 1; + localparam int unsigned I2C_SCL_WIDTH = 1; + localparam int unsigned I2C_SDA_WIDTH = 1; + localparam int unsigned SPI_LCD_CIPO_WIDTH = 1; + localparam int unsigned SPI_LCD_COPI_WIDTH = 1; + localparam int unsigned SPI_LCD_SCLK_WIDTH = 1; + localparam int unsigned SPI_LCD_CS_WIDTH = 4; + localparam int unsigned SPI_ETHMAC_CIPO_WIDTH = 1; + localparam int unsigned SPI_ETHMAC_COPI_WIDTH = 1; + localparam int unsigned SPI_ETHMAC_SCLK_WIDTH = 1; + localparam int unsigned SPI_ETHMAC_CS_WIDTH = 4; + localparam int unsigned SPI_CIPO_WIDTH = 1; + localparam int unsigned SPI_COPI_WIDTH = 1; + localparam int unsigned SPI_SCLK_WIDTH = 1; localparam int unsigned SPI_CS_WIDTH = 4; // Instance-specific GPIO core input/output widths. // Include the fixed (non-pinmux) GPIO used for on-board peripherals. // Each must be less than GPIO_IOS_WIDTH. - localparam int unsigned GPIO_INST_IN_WIDTH[GPIO_NUM+1] = {17, 28, 14, 8, 8, 6}; - localparam int unsigned GPIO_INST_OUT_WIDTH[GPIO_NUM+1] = { 8, 28, 14, 8, 8, 6}; + localparam int unsigned GPIO_INST_IN_WIDTH[GPIO_NUM] = {17, 28, 14, 8, 8, 6}; + localparam int unsigned GPIO_INST_OUT_WIDTH[GPIO_NUM] = { 8, 28, 14, 8, 8, 6}; // Number of input, output, and inout pins localparam int unsigned IN_PIN_NUM = 8; diff --git a/rtl/system/sonata_system.sv b/rtl/system/sonata_system.sv index c97ac152b..8377bc0ea 100644 --- a/rtl/system/sonata_system.sv +++ b/rtl/system/sonata_system.sv @@ -129,7 +129,7 @@ module sonata_system localparam int unsigned FixedSpiNum = 2; // Number of SPI devices that don't pass through the pinmux localparam int unsigned TotalSpiNum = SPI_NUM + FixedSpiNum; // The total number of SPI devices localparam int unsigned FixedGpioNum = 1; // Number of GPIO instances that don't pass through the pinmux - localparam int unsigned TotalGpioNum = GPIO_NUM + FixedGpioNum; // The total number of GPIO instances + localparam int unsigned TotalGpioNum = GPIO_NUM; // The total number of GPIO instances localparam int unsigned TAccessLatency = 0; // Cycles of read data latency. // The number of data bits controlled by each mask bit; since the CPU requires @@ -301,8 +301,8 @@ module sonata_system tlul_pkg::tl_d2h_t tl_sram_b_d2h; tlul_pkg::tl_h2d_t tl_hyperram_h2d[2]; tlul_pkg::tl_d2h_t tl_hyperram_d2h[2]; - tlul_pkg::tl_h2d_t tl_gpio_h2d; - tlul_pkg::tl_d2h_t tl_gpio_d2h; + tlul_pkg::tl_h2d_t tl_gpio_h2d[GPIO_NUM]; + tlul_pkg::tl_d2h_t tl_gpio_d2h[GPIO_NUM]; tlul_pkg::tl_h2d_t tl_xadc_h2d; tlul_pkg::tl_d2h_t tl_xadc_d2h; tlul_pkg::tl_h2d_t tl_uart_h2d[UART_NUM]; @@ -360,8 +360,8 @@ module sonata_system .tl_rev_tag_i (tl_rev_tag_d2h), .tl_gpio_o (tl_gpio_h2d), .tl_gpio_i (tl_gpio_d2h), - .tl_pwm_o ('{tl_pwm_h2d}), - .tl_pwm_i ('{tl_pwm_d2h}), + .tl_pwm_o (tl_pwm_h2d), + .tl_pwm_i (tl_pwm_d2h), .tl_system_info_o (tl_system_info_h2d), .tl_system_info_i (tl_system_info_d2h), .tl_pinmux_o (tl_pinmux_h2d), @@ -1263,9 +1263,9 @@ module sonata_system .spi_cs_i(spi_cs), .spi_cs_en_i('{default: '1}), // All continuously enabled. - .gpio_ios_o(gpio_from_pins[1:GPIO_NUM]), - .gpio_ios_i(gpio_to_pins[1:GPIO_NUM]), - .gpio_ios_en_i(gpio_to_pins_enable[1:GPIO_NUM]), + .gpio_ios_o(gpio_from_pins[1:GPIO_NUM-FixedGpioNum]), + .gpio_ios_i(gpio_to_pins[1:GPIO_NUM-FixedGpioNum]), + .gpio_ios_en_i(gpio_to_pins_enable[1:GPIO_NUM-FixedGpioNum]), .in_from_pins_i, .out_to_pins_o(out_to_pins_data), diff --git a/rtl/templates/pinmux.sv.tpl b/rtl/templates/pinmux.sv.tpl index 1847fe54b..7ddc2f863 100644 --- a/rtl/templates/pinmux.sv.tpl +++ b/rtl/templates/pinmux.sv.tpl @@ -13,10 +13,12 @@ module pinmux input logic rst_ni, % for block in config.blocks: + % if block.muxed_instances > 0: // ${block.name.upper()} IOs - % for port_definition in block_port_definitions(block): + % for port_definition in block_port_definitions(block): ${port_definition}, - % endfor + % endfor + % endif % endfor // Pin Signals diff --git a/rtl/templates/sonata_pkg.sv.tpl b/rtl/templates/sonata_pkg.sv.tpl index db397630b..297981147 100644 --- a/rtl/templates/sonata_pkg.sv.tpl +++ b/rtl/templates/sonata_pkg.sv.tpl @@ -23,8 +23,8 @@ package sonata_pkg; // Instance-specific GPIO core input/output widths. // Include the fixed (non-pinmux) GPIO used for on-board peripherals. // Each must be less than GPIO_IOS_WIDTH. - localparam int unsigned GPIO_INST_IN_WIDTH[GPIO_NUM+1] = {17, 28, 14, 8, 8, 6}; - localparam int unsigned GPIO_INST_OUT_WIDTH[GPIO_NUM+1] = { 8, 28, 14, 8, 8, 6}; + localparam int unsigned GPIO_INST_IN_WIDTH[GPIO_NUM] = {17, 28, 14, 8, 8, 6}; + localparam int unsigned GPIO_INST_OUT_WIDTH[GPIO_NUM] = { 8, 28, 14, 8, 8, 6}; // Number of input, output, and inout pins localparam int unsigned IN_PIN_NUM = ${len(in_pins)}; diff --git a/rtl/templates/sonata_xbar_main.sv.tpl b/rtl/templates/sonata_xbar_main.sv.tpl index 9a6f6a065..65e5ce3e3 100644 --- a/rtl/templates/sonata_xbar_main.sv.tpl +++ b/rtl/templates/sonata_xbar_main.sv.tpl @@ -21,42 +21,10 @@ module sonata_xbar_main output tlul_pkg::tl_d2h_t tl_dbg_host_o, // Device interfaces - output tlul_pkg::tl_h2d_t tl_sram_o, - input tlul_pkg::tl_d2h_t tl_sram_i, - output tlul_pkg::tl_h2d_t tl_hyperram_o, - input tlul_pkg::tl_d2h_t tl_hyperram_i, - output tlul_pkg::tl_h2d_t tl_rev_tag_o, - input tlul_pkg::tl_d2h_t tl_rev_tag_i, - output tlul_pkg::tl_h2d_t tl_gpio_o, - input tlul_pkg::tl_d2h_t tl_gpio_i, - output tlul_pkg::tl_h2d_t tl_pinmux_o, - input tlul_pkg::tl_d2h_t tl_pinmux_i, - output tlul_pkg::tl_h2d_t tl_system_info_o, - input tlul_pkg::tl_d2h_t tl_system_info_i, - output tlul_pkg::tl_h2d_t tl_rgbled_ctrl_o, - input tlul_pkg::tl_d2h_t tl_rgbled_ctrl_i, - output tlul_pkg::tl_h2d_t tl_hw_rev_o, - input tlul_pkg::tl_d2h_t tl_hw_rev_i, - output tlul_pkg::tl_h2d_t tl_xadc_o, - input tlul_pkg::tl_d2h_t tl_xadc_i, - output tlul_pkg::tl_h2d_t tl_timer_o, - input tlul_pkg::tl_d2h_t tl_timer_i, - output tlul_pkg::tl_h2d_t tl_spi_lcd_o, - input tlul_pkg::tl_d2h_t tl_spi_lcd_i, - output tlul_pkg::tl_h2d_t tl_spi_ethmac_o, - input tlul_pkg::tl_d2h_t tl_spi_ethmac_i, - % for block in config.blocks: - % if not block.name == "gpio": - output tlul_pkg::tl_h2d_t tl_${block.name}_o[${block.name.upper()}_NUM], - input tlul_pkg::tl_d2h_t tl_${block.name}_i[${block.name.upper()}_NUM], - % endif + % for num, block in enumerate(config.blocks): + output tlul_pkg::tl_h2d_t tl_${block.name}_o${("[" + block.name.upper()+"_NUM]") if block.instances > 1 else ""}, + input tlul_pkg::tl_d2h_t tl_${block.name}_i${("[" + block.name.upper()+"_NUM]") if block.instances > 1 else ""}${',' if num < len(config.blocks) - 1 else ''} % endfor - output tlul_pkg::tl_h2d_t tl_usbdev_o, - input tlul_pkg::tl_d2h_t tl_usbdev_i, - output tlul_pkg::tl_h2d_t tl_dbg_dev_o, - input tlul_pkg::tl_d2h_t tl_dbg_dev_i, - output tlul_pkg::tl_h2d_t tl_rv_plic_o, - input tlul_pkg::tl_d2h_t tl_rv_plic_i ); xbar_main xbar ( @@ -73,44 +41,12 @@ module sonata_xbar_main .tl_dbg_host_o (tl_dbg_host_o), // Device interfaces. - .tl_sram_o (tl_sram_o), - .tl_sram_i (tl_sram_i), - .tl_hyperram_o (tl_hyperram_o), - .tl_hyperram_i (tl_hyperram_i), - .tl_rev_tag_o (tl_rev_tag_o), - .tl_rev_tag_i (tl_rev_tag_i), - .tl_gpio_o (tl_gpio_o), - .tl_gpio_i (tl_gpio_i), - .tl_pinmux_o (tl_pinmux_o), - .tl_pinmux_i (tl_pinmux_i), - .tl_system_info_o (tl_system_info_o), - .tl_system_info_i (tl_system_info_i), - .tl_rgbled_ctrl_o (tl_rgbled_ctrl_o), - .tl_rgbled_ctrl_i (tl_rgbled_ctrl_i), - .tl_hw_rev_o (tl_hw_rev_o), - .tl_hw_rev_i (tl_hw_rev_i), - .tl_xadc_o (tl_xadc_o), - .tl_xadc_i (tl_xadc_i), - .tl_timer_o (tl_timer_o), - .tl_timer_i (tl_timer_i), - .tl_spi_lcd_i (tl_spi_lcd_i), - .tl_spi_lcd_o (tl_spi_lcd_o), - .tl_spi_ethmac_i (tl_spi_ethmac_i), - .tl_spi_ethmac_o (tl_spi_ethmac_o), % for block in config.blocks: - % if not block.name == "gpio": - % for i in range(block.instances): - .tl_${block.name}${i}_o (tl_${block.name}_o[${i}]), - .tl_${block.name}${i}_i (tl_${block.name}_i[${i}]), + % for i in range(block.instances): + .tl_${block.name}${i if block.instances > 1 else ""}_o (tl_${block.name}_o${f"[{i}]" if block.instances > 1 else ""}), + .tl_${block.name}${i if block.instances > 1 else ""}_i (tl_${block.name}_i${f"[{i}]" if block.instances > 1 else ""}), + % endfor % endfor - % endif - % endfor - .tl_usbdev_o (tl_usbdev_o), - .tl_usbdev_i (tl_usbdev_i), - .tl_dbg_dev_o (tl_dbg_dev_o), - .tl_dbg_dev_i (tl_dbg_dev_i), - .tl_rv_plic_o (tl_rv_plic_o), - .tl_rv_plic_i (tl_rv_plic_i), .scanmode_i (prim_mubi_pkg::MuBi4False) ); diff --git a/util/top_gen.py b/util/top_gen.py index 129607609..79cfdf068 100755 --- a/util/top_gen.py +++ b/util/top_gen.py @@ -3,10 +3,22 @@ # Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 +import subprocess from pathlib import Path from top_gen import generator, parser +RDL_GEN_FOLDER = Path("build/rdl") + if __name__ == "__main__": - config = parser.parse_top_config(Path("data/top_config.toml")) + # Generates reg2hw, hw2reg and rdl.json from the rdl files. + RDL_GEN_FOLDER.mkdir(parents=True, exist_ok=True) + subprocess.run( + ["rdl2ot", "export-rtl", "--soc", "data/top.rdl", RDL_GEN_FOLDER], + check=True, + ) + + config = parser.parse_top_config( + Path("data/top_config.toml"), RDL_GEN_FOLDER / "rdl.json" + ) generator.generate_top(config) diff --git a/util/top_gen/generator.py b/util/top_gen/generator.py index 7f5292440..6f1735453 100644 --- a/util/top_gen/generator.py +++ b/util/top_gen/generator.py @@ -43,7 +43,7 @@ def is_inout(self) -> bool: @property def name(self) -> str: uid = self.uid - suffix = f"_{uid.io_index}" if uid.io_index is not None else "" + suffix = "" if uid.io_index in [None] else f"_{uid.io_index}" return f"{uid.block}_{uid.io}_{uid.instance}{suffix}" @property @@ -55,7 +55,7 @@ def io_idx_str(self) -> str: @property def doc_name(self) -> str: uid = self.uid - suffix = f"_{uid.io_index}" if uid.io_index is not None else "" + suffix = "" if uid.io_index in [None] else f"_{uid.io_index}" if self.only_instance: return f"{uid.block}_{uid.io}{suffix}" else: @@ -78,14 +78,14 @@ class PinFlat: @property def name(self) -> str: - if self.group_index is None: + if self.group_index in [None]: return f"{self.group_name}" else: return f"{self.group_name}_{self.group_index}" @property def doc_name(self) -> str: - if self.group_index is None: + if self.group_index in [None]: return f"{self.group_name}" else: return f"{self.group_name}[{self.group_index}]" @@ -147,7 +147,7 @@ def flatten_block_ios(blocks: list[Block]) -> Iterator[BlockIoFlat]: for block in blocks: for instance in range(block.instances): for io in block.ios: - if io.length is None: + if io.length in [None, 1]: yield BlockIoFlat( uid=BlockIoUid( block.name, @@ -160,7 +160,7 @@ def flatten_block_ios(blocks: list[Block]) -> Iterator[BlockIoFlat]: combine=io.combine, ) else: - for io_index in range(io.length): + for io_index in range(io.length if io.length else 0): yield BlockIoFlat( uid=BlockIoUid( block.name, @@ -193,7 +193,7 @@ def pin_direction(pin: Pin) -> Direction: for pin in pins: direction = pin_direction(pin) - if pin.length is None: + if pin.length in [None, 1]: yield PinFlat( pin.name, pin.block_ios, @@ -201,7 +201,7 @@ def pin_direction(pin: Pin) -> Direction: no_default_out=pin.no_default_out, ) else: - for group_index in range(pin.length): + for group_index in range(pin.length if pin.length else 0): block_io_links = [ BlockIoUid( block_io.block, @@ -225,10 +225,10 @@ def pin_direction(pin: Pin) -> Direction: def block_io_to_pin_map( blocks: list[BlockIoFlat], pins: list[PinFlat] ) -> BlockIoToPinsMap: - mapping: BlockIoToPinsMap = {block_io.uid: [] for block_io in blocks} + mapping: BlockIoToPinsMap = {} for pin in pins: for link in pin.block_io_links: - mapping[link].append(pin) + mapping.setdefault(link, []).append(pin) return mapping @@ -242,16 +242,12 @@ def output_block_ios_iter( ): continue - possible_pins = block_io_to_pins[block_io.uid] - - if len(possible_pins) == 0: - continue - - yield OutputBlockIo( - block_io, - possible_pins, - max(len(possible_pins) + 1, 2), - ) + if possible_pins := block_io_to_pins.get(block_io.uid): + yield OutputBlockIo( + block_io, + possible_pins, + max(len(possible_pins) + 1, 2), + ) def output_pins_iter( @@ -306,10 +302,12 @@ def combined_input_block_ios_iter( def block_port_definitions(block: Block) -> Iterator[str]: - instances_param = f"{block.name.upper()}_NUM" + instances_param = f"{block.muxed_instances}" for io in block.ios: name = f"{block.name}_{io.name}" - width = "" if io.length is None else f"[{io.length - 1}:0] " + width = "" + if (length := io.length) and (io.length > 1): + width = f"[{length - 1}:0] " match io.type: case Direction.INPUT: yield f"output {width}{name}_o[{instances_param}]" @@ -322,13 +320,30 @@ def block_port_definitions(block: Block) -> Iterator[str]: yield f"input {width}{name}_en_i[{instances_param}]" +def set_muxed_instances(config: TopConfig, mapping: BlockIoToPinsMap) -> None: + """Compute how many instances of each block have pins connected to + pinmux. + """ + + muxed_blocks = {(b.block, b.instance) for b in mapping} + for block in config.blocks: + block.muxed_instances = len( + list(filter(lambda b: b[0] == block.name, muxed_blocks)) + ) + if block.muxed_instances > block.instances: + err_msg = f"""The number of muxed instances can't exceed the + number of instances for block {block.name}""" + raise Exception(err_msg) + + def generate_top(config: TopConfig) -> None: """Generate a top from a top configuration.""" - block_ios = list(flatten_block_ios(config.blocks)) - pins = list(flatten_pins(config.pins, block_ios)) + block_ios: list[BlockIoFlat] = list(flatten_block_ios(config.blocks)) + pins: list[PinFlat] = list(flatten_pins(config.pins, block_ios)) + block_io_to_pins: BlockIoToPinsMap = block_io_to_pin_map(block_ios, pins) - block_io_to_pins = block_io_to_pin_map(block_ios, pins) + set_muxed_instances(config, block_io_to_pins) template_variables = { "config": config, diff --git a/util/top_gen/parser.py b/util/top_gen/parser.py index 16694099f..84e0dd466 100644 --- a/util/top_gen/parser.py +++ b/util/top_gen/parser.py @@ -3,8 +3,10 @@ # SPDX-License-Identifier: Apache-2.0 """Top configuration structures and deserialiser from TOML files.""" +import json from enum import Enum from pathlib import Path +from typing import Any import toml from pydantic import BaseModel, field_validator, model_validator @@ -26,6 +28,17 @@ def __and__(self, other: "Direction") -> "Direction": case _: return Direction.INOUT + @staticmethod + def from_rdl_sigtype(sigtype: str) -> "Direction": + match sigtype: + case "PadInOut": + return Direction("inout") + case "PadInput": + return Direction("input") + case "PadOutput": + return Direction("output") + raise Exception("No type") + class BlockIoCombine(str, Enum): AND = "and" @@ -48,13 +61,14 @@ def verify_block(self) -> Self: return self -class Block(BaseModel, frozen=True): +class Block(BaseModel, frozen=False): name: str instances: int - ios: list[BlockIo] - memory_start: int - memory_size: int + ios: list[BlockIo] = [] + memory_start: int = 0 + memory_size: int = 0 xbar: dict[str, str] = {} + muxed_instances: int = 0 @field_validator("instances") @staticmethod @@ -92,7 +106,7 @@ def verify_pin(self) -> Self: return self -class TopConfig(BaseModel, frozen=True): +class TopConfig(BaseModel, frozen=False): blocks: list[Block] pins: list[Pin] @@ -112,8 +126,69 @@ def get_pin(self, name: str) -> Pin: exit(3) -def parse_top_config(filename: Path) -> TopConfig: +def next_power_of_two(x: int) -> int: + return 1 << (x - 1).bit_length() + + +def _make_ios(device: dict[str, Any]) -> list[dict[str, str]]: + ios = [] + for pad in device.get("pads", []): + # Todo: Try to remove the thanslation. + io = { + "name": pad["name"], + "length": pad.get("width", 1), + } + if type_ := pad["type"]: + io["type"] = Direction.from_rdl_sigtype(type_).value + if val := pad.get("combine"): + io["combine"] = val.lower() + ios.append(io) + return ios + + +def parse_top_config(cfg_file: Path, rdl_file: Path) -> TopConfig: """Load the top configuration from the given TOML file.""" - with filename.open() as file: + with cfg_file.open() as file: config_dict = toml.load(file) + + with rdl_file.open() as file: + rdl_dict = json.load(file) + + for device in rdl_dict["devices"]: + if device["type"] == "mem": + instances = 1 + mem_start = device["offset"] + else: + instances = len(device["offsets"]) + mem_start = device["offsets"][0] + size = next_power_of_two(device.get("size", 0x1000)) + + obj = { + "name": device["name"].lower(), + "instances": instances, + "memory_start": mem_start, + "memory_size": size, + "ios": _make_ios(device), + } + if udps := device.get("udps"): + if "xbar" in udps: + obj["xbar"] = { + item["name"]: item["value"] for item in udps["xbar"] + } + + if "clk_input" in udps: + obj.setdefault("xbar", {})["clock"] = '"{}"'.format( + udps["clk_input"][0] + ) + + if "rst_input" in udps: + obj.setdefault("xbar", {})["reset"] = '"{}"'.format( + udps["rst_input"][0] + ) + + config_dict.setdefault("blocks", []).append(obj) + + # Sort the blocks by the start address. + Path("/tmp/log_top_config.txt").write_text(str(TopConfig(**config_dict))) + config_dict["blocks"].sort(key=lambda b: b["memory_start"]) return TopConfig(**config_dict) diff --git a/uv.lock b/uv.lock index 59892f183..1807b47a8 100644 --- a/uv.lock +++ b/uv.lock @@ -11,6 +11,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] +[[package]] +name = "antlr4-python3-runtime" +version = "4.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/33/5f/2cdf6f7aca3b20d3f316e9f505292e1f256a32089bd702034c29ebde6242/antlr4_python3_runtime-4.13.2.tar.gz", hash = "sha256:909b647e1d2fc2b70180ac586df3933e38919c85f98ccc656a96cd3f25ef3916", size = 117467, upload-time = "2024-08-03T19:00:12.757Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/03/a851e84fcbb85214dc637b6378121ef9a0dd61b4c65264675d8a5c9b1ae7/antlr4_python3_runtime-4.13.2-py3-none-any.whl", hash = "sha256:fe3835eb8d33daece0e799090eda89719dbccee7aa39ef94eed3818cafa5a7e8", size = 144462, upload-time = "2024-08-03T19:00:11.134Z" }, +] + [[package]] name = "anytree" version = "2.8.0" @@ -32,6 +41,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] +[[package]] +name = "click" +version = "8.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + [[package]] name = "edalize" version = "0.4.0" @@ -126,6 +156,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", size = 78509, upload-time = "2025-04-10T12:50:53.297Z" }, ] +[[package]] +name = "markdown" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/ab/7dd27d9d863b3376fcf23a5a13cb5d024aed1db46f963f1b5735ae43b3be/markdown-3.10.tar.gz", hash = "sha256:37062d4f2aa4b2b6b32aefb80faa300f82cc790cb949a35b8caede34f2b68c0e", size = 364931, upload-time = "2025-11-03T19:51:15.007Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/81/54e3ce63502cd085a0c556652a4e1b919c45a446bd1e5300e10c44c8c521/markdown-3.10-py3-none-any.whl", hash = "sha256:b5b99d6951e2e4948d939255596523444c0e677c669700b1d17aa4a8a464cb7c", size = 107678, upload-time = "2025-11-03T19:51:13.887Z" }, +] + [[package]] name = "markupsafe" version = "3.0.3" @@ -522,6 +561,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] +[[package]] +name = "rdl2ot" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "jinja2" }, + { name = "systemrdl-compiler" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c8/6c/c7577b187ce6e28f90090af3ee4d190af2ec20b8d19a4bf83ae862f458ef/rdl2ot-0.3.0.tar.gz", hash = "sha256:6f187a4dcb6ec2f672dfb25fe9b88896bdf6edad004e29840cb8da69a22dc116", size = 37890, upload-time = "2025-11-04T17:30:56.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/3b/127e8426c564c764bc12d185c9cdcb1ea1035e4c9a024f0d6d114a3777bb/rdl2ot-0.3.0-py3-none-any.whl", hash = "sha256:1c335fefdb1d1d82e46d0c43d9bedb6b03bc360f92e11f6ddda1d4496349b946", size = 19889, upload-time = "2025-11-04T17:30:54.821Z" }, +] + [[package]] name = "ruff" version = "0.5.7" @@ -615,6 +668,7 @@ dependencies = [ { name = "pycryptodome" }, { name = "pydantic" }, { name = "pyserial" }, + { name = "rdl2ot" }, { name = "ruff" }, { name = "semantic-version" }, { name = "setuptools" }, @@ -638,6 +692,7 @@ requires-dist = [ { name = "pycryptodome", specifier = ">=3.23.0,<4" }, { name = "pydantic", specifier = ">=2.8.2,<3" }, { name = "pyserial", specifier = "==3.5" }, + { name = "rdl2ot", specifier = ">=0.3.0" }, { name = "ruff", specifier = "==0.5.7" }, { name = "semantic-version", specifier = ">=2.10.0,<3" }, { name = "setuptools", specifier = ">=80.9.0" }, @@ -646,6 +701,28 @@ requires-dist = [ { name = "wheel", specifier = "==0.41.2" }, ] +[[package]] +name = "systemrdl-compiler" +version = "1.30.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "antlr4-python3-runtime" }, + { name = "colorama" }, + { name = "markdown" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a6/31/8ca0c5748e7dd566088e9ad84ca129627dc54421ba4397ade3bcc3beea84/systemrdl_compiler-1.30.1.tar.gz", hash = "sha256:ba8411aa53052da52fe5f4de3061905360154a48c1855236aecbb377b08b9654", size = 483996, upload-time = "2025-09-24T04:58:18.994Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/10/cb0bc743910fcf80859c90cf0b0754527c2e5cf6caadfc7e3bab3bb1d166/systemrdl_compiler-1.30.1-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:51f2c8c56bc4552b5751f08e2bef511ba10cb5a65cab79e3c4b44591d176eb99", size = 1170794, upload-time = "2025-09-24T04:58:02.172Z" }, + { url = "https://files.pythonhosted.org/packages/a7/fa/d26431aa07b0d1d1784c6ab5077736b832a30dc647212e8535f1484c18ed/systemrdl_compiler-1.30.1-cp37-abi3-macosx_11_0_x86_64.whl", hash = "sha256:276f4fce1254c5f57da4cfd7cacd0872d84134a1bb210a46bd7f79d04a7e0329", size = 1174880, upload-time = "2025-09-24T04:58:04.029Z" }, + { url = "https://files.pythonhosted.org/packages/47/ee/9c76699bb24adf5400a7fea305b9fcc46b70b12aa70eaa6f4e00cf17ad1e/systemrdl_compiler-1.30.1-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:281f411e74663d4c7bf2fd73db63ba1887d5cc55accbe67fa373aaba05848613", size = 10844382, upload-time = "2025-09-24T04:58:05.704Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9f/de0b43c4e662256aa1955d116e7703b647fc4b83289d6a57baea9a540a38/systemrdl_compiler-1.30.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f639d551567a136ff1ed5d62b17162e5c2e2cd51c0c4c1488cde0712e73cb4a", size = 11019356, upload-time = "2025-09-24T04:58:08.276Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/7d00173f47396a49be7f99a3f8239707620e86253702236d330fae627134/systemrdl_compiler-1.30.1-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:a43e8f1a0afeb35f56a748471fc1d0cac60cf0f04cefd14fedb1b53f8abeab6f", size = 11260909, upload-time = "2025-09-24T04:58:11.171Z" }, + { url = "https://files.pythonhosted.org/packages/48/18/be05a311f89838e30aca12cb5b10d4ed5d9a91ec3c8c11b78250e6dbc8c7/systemrdl_compiler-1.30.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:c9ef2b2480c02e30f6627731d700f174039c1407bb5ae33b1817d06a39e080b0", size = 11301190, upload-time = "2025-09-24T04:58:13.53Z" }, + { url = "https://files.pythonhosted.org/packages/af/71/9c47aed48dc2be6ce36fa41b092749fce8228812186040277929fe94b750/systemrdl_compiler-1.30.1-cp37-abi3-win32.whl", hash = "sha256:b8583e0210619fbcfebea2e03fa780fd7604188b83afbba47fd8e559944f8667", size = 922325, upload-time = "2025-09-24T04:58:15.534Z" }, + { url = "https://files.pythonhosted.org/packages/46/6a/08297441b88c0e0f5b352964d3376bd386f17b4194e077d356e8346ff322/systemrdl_compiler-1.30.1-cp37-abi3-win_amd64.whl", hash = "sha256:59d580b235dc30224c3ae6038fac05c0c6c0d7f96abe6ad3979550c89a6bec99", size = 955160, upload-time = "2025-09-24T04:58:17.25Z" }, +] + [[package]] name = "tabulate" version = "0.9.0" diff --git a/vendor/lowrisc_ip/util/tlgen/validate.py b/vendor/lowrisc_ip/util/tlgen/validate.py index d492d3e15..6c3cb6db8 100644 --- a/vendor/lowrisc_ip/util/tlgen/validate.py +++ b/vendor/lowrisc_ip/util/tlgen/validate.py @@ -116,7 +116,7 @@ # by inspecting the base addresses. Note that the validation # script also ensures that base addresses are aligned with # to this granularity. -MIN_DEVICE_SPACING = 0x1000 +MIN_DEVICE_SPACING = 0x4 def check_keys(obj: Dict[Any, Any], diff --git a/vendor/patches/lowrisc_ip/tlgen/0002-min_device_spacing.patch b/vendor/patches/lowrisc_ip/tlgen/0002-min_device_spacing.patch new file mode 100644 index 000000000..c0dd936e9 --- /dev/null +++ b/vendor/patches/lowrisc_ip/tlgen/0002-min_device_spacing.patch @@ -0,0 +1,13 @@ +diff --git a/validate.py b/validate.py +index d492d3e..6c3cb6d 100644 +--- a/validate.py ++++ b/validate.py +@@ -116,7 +116,7 @@ Crossbar configuration format. + # by inspecting the base addresses. Note that the validation + # script also ensures that base addresses are aligned with + # to this granularity. +-MIN_DEVICE_SPACING = 0x1000 ++MIN_DEVICE_SPACING = 0x4 + + + def check_keys(obj: Dict[Any, Any],