diff --git a/data/top_config.toml b/data/top_config.toml index d86e8d42d..624585f46 100644 --- a/data/top_config.toml +++ b/data/top_config.toml @@ -1,6 +1,6 @@ [[blocks]] name = "gpio" -instances = 5 # RPi, Ard, Pmod0, Pmod1, PmodC +instances = 6 # RPi, Ard, Pmod0, Pmod1, PmodC ios = [ { name = "ios", @@ -9,8 +9,9 @@ ios = [ length = 32 }, ] -memory_start = 0x80000040 +memory_start = 0x80000000 memory_size = 0x00000040 +xbar = { pipeline = "true"} [[blocks]] name = "pwm" diff --git a/data/xbar_main.hjson b/data/xbar_main.hjson index a2c0f1dc5..0ba8296ee 100644 --- a/data/xbar_main.hjson +++ b/data/xbar_main.hjson @@ -61,7 +61,7 @@ size_byte: "0x00000800", }], }, - { name: "gpio", // General purpose input and output + { name: "gpio0", type: "device", clock: "clk_sys_i", reset: "rst_sys_ni", @@ -70,7 +70,72 @@ xbar: false, addr_range: [{ base_addr: "0x80000000", - size_byte: "0x00001000", + size_byte: "0x40", + }], + pipeline: true, + }, + { name: "gpio1", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + req_fifo_pass: false, + rsp_fifo_pass: false, + xbar: false, + addr_range: [{ + base_addr: "0x80000040", + size_byte: "0x40", + }], + pipeline: true, + }, + { name: "gpio2", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + req_fifo_pass: false, + rsp_fifo_pass: false, + xbar: false, + addr_range: [{ + base_addr: "0x80000080", + size_byte: "0x40", + }], + pipeline: true, + }, + { name: "gpio3", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + req_fifo_pass: false, + rsp_fifo_pass: false, + xbar: false, + addr_range: [{ + base_addr: "0x800000c0", + size_byte: "0x40", + }], + pipeline: true, + }, + { name: "gpio4", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + req_fifo_pass: false, + rsp_fifo_pass: false, + xbar: false, + addr_range: [{ + base_addr: "0x80000100", + size_byte: "0x40", + }], + pipeline: true, + }, + { name: "gpio5", + type: "device", + clock: "clk_sys_i", + reset: "rst_sys_ni", + req_fifo_pass: false, + rsp_fifo_pass: false, + xbar: false, + addr_range: [{ + base_addr: "0x80000140", + size_byte: "0x40", }], pipeline: true, }, @@ -313,7 +378,6 @@ "hyperram", "rev_tag", "dbg_dev", - "gpio", "pinmux", "system_info", "rgbled_ctrl", @@ -322,6 +386,12 @@ "timer", "spi_lcd", "spi_ethmac", + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", "pwm0", "uart0", "uart1", diff --git a/data/xbar_main.hjson.tpl b/data/xbar_main.hjson.tpl index 896b6311f..7c706ae02 100644 --- a/data/xbar_main.hjson.tpl +++ b/data/xbar_main.hjson.tpl @@ -61,7 +61,10 @@ size_byte: "0x00000800", }], }, - { name: "gpio", // General purpose input and output + % for block in config.blocks: + % if block.name == "gpio": + % for i in range(block.instances): + { name: "${f"{block.name}{i}"}", type: "device", clock: "clk_sys_i", reset: "rst_sys_ni", @@ -69,11 +72,16 @@ rsp_fifo_pass: false, xbar: false, addr_range: [{ - base_addr: "0x80000000", - size_byte: "0x00001000", + base_addr: "${hex(block.memory_start + i * block.memory_size)}", + size_byte: "${hex(block.memory_size)}", }], - pipeline: true, + % for (setting, value) in block.xbar.items(): + ${setting}: ${value}, + % endfor }, + % endfor + % endif + % endfor { name: "pinmux", // Pin multiplexer type: "device", clock: "clk_sys_i", @@ -224,7 +232,6 @@ "hyperram", "rev_tag", "dbg_dev", - "gpio", "pinmux", "system_info", "rgbled_ctrl", @@ -234,11 +241,9 @@ "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", diff --git a/rtl/bus/sonata_xbar_main.sv b/rtl/bus/sonata_xbar_main.sv index 8746c1de8..ef0284f0f 100644 --- a/rtl/bus/sonata_xbar_main.sv +++ b/rtl/bus/sonata_xbar_main.sv @@ -27,8 +27,6 @@ module sonata_xbar_main 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, @@ -45,6 +43,8 @@ module sonata_xbar_main 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_gpio_o[GPIO_NUM], + input tlul_pkg::tl_d2h_t tl_gpio_i[GPIO_NUM], 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], @@ -81,8 +81,6 @@ module sonata_xbar_main .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), @@ -99,6 +97,18 @@ module sonata_xbar_main .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_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_pwm0_o (tl_pwm_o[0]), .tl_pwm0_i (tl_pwm_i[0]), .tl_uart0_o (tl_uart_o[0]), diff --git a/rtl/bus/tl_main_pkg.sv b/rtl/bus/tl_main_pkg.sv index 2371e71eb..b7e5f54c8 100644 --- a/rtl/bus/tl_main_pkg.sv +++ b/rtl/bus/tl_main_pkg.sv @@ -9,7 +9,12 @@ 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_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_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; @@ -34,7 +39,12 @@ package tl_main_pkg; 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_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_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; @@ -57,33 +67,38 @@ package tl_main_pkg; localparam logic [31:0] ADDR_MASK_RV_PLIC = 32'h 07ffffff; 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 + TlGpio0 = 3, + TlGpio1 = 4, + TlGpio2 = 5, + TlGpio3 = 6, + TlGpio4 = 7, + TlGpio5 = 8, + TlPinmux = 9, + TlRgbledCtrl = 10, + TlHwRev = 11, + TlXadc = 12, + TlSystemInfo = 13, + TlTimer = 14, + TlSpiLcd = 15, + TlSpiEthmac = 16, + TlPwm0 = 17, + TlUart0 = 18, + TlUart1 = 19, + TlUart2 = 20, + TlI2C0 = 21, + TlI2C1 = 22, + TlSpi0 = 23, + TlSpi1 = 24, + TlSpi2 = 25, + TlUsbdev = 26, + TlDbgDev = 27, + TlRvPlic = 28 } tl_device_e; typedef enum int { diff --git a/rtl/bus/xbar_main.sv b/rtl/bus/xbar_main.sv index 0292d2030..0715e8767 100644 --- a/rtl/bus/xbar_main.sv +++ b/rtl/bus/xbar_main.sv @@ -7,16 +7,15 @@ // // Interconnect // ibex_lsu -// -> s1n_26 -// -> sm1_27 +// -> s1n_31 +// -> sm1_32 // -> sram -// -> sm1_28 +// -> sm1_33 // -> hyperram // -> rev_tag // -> dbg_dev -// -> gpio // -> pinmux -// -> sm1_29 +// -> sm1_34 // -> system_info // -> rgbled_ctrl // -> hw_rev @@ -24,6 +23,12 @@ // -> timer // -> spi_lcd // -> spi_ethmac +// -> gpio0 +// -> gpio1 +// -> gpio2 +// -> gpio3 +// -> gpio4 +// -> gpio5 // -> pwm0 // -> uart0 // -> uart1 @@ -33,16 +38,16 @@ // -> spi0 // -> spi1 // -> spi2 -// -> asf_30 +// -> asf_35 // -> usbdev // -> rv_plic // 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 ( @@ -64,8 +69,18 @@ module xbar_main ( 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_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_pinmux_o, input tlul_pkg::tl_d2h_t tl_pinmux_i, output tlul_pkg::tl_h2d_t tl_rgbled_ctrl_o, @@ -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_33_us_h2d[0] = tl_s1n_31_ds_h2d[1]; + assign tl_s1n_31_ds_d2h[1] = tl_sm1_33_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[2]; + assign tl_s1n_31_ds_d2h[2] = 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_dbg_dev_o = tl_s1n_31_ds_h2d[3]; + assign tl_s1n_31_ds_d2h[3] = tl_dbg_dev_i; - assign tl_rev_tag_o = tl_s1n_26_ds_h2d[2]; - assign tl_s1n_26_ds_d2h[2] = tl_rev_tag_i; + assign tl_pinmux_o = tl_s1n_31_ds_h2d[4]; + assign tl_s1n_31_ds_d2h[4] = tl_pinmux_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_sm1_34_us_h2d[0] = tl_s1n_31_ds_h2d[5]; + assign tl_s1n_31_ds_d2h[5] = tl_sm1_34_us_d2h[0]; - assign tl_gpio_o = tl_s1n_26_ds_h2d[4]; - assign tl_s1n_26_ds_d2h[4] = tl_gpio_i; + assign tl_rgbled_ctrl_o = tl_s1n_31_ds_h2d[6]; + assign tl_s1n_31_ds_d2h[6] = tl_rgbled_ctrl_i; - assign tl_pinmux_o = tl_s1n_26_ds_h2d[5]; - assign tl_s1n_26_ds_d2h[5] = tl_pinmux_i; + assign tl_hw_rev_o = tl_s1n_31_ds_h2d[7]; + assign tl_s1n_31_ds_d2h[7] = tl_hw_rev_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_xadc_o = tl_s1n_31_ds_h2d[8]; + assign tl_s1n_31_ds_d2h[8] = tl_xadc_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_timer_o = tl_s1n_31_ds_h2d[9]; + assign tl_s1n_31_ds_d2h[9] = tl_timer_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_spi_lcd_o = tl_s1n_31_ds_h2d[10]; + assign tl_s1n_31_ds_d2h[10] = tl_spi_lcd_i; - assign tl_xadc_o = tl_s1n_26_ds_h2d[9]; - assign tl_s1n_26_ds_d2h[9] = tl_xadc_i; + assign tl_spi_ethmac_o = tl_s1n_31_ds_h2d[11]; + assign tl_s1n_31_ds_d2h[11] = tl_spi_ethmac_i; - assign tl_timer_o = tl_s1n_26_ds_h2d[10]; - assign tl_s1n_26_ds_d2h[10] = tl_timer_i; + assign tl_gpio0_o = tl_s1n_31_ds_h2d[12]; + assign tl_s1n_31_ds_d2h[12] = tl_gpio0_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_gpio1_o = tl_s1n_31_ds_h2d[13]; + assign tl_s1n_31_ds_d2h[13] = tl_gpio1_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_gpio2_o = tl_s1n_31_ds_h2d[14]; + assign tl_s1n_31_ds_d2h[14] = tl_gpio2_i; - assign tl_pwm0_o = tl_s1n_26_ds_h2d[13]; - assign tl_s1n_26_ds_d2h[13] = tl_pwm0_i; + assign tl_gpio3_o = tl_s1n_31_ds_h2d[15]; + assign tl_s1n_31_ds_d2h[15] = tl_gpio3_i; - assign tl_uart0_o = tl_s1n_26_ds_h2d[14]; - assign tl_s1n_26_ds_d2h[14] = tl_uart0_i; + assign tl_gpio4_o = tl_s1n_31_ds_h2d[16]; + assign tl_s1n_31_ds_d2h[16] = tl_gpio4_i; - assign tl_uart1_o = tl_s1n_26_ds_h2d[15]; - assign tl_s1n_26_ds_d2h[15] = tl_uart1_i; + assign tl_gpio5_o = tl_s1n_31_ds_h2d[17]; + assign tl_s1n_31_ds_d2h[17] = tl_gpio5_i; - assign tl_uart2_o = tl_s1n_26_ds_h2d[16]; - assign tl_s1n_26_ds_d2h[16] = tl_uart2_i; + assign tl_pwm0_o = tl_s1n_31_ds_h2d[18]; + assign tl_s1n_31_ds_d2h[18] = tl_pwm0_i; - assign tl_i2c0_o = tl_s1n_26_ds_h2d[17]; - assign tl_s1n_26_ds_d2h[17] = tl_i2c0_i; + assign tl_uart0_o = tl_s1n_31_ds_h2d[19]; + assign tl_s1n_31_ds_d2h[19] = tl_uart0_i; - assign tl_i2c1_o = tl_s1n_26_ds_h2d[18]; - assign tl_s1n_26_ds_d2h[18] = tl_i2c1_i; + assign tl_uart1_o = tl_s1n_31_ds_h2d[20]; + assign tl_s1n_31_ds_d2h[20] = tl_uart1_i; - assign tl_spi0_o = tl_s1n_26_ds_h2d[19]; - assign tl_s1n_26_ds_d2h[19] = tl_spi0_i; + assign tl_uart2_o = tl_s1n_31_ds_h2d[21]; + assign tl_s1n_31_ds_d2h[21] = tl_uart2_i; - assign tl_spi1_o = tl_s1n_26_ds_h2d[20]; - assign tl_s1n_26_ds_d2h[20] = tl_spi1_i; + assign tl_i2c0_o = tl_s1n_31_ds_h2d[22]; + assign tl_s1n_31_ds_d2h[22] = tl_i2c0_i; - assign tl_spi2_o = tl_s1n_26_ds_h2d[21]; - assign tl_s1n_26_ds_d2h[21] = tl_spi2_i; + assign tl_i2c1_o = tl_s1n_31_ds_h2d[23]; + assign tl_s1n_31_ds_d2h[23] = tl_i2c1_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[24]; + assign tl_s1n_31_ds_d2h[24] = 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[25]; + assign tl_s1n_31_ds_d2h[25] = 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[26]; + assign tl_s1n_31_ds_d2h[26] = 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[27]; + assign tl_s1n_31_ds_d2h[27] = 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[28]; + assign tl_s1n_31_ds_d2h[28] = 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_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_sram_o = tl_sm1_27_ds_h2d; - assign tl_sm1_27_ds_d2h = tl_sram_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_hyperram_o = tl_sm1_28_ds_h2d; - assign tl_sm1_28_ds_d2h = tl_hyperram_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_system_info_o = tl_sm1_29_ds_h2d; - assign tl_sm1_29_ds_d2h = tl_system_info_i; + assign tl_s1n_31_us_h2d = tl_ibex_lsu_i; + assign tl_ibex_lsu_o = tl_s1n_31_us_d2h; - assign tl_usbdev_o = tl_asf_30_ds_h2d; - assign tl_asf_30_ds_d2h = tl_usbdev_i; + assign tl_sram_o = tl_sm1_32_ds_h2d; + assign tl_sm1_32_ds_d2h = tl_sram_i; - assign tl_s1n_31_us_h2d = tl_dbg_host_i; - assign tl_dbg_host_o = tl_s1n_31_us_d2h; + 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_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'd1; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_REV_TAG)) == ADDR_SPACE_REV_TAG) begin - dev_sel_s1n_26 = 5'd2; + dev_sel_s1n_31 = 5'd2; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_DBG_DEV)) == ADDR_SPACE_DBG_DEV) begin - dev_sel_s1n_26 = 5'd3; - - end else if ((tl_s1n_26_us_h2d.a_address & - ~(ADDR_MASK_GPIO)) == ADDR_SPACE_GPIO) begin - dev_sel_s1n_26 = 5'd4; + dev_sel_s1n_31 = 5'd3; - 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_26 = 5'd5; + dev_sel_s1n_31 = 5'd4; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_SYSTEM_INFO)) == ADDR_SPACE_SYSTEM_INFO) begin - dev_sel_s1n_26 = 5'd6; + dev_sel_s1n_31 = 5'd5; - end else if ((tl_s1n_26_us_h2d.a_address & + 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'd6; - 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'd7; - 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; + dev_sel_s1n_31 = 5'd8; - end else if ((tl_s1n_26_us_h2d.a_address & + end else if ((tl_s1n_31_us_h2d.a_address & ~(ADDR_MASK_TIMER)) == ADDR_SPACE_TIMER) begin - dev_sel_s1n_26 = 5'd10; + 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_SPI_LCD)) == ADDR_SPACE_SPI_LCD) begin - dev_sel_s1n_26 = 5'd11; + dev_sel_s1n_31 = 5'd10; - 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_26 = 5'd12; + dev_sel_s1n_31 = 5'd11; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO0)) == ADDR_SPACE_GPIO0) begin + dev_sel_s1n_31 = 5'd12; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO1)) == ADDR_SPACE_GPIO1) begin + dev_sel_s1n_31 = 5'd13; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO2)) == ADDR_SPACE_GPIO2) begin + dev_sel_s1n_31 = 5'd14; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO3)) == ADDR_SPACE_GPIO3) begin + dev_sel_s1n_31 = 5'd15; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO4)) == ADDR_SPACE_GPIO4) begin + dev_sel_s1n_31 = 5'd16; + + end else if ((tl_s1n_31_us_h2d.a_address & + ~(ADDR_MASK_GPIO5)) == ADDR_SPACE_GPIO5) begin + 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_PWM0)) == ADDR_SPACE_PWM0) begin - dev_sel_s1n_26 = 5'd13; + 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_UART0)) == ADDR_SPACE_UART0) begin - dev_sel_s1n_26 = 5'd14; + 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_UART1)) == ADDR_SPACE_UART1) begin - dev_sel_s1n_26 = 5'd15; + dev_sel_s1n_31 = 5'd20; - 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'd21; - 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'd22; - 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'd23; - end else if ((tl_s1n_26_us_h2d.a_address & + 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'd24; - 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'd25; - 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'd26; - 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'd27; - 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'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'hf000ea7), + .DRspPass (29'hf000ea7), + .DReqDepth (116'h10000111111111111000101011000), + .DRspDepth (116'h10000111111111111000101011000), + .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/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/system/pinmux.sv b/rtl/system/pinmux.sv index 3e11575a5..64c3b1cf4 100644 --- a/rtl/system/pinmux.sv +++ b/rtl/system/pinmux.sv @@ -13,35 +13,35 @@ module pinmux 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, diff --git a/rtl/system/sonata_pkg.sv b/rtl/system/sonata_pkg.sv index d7695ee62..1eeba2c96 100644 --- a/rtl/system/sonata_pkg.sv +++ b/rtl/system/sonata_pkg.sv @@ -7,7 +7,7 @@ package sonata_pkg; // Number of Instances - localparam int unsigned GPIO_NUM = 5; + localparam int unsigned GPIO_NUM = 6; localparam int unsigned PWM_NUM = 1; localparam int unsigned UART_NUM = 3; localparam int unsigned I2C_NUM = 2; @@ -21,8 +21,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 = 8; diff --git a/rtl/system/sonata_system.sv b/rtl/system/sonata_system.sv index c97ac152b..03d36dfd3 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]; @@ -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/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..0618a8735 100644 --- a/rtl/templates/sonata_xbar_main.sv.tpl +++ b/rtl/templates/sonata_xbar_main.sv.tpl @@ -27,8 +27,6 @@ module sonata_xbar_main 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, @@ -46,10 +44,8 @@ module sonata_xbar_main 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 % endfor output tlul_pkg::tl_h2d_t tl_usbdev_o, input tlul_pkg::tl_d2h_t tl_usbdev_i, @@ -79,8 +75,6 @@ module sonata_xbar_main .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), @@ -98,12 +92,10 @@ module sonata_xbar_main .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}]), % endfor - % endif % endfor .tl_usbdev_o (tl_usbdev_o), .tl_usbdev_i (tl_usbdev_i), diff --git a/util/top_gen/generator.py b/util/top_gen/generator.py index 7f5292440..c71d5c738 100644 --- a/util/top_gen/generator.py +++ b/util/top_gen/generator.py @@ -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,7 +302,7 @@ 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] " @@ -322,13 +318,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..97c546382 100644 --- a/util/top_gen/parser.py +++ b/util/top_gen/parser.py @@ -48,13 +48,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 xbar: dict[str, str] = {} + muxed_instances: int = 0 @field_validator("instances") @staticmethod @@ -92,7 +93,7 @@ def verify_pin(self) -> Self: return self -class TopConfig(BaseModel, frozen=True): +class TopConfig(BaseModel, frozen=False): blocks: list[Block] pins: list[Pin] 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],