dakies/OSS_Verilog huggingface dataset:
module tb_axi_id_remap;

  parameter AW = 32;
  parameter DW = 32;
  parameter IW = 8;
  parameter UW = 8;
  parameter IWO = 4;
  parameter TS = 4;

  localparam tCK = 1ns;

  logic clk = 0;
  logic rst = 1;
  logic done = 0;

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IWO),
    .AXI_USER_WIDTH(UW)
  ) axi_slave_dv(clk);

  AXI_BUS #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IWO),
    .AXI_USER_WIDTH(UW)
  ) axi_slave();

  `AXI_ASSIGN(axi_slave_dv, axi_slave);

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi_master_dv(clk);

  AXI_BUS #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi_master();

  `AXI_ASSIGN(axi_master, axi_master_dv);

  axi_id_remap #(
    .ADDR_WIDTH     (AW),
    .DATA_WIDTH     (DW),
    .USER_WIDTH     (UW),
    .ID_WIDTH_IN    (IW),
    .ID_WIDTH_OUT   (IWO),
    .TABLE_SIZE     (TS)
  ) i_dut (
    .clk_i  ( clk        ),
    .rst_ni ( rst        ),
    .in     ( axi_master ),
    .out    ( axi_slave  )
  );

  axi_test::axi_driver #(.AW(AW), .DW(DW), .IW(IWO), .UW(UW), .TA(200ps), .TT(700ps)) axi_slave_drv = new(axi_slave_dv);
  axi_test::axi_driver #(.AW(AW), .DW(DW), .IW(IW), .UW(UW), .TA(200ps), .TT(700ps)) axi_master_drv = new(axi_master_dv);

  initial begin
    #tCK;
    rst <= 0;
    #tCK;
    rst <= 1;
    #tCK;
    while (!done) begin
      clk <= 1;
      #(tCK/2);
      clk <= 0;
      #(tCK/2);
    end
  end

  initial begin
    automatic axi_test::axi_ax_beat #(.AW(AW), .IW(IW), .UW(UW)) ax_beat = new;
    automatic axi_test::axi_w_beat #(.DW(DW), .UW(UW)) w_beat = new;
    automatic axi_test::axi_b_beat  #(.IW(IW), .UW(UW)) b_beat;
    axi_master_drv.reset_master();
    @(posedge clk);
    repeat (4) begin
        @(posedge clk);
        void'(randomize(ax_beat));
        axi_master_drv.send_aw(ax_beat);
        w_beat.w_data = 'hcafebabe;
        axi_master_drv.send_w(w_beat);
    end

    repeat (4) axi_master_drv.recv_b(b_beat);

    done = 1;
  end

  initial begin
    automatic axi_test::axi_ax_beat #(.AW(AW), .IW(IWO), .UW(UW)) ax_beat;
    automatic axi_test::axi_w_beat #(.DW(DW), .UW(UW)) w_beat;
    automatic axi_test::axi_b_beat #(.IW(IWO), .UW(UW)) b_beat = new;
    axi_slave_drv.reset_slave();
    @(posedge clk);
    repeat (4) begin
        axi_slave_drv.recv_aw(ax_beat);
        $info("AXI AW: addr %h", ax_beat.ax_addr);
        axi_slave_drv.recv_w(w_beat);
        $info("AXI W: data %h, strb %h", w_beat.w_data, w_beat.w_strb);
    end
    b_beat.b_id = 2;
    axi_slave_drv.send_b(b_beat);
    b_beat.b_id = 0;
    axi_slave_drv.send_b(b_beat);
    b_beat.b_id = 1;
    axi_slave_drv.send_b(b_beat);
    b_beat.b_id = 3;
    axi_slave_drv.send_b(b_beat);
  end
// vsim -voptargs=+acc work.tb_axi_id_remap
endmodule
module tb_axi_to_axi_lite;

  parameter AW = 32;
  parameter DW = 32;
  parameter IW = 8;
  parameter UW = 8;

  localparam tCK = 1ns;
  localparam TA = tCK * 1/4;
  localparam TT = tCK * 3/4;

  logic clk = 0;
  logic rst = 1;
  logic done = 0;

  AXI_LITE_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW)
  ) axi_lite_dv(clk);

  AXI_LITE #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW)
  ) axi_lite();

  `AXI_LITE_ASSIGN(axi_lite_dv, axi_lite);

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi_dv(clk);

  AXI_BUS #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi();

  `AXI_ASSIGN(axi, axi_dv);

  axi_to_axi_lite i_dut (
    .clk_i      ( clk      ),
    .rst_ni     ( rst      ),
    .testmode_i ( 1'b0     ),
    .in         ( axi      ),
    .out        ( axi_lite )
  );

  typedef axi_test::axi_lite_driver #(.AW(AW), .DW(DW), .TA(TA), .TT(TT)) axi_lite_drv_t;
  typedef axi_test::axi_driver #(.AW(AW), .DW(DW), .IW(IW), .UW(UW), .TA(TA), .TT(TT)) axi_drv_t;
  axi_lite_drv_t axi_lite_drv = new(axi_lite_dv);
  axi_drv_t axi_drv = new(axi_dv);

  initial begin
    #tCK;
    rst <= 0;
    #tCK;
    rst <= 1;
    #tCK;
    while (!done) begin
      clk <= 1;
      #(tCK/2);
      clk <= 0;
      #(tCK/2);
    end
  end

  initial begin
    automatic axi_drv_t::ax_beat_t ax = new;
    automatic axi_drv_t::w_beat_t w = new;
    automatic axi_drv_t::b_beat_t b = new;
    automatic axi_drv_t::r_beat_t r = new;
    axi_drv.reset_master();
    @(posedge clk);

    ax.randomize();
    w.randomize();
    w.last = 1'b1;
    axi_drv.send_aw(ax);
    axi_drv.send_w(w);
    axi_drv.recv_b(b);

    ax.randomize();
    axi_drv.send_ar(ax);
    axi_drv.recv_r(r);

    repeat (4) @(posedge clk);
    done = 1;
  end

  initial begin
    automatic logic [AW-1:0] addr;
    automatic logic [DW-1:0] data;
    automatic logic [DW/8-1:0] strb;

    axi_lite_drv.reset_slave();
    @(posedge clk);

    axi_lite_drv.recv_aw(addr);
    axi_lite_drv.recv_w(data, strb);
    axi_lite_drv.send_b(axi_pkg::RESP_OKAY);

    axi_lite_drv.recv_ar(addr);
    axi_lite_drv.send_r('0, axi_pkg::RESP_OKAY);
  end

endmodule
module tb_axi_lite_to_axi;

  parameter AW = 32;
  parameter DW = 32;
  parameter IW = 8;
  parameter UW = 8;

  localparam tCK = 1ns;

  logic clk = 0;
  logic rst = 1;
  logic done = 0;

  AXI_LITE_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW)
  ) axi_lite_dv(clk);

  AXI_LITE #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW)
  ) axi_lite();

  `AXI_LITE_ASSIGN(axi_lite, axi_lite_dv);

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi_dv(clk);

  AXI_BUS #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi();

  `AXI_ASSIGN(axi_dv, axi);

  axi_lite_to_axi i_dut (
    .in   ( axi_lite ),
    .out  ( axi      )
  );

  axi_test::axi_lite_driver #(.AW(AW), .DW(DW)) axi_lite_drv = new(axi_lite_dv);
  axi_test::axi_driver #(.AW(AW), .DW(DW), .IW(IW), .UW(UW)) axi_drv = new(axi_dv);

  initial begin
    #tCK;
    rst <= 0;
    #tCK;
    rst <= 1;
    #tCK;
    while (!done) begin
      clk <= 1;
      #(tCK/2);
      clk <= 0;
      #(tCK/2);
    end
  end

  initial begin
    automatic axi_pkg::resp_t resp;
    axi_lite_drv.reset_master();
    @(posedge clk);
    axi_lite_drv.send_aw('hdeadbeef);
    axi_lite_drv.send_w('hdeadbeef, '1);
    axi_lite_drv.recv_b(resp);
    $info("AXI-Lite B: resp %h", resp);
    repeat (4) @(posedge clk);
    done = 1;
  end

  initial begin
    automatic axi_test::axi_ax_beat #(.AW(AW), .IW(IW), .UW(UW)) ax_beat;
    automatic axi_test::axi_w_beat #(.DW(DW), .UW(UW)) w_beat;
    automatic axi_test::axi_b_beat #(.IW(IW), .UW(UW)) b_beat = new;
    axi_drv.reset_slave();
    @(posedge clk);
    axi_drv.recv_aw(ax_beat);
    $info("AXI AW: addr %h", ax_beat.ax_addr);
    axi_drv.recv_w(w_beat);
    $info("AXI W: data %h, strb %h", w_beat.w_data, w_beat.w_strb);
    axi_drv.send_b(b_beat);
  end

endmodule
module pulp_clock_mux2
  (
   input  logic clk0_i,
   input  logic clk1_i,
   input  logic clk_sel_i,
   output logic clk_o
   );
   
  BUFGMUX bufgmux_i (
    .S(clk_sel_i),
    .I0(clk0_i),
    .I1(clk1_i),
    .O(clk_o)
  );
   
endmodule
module rgmii_core #
(
    parameter TARGET = "XILINX"
)
(
    /*
     * Clock: 125MHz
     * Synchronous reset
     */
    input wire         clk,
    input wire         clk90,
    input wire         rst,

    /*
     * Ethernet: 1000BASE-T RGMII
     */
    input wire         phy_rx_clk,
    input wire [3:0]   phy_rxd,
    input wire         phy_rx_ctl,
    output wire        phy_tx_clk,
    output wire [3:0]  phy_txd,
    output wire        phy_tx_ctl,
    output wire        phy_reset_n,
    input wire         phy_int_n,
    input wire         phy_pme_n,
    output wire        mac_gmii_tx_en,

       /*
        * AXI input
        */
 
    input wire         tx_axis_tvalid,
    input wire         tx_axis_tlast,
    input wire [7:0]   tx_axis_tdata,
    output wire        tx_axis_tready,
    input wire         tx_axis_tuser,
   
       /*
        * AXI output
        */
 
    output wire        rx_clk,
    output wire [7:0]  rx_axis_tdata,
    output wire        rx_axis_tvalid,
    output wire        rx_axis_tlast,
    output wire        rx_axis_tuser,

    /*
     * Status
     */

    output wire [31:0] rx_fcs_reg,
    output wire [31:0] tx_fcs_reg

);

assign phy_reset_n = !rst;

eth_mac_1g_rgmii_fifo #(
    .TARGET(TARGET),
    .IODDR_STYLE("IODDR"),
    .CLOCK_INPUT_STYLE("BUFR"),
    .USE_CLK90("TRUE"),
    .ENABLE_PADDING(1),
    .MIN_FRAME_LENGTH(64),
    .TX_FIFO_ADDR_WIDTH(12),
    .TX_FRAME_FIFO(1),
    .RX_FIFO_ADDR_WIDTH(12),
    .RX_FRAME_FIFO(1)
)
eth_mac_inst (
    .gtx_clk(clk),
    .gtx_clk90(clk90),
    .gtx_rst(rst),
    .logic_clk(clk),
    .logic_rst(rst),
    .rx_clk(rx_clk),

    .tx_axis_tdata(tx_axis_tdata),
    .tx_axis_tvalid(tx_axis_tvalid),
    .tx_axis_tready(tx_axis_tready),
    .tx_axis_tlast(tx_axis_tlast),
    .tx_axis_tuser(tx_axis_tuser),

    .rx_axis_tdata(rx_axis_tdata),
    .rx_axis_tvalid(rx_axis_tvalid),
    .rx_axis_tlast(rx_axis_tlast),
    .rx_axis_tuser(rx_axis_tuser),

    .rgmii_rx_clk(phy_rx_clk),
    .rgmii_rxd(phy_rxd),
    .rgmii_rx_ctl(phy_rx_ctl),
    .rgmii_tx_clk(phy_tx_clk),
    .rgmii_txd(phy_txd),
    .rgmii_tx_ctl(phy_tx_ctl),
    .mac_gmii_tx_en(mac_gmii_tx_en),

    .tx_fifo_overflow(),
    .tx_fifo_bad_frame(),
    .tx_fifo_good_frame(),
    .rx_error_bad_frame(),
    .rx_error_bad_fcs(),
    .rx_fcs_reg(rx_fcs_reg),
    .tx_fcs_reg(tx_fcs_reg),
    .rx_fifo_overflow(),
    .rx_fifo_bad_frame(),
    .rx_fifo_good_frame(),
    .speed(),

    .ifg_delay(12)
);

endmodule
module dualmem_widen(clka, clkb, dina, dinb, addra, addrb, wea, web, douta, doutb, ena, enb);

   input wire clka, clkb;
   input  [15:0] dina;
   input  [63:0] dinb;
   input  [10:0] addra;
   input   [8:0] addrb;
   input   [1:0]        wea;
   input   [1:0]        web;
   input   [0:0]        ena, enb;
   output [15:0]      douta;
   output [63:0]      doutb;

   genvar r;
   wire [47:0]        dout;

/*   
`ifndef verilator
 `define RAMB16
`endif
*/
   
`ifdef KINTEX7
 `define RAMB16
`endif

`ifdef RAMB16
   
   generate for (r = 0; r < 2; r=r+1)
     RAMB16_S9_S36
     RAMB16_S9_S36_inst
       (
        .CLKA   ( clka                     ),     // Port A Clock
        .DOA    ( douta[r*8 +: 8]          ),     // Port A 1-bit Data Output
        .DOPA   (                          ),
        .ADDRA  ( addra                    ),     // Port A 14-bit Address Input
        .DIA    ( dina[r*8 +: 8]           ),     // Port A 1-bit Data Input
        .DIPA   ( 1'b0                     ),
        .ENA    ( ena                      ),     // Port A RAM Enable Input
        .SSRA   ( 1'b0                     ),     // Port A Synchronous Set/Reset Input
        .WEA    ( wea[r]                   ),     // Port A Write Enable Input
        .CLKB   ( clkb                     ),     // Port B Clock
        .DOB    ( doutb[r*32 +: 32]        ),     // Port B 1-bit Data Output
        .DOPB   (                          ),
        .ADDRB  ( addrb                    ),     // Port B 14-bit Address Input
        .DIB    ( dinb[r*32 +: 32]         ),     // Port B 1-bit Data Input
        .DIPB   ( 4'b0                     ),
        .ENB    ( enb                      ),     // Port B RAM Enable Input
        .SSRB   ( 1'b0                     ),     // Port B Synchronous Set/Reset Input
        .WEB    ( web[r]                   )      // Port B Write Enable Input
        );
   endgenerate

`else // !`ifdef RAMB16

// This bit is a placeholder

infer_dpram #(.RAM_SIZE(11), .BYTE_WIDTH(8)) ram1 // RAM_SIZE is in words
(
.ram_clk_a(clka),
.ram_en_a(|ena),
.ram_we_a({wea[1],wea[1],wea[1],wea[1],wea[0],wea[0],wea[0],wea[0]}),
.ram_addr_a(addra),
.ram_wrdata_a({dina,dina,dina,dina}),
.ram_rddata_a({dout,douta}),
.ram_clk_b(clkb),
.ram_en_b(|enb),
.ram_we_b({web[1],web[1],web[1],web[1],web[0],web[0],web[0],web[0]}),
.ram_addr_b({2'b0,addrb}),
.ram_wrdata_b(dinb),
.ram_rddata_b(doutb)
 );
   
`endif
   
endmodule // dualmem
module dualmem_widen8(clka, clkb, dina, dinb, addra, addrb, wea, web, douta, doutb, ena, enb);

   input wire clka, clkb;
   input  [15:0] dina;
   input  [63:0] dinb;
   input  [12:0] addra;
   input  [10:0] addrb;
   input   [1:0]        wea;
   input   [1:0]        web;
   input   [0:0]        ena, enb;
   output [15:0]      douta;
   output [63:0]      doutb;

   genvar r;
   wire [63:0]        dout0;
   wire [255:0]       dout1;
   wire [7:0] 	      we0, we1, en0, en1;
   wire [63:0]        din0;
   wire [255:0]       din1;
   
   reg [12:0]       addra_dly;
   reg [10:0]       addrb_dly;

/*
`ifndef verilator
 `define RAMB16
`endif
*/
   
`ifdef KINTEX7
 `define RAMB16
`endif

`ifdef RAMB16
   
   assign douta = dout0 >> {addra_dly[12:11],4'b0000};
   assign doutb = dout1 >> {addrb_dly[10:9],6'b000000};
   assign we0 = wea << {addra[12:11],1'b0};
   assign we1 = web << {addrb[10:9],1'b0};
   assign en0 = {ena,ena} << {addra[12:11],1'b0};
   assign en1 = {enb,enb} << {addrb[10:9],1'b0};
   assign din0 = {dina,dina,dina,dina};
   assign din1 = {dinb,dinb,dinb,dinb};
   
   always @(posedge clka)
     begin
	addra_dly <= addra;
	addrb_dly <= addrb;
     end
   
   generate for (r = 0; r < 8; r=r+1)
     RAMB16_S9_S36
     RAMB16_S9_S36_inst
       (
        .CLKA   ( clka                     ),     // Port A Clock
        .DOA    ( dout0[r*8 +: 8]          ),     // Port A 1-bit Data Output
        .DOPA   (                          ),
        .ADDRA  ( addra[10:0]              ),     // Port A 14-bit Address Input
        .DIA    ( din0[r*8 +: 8]           ),     // Port A 1-bit Data Input
        .DIPA   ( 1'b0                     ),
        .ENA    ( en0[r]                   ),     // Port A RAM Enable Input
        .SSRA   ( 1'b0                     ),     // Port A Synchronous Set/Reset Input
        .WEA    ( we0[r]                   ),     // Port A Write Enable Input
        .CLKB   ( clkb                     ),     // Port B Clock
        .DOB    ( dout1[r*32 +: 32]        ),     // Port B 1-bit Data Output
        .DOPB   (                          ),
        .ADDRB  ( addrb[8:0]               ),     // Port B 14-bit Address Input
        .DIB    ( din1[r*32 +: 32]         ),     // Port B 1-bit Data Input
        .DIPB   ( 4'b0                     ),
        .ENB    ( en1[r]                   ),     // Port B RAM Enable Input
        .SSRB   ( 1'b0                     ),     // Port B Synchronous Set/Reset Input
        .WEB    ( we1[r]                   )      // Port B Write Enable Input
        );
   endgenerate

`else // !`ifdef RAMB16

// This bit is a placeholder

infer_dpram #(.RAM_SIZE(11), .BYTE_WIDTH(8)) ram1 // RAM_SIZE is in words
(
.ram_clk_a(clka),
.ram_en_a(|ena),
.ram_we_a({wea[1],wea[1],wea[1],wea[1],wea[0],wea[0],wea[0],wea[0]}),
.ram_addr_a(addra),
.ram_wrdata_a({dina,dina,dina,dina}),
.ram_rddata_a({dout,douta}),
.ram_clk_b(clkb),
.ram_en_b(|enb),
.ram_we_b({web[1],web[1],web[1],web[1],web[0],web[0],web[0],web[0]}),
.ram_addr_b({2'b0,addrb}),
.ram_wrdata_b(dinb),
.ram_rddata_b(doutb)
 );
   
`endif
   
endmodule // dualmem
module eth_mac_1g #
(
    parameter ENABLE_PADDING = 1,
    parameter MIN_FRAME_LENGTH = 64
)
(
    input wire         rx_clk,
    input wire         rx_rst,
    input wire         tx_clk,
    input wire         tx_rst,

    /*
     * AXI input
     */
    input wire [7:0]   tx_axis_tdata,
    input wire         tx_axis_tvalid,
    output wire        tx_axis_tready,
    input wire         tx_axis_tlast,
    input wire         tx_axis_tuser,

    /*
     * AXI output
     */
    output wire [7:0]  rx_axis_tdata,
    output wire        rx_axis_tvalid,
    output wire        rx_axis_tlast,
    output wire        rx_axis_tuser,

    /*
     * GMII interface
     */
    input wire [7:0]   gmii_rxd,
    input wire         gmii_rx_dv,
    input wire         gmii_rx_er,
    output wire [7:0]  gmii_txd,
    output wire        gmii_tx_en,
    output wire        gmii_tx_er,

    /*
     * Control
     */
    input wire         rx_clk_enable,
    input wire         tx_clk_enable,
    input wire         rx_mii_select,
    input wire         tx_mii_select,
 
    /*
     * Status
     */
    output wire        rx_error_bad_frame,
    output wire        rx_error_bad_fcs,
    output wire [31:0] rx_fcs_reg,
    output wire [31:0] tx_fcs_reg,

    /*
     * Configuration
     */
    input wire [7:0]   ifg_delay
);

axis_gmii_rx
axis_gmii_rx_inst (
    .clk(rx_clk),
    .rst(rx_rst),
    .gmii_rxd(gmii_rxd),
    .gmii_rx_dv(gmii_rx_dv),
    .gmii_rx_er(gmii_rx_er),
    .m_axis_tdata(rx_axis_tdata),
    .m_axis_tvalid(rx_axis_tvalid),
    .m_axis_tlast(rx_axis_tlast),
    .m_axis_tuser(rx_axis_tuser),
    .clk_enable(rx_clk_enable),
    .mii_select(rx_mii_select),
    .error_bad_frame(rx_error_bad_frame),
    .error_bad_fcs(rx_error_bad_fcs),
    .fcs_reg(rx_fcs_reg)
);

axis_gmii_tx #(
    .ENABLE_PADDING(ENABLE_PADDING),
    .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH)
)
axis_gmii_tx_inst (
    .clk(tx_clk),
    .rst(tx_rst),
    .s_axis_tdata(tx_axis_tdata),
    .s_axis_tvalid(tx_axis_tvalid),
    .s_axis_tready(tx_axis_tready),
    .s_axis_tlast(tx_axis_tlast),
    .s_axis_tuser(tx_axis_tuser),
    .gmii_txd(gmii_txd),
    .gmii_tx_en(gmii_tx_en),
    .gmii_tx_er(gmii_tx_er),
    .clk_enable(tx_clk_enable),
    .mii_select(tx_mii_select),
    .ifg_delay(ifg_delay),
    .fcs_reg(tx_fcs_reg)
);

endmodule
module reg_uart_wrap #(
    parameter int unsigned AddrWidth = -1,
    parameter type reg_req_t = logic,
    parameter type reg_rsp_t = logic
) (
  input  logic clk_i,
  input  logic rst_ni,

  // Regbus
  input  reg_req_t reg_req_i,
  output reg_rsp_t reg_rsp_o,

  // Physical interface
  output logic intr_o,
  output logic out1_no,
  output logic out2_no,
  output logic rts_no,
  output logic dtr_no,
  input  logic cts_ni,
  input  logic dsr_ni,
  input  logic dcd_ni,
  input  logic rin_ni,
  input  logic sin_i,   // RX
  output logic sout_o   // TX
);
  `APB_TYPEDEF_REQ_T(reg_uart_apb_req_t, logic [AddrWidth-1:0], logic [31:0], logic [3:0])
  `APB_TYPEDEF_RESP_T(reg_uart_apb_rsp_t, logic [31:0])

  reg_uart_apb_req_t uart_apb_req;
  reg_uart_apb_rsp_t uart_apb_rsp;

  reg_to_apb #(
    .reg_req_t  ( reg_req_t             ),
    .reg_rsp_t  ( reg_rsp_t             ),
    .apb_req_t  ( reg_uart_apb_req_t    ),
    .apb_rsp_t  ( reg_uart_apb_rsp_t    )
  ) i_reg_uart_reg_to_apb (
    .clk_i,
    .rst_ni,
    .reg_req_i,
    .reg_rsp_o,
    .apb_req_o  ( uart_apb_req          ),
    .apb_rsp_i  ( uart_apb_rsp          )
  );

  apb_uart i_apb_uart (
    .CLK      ( clk_i   ),
    .RSTN     ( rst_ni  ),
    .PSEL     ( uart_apb_req.psel        ),
    .PENABLE  ( uart_apb_req.penable     ),
    .PWRITE   ( uart_apb_req.pwrite      ),
    .PADDR    ( uart_apb_req.paddr[4:2]  ),
    .PWDATA   ( uart_apb_req.pwdata      ),
    .PRDATA   ( uart_apb_rsp.prdata      ),
    .PREADY   ( uart_apb_rsp.pready      ),
    .PSLVERR  ( uart_apb_rsp.pslverr     ),
    .INT      ( intr_o  ),
    .OUT1N    ( out1_no ),
    .OUT2N    ( out2_no ),
    .RTSN     ( rts_no  ),
    .DTRN     ( dtr_no  ),
    .CTSN     ( cts_ni  ),
    .DSRN     ( dsr_ni  ),
    .DCDN     ( dcd_ni  ),
    .RIN      ( rin_ni  ),
    .SIN      ( sin_i   ),
    .SOUT     ( sout_o  )
  );

endmodule
module isochronous_spill_register #(
  /// Data type of spill register.
  parameter type T      = logic,
  /// Make this spill register transparent.
  parameter bit  Bypass = 1'b0
) (
  /// Clock of source clock domain.
  input  logic src_clk_i,
  /// Active low async reset in source domain.
  input  logic src_rst_ni,
  /// Source input data is valid.
  input  logic src_valid_i,
  /// Source is ready to accept.
  output logic src_ready_o,
  /// Source input data.
  input  T     src_data_i,
  /// Clock of destination clock domain.
  input  logic dst_clk_i,
  /// Active low async reset in destination domain.
  input  logic dst_rst_ni,
  /// Destination output data is valid.
  output logic dst_valid_o,
  /// Destination is ready to accept.
  input  logic dst_ready_i,
  /// Destination output data.
  output T     dst_data_o
);
  // Don't generate the spill register.
  if (Bypass) begin : gen_bypass
    assign dst_valid_o = src_valid_i;
    assign src_ready_o = dst_ready_i;
    assign dst_data_o  = src_data_i;
  // Generate the spill register
  end else begin : gen_isochronous_spill_register
    /// Read/write pointer are one bit wider than necessary.
    /// We implicitly capture the full and empty state with the second bit:
    /// If all but the topmost bit of `rd_pointer_q` and `wr_pointer_q` agree, the
    /// FIFO is in a critical state. If the topmost bit is equal, the FIFO is
    /// empty, otherwise it is full.
    logic [1:0] rd_pointer_q, wr_pointer_q;
    // Advance write pointer if we pushed a new item into the FIFO. (Source clock domain)
    `FFLARN(wr_pointer_q, wr_pointer_q+1, (src_valid_i && src_ready_o), '0, src_clk_i, src_rst_ni)
    // Advance read pointer if downstream consumed an item. (Destination clock domain)
    `FFLARN(rd_pointer_q, rd_pointer_q+1, (dst_valid_o && dst_ready_i), '0, dst_clk_i, dst_rst_ni)

    T [1:0] mem_d, mem_q;
    `FFLNR(mem_q, mem_d, (src_valid_i && src_ready_o), src_clk_i)
    always_comb begin
      mem_d = mem_q;
      mem_d[wr_pointer_q[0]] = src_data_i;
    end

    assign src_ready_o = (rd_pointer_q ^ wr_pointer_q) != 2'b10;

    assign dst_valid_o = (rd_pointer_q ^ wr_pointer_q) != '0;
    assign dst_data_o = mem_q[rd_pointer_q[0]];
  end
endmodule
module cdc_fifo_gray #(
  /// The width of the default logic type.
  parameter int unsigned WIDTH = 1,
  /// The data type of the payload transported by the FIFO.
  parameter type T = logic [WIDTH-1:0],
  /// The FIFO's depth given as 2**LOG_DEPTH.
  parameter int LOG_DEPTH = 3,
  /// The number of synchronization registers to insert on the async pointers.
  parameter int SYNC_STAGES = 2
) (
  input  logic src_rst_ni,
  input  logic src_clk_i,
  input  T     src_data_i,
  input  logic src_valid_i,
  output logic src_ready_o,

  input  logic dst_rst_ni,
  input  logic dst_clk_i,
  output T     dst_data_o,
  output logic dst_valid_o,
  input  logic dst_ready_i
);

  T [2**LOG_DEPTH-1:0] async_data;
  logic [LOG_DEPTH:0]  async_wptr;
  logic [LOG_DEPTH:0]  async_rptr;

  cdc_fifo_gray_src #(
    .T         ( T         ),
    .LOG_DEPTH ( LOG_DEPTH )
  ) i_src (
    .src_rst_ni,
    .src_clk_i,
    .src_data_i,
    .src_valid_i,
    .src_ready_o,

    (* async *) .async_data_o ( async_data ),
    (* async *) .async_wptr_o ( async_wptr ),
    (* async *) .async_rptr_i ( async_rptr )
  );

  cdc_fifo_gray_dst #(
    .T         ( T         ),
    .LOG_DEPTH ( LOG_DEPTH )
  ) i_dst (
    .dst_rst_ni,
    .dst_clk_i,
    .dst_data_o,
    .dst_valid_o,
    .dst_ready_i,

    (* async *) .async_data_i ( async_data ),
    (* async *) .async_wptr_i ( async_wptr ),
    (* async *) .async_rptr_o ( async_rptr )
  );

  // Check the invariants.
  // pragma translate_off
  `ifndef VERILATOR
  initial assert(LOG_DEPTH > 0);
  initial assert(SYNC_STAGES >= 2);
  `endif
  // pragma translate_on

endmodule
module cdc_fifo_gray_src #(
  parameter type T = logic,
  parameter int LOG_DEPTH = 3,
  parameter int SYNC_STAGES = 2
)(
  input  logic src_rst_ni,
  input  logic src_clk_i,
  input  T     src_data_i,
  input  logic src_valid_i,
  output logic src_ready_o,

  output T [2**LOG_DEPTH-1:0] async_data_o,
  output logic [LOG_DEPTH:0]  async_wptr_o,
  input  logic [LOG_DEPTH:0]  async_rptr_i
);

  localparam int PtrWidth = LOG_DEPTH+1;
  localparam logic [PtrWidth-1:0] PtrFull = (1 << LOG_DEPTH);

  T [2**LOG_DEPTH-1:0] data_q;
  logic [PtrWidth-1:0] wptr_q, wptr_d, wptr_bin, wptr_next, rptr, rptr_bin;

  // Data FIFO.
  assign async_data_o = data_q;
  for (genvar i = 0; i < 2**LOG_DEPTH; i++) begin : gen_word
    `FFLNR(data_q[i], src_data_i,
          src_valid_i & src_ready_o & (wptr_bin[LOG_DEPTH-1:0] == i), src_clk_i)
  end

  // Read pointer.
  for (genvar i = 0; i < PtrWidth; i++) begin : gen_sync
    sync #(.STAGES(SYNC_STAGES)) i_sync (
      .clk_i    ( src_clk_i       ),
      .rst_ni   ( src_rst_ni      ),
      .serial_i ( async_rptr_i[i] ),
      .serial_o ( rptr[i]         )
    );
  end
  gray_to_binary #(PtrWidth) i_rptr_g2b (.A(rptr), .Z(rptr_bin));

  // Write pointer.
  assign wptr_next = wptr_bin+1;
  gray_to_binary #(PtrWidth) i_wptr_g2b (.A(wptr_q), .Z(wptr_bin));
  binary_to_gray #(PtrWidth) i_wptr_b2g (.A(wptr_next), .Z(wptr_d));
  `FFLARN(wptr_q, wptr_d, src_valid_i & src_ready_o, '0, src_clk_i, src_rst_ni)
  assign async_wptr_o = wptr_q;

  // The pointers into the FIFO are one bit wider than the actual address into
  // the FIFO. This makes detecting critical states very simple: if all but the
  // topmost bit of rptr and wptr agree, the FIFO is in a critical state. If the
  // topmost bit is equal, the FIFO is empty, otherwise it is full.
  assign src_ready_o = ((wptr_bin ^ rptr_bin) != PtrFull);

endmodule
module cdc_fifo_gray_dst #(
  parameter type T = logic,
  parameter int LOG_DEPTH = 3,
  parameter int SYNC_STAGES = 2
)(
  input  logic dst_rst_ni,
  input  logic dst_clk_i,
  output T     dst_data_o,
  output logic dst_valid_o,
  input  logic dst_ready_i,

  input  T [2**LOG_DEPTH-1:0] async_data_i,
  input  logic [LOG_DEPTH:0]  async_wptr_i,
  output logic [LOG_DEPTH:0]  async_rptr_o
);

  localparam int PtrWidth = LOG_DEPTH+1;
  localparam logic [PtrWidth-1:0] PtrEmpty = '0;

  T dst_data;
  logic [PtrWidth-1:0] rptr_q, rptr_d, rptr_bin, rptr_bin_d, rptr_next, wptr, wptr_bin;
  logic dst_valid, dst_ready;
  // Data selector and register.
  assign dst_data = async_data_i[rptr_bin[LOG_DEPTH-1:0]];

  // Read pointer.
  assign rptr_next = rptr_bin+1;
  gray_to_binary #(PtrWidth) i_rptr_g2b (.A(rptr_q), .Z(rptr_bin));
  binary_to_gray #(PtrWidth) i_rptr_b2g (.A(rptr_next), .Z(rptr_d));
  `FFLARN(rptr_q, rptr_d, dst_valid & dst_ready, '0, dst_clk_i, dst_rst_ni)
  assign async_rptr_o = rptr_q;

  // Write pointer.
  for (genvar i = 0; i < PtrWidth; i++) begin : gen_sync
    sync #(.STAGES(SYNC_STAGES)) i_sync (
      .clk_i    ( dst_clk_i       ),
      .rst_ni   ( dst_rst_ni      ),
      .serial_i ( async_wptr_i[i] ),
      .serial_o ( wptr[i]         )
    );
  end
  gray_to_binary #(PtrWidth) i_wptr_g2b (.A(wptr), .Z(wptr_bin));

  // The pointers into the FIFO are one bit wider than the actual address into
  // the FIFO. This makes detecting critical states very simple: if all but the
  // topmost bit of rptr and wptr agree, the FIFO is in a critical state. If the
  // topmost bit is equal, the FIFO is empty, otherwise it is full.
  assign dst_valid = ((wptr_bin ^ rptr_bin) != PtrEmpty);

  // Cut the combinatorial path with a spill register.
  spill_register #(
    .T       ( T           )
  ) i_spill_register (
    .clk_i   ( dst_clk_i   ),
    .rst_ni  ( dst_rst_ni  ),
    .valid_i ( dst_valid   ),
    .ready_o ( dst_ready   ),
    .data_i  ( dst_data    ),
    .valid_o ( dst_valid_o ),
    .ready_i ( dst_ready_i ),
    .data_o  ( dst_data_o  )
  );

endmodule
module tb_axi_delayer;

  parameter AW = 32;
  parameter DW = 32;
  parameter IW = 8;
  parameter UW = 8;
  parameter TS = 4;

  localparam tCK = 1ns;

  logic clk = 0;
  logic rst = 1;
  logic done = 0;

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi_slave_dv(clk), axi_master_dv(clk);
  AXI_BUS #(
    .AXI_ADDR_WIDTH(AW),
    .AXI_DATA_WIDTH(DW),
    .AXI_ID_WIDTH(IW),
    .AXI_USER_WIDTH(UW)
  ) axi_slave(), axi_master();
  `AXI_ASSIGN(axi_slave_dv, axi_slave)
  `AXI_ASSIGN(axi_master, axi_master_dv)

  axi_delayer_intf #(
    .AXI_ADDR_WIDTH     ( AW ),
    .AXI_DATA_WIDTH     ( DW ),
    .AXI_ID_WIDTH       ( IW ),
    .AXI_USER_WIDTH     ( UW ),
    .FIXED_DELAY_INPUT  ( 0  ),
    .STALL_RANDOM_INPUT ( 1  )
  ) i_axi_delayer (
    .clk_i      ( clk         ),
    .rst_ni     ( rst         ),
    .slv        ( axi_master  ),
    .mst        ( axi_slave   )
  );

  axi_test::axi_driver #(.AW(AW), .DW(DW), .IW(IW), .UW(UW), .TA(200ps), .TT(700ps)) axi_slave_drv = new(axi_slave_dv);
  axi_test::axi_driver #(.AW(AW), .DW(DW), .IW(IW), .UW(UW), .TA(200ps), .TT(700ps)) axi_master_drv = new(axi_master_dv);

  initial begin
    #tCK;
    rst <= 0;
    #tCK;
    rst <= 1;
    #tCK;
    while (!done) begin
      clk <= 1;
      #(tCK/2);
      clk <= 0;
      #(tCK/2);
    end
  end

  initial begin
    automatic axi_test::axi_ax_beat #(.AW(AW), .IW(IW), .UW(UW)) ax_beat = new;
    automatic axi_test::axi_w_beat #(.DW(DW), .UW(UW)) w_beat = new;
    automatic axi_test::axi_b_beat  #(.IW(IW), .UW(UW)) b_beat;
    automatic logic rand_success;
    axi_master_drv.reset_master();
    @(posedge clk);
    repeat (200) begin
        @(posedge clk);
        rand_success = ax_beat.randomize(); assert(rand_success);
        axi_master_drv.send_aw(ax_beat);
        w_beat.w_data = 'hcafebabe;
        axi_master_drv.send_w(w_beat);
    end

    repeat (200) axi_master_drv.recv_b(b_beat);

    done = 1;
  end

  initial begin
    automatic axi_test::axi_ax_beat #(.AW(AW), .IW(IW), .UW(UW)) ax_beat;
    automatic axi_test::axi_w_beat #(.DW(DW), .UW(UW)) w_beat;
    automatic axi_test::axi_b_beat #(.IW(IW), .UW(UW)) b_beat = new;
    automatic int b_id_queue[$];
    axi_slave_drv.reset_slave();
    @(posedge clk);
    repeat (200) begin
        axi_slave_drv.recv_aw(ax_beat);
        $info("AXI AW: addr %h", ax_beat.ax_addr);
        axi_slave_drv.recv_w(w_beat);
        $info("AXI W: data %h, strb %h", w_beat.w_data, w_beat.w_strb);
        b_id_queue.push_back(ax_beat.ax_id);
    end
    while (b_id_queue.size() != 0) begin
      b_beat.b_id = b_id_queue.pop_front();
      axi_slave_drv.send_b(b_beat);
    end
  end
// vsim -voptargs=+acc work.tb_axi_delayer
endmodule
module tb_axi_lite_to_axi;

  parameter TB_AW = 32;
  parameter TB_DW = 32;
  parameter TB_IW = 8;
  parameter TB_UW = 8;

  localparam tCK = 1ns;

  logic clk = 0;
  logic rst = 1;
  logic done = 0;

  AXI_LITE_DV #(
    .AXI_ADDR_WIDTH(TB_AW),
    .AXI_DATA_WIDTH(TB_DW)
  ) axi_lite_dv(clk);

  AXI_LITE #(
    .AXI_ADDR_WIDTH(TB_AW),
    .AXI_DATA_WIDTH(TB_DW)
  ) axi_lite();

  `AXI_LITE_ASSIGN(axi_lite, axi_lite_dv)

  AXI_BUS_DV #(
    .AXI_ADDR_WIDTH(TB_AW),
    .AXI_DATA_WIDTH(TB_DW),
    .AXI_ID_WIDTH(TB_IW),
    .AXI_USER_WIDTH(TB_UW)
  ) axi_dv(clk);

  AXI_BUS #(
    .AXI_ADDR_WIDTH(TB_AW),
    .AXI_DATA_WIDTH(TB_DW),
    .AXI_ID_WIDTH(TB_IW),
    .AXI_USER_WIDTH(TB_UW)
  ) axi();

  `AXI_ASSIGN(axi_dv, axi)

  axi_lite_to_axi_intf #(
    .AXI_DATA_WIDTH (TB_DW)
  ) i_dut (
    .in   ( axi_lite ),
    .slv_aw_cache_i ('0),
    .slv_ar_cache_i ('0),
    .out  ( axi      )
  );

  axi_test::axi_lite_driver #(.AW(TB_AW), .DW(TB_DW)) axi_lite_drv = new(axi_lite_dv);
  axi_test::axi_driver #(.AW(TB_AW), .DW(TB_DW), .IW(TB_IW), .UW(TB_UW)) axi_drv = new(axi_dv);

  initial begin
    #tCK;
    rst <= 0;
    #tCK;
    rst <= 1;
    #tCK;
    while (!done) begin
      clk <= 1;
      #(tCK/2);
      clk <= 0;
      #(tCK/2);
    end
  end

  initial begin
    automatic axi_pkg::resp_t resp;
    axi_lite_drv.reset_master();
    @(posedge clk);
    axi_lite_drv.send_aw('hdeadbeef, axi_pkg::prot_t'('0));
    axi_lite_drv.send_w('hdeadbeef, '1);
    axi_lite_drv.recv_b(resp);
    $info("AXI-Lite B: resp %h", resp);
    repeat (4) @(posedge clk);
    done = 1;
  end

  initial begin
    automatic axi_test::axi_ax_beat #(.AW(TB_AW), .IW(TB_IW), .UW(TB_UW)) ax_beat;
    automatic axi_test::axi_w_beat #(.DW(TB_DW), .UW(TB_UW)) w_beat;
    automatic axi_test::axi_b_beat #(.IW(TB_IW), .UW(TB_UW)) b_beat = new;
    axi_drv.reset_slave();
    @(posedge clk);
    axi_drv.recv_aw(ax_beat);
    $info("AXI AW: addr %h", ax_beat.ax_addr);
    axi_drv.recv_w(w_beat);
    $info("AXI W: data %h, strb %h", w_beat.w_data, w_beat.w_strb);
    axi_drv.send_b(b_beat);
  end

endmodule
module axi_join_intf (
  AXI_BUS.Slave  in,
  AXI_BUS.Master out
);

  `AXI_ASSIGN(out, in)

// pragma translate_off
`ifndef VERILATOR
  initial begin
    assert(in.AXI_ADDR_WIDTH == out.AXI_ADDR_WIDTH);
    assert(in.AXI_DATA_WIDTH == out.AXI_DATA_WIDTH);
    assert(in.AXI_ID_WIDTH   <= out.AXI_ID_WIDTH  );
    assert(in.AXI_USER_WIDTH == out.AXI_USER_WIDTH);
  end
`endif
// pragma translate_on

endmodule
module axi_isolate_intf #(
  parameter int unsigned NUM_PENDING    = 32'd16, // Number of pending requests
  parameter int unsigned AXI_ID_WIDTH   = 32'd0,  // AXI ID width
  parameter int unsigned AXI_ADDR_WIDTH = 32'd0,  // AXI address width
  parameter int unsigned AXI_DATA_WIDTH = 32'd0,  // AXI data width
  parameter int unsigned AXI_USER_WIDTH = 32'd0   // AXI user width
) (
  input  logic   clk_i,      // clock
  input  logic   rst_ni,     // asynchronous reset active low
  AXI_BUS.Slave  slv,        // slave port
  AXI_BUS.Master mst,        // master port
  input  logic   isolate_i,  // isolate master port from slave port
  output logic   isolated_o  // master port is isolated from slave port
);
  typedef logic [AXI_ID_WIDTH-1:0]     id_t;
  typedef logic [AXI_ADDR_WIDTH-1:0]   addr_t;
  typedef logic [AXI_DATA_WIDTH-1:0]   data_t;
  typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
  typedef logic [AXI_USER_WIDTH-1:0]   user_t;

  `AXI_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t, id_t, user_t)
  `AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t)
  `AXI_TYPEDEF_B_CHAN_T(b_chan_t, id_t, user_t)

  `AXI_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t, id_t, user_t)
  `AXI_TYPEDEF_R_CHAN_T(r_chan_t, data_t, id_t, user_t)

  `AXI_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
  `AXI_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)

  req_t  slv_req,  mst_req;
  resp_t slv_resp, mst_resp;

  `AXI_ASSIGN_TO_REQ(slv_req, slv)
  `AXI_ASSIGN_FROM_RESP(slv, slv_resp)

  `AXI_ASSIGN_FROM_REQ(mst, mst_req)
  `AXI_ASSIGN_TO_RESP(mst_resp, mst)

  axi_isolate #(
    .NumPending ( NUM_PENDING ), // Number of pending requests per channel
    .req_t      ( req_t       ), // AXI request struct definition
    .resp_t     ( resp_t      )  // AXI response struct definition
  ) i_axi_isolate (
    .clk_i,                   // clock
    .rst_ni,                  // reset
    .slv_req_i  ( slv_req  ), // slave port request struct
    .slv_resp_o ( slv_resp ), // slave port response struct
    .mst_req_o  ( mst_req  ), // master port request struct
    .mst_resp_i ( mst_resp ), // master port response struct
    .isolate_i,               // isolate master port from slave port
    .isolated_o               // master port is isolated from slave port
  );

  // pragma translate_off
  `ifndef VERILATOR
  initial begin
    assume (AXI_ID_WIDTH   > 0) else $fatal(1, "AXI_ID_WIDTH   has to be > 0.");
    assume (AXI_ADDR_WIDTH > 0) else $fatal(1, "AXI_ADDR_WIDTH has to be > 0.");
    assume (AXI_DATA_WIDTH > 0) else $fatal(1, "AXI_DATA_WIDTH has to be > 0.");
    assume (AXI_USER_WIDTH > 0) else $fatal(1, "AXI_USER_WIDTH has to be > 0.");
  end
  `endif
  // pragma translate_on
endmodule
module axi_lite_join_intf (
  AXI_LITE.Slave  in,
  AXI_LITE.Master out
);

  `AXI_LITE_ASSIGN(out, in)

// pragma translate_off
`ifndef VERILATOR
  initial begin
    assert(in.AXI_ADDR_WIDTH == out.AXI_ADDR_WIDTH);
    assert(in.AXI_DATA_WIDTH == out.AXI_DATA_WIDTH);
  end
`endif
// pragma translate_on

endmodule
module axi_lite_mailbox_intf #(
  parameter int unsigned MAILBOX_DEPTH  = 32'd0,
  parameter bit unsigned IRQ_EDGE_TRIG  = 1'b0,
  parameter bit unsigned IRQ_ACT_HIGH   = 1'b1,
  parameter int unsigned AXI_ADDR_WIDTH = 32'd0,
  parameter int unsigned AXI_DATA_WIDTH = 32'd0,
  // DEPENDENT PARAMETERS, DO NOT OVERRIDE!
  parameter type addr_t               = logic [AXI_ADDR_WIDTH-1:0]
) (
  input  logic         clk_i,      // Clock
  input  logic         rst_ni,     // Asynchronous reset active low
  input  logic         test_i,     // Testmode enable
  AXI_LITE.Slave       slv [1:0],  // slave ports [1:0]
  output logic   [1:0] irq_o,      // interrupt output for each port
  input  addr_t  [1:0] base_addr_i // base address for each port
);
  typedef logic [AXI_DATA_WIDTH-1:0]   data_t;
  typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
  `AXI_LITE_TYPEDEF_AW_CHAN_T(aw_chan_lite_t, addr_t)
  `AXI_LITE_TYPEDEF_W_CHAN_T(w_chan_lite_t, data_t, strb_t)
  `AXI_LITE_TYPEDEF_B_CHAN_T(b_chan_lite_t)
  `AXI_LITE_TYPEDEF_AR_CHAN_T(ar_chan_lite_t, addr_t)
  `AXI_LITE_TYPEDEF_R_CHAN_T(r_chan_lite_t, data_t)
  `AXI_LITE_TYPEDEF_REQ_T(req_lite_t, aw_chan_lite_t, w_chan_lite_t, ar_chan_lite_t)
  `AXI_LITE_TYPEDEF_RESP_T(resp_lite_t, b_chan_lite_t, r_chan_lite_t)

  req_lite_t  [1:0] slv_reqs;
  resp_lite_t [1:0] slv_resps;

  for (genvar i = 0; i < 2; i++) begin : gen_port_assign
    `AXI_LITE_ASSIGN_TO_REQ(slv_reqs[i], slv[i])
    `AXI_LITE_ASSIGN_FROM_RESP(slv[i], slv_resps[i])
  end

  axi_lite_mailbox #(
    .MailboxDepth ( MAILBOX_DEPTH  ),
    .IrqEdgeTrig  ( IRQ_EDGE_TRIG  ),
    .IrqActHigh   ( IRQ_ACT_HIGH   ),
    .AxiAddrWidth ( AXI_ADDR_WIDTH ),
    .AxiDataWidth ( AXI_DATA_WIDTH ),
    .req_lite_t   ( req_lite_t     ),
    .resp_lite_t  ( resp_lite_t    )
  ) i_axi_lite_mailbox (
    .clk_i,      // Clock
    .rst_ni,     // Asynchronous reset active low
    .test_i,     // Testmode enable
    // slave ports [1:0]
    .slv_reqs_i  ( slv_reqs  ),
    .slv_resps_o ( slv_resps ),
    .irq_o,      // interrupt output for each port
    .base_addr_i // base address for each port
  );

  // pragma translate_off
  `ifndef VERILATOR
  initial begin
    assert (slv[0].AXI_ADDR_WIDTH == AXI_ADDR_WIDTH)
        else $fatal(1, "LITE Interface [0] AXI_ADDR_WIDTH missmatch!");
    assert (slv[1].AXI_ADDR_WIDTH == AXI_ADDR_WIDTH)
        else $fatal(1, "LITE Interface [1] AXI_ADDR_WIDTH missmatch!");
    assert (slv[0].AXI_DATA_WIDTH == AXI_DATA_WIDTH)
        else $fatal(1, "LITE Interface [0] AXI_DATA_WIDTH missmatch!");
    assert (slv[1].AXI_DATA_WIDTH == AXI_DATA_WIDTH)
        else $fatal(1, "LITE Interface [1] AXI_DATA_WIDTH missmatch!");
  end
  `endif
  // pragma translate_on
endmodule
module axi_cdc_src_intf #(
  parameter int unsigned AXI_ID_WIDTH = 0,
  parameter int unsigned AXI_ADDR_WIDTH = 0,
  parameter int unsigned AXI_DATA_WIDTH = 0,
  parameter int unsigned AXI_USER_WIDTH = 0,
  /// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
  parameter int unsigned LOG_DEPTH = 1
) (
  // synchronous slave port - clocked by `src_clk_i`
  input  logic                src_clk_i,
  input  logic                src_rst_ni,
  AXI_BUS.Slave               src,
  // asynchronous master port
  AXI_BUS_ASYNC_GRAY.Master   dst
);

  typedef logic [AXI_ID_WIDTH-1:0]     id_t;
  typedef logic [AXI_ADDR_WIDTH-1:0]   addr_t;
  typedef logic [AXI_DATA_WIDTH-1:0]   data_t;
  typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
  typedef logic [AXI_USER_WIDTH-1:0]   user_t;
  `AXI_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t, id_t, user_t)
  `AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t)
  `AXI_TYPEDEF_B_CHAN_T(b_chan_t, id_t, user_t)
  `AXI_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t, id_t, user_t)
  `AXI_TYPEDEF_R_CHAN_T(r_chan_t, data_t, id_t, user_t)
  `AXI_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
  `AXI_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)

  req_t  src_req;
  resp_t src_resp;

  `AXI_ASSIGN_TO_REQ(src_req, src)
  `AXI_ASSIGN_FROM_RESP(src, src_resp)

  axi_cdc_src #(
    .aw_chan_t  ( aw_chan_t ),
    .w_chan_t   ( w_chan_t  ),
    .b_chan_t   ( b_chan_t  ),
    .ar_chan_t  ( ar_chan_t ),
    .r_chan_t   ( r_chan_t  ),
    .axi_req_t  ( req_t     ),
    .axi_resp_t ( resp_t    ),
    .LogDepth   ( LOG_DEPTH )
  ) i_axi_cdc_src (
    .src_clk_i,
    .src_rst_ni,
    .src_req_i                    ( src_req     ),
    .src_resp_o                   ( src_resp    ),
    .async_data_master_aw_data_o  ( dst.aw_data ),
    .async_data_master_aw_wptr_o  ( dst.aw_wptr ),
    .async_data_master_aw_rptr_i  ( dst.aw_rptr ),
    .async_data_master_w_data_o   ( dst.w_data  ),
    .async_data_master_w_wptr_o   ( dst.w_wptr  ),
    .async_data_master_w_rptr_i   ( dst.w_rptr  ),
    .async_data_master_b_data_i   ( dst.b_data  ),
    .async_data_master_b_wptr_i   ( dst.b_wptr  ),
    .async_data_master_b_rptr_o   ( dst.b_rptr  ),
    .async_data_master_ar_data_o  ( dst.ar_data ),
    .async_data_master_ar_wptr_o  ( dst.ar_wptr ),
    .async_data_master_ar_rptr_i  ( dst.ar_rptr ),
    .async_data_master_r_data_i   ( dst.r_data  ),
    .async_data_master_r_wptr_i   ( dst.r_wptr  ),
    .async_data_master_r_rptr_o   ( dst.r_rptr  )
  );

endmodule
module axi_lite_cdc_src_intf #(
  parameter int unsigned AXI_ADDR_WIDTH = 0,
  parameter int unsigned AXI_DATA_WIDTH = 0,
  /// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
  parameter int unsigned LOG_DEPTH = 1
) (
  // synchronous slave port - clocked by `src_clk_i`
  input  logic                src_clk_i,
  input  logic                src_rst_ni,
  AXI_BUS.Slave               src,
  // asynchronous master port
  AXI_LITE_ASYNC_GRAY.Master  dst
);

  typedef logic [AXI_ADDR_WIDTH-1:0]   addr_t;
  typedef logic [AXI_DATA_WIDTH-1:0]   data_t;
  typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
  `AXI_LITE_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t)
  `AXI_LITE_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t)
  `AXI_LITE_TYPEDEF_B_CHAN_T(b_chan_t)
  `AXI_LITE_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t)
  `AXI_LITE_TYPEDEF_R_CHAN_T(r_chan_t, data_t)
  `AXI_LITE_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
  `AXI_LITE_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)

  req_t  src_req;
  resp_t src_resp;

  `AXI_LITE_ASSIGN_TO_REQ(src_req, src)
  `AXI_LITE_ASSIGN_FROM_RESP(src, src_resp)

  axi_cdc_src #(
    .aw_chan_t  ( aw_chan_t ),
    .w_chan_t   ( w_chan_t  ),
    .b_chan_t   ( b_chan_t  ),
    .ar_chan_t  ( ar_chan_t ),
    .r_chan_t   ( r_chan_t  ),
    .axi_req_t  ( req_t     ),
    .axi_resp_t ( resp_t    ),
    .LogDepth   ( LOG_DEPTH )
  ) i_axi_cdc_src (
    .src_clk_i,
    .src_rst_ni,
    .src_req_o                    ( src_req     ),
    .src_resp_i                   ( src_resp    ),
    .async_data_master_aw_data_o  ( dst.aw_data ),
    .async_data_master_aw_wptr_o  ( dst.aw_wptr ),
    .async_data_master_aw_rptr_i  ( dst.aw_rptr ),
    .async_data_master_w_data_o   ( dst.w_data  ),
    .async_data_master_w_wptr_o   ( dst.w_wptr  ),
    .async_data_master_w_rptr_i   ( dst.w_rptr  ),
    .async_data_master_b_data_i   ( dst.b_data  ),
    .async_data_master_b_wptr_i   ( dst.b_wptr  ),
    .async_data_master_b_rptr_o   ( dst.b_rptr  ),
    .async_data_master_ar_data_o  ( dst.ar_data ),
    .async_data_master_ar_wptr_o  ( dst.ar_wptr ),
    .async_data_master_ar_rptr_i  ( dst.ar_rptr ),
    .async_data_master_r_data_i   ( dst.r_data  ),
    .async_data_master_r_wptr_i   ( dst.r_wptr  ),
    .async_data_master_r_rptr_o   ( dst.r_rptr  )
  );

endmodule
module axi_cdc_dst_intf #(
  parameter int unsigned AXI_ID_WIDTH = 0,
  parameter int unsigned AXI_ADDR_WIDTH = 0,
  parameter int unsigned AXI_DATA_WIDTH = 0,
  parameter int unsigned AXI_USER_WIDTH = 0,
  /// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
  parameter int unsigned LOG_DEPTH = 1
) (
  // asynchronous slave port
  AXI_BUS_ASYNC_GRAY.Slave  src,
  // synchronous master port - clocked by `dst_clk_i`
  input  logic              dst_clk_i,
  input  logic              dst_rst_ni,
  AXI_BUS.Master            dst
);

  typedef logic [AXI_ID_WIDTH-1:0]     id_t;
  typedef logic [AXI_ADDR_WIDTH-1:0]   addr_t;
  typedef logic [AXI_DATA_WIDTH-1:0]   data_t;
  typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
  typedef logic [AXI_USER_WIDTH-1:0]   user_t;
  `AXI_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t, id_t, user_t)
  `AXI_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t, user_t)
  `AXI_TYPEDEF_B_CHAN_T(b_chan_t, id_t, user_t)
  `AXI_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t, id_t, user_t)
  `AXI_TYPEDEF_R_CHAN_T(r_chan_t, data_t, id_t, user_t)
  `AXI_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
  `AXI_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)

  req_t  dst_req;
  resp_t dst_resp;

  axi_cdc_dst #(
    .aw_chan_t  ( aw_chan_t ),
    .w_chan_t   ( w_chan_t  ),
    .b_chan_t   ( b_chan_t  ),
    .ar_chan_t  ( ar_chan_t ),
    .r_chan_t   ( r_chan_t  ),
    .axi_req_t  ( req_t     ),
    .axi_resp_t ( resp_t    ),
    .LogDepth   ( LOG_DEPTH )
  ) i_axi_cdc_dst (
    .async_data_slave_aw_data_i ( src.aw_data ),
    .async_data_slave_aw_wptr_i ( src.aw_wptr ),
    .async_data_slave_aw_rptr_o ( src.aw_rptr ),
    .async_data_slave_w_data_i  ( src.w_data  ),
    .async_data_slave_w_wptr_i  ( src.w_wptr  ),
    .async_data_slave_w_rptr_o  ( src.w_rptr  ),
    .async_data_slave_b_data_o  ( src.b_data  ),
    .async_data_slave_b_wptr_o  ( src.b_wptr  ),
    .async_data_slave_b_rptr_i  ( src.b_rptr  ),
    .async_data_slave_ar_data_i ( src.ar_data ),
    .async_data_slave_ar_wptr_i ( src.ar_wptr ),
    .async_data_slave_ar_rptr_o ( src.ar_rptr ),
    .async_data_slave_r_data_o  ( src.r_data  ),
    .async_data_slave_r_wptr_o  ( src.r_wptr  ),
    .async_data_slave_r_rptr_i  ( src.r_rptr  ),
    .dst_clk_i,
    .dst_rst_ni,
    .dst_req_o                  ( dst_req     ),
    .dst_resp_i                 ( dst_resp    )
  );

  `AXI_ASSIGN_FROM_REQ(dst, dst_req)
  `AXI_ASSIGN_TO_RESP(dst_resp, dst)

endmodule
module axi_lite_cdc_dst_intf #(
  parameter int unsigned AXI_ADDR_WIDTH = 0,
  parameter int unsigned AXI_DATA_WIDTH = 0,
  /// Depth of the FIFO crossing the clock domain, given as 2**LOG_DEPTH.
  parameter int unsigned LOG_DEPTH = 1
) (
  // asynchronous slave port
  AXI_LITE_ASYNC_GRAY.Slave   src,
  // synchronous master port - clocked by `dst_clk_i`
  input  logic                dst_clk_i,
  input  logic                dst_rst_ni,
  AXI_LITE.Master             dst
);

  typedef logic [AXI_ADDR_WIDTH-1:0]   addr_t;
  typedef logic [AXI_DATA_WIDTH-1:0]   data_t;
  typedef logic [AXI_DATA_WIDTH/8-1:0] strb_t;
  `AXI_LITE_TYPEDEF_AW_CHAN_T(aw_chan_t, addr_t)
  `AXI_LITE_TYPEDEF_W_CHAN_T(w_chan_t, data_t, strb_t)
  `AXI_LITE_TYPEDEF_B_CHAN_T(b_chan_t)
  `AXI_LITE_TYPEDEF_AR_CHAN_T(ar_chan_t, addr_t)
  `AXI_LITE_TYPEDEF_R_CHAN_T(r_chan_t, data_t)
  `AXI_LITE_TYPEDEF_REQ_T(req_t, aw_chan_t, w_chan_t, ar_chan_t)
  `AXI_LITE_TYPEDEF_RESP_T(resp_t, b_chan_t, r_chan_t)

  req_t   dst_req;
  resp_t  dst_resp;

  axi_cdc_dst #(
    .aw_chan_t  ( aw_chan_t ),
    .w_chan_t   ( w_chan_t  ),
    .b_chan_t   ( b_chan_t  ),
    .ar_chan_t  ( ar_chan_t ),
    .r_chan_t   ( r_chan_t  ),
    .axi_req_t  ( req_t     ),
    .axi_resp_t ( resp_t    ),
    .LogDepth   ( LOG_DEPTH )
  ) i_axi_cdc_dst (
    .async_data_slave_aw_data_i ( src.aw_data ),
    .async_data_slave_aw_wptr_i ( src.aw_wptr ),
    .async_data_slave_aw_rptr_o ( src.aw_rptr ),
    .async_data_slave_w_data_i  ( src.w_data  ),
    .async_data_slave_w_wptr_i  ( src.w_wptr  ),
    .async_data_slave_w_rptr_o  ( src.w_rptr  ),
    .async_data_slave_b_data_o  ( src.b_data  ),
    .async_data_slave_b_wptr_o  ( src.b_wptr  ),
    .async_data_slave_b_rptr_i  ( src.b_rptr  ),
    .async_data_slave_ar_data_i ( src.ar_data ),
    .async_data_slave_ar_wptr_i ( src.ar_wptr ),
    .async_data_slave_ar_rptr_o ( src.ar_rptr ),
    .async_data_slave_r_data_o  ( src.r_data  ),
    .async_data_slave_r_wptr_o  ( src.r_wptr  ),
    .async_data_slave_r_rptr_i  ( src.r_rptr  ),
    .dst_clk_i,
    .dst_rst_ni,
    .dst_req_o                  ( dst_req     ),
    .dst_resp_i                 ( dst_resp    )
  );

  `AXI_LITE_ASSIGN_FROM_REQ(dst, dst_req)
  `AXI_LITE_ASSIGN_TO_RESP(dst_resp, dst)

endmodule