-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--
-- Copyright 2025 VLSI Solution Oy
-- SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
--
-- Licensed under the Solderpad Hardware License v 2.1 (the "License");
-- you may not use this file except in compliance with the License, or,
-- at your option, the Apache License version 2.0.
-- You may obtain a copy of the License at
--
--    https://solderpad.org/licenses/SHL-2.1/
--
-- Unless required by applicable law or agreed to in writing, any work
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
--                               RISCV core
--                                 V1.1
--
--
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

-- - - - - - - -
--  libraries
-- - - - - - - -
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.rv_pkg.all;


entity rv_soc is
  generic ( AXIDATA_W   : natural range 32 to 64 := 64;       -- 32b/64b allowed
            CLK_FREQ    : natural := 50000000;                -- default 50M
            UART_SPEED  : natural :=  1000000;                -- default 1M
            NR_GPIOS    : integer range 1 to 32 := 16 );      --
  port ( clk_i           : in  std_logic;
         xrst_i          : in  std_logic;
         --  NOTE: vs_rst_cpu_i is actually "enable", synchronized to clk_i
         vs_rst_cpu_i    : in  std_logic;                    -- riscv core only
         --
         xmem_awready_i  : in  std_logic;                     -- xmem
         xmem_wready_i   : in  std_logic;
         xmem_bvalid_i   : in  std_logic;
         xmem_bresp_i    : in  slv_01_00;
         xmem_bid_i      : in  slv_03_00;
         xmem_arready_i  : in  std_logic;
         xmem_rvalid_i   : in  std_logic;
         xmem_rdata_i    : in  slv_t(AXIDATA_W-1 downto 0);
         xmem_rresp_i    : in  slv_01_00;
         xmem_rid_i      : in  slv_03_00;
         xmem_rlast_i    : in  std_logic;
         xmem_awvalid_o  : out std_logic;
         xmem_awaddr_o   : out slv_31_00;
         xmem_awid_o     : out slv_03_00;
         xmem_awlen_o    : out slv_07_00;
         xmem_awburst_o  : out slv_01_00;
         xmem_wvalid_o   : out std_logic;
         xmem_wdata_o    : out slv_t(AXIDATA_W-1 downto 0);
         xmem_wstrb_o    : out slv_t(AXIDATA_W/8-1 downto 0);
         xmem_wlast_o    : out std_logic;
         xmem_bready_o   : out std_logic;
         xmem_arvalid_o  : out std_logic;
         xmem_araddr_o   : out slv_31_00;
         xmem_arid_o     : out slv_03_00;
         xmem_arlen_o    : out slv_07_00;
         xmem_arburst_o  : out slv_01_00;
         xmem_rready_o   : out std_logic;
         --
         pll_cfg_i       : in slv_08_00;
         --
         -- io pins
         uart_txd_i      : in  std_logic;  -- dbg_uart/uart_lite
         uart_rxd_o      : out std_logic;
         uart2_txd_i     : in  std_logic;  -- uart2
         uart2_rxd_o     : out std_logic;
         --
         spi_clk_o       : out std_logic;
         spi_cs_o        : out std_logic;
         spi_miso_i      : in  std_logic;
         spi_mosi_o      : out std_logic;
         spi_mosi_i      : in  std_logic;
         --
         gpio_i          : in  slv_t(NR_GPIOS-1 downto 0);
         gpio_o          : out slv_t(NR_GPIOS-1 downto 0);
         gpio_xena_o     : out slv_t(NR_GPIOS-1 downto 0);
         gpio_pdena_o    : out slv_t(NR_GPIOS-1 downto 0);
         gpio_puena_o    : out slv_t(NR_GPIOS-1 downto 0)
        );
end entity rv_soc;


architecture rtl of rv_soc is

  component rv_core
    generic ( AXIDATA_W     : natural range 32 to 64 := 32;  -- 32b/64b alowed
              BOOT_ADDR     : slv_31_00 := X"80000000";
              CPU_ID        : slv_31_00 := X"00000000";
              AXI_ID        : slv_03_00 := X"4";
              CACHE_ADDR_L  : slv_31_00 := X"70000000";      -- X"80000000";
              CACHE_ADDR_H  : slv_31_00 := X"8FFFFFFF" );
    port ( clk_i            : in  std_logic;
           xrst_i           : in  std_logic;
           --
           xrst_core_i      : in  std_logic;                 -- cpu/cache xreset
           xrst_cpu_i       : in  std_logic;                 -- cpu xreset only
           --  mem bist if
           --  (NOTE: mem count is 2x WAYS as there are tag/data rams)
           --  rd/wr select is 1-hot style in order like ...t1,d1,t0,d0
           mbist_ena_i      : in  std_logic;
           imbist_rd_i      : in  slv_03_00;                  -- t1,d1,t0,d0
           imbist_wr_i      : in  slv_03_00;                  -- t1,d1,t0,d0
           dmbist_rd_i      : in  slv_03_00;                  -- t1,d1,t0,d0
           dmbist_wr_i      : in  slv_03_00;                  -- t1,d1,t0,d0
           mbist_addr_i     : in  slv_12_00;
           mbist_data_i     : in  slv_t(AXIDATA_W-1 downto 0);
           mbist_data_o     : out slv_t(AXIDATA_W-1 downto 0);
           --
           axi_awready_i    : in  std_logic;
           axi_wready_i     : in  std_logic;
           axi_bvalid_i     : in  std_logic;
           axi_bresp_i      : in  slv_01_00;
           axi_bid_i        : in  slv_03_00;
           axi_arready_i    : in  std_logic;
           axi_rvalid_i     : in  std_logic;
           axi_rdata_i      : in  slv_t(AXIDATA_W-1 downto 0);
           axi_rresp_i      : in  slv_01_00;
           axi_rid_i        : in  slv_03_00;
           axi_rlast_i      : in  std_logic;
           axi_awvalid_o    : out std_logic;
           axi_awaddr_o     : out slv_31_00;
           axi_awid_o       : out slv_03_00;
           axi_awlen_o      : out slv_07_00;
           axi_awburst_o    : out slv_01_00;
           axi_wvalid_o     : out std_logic;
           axi_wdata_o      : out slv_t(AXIDATA_W-1 downto 0);
           axi_wstrb_o      : out slv_t(AXIDATA_W/8-1 downto 0);
           axi_wlast_o      : out std_logic;
           axi_bready_o     : out std_logic;
           axi_arvalid_o    : out std_logic;
           axi_araddr_o     : out slv_31_00;
           axi_arid_o       : out slv_03_00;
           axi_arlen_o      : out slv_07_00;
           axi_arburst_o    : out slv_01_00;
           axi_rready_o     : out std_logic;
           --  vsbus for perips
           pp_irq_i         : in  std_logic;                -- perip interrupt
           pp_addr_o        : out slv_31_00;
           pp_rd_o          : out std_logic;
           pp_rd_data_i     : in  slv_31_00;
           pp_wr_o          : out slv_03_00;
           pp_wr_data_o     : out slv_31_00;
           -- dma
           dma_rd_i         : in  std_logic;
           dma_wr_i         : in  std_logic;
           dma_addr_i       : in  slv_31_02;
           dma_wr_data_i    : in  slv_31_00;
           dma_rd_data_o    : out slv_31_00;
           dma_intr_o       : out std_logic );              -- dma interrupt
  end component;


  component vsperips
    generic ( CLK_FREQ   : natural := 50000000;             -- default 50M
              UART_SPEED : natural :=  1000000;             -- default 1M
              AXIDATA_W  : natural := 32;
              NR_GPIOS   : integer range 1 to 32 := 9 );
    port ( clk_i          : in  std_logic;
           xrst_i         : in  std_logic;                  -- syncr reset
           --  vsbus for peripherals
           pp_addr_i      : in  slv_31_00;
           pp_rd_i        : in  std_logic;
           pp_wr_i        : in  slv_03_00;
           pp_wr_data_i   : in  slv_31_00;
           pp_rd_data_o   : out slv_31_00;
           pp_irq_o       : out std_logic;                  -- pp interrupt
           --
           pll_cfg_i      : in slv_08_00;
           --
           --  peripheral ios to pads
           rx_i           : in  std_logic;                  -- ulite
           tx_o           : out std_logic;
           rx2_i          : in  std_logic;                  -- uart2
           tx2_o          : out std_logic;
           --
           spi_clk_o      : out std_logic;
           spi_cs_o       : out std_logic;
           spi_miso_i     : in  std_logic;
           spi_mosi_o     : out std_logic;
           --
           gpio_i         : in  slv_t(NR_GPIOS-1 downto 0);
           gpio_o         : out slv_t(NR_GPIOS-1 downto 0);
           gpio_oena_o    : out slv_t(NR_GPIOS-1 downto 0);
           gpio_pdena_o   : out slv_t(NR_GPIOS-1 downto 0);
           gpio_puena_o   : out slv_t(NR_GPIOS-1 downto 0);
           --  DMA bus
           dma_rd_o       : out std_logic;
           dma_wr_o       : out slv_03_00;
           dma_addr_o     : out slv_31_02;
           dma_wr_data_o  : out slv_31_00;
           dma_rd_data_i  : in  slv_31_00;
           dma_intr_i     : in  std_logic );                -- dma interrupt
  end component;


  component axi_mem_if
    generic ( AXIDATA_W  : natural range 32 to 64 := 32 );  -- select 32 / 64
    port ( clk_i             : in  std_logic;
           xrst_i            : in  std_logic;               -- syncr reset
           --
           axi_a_awvalid_i   : in  std_logic;            -- AXI A-port: dbg uart
           axi_a_awaddr_i    : in  slv_31_00;
           axi_a_awid_i      : in  slv_03_00;
           axi_a_awlen_i     : in  slv_07_00;
           axi_a_awburst_i   : in  slv_01_00;
           axi_a_wvalid_i    : in  std_logic;
           axi_a_wdata_i     : in  slv_t(AXIDATA_W-1 downto 0);
           axi_a_wstrb_i     : in  slv_t(AXIDATA_W/8-1 downto 0); -- 8 / 4
           axi_a_wlast_i     : in  std_logic;
           axi_a_bready_i    : in  std_logic;
           axi_a_arvalid_i   : in  std_logic;
           axi_a_araddr_i    : in  slv_31_00;
           axi_a_arid_i      : in  slv_03_00;
           axi_a_arlen_i     : in  slv_07_00;
           axi_a_arburst_i   : in  slv_01_00;
           axi_a_rready_i    : in  std_logic;
           axi_a_awready_o   : out std_logic;
           axi_a_wready_o    : out std_logic;
           axi_a_bvalid_o    : out std_logic;
           axi_a_bresp_o     : out slv_01_00;
           axi_a_bid_o       : out slv_03_00;
           axi_a_arready_o   : out std_logic;
           axi_a_rvalid_o    : out std_logic;
           axi_a_rdata_o     : out slv_t(AXIDATA_W-1 downto 0);
           axi_a_rresp_o     : out slv_01_00;
           axi_a_rid_o       : out slv_03_00;
           axi_a_rlast_o     : out std_logic;
           --
           axi_b_awvalid_i   : in  std_logic;            -- AXI B-port: NC
           axi_b_awaddr_i    : in  slv_31_00;
           axi_b_awid_i      : in  slv_03_00;
           axi_b_awlen_i     : in  slv_07_00;
           axi_b_awburst_i   : in  slv_01_00;
           axi_b_wvalid_i    : in  std_logic;
           axi_b_wdata_i     : in  slv_t(AXIDATA_W-1 downto 0);
           axi_b_wstrb_i     : in  slv_t(AXIDATA_W/8-1 downto 0);  -- 8 / 4
           axi_b_wlast_i     : in  std_logic;
           axi_b_bready_i    : in  std_logic;
           axi_b_arvalid_i   : in  std_logic;
           axi_b_araddr_i    : in  slv_31_00;
           axi_b_arid_i      : in  slv_03_00;
           axi_b_arlen_i     : in  slv_07_00;
           axi_b_arburst_i   : in  slv_01_00;
           axi_b_rready_i    : in  std_logic;
           axi_b_awready_o   : out std_logic;
           axi_b_wready_o    : out std_logic;
           axi_b_bvalid_o    : out std_logic;
           axi_b_bresp_o     : out slv_01_00;
           axi_b_bid_o       : out slv_03_00;
           axi_b_arready_o   : out std_logic;
           axi_b_rvalid_o    : out std_logic;
           axi_b_rdata_o     : out slv_t(AXIDATA_W-1 downto 0);
           axi_b_rresp_o     : out slv_01_00;
           axi_b_rid_o       : out slv_03_00;
           axi_b_rlast_o     : out std_logic;
           --
           axi_c_awvalid_i   : in  std_logic;            -- AXI C-port: cpu
           axi_c_awaddr_i    : in  slv_31_00;
           axi_c_awid_i      : in  slv_03_00;
           axi_c_awlen_i     : in  slv_07_00;
           axi_c_awburst_i   : in  slv_01_00;
           axi_c_wvalid_i    : in  std_logic;
           axi_c_wdata_i     : in  slv_t(AXIDATA_W-1 downto 0);
           axi_c_wstrb_i     : in  slv_t(AXIDATA_W/8-1 downto 0); -- 8 / 4
           axi_c_wlast_i     : in  std_logic;
           axi_c_bready_i    : in  std_logic;
           axi_c_arvalid_i   : in  std_logic;
           axi_c_araddr_i    : in  slv_31_00;
           axi_c_arid_i      : in  slv_03_00;
           axi_c_arlen_i     : in  slv_07_00;
           axi_c_arburst_i   : in  slv_01_00;
           axi_c_rready_i    : in  std_logic;
           axi_c_awready_o   : out std_logic;
           axi_c_wready_o    : out std_logic;
           axi_c_bvalid_o    : out std_logic;
           axi_c_bresp_o     : out slv_01_00;
           axi_c_bid_o       : out slv_03_00;
           axi_c_arready_o   : out std_logic;
           axi_c_rvalid_o    : out std_logic;
           axi_c_rdata_o     : out slv_t(AXIDATA_W-1 downto 0);
           axi_c_rresp_o     : out slv_01_00;
           axi_c_rid_o       : out slv_03_00;
           axi_c_rlast_o     : out std_logic;
           --
           xmem_awready_i    : in  std_logic;            -- AXI out port: xmem
           xmem_wready_i     : in  std_logic;
           xmem_bvalid_i     : in  std_logic;
           xmem_bresp_i      : in  slv_01_00;
           xmem_bid_i        : in  slv_03_00;
           xmem_arready_i    : in  std_logic;
           xmem_rvalid_i     : in  std_logic;
           xmem_rdata_i      : in  slv_t(AXIDATA_W-1 downto 0);
           xmem_rresp_i      : in  slv_01_00;
           xmem_rid_i        : in  slv_03_00;
           xmem_rlast_i      : in  std_logic;
           xmem_awvalid_o    : out std_logic;
           xmem_awaddr_o     : out slv_31_00;
           xmem_awid_o       : out slv_03_00;
           xmem_awlen_o      : out slv_07_00;
           xmem_awburst_o    : out slv_01_00;
           xmem_wvalid_o     : out std_logic;
           xmem_wdata_o      : out slv_t(AXIDATA_W-1 downto 0);
           xmem_wstrb_o      : out slv_t(AXIDATA_W/8-1 downto 0);  -- 8 / 4
           xmem_wlast_o      : out std_logic;
           xmem_bready_o     : out std_logic;
           xmem_arvalid_o    : out std_logic;
           xmem_araddr_o     : out slv_31_00;
           xmem_arid_o       : out slv_03_00;
           xmem_arlen_o      : out slv_07_00;
           xmem_arburst_o    : out slv_01_00;
           xmem_rready_o     : out std_logic );
  end component;


  component dbg_bridge
    generic ( CLK_FREQ    : natural := 50000000;             -- default 50M
              UART_SPEED  : natural :=  1000000;             -- default 1M
              AXIDATA_W   : natural range 32 to 64 := 32 );  -- select 32 / 64
    port ( clk_i          : in  std_logic;
           xrst_i         : in  std_logic;
           vs_rst_cpu_i   : in  std_logic;                   -- riscv core only
           --  mem bist if
           --  (NOTE: mem count is 2x WAYS as there are tag/data rams)
           --  rd/wr select is 1-hot style in order like ...t1,d1,t0,d0
           mbist_ena_o    : out std_logic;
           imbist_rd_o    : out slv_03_00;                   -- t1,d1,t0,d0
           imbist_wr_o    : out slv_03_00;                   -- t1,d1,t0,d0
           dmbist_rd_o    : out slv_03_00;                   -- t1,d1,t0,d0
           dmbist_wr_o    : out slv_03_00;                   -- t1,d1,t0,d0
           mbist_addr_o   : out slv_12_00;                   -- 8k ram max
           mbist_data_o   : out slv_t(AXIDATA_W-1 downto 0);
           mbist_data_i   : in  slv_t(AXIDATA_W-1 downto 0);
           --  AXI bus to DDR / TCM ram if
           mem_awready_i  : in  std_logic;
           mem_wready_i   : in  std_logic;
           mem_bvalid_i   : in  std_logic;
           mem_arready_i  : in  std_logic;
           mem_rvalid_i   : in  std_logic;
           mem_rdata_i    : in  slv_t(AXIDATA_W-1 downto 0);
           mem_awvalid_o  : out std_logic;
           mem_awaddr_o   : out slv_31_00;
           mem_wvalid_o   : out std_logic;
           mem_wdata_o    : out slv_t(AXIDATA_W-1 downto 0);
           mem_wstrb_o    : out slv_t(AXIDATA_W/8-1 downto 0);  -- 64b / 32b
           mem_bready_o   : out std_logic;
           mem_arvalid_o  : out std_logic;
           mem_araddr_o   : out slv_31_00;
           mem_rready_o   : out std_logic;
           --  pp io
           uart_rxd_i     : in  std_logic;
           uart_txd_o     : out std_logic;
           rv_cpu_xrst_o  : out std_logic;      -- cpu xreset  (cpu only, halt)
           rv_core_ena_o  : out std_logic );    -- core enable (cpu/caches)
  end component;


  signal axi4_awvalid_w    : std_logic;                  -- w-chan
  signal axi4_awaddr_w     : slv_31_00;
  signal axi4_awid_w       : slv_03_00;
  signal axi4_awlen_w      : slv_07_00;
  signal axi4_awburst_w    : slv_01_00;
  signal axi4_wvalid_w     : std_logic;
  signal axi4_wdata_w      : slv_t(AXIDATA_W-1 downto 0);
  signal axi4_wstrb_w      : slv_t(AXIDATA_W/8-1 downto 0);
  signal axi4_wlast_w      : std_logic;
  signal axi4_bready_w     : std_logic;
  signal axi4_arvalid_w    : std_logic;                 -- r-chan
  signal axi4_araddr_w     : slv_31_00;
  signal axi4_arid_w       : slv_03_00;
  signal axi4_arlen_w      : slv_07_00;
  signal axi4_arburst_w    : slv_01_00;
  signal axi4_rready_w     : std_logic;
  signal axi4_awready_w    : std_logic;                 -- w-chan
  signal axi4_wready_w     : std_logic;
  signal axi4_bvalid_w     : std_logic;
  signal axi4_bresp_w      : slv_01_00;
  signal axi4_bid_w        : slv_03_00;
  signal axi4_arready_w    : std_logic;                 -- r-chan
  signal axi4_rvalid_w     : std_logic;
  signal axi4_rdata_w      : slv_t(AXIDATA_W-1 downto 0);
  signal axi4_rresp_w      : slv_01_00;
  signal axi4_rid_w        : slv_03_00;
  signal axi4_rlast_w      : std_logic;


  signal axi_awvalid_w     : std_logic;                 -- dbg uart
  signal axi_awaddr_w      : slv_31_00;

  signal axi_wvalid_w      : std_logic;
  signal axi_wdata_w       : slv_t(AXIDATA_W-1 downto 0);
  signal axi_wstrb_w       : slv_t(AXIDATA_W/8-1 downto 0);

  signal axi_bready_w      : std_logic;
  signal axi_arvalid_w     : std_logic;
  signal axi_araddr_w      : slv_31_00;

  signal axi_rready_w      : std_logic;
  signal axi_awready_w     : std_logic;
  signal axi_wready_w      : std_logic;
  signal axi_bvalid_w      : std_logic;

  signal axi_arready_w     : std_logic;
  signal axi_rvalid_w      : std_logic;
  signal axi_rdata_w       : slv_t(AXIDATA_W-1 downto 0);


  signal pp_irq_w          : std_logic;                 -- perip interrupt
  signal pp_addr_w         : slv_31_00;
  signal pp_rd_w           : std_logic;
  signal pp_rd_data_w      : slv_31_00;
  signal pp_wr_w           : slv_03_00;
  signal pp_wr_data_w      : slv_31_00;

  signal mbist_ena_w       : std_logic;
  signal imbist_rd_w       : slv_03_00;                  -- t1,d1,t0,d0
  signal imbist_wr_w       : slv_03_00;                  -- t1,d1,t0,d0
  signal dmbist_rd_w       : slv_03_00;                  -- t1,d1,t0,d0
  signal dmbist_wr_w       : slv_03_00;                  -- t1,d1,t0,d0
  signal mbist_addr_w      : slv_12_00;
  signal mbist_din_w       : slv_t(AXIDATA_W-1 downto 0);
  signal mbist_dout_w      : slv_t(AXIDATA_W-1 downto 0);

  signal xrst_core_w       : std_logic;
  signal xrst_cpu_w        : std_logic;
  signal rv_core_ena_w     : std_logic;
  signal rv_cpu_xrst_w     : std_logic; -- cpu xreset (cpu only, halt)

  signal uart_rxd_i_w      : std_logic; -- ulite/uart2  to pads/vsdsp
  signal uart_txd_o_w      : std_logic;
  signal dbg_uart_rxd_i_w  : std_logic; -- dbg_uart     to pads/vsdsp
  signal dbg_uart_txd_o_w  : std_logic;
  signal txd_q             : std_logic;

  signal gpio_oena_w       : slv_t(NR_GPIOS-1 downto 0);
  signal gpio_pdena_w      : slv_t(NR_GPIOS-1 downto 0);
  signal gpio_puena_w      : slv_t(NR_GPIOS-1 downto 0);

  --  DMA bus
  signal dma_rd_w          : std_logic;
  signal dma_wr_w          : slv_03_00;
  signal dma_addr_w        : slv_31_02;
  signal dma_wr_data_w     : slv_31_00;
  signal dma_rd_data_w     : slv_31_00;
  signal dma_intr_w        : std_logic;  -- dma interrupt

begin



  xrst_core_w   <= rv_core_ena_w and xrst_i;
  xrst_cpu_w    <= rv_core_ena_w and rv_cpu_xrst_w and xrst_i;

  --
  -- ASYNC RESET
  --
  -- PADS : 0 = out, 1 = in
  gpio_xena_o   <= (others => '1') when (xrst_i = '0') else (not gpio_oena_w);
  gpio_pdena_o  <= (others => '1') when (xrst_i = '0') else gpio_pdena_w;
  gpio_puena_o  <= (others => '0') when (xrst_i = '0') else gpio_puena_w;


  uart_rxd_i_w      <= uart_txd_i;
  dbg_uart_rxd_i_w  <= uart_txd_i;


  p_txd : process (clk_i)
  begin
    if (clk_i'event and clk_i = '1') then
      if (xrst_i = '0') then
        txd_q <= '1';
      else
        txd_q <= dbg_uart_txd_o_w and uart_txd_o_w;
      end if;
    end if;
  end process p_txd;

  uart_rxd_o     <= txd_q;



  u_core : rv_core
    generic map ( AXIDATA_W  => AXIDATA_W )
    port map ( clk_i            => clk_i,
               xrst_i           => xrst_i,
               xrst_core_i      => xrst_core_w,          -- cpu+cache reset
               xrst_cpu_i       => xrst_cpu_w,           -- cpu reset
               --
               --  mem bist if
               --  (NOTE: mem count is 2x WAYS as there are tag/data rams)
               --  rd/wr select is 1-hot style in order like ...t1,d1,t0,d0
               mbist_ena_i      => mbist_ena_w,
               imbist_rd_i      => imbist_rd_w,          -- t1,d1,t0,d0
               imbist_wr_i      => imbist_wr_w,          -- t1,d1,t0,d0
               dmbist_rd_i      => dmbist_rd_w,          -- t1,d1,t0,d0
               dmbist_wr_i      => dmbist_wr_w,          -- t1,d1,t0,d0
               mbist_addr_i     => mbist_addr_w,
               mbist_data_i     => mbist_dout_w,
               mbist_data_o     => mbist_din_w,
               --
               axi_awready_i    => axi4_awready_w,
               axi_wready_i     => axi4_wready_w,
               axi_bvalid_i     => axi4_bvalid_w,
               axi_bresp_i      => axi4_bresp_w,
               axi_bid_i        => axi4_bid_w,
               axi_arready_i    => axi4_arready_w,
               axi_rvalid_i     => axi4_rvalid_w,
               axi_rdata_i      => axi4_rdata_w,
               axi_rresp_i      => axi4_rresp_w,
               axi_rid_i        => axi4_rid_w,
               axi_rlast_i      => axi4_rlast_w,
               axi_awvalid_o    => axi4_awvalid_w,
               axi_awaddr_o     => axi4_awaddr_w,
               axi_awid_o       => axi4_awid_w,
               axi_awlen_o      => axi4_awlen_w,
               axi_awburst_o    => axi4_awburst_w,
               axi_wvalid_o     => axi4_wvalid_w,
               axi_wdata_o      => axi4_wdata_w,
               axi_wstrb_o      => axi4_wstrb_w,
               axi_wlast_o      => axi4_wlast_w,
               axi_bready_o     => axi4_bready_w,
               axi_arvalid_o    => axi4_arvalid_w,
               axi_araddr_o     => axi4_araddr_w,
               axi_arid_o       => axi4_arid_w,
               axi_arlen_o      => axi4_arlen_w,
               axi_arburst_o    => axi4_arburst_w,
               axi_rready_o     => axi4_rready_w,
               --  vsbus for peripherals
               pp_irq_i         => pp_irq_w,             -- perip interrupt
               pp_addr_o        => pp_addr_w,
               pp_rd_o          => pp_rd_w,
               pp_rd_data_i     => pp_rd_data_w,
               pp_wr_o          => pp_wr_w,
               pp_wr_data_o     => pp_wr_data_w,
               -- from dma
               dma_rd_i         => dma_rd_w,
               dma_wr_i         => dma_wr_w(0),
               dma_addr_i       => dma_addr_w,
               dma_wr_data_i    => dma_wr_data_w,
               dma_rd_data_o    => dma_rd_data_w,
               dma_intr_o       => dma_intr_w );



  u_vsperips : vsperips
    generic map ( CLK_FREQ    => CLK_FREQ,               -- default 50M
                  UART_SPEED  => UART_SPEED,             -- default 1M
                  AXIDATA_W   => AXIDATA_W,
                  NR_GPIOS    => NR_GPIOS )
    port map ( clk_i          => clk_i,
               xrst_i         => xrst_i,                 -- syncr reset
               --
               --  vsbus for peripherals
               pp_addr_i      => pp_addr_w,
               pp_rd_i        => pp_rd_w,
               pp_wr_i        => pp_wr_w,
               pp_wr_data_i   => pp_wr_data_w,
               pp_rd_data_o   => pp_rd_data_w,
               pp_irq_o       => pp_irq_w,               -- pp intr
               --
               pll_cfg_i      => pll_cfg_i,
               --  perip IO
               rx_i           => uart_rxd_i_w,           -- ulite
               tx_o           => uart_txd_o_w,
               rx2_i          => uart2_txd_i,            -- uart2
               tx2_o          => uart2_rxd_o,
               --
               spi_clk_o      => spi_clk_o,
               spi_cs_o       => spi_cs_o,
               spi_miso_i     => spi_miso_i,
               spi_mosi_o     => spi_mosi_o,
               --
               gpio_i         => gpio_i,
               gpio_o         => gpio_o,
               gpio_oena_o    => gpio_oena_w,
               gpio_pdena_o   => gpio_pdena_w,
               gpio_puena_o   => gpio_puena_w,
               --  DMA bus
               dma_rd_o       => dma_rd_w,
               dma_wr_o       => dma_wr_w,
               dma_addr_o     => dma_addr_w,
               dma_wr_data_o  => dma_wr_data_w,
               dma_rd_data_i  => dma_rd_data_w,
               dma_intr_i     => dma_intr_w );




  u_axi_mem_if : axi_mem_if
    generic map ( AXIDATA_W  => AXIDATA_W )
    port map ( clk_i             => clk_i,
               xrst_i            => xrst_i,
               --
               axi_a_awvalid_i   => axi_awvalid_w,       -- AXI A-port: dbg uart
               axi_a_awaddr_i    => axi_awaddr_w,
               axi_a_awid_i      => X"0",                -- !
               axi_a_awlen_i     => X"00",               -- !
               axi_a_awburst_i   => "01",                -- !
               axi_a_wvalid_i    => axi_wvalid_w,
               axi_a_wdata_i     => axi_wdata_w,
               axi_a_wstrb_i     => axi_wstrb_w,
               axi_a_wlast_i     => '1',                 -- !
               axi_a_bready_i    => axi_bready_w,
               axi_a_arvalid_i   => axi_arvalid_w,
               axi_a_araddr_i    => axi_araddr_w,
               axi_a_arid_i      => X"0",                -- !
               axi_a_arlen_i     => X"00",               -- !
               axi_a_arburst_i   => "01",                -- !
               axi_a_rready_i    => axi_rready_w,
               axi_a_awready_o   => axi_awready_w,
               axi_a_wready_o    => axi_wready_w,
               axi_a_bvalid_o    => axi_bvalid_w,
               axi_a_bresp_o     => OPEN,                -- !
               axi_a_bid_o       => OPEN,                -- !
               axi_a_arready_o   => axi_arready_w,
               axi_a_rvalid_o    => axi_rvalid_w,
               axi_a_rdata_o     => axi_rdata_w,
               axi_a_rresp_o     => OPEN,                -- !
               axi_a_rid_o       => OPEN,                -- !
               axi_a_rlast_o     => OPEN,                -- !
               --
               axi_b_awvalid_i   => '0',                 -- AXI B-port: NC
               axi_b_awaddr_i    => X"00000000",
               axi_b_awid_i      => X"0",
               axi_b_awlen_i     => X"00",
               axi_b_awburst_i   => "00",
               axi_b_wvalid_i    => '0',
               axi_b_wdata_i     => (others => '0'),     -- AXIDATA_W-1:0
               axi_b_wstrb_i     => (others => '0'),     -- AXIDATA_W/8-1:0
               axi_b_wlast_i     => '0',
               axi_b_bready_i    => '0',
               axi_b_arvalid_i   => '0',
               axi_b_araddr_i    => X"00000000",
               axi_b_arid_i      => X"0",
               axi_b_arlen_i     => X"00",
               axi_b_arburst_i   => "00",
               axi_b_rready_i    => '0',
               axi_b_awready_o   => OPEN,
               axi_b_wready_o    => OPEN,
               axi_b_bvalid_o    => OPEN,
               axi_b_bresp_o     => OPEN,
               axi_b_bid_o       => OPEN,
               axi_b_arready_o   => OPEN,
               axi_b_rvalid_o    => OPEN,
               axi_b_rdata_o     => OPEN,
               axi_b_rresp_o     => OPEN,
               axi_b_rid_o       => OPEN,
               axi_b_rlast_o     => OPEN,
               --
               axi_c_awvalid_i   => axi4_awvalid_w,      -- AXI C-port: cpu
               axi_c_awaddr_i    => axi4_awaddr_w,
               axi_c_awid_i      => axi4_awid_w,
               axi_c_awlen_i     => axi4_awlen_w,
               axi_c_awburst_i   => axi4_awburst_w,
               axi_c_wvalid_i    => axi4_wvalid_w,
               axi_c_wdata_i     => axi4_wdata_w,
               axi_c_wstrb_i     => axi4_wstrb_w,
               axi_c_wlast_i     => axi4_wlast_w,
               axi_c_bready_i    => axi4_bready_w,
               axi_c_arvalid_i   => axi4_arvalid_w,
               axi_c_araddr_i    => axi4_araddr_w,
               axi_c_arid_i      => axi4_arid_w,
               axi_c_arlen_i     => axi4_arlen_w,
               axi_c_arburst_i   => axi4_arburst_w,
               axi_c_rready_i    => axi4_rready_w,
               axi_c_awready_o   => axi4_awready_w,
               axi_c_wready_o    => axi4_wready_w,
               axi_c_bvalid_o    => axi4_bvalid_w,
               axi_c_bresp_o     => axi4_bresp_w,
               axi_c_bid_o       => axi4_bid_w,
               axi_c_arready_o   => axi4_arready_w,
               axi_c_rvalid_o    => axi4_rvalid_w,
               axi_c_rdata_o     => axi4_rdata_w,
               axi_c_rresp_o     => axi4_rresp_w,
               axi_c_rid_o       => axi4_rid_w,
               axi_c_rlast_o     => axi4_rlast_w,
               --
               xmem_awready_i    => xmem_awready_i,      -- AXI out port: xmem
               xmem_wready_i     => xmem_wready_i,
               xmem_bvalid_i     => xmem_bvalid_i,
               xmem_bresp_i      => xmem_bresp_i,
               xmem_bid_i        => xmem_bid_i,
               xmem_arready_i    => xmem_arready_i,
               xmem_rvalid_i     => xmem_rvalid_i,
               xmem_rdata_i      => xmem_rdata_i,
               xmem_rresp_i      => xmem_rresp_i,
               xmem_rid_i        => xmem_rid_i,
               xmem_rlast_i      => xmem_rlast_i,
               xmem_awvalid_o    => xmem_awvalid_o,
               xmem_awaddr_o     => xmem_awaddr_o,
               xmem_awid_o       => xmem_awid_o,
               xmem_awlen_o      => xmem_awlen_o,
               xmem_awburst_o    => xmem_awburst_o,
               xmem_wvalid_o     => xmem_wvalid_o,
               xmem_wdata_o      => xmem_wdata_o,
               xmem_wstrb_o      => xmem_wstrb_o,
               xmem_wlast_o      => xmem_wlast_o,
               xmem_bready_o     => xmem_bready_o,
               xmem_arvalid_o    => xmem_arvalid_o,
               xmem_araddr_o     => xmem_araddr_o,
               xmem_arid_o       => xmem_arid_o,
               xmem_arlen_o      => xmem_arlen_o,
               xmem_arburst_o    => xmem_arburst_o,
               xmem_rready_o     => xmem_rready_o );


  u_dbg_bridge : dbg_bridge
    generic map ( CLK_FREQ    => CLK_FREQ,        -- default 50M
                  UART_SPEED  => UART_SPEED,      -- default 1M
                  AXIDATA_W   => AXIDATA_W )      -- select 32 / 64
    port map ( clk_i          => clk_i,
               xrst_i         => xrst_i,
               --
               --
               vs_rst_cpu_i   => vs_rst_cpu_i,    -- riscv core only, '1' if NC
               --  mem bist if
               --  (NOTE: mem count is 2x WAYS as there are tag/data rams)
               --  rd/wr select is 1-hot style in order like ...t1,d1,t0,d0
               --
               mbist_ena_o     => mbist_ena_w,
               imbist_rd_o     => imbist_rd_w,    -- t1,d1,t0,d0
               imbist_wr_o     => imbist_wr_w,    -- t1,d1,t0,d0
               dmbist_rd_o     => dmbist_rd_w,    -- t1,d1,t0,d0
               dmbist_wr_o     => dmbist_wr_w,    -- t1,d1,t0,d0
               mbist_addr_o    => mbist_addr_w,
               mbist_data_o    => mbist_dout_w,
               mbist_data_i    => mbist_din_w,
               --
               --
               --  AXI bus to DDR / TCM ram if
               mem_awready_i  => axi_awready_w,
               mem_wready_i   => axi_wready_w,
               mem_bvalid_i   => axi_bvalid_w,
               --
               mem_awvalid_o  => axi_awvalid_w,
               mem_awaddr_o   => axi_awaddr_w,
               mem_wvalid_o   => axi_wvalid_w,
               mem_wdata_o    => axi_wdata_w,
               mem_wstrb_o    => axi_wstrb_w,
               mem_bready_o   => axi_bready_w,
               --
               mem_arready_i  => axi_arready_w,
               mem_rvalid_i   => axi_rvalid_w,
               mem_rdata_i    => axi_rdata_w,
               --
               mem_arvalid_o  => axi_arvalid_w,
               mem_araddr_o   => axi_araddr_w,
               mem_rready_o   => axi_rready_w,
               --  pp io
               uart_rxd_i     => dbg_uart_rxd_i_w,
               uart_txd_o     => dbg_uart_txd_o_w,
               rv_cpu_xrst_o  => rv_cpu_xrst_w,   -- cpu xreset (halt)
               rv_core_ena_o  => rv_core_ena_w ); -- cpu / cache enable


end rtl;
