`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/03/20 14:38:30
// Design Name: 
// Module Name: axi_ddr_top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module axi_ddr_top(
    // Inouts
    inout [63:0]                                ddr3_dq,
    inout [7:0]                                 ddr3_dqs_n,
    inout [7:0]                                 ddr3_dqs_p,
    // Outputs
    output [15:0]                               ddr3_addr,
    output [2:0]                                ddr3_ba,
    output                                      ddr3_ras_n,
    output                                      ddr3_cas_n,
    output                                      ddr3_we_n,
    output                                      ddr3_reset_n,
    output [1:0]                                ddr3_ck_p,
    output [1:0]                                ddr3_ck_n,
    output [1:0]                                ddr3_cke,
    output [1:0]                                ddr3_cs_n,
    output [7:0]                                ddr3_dm,
    output [1:0]                                ddr3_odt,
    // Inputs
    // Single-ended system clock
    input                                        sys_clk_i,
    input                                        sys_rst_i,
    output                                       init_calib_complete
    );

     // Wire declarations
    wire                              ui_clk;
    wire                              ui_rst;


    // Slave Interface Write Address Ports
    wire [3:0]                        s_axi_awid;
    wire [32:0]                       s_axi_awaddr;
    wire [7:0]                        s_axi_awlen;
    wire [2:0]                        s_axi_awsize;
    wire [1:0]                        s_axi_awburst;
    wire [0:0]                        s_axi_awlock;
    wire [3:0]                        s_axi_awcache;
    wire [2:0]                        s_axi_awprot;
    wire                              s_axi_awvalid;
    wire                              s_axi_awready;
    // Slave Interface Write Data Ports
    wire [512:0]                      s_axi_wdata;
    wire [63:0]                       s_axi_wstrb;
    wire                              s_axi_wlast;
    wire                              s_axi_wvalid;
    wire                              s_axi_wready;
    // Slave Interface Write Response Ports
    wire                              s_axi_bready;
    wire [3:0]                        s_axi_bid;
    wire [1:0]                        s_axi_bresp;
    wire                              s_axi_bvalid;
    // Slave Interface Read Address Ports
    wire [3:0]                        s_axi_arid;
    wire [32:0]                       s_axi_araddr;
    wire [7:0]                        s_axi_arlen;
    wire [2:0]                        s_axi_arsize;
    wire [1:0]                        s_axi_arburst;
    wire [0:0]                        s_axi_arlock;
    wire [3:0]                        s_axi_arcache;
    wire [2:0]                        s_axi_arprot;
    wire                              s_axi_arvalid;
    wire                              s_axi_arready;
    // Slave Interface Read Data Ports
    wire                              s_axi_rready;
    wire [3:0]                        s_axi_rid;
    wire [32:0]                       s_axi_rdata;
    wire [1:0]                        s_axi_rresp;
    wire                              s_axi_rlast;
    wire                              s_axi_rvalid;

    wire                            rd_fifo_re;
    wire [ 7:0]                     rd_fifo_len;
    wire [32:0]                     rd_fifo_addr;
    wire                            rd_fifo_len_empty;
    wire                            rd_fifo_addr_empty;
    wire [511:0]                    rd_fifo_data;
    wire                            rd_fifo_we;
    wire                            rd_fifo_almost_full;
    wire                            wr_fifo_re;
    wire [32:0]                     wr_fifo_addr;
    wire [511:0]                    wr_fifo_data;
    wire [63:0]                     wr_fifo_mask;
    wire                            wr_fifo_addr_empty;
    wire                            wr_fifo_data_empty;
    wire                            wr_fifo_mask_empty;


ddr_ctrl u_ddr_ctrl(
// Memory interface ports
       .ddr3_addr                      (ddr3_addr),
       .ddr3_ba                        (ddr3_ba),
       .ddr3_cas_n                     (ddr3_cas_n),
       .ddr3_ck_n                      (ddr3_ck_n),
       .ddr3_ck_p                      (ddr3_ck_p),
       .ddr3_cke                       (ddr3_cke),
       .ddr3_ras_n                     (ddr3_ras_n),
       .ddr3_we_n                      (ddr3_we_n),
       .ddr3_dq                        (ddr3_dq),
       .ddr3_dqs_n                     (ddr3_dqs_n),
       .ddr3_dqs_p                     (ddr3_dqs_p),
       .ddr3_reset_n                   (ddr3_reset_n),
       .init_calib_complete            (init_calib_complete),
       .ddr3_cs_n                      (ddr3_cs_n),
       .ddr3_dm                        (ddr3_dm),
       .ddr3_odt                       (ddr3_odt),


// Application interface ports
       .ui_clk                         (ui_clk),        // 100 Mhz
       .ui_clk_sync_rst                (ui_rst),
       .mmcm_locked                    (),
       .aresetn                        (),
       .app_sr_req                     (1'b0),
       .app_ref_req                    (1'b0),
       .app_zq_req                     (1'b0),
       .app_sr_active                  (),
       .app_ref_ack                    (),
       .app_zq_ack                     (),

// Slave Interface Write Address Ports
       .s_axi_awid                     (s_axi_awid),
       .s_axi_awaddr                   (s_axi_awaddr),
       .s_axi_awlen                    (s_axi_awlen),
       .s_axi_awsize                   (s_axi_awsize),
       .s_axi_awburst                  (s_axi_awburst),
       .s_axi_awlock                   (s_axi_awlock),
       .s_axi_awcache                  (s_axi_awcache),
       .s_axi_awprot                   (s_axi_awprot),
       .s_axi_awqos                    (4'h0),
       .s_axi_awvalid                  (s_axi_awvalid),
       .s_axi_awready                  (s_axi_awready),


// Slave Interface Write Data Ports
       .s_axi_wdata                    (s_axi_wdata),
       .s_axi_wstrb                    (s_axi_wstrb),
       .s_axi_wlast                    (s_axi_wlast),
       .s_axi_wvalid                   (s_axi_wvalid),
       .s_axi_wready                   (s_axi_wready),


// Slave Interface Write Response Ports
       .s_axi_bid                      (s_axi_bid),
       .s_axi_bresp                    (s_axi_bresp),
       .s_axi_bvalid                   (s_axi_bvalid),
       .s_axi_bready                   (s_axi_bready),

// Slave Interface Read Address Ports
       .s_axi_arid                     (s_axi_arid),
       .s_axi_araddr                   (s_axi_araddr),
       .s_axi_arlen                    (s_axi_arlen),
       .s_axi_arsize                   (s_axi_arsize),
       .s_axi_arburst                  (s_axi_arburst),
       .s_axi_arlock                   (s_axi_arlock),
       .s_axi_arcache                  (s_axi_arcache),
       .s_axi_arprot                   (s_axi_arprot),
       .s_axi_arqos                    (4'h0),
       .s_axi_arvalid                  (s_axi_arvalid),
       .s_axi_arready                  (s_axi_arready),
// Slave Interface Read Data Ports
       .s_axi_rid                      (s_axi_rid),
       .s_axi_rdata                    (s_axi_rdata),
       .s_axi_rresp                    (s_axi_rresp),
       .s_axi_rlast                    (s_axi_rlast),
       .s_axi_rvalid                   (s_axi_rvalid),
       .s_axi_rready                   (s_axi_rready),
// System Clock Ports
       .sys_clk_i                      (sys_clk_i),            // 200 Mhz
       .sys_rst                        (sys_rst_i)
       );

// Instance of axi_m_rd
axi_m_rd u_axi_m_rd (
       .ui_clk_i(ui_clk),
       .ui_rst_i(ui_rst),

       // Connect m_axi to s_axi
       .m_axi_arid_o(s_axi_arid),
       .m_axi_araddr_o(s_axi_araddr),
       .m_axi_arlen_o(s_axi_arlen),
       .m_axi_arsize_o(s_axi_arsize),
       .m_axi_arburst_o(s_axi_arburst),
       .m_axi_arlock_o(s_axi_arlock),
       .m_axi_arcache_o(s_axi_arcache),
       .m_axi_arprot_o(s_axi_arprot),
       .m_axi_arvalid_o(s_axi_arvalid),
       .m_axi_arready_i(s_axi_arready),
       .m_axi_rready_o(s_axi_rready),
       .m_axi_rid_i(s_axi_rid),
       .m_axi_rdata_i(s_axi_rdata),
       .m_axi_rresp_i(s_axi_rresp),
       .m_axi_rlast_i(s_axi_rlast),
       .m_axi_rvalid_i(s_axi_rvalid),

       // Remaining ports
       .rd_fifo_empty_i(rd_fifo_addr_empty & rd_fifo_len_empty), 
       .rd_fifo_re_o(rd_fifo_re),        
       .rd_fifo_addr_i(rd_fifo_addr), 
       .rd_fifo_len_i(rd_fifo_len),   
       .rd_fifo_almost_full_i(rd_fifo_almost_full), 
       .rd_fifo_we_o(rd_fifo_we),        
       .rd_fifo_din_o(rd_fifo_data)        
);



fifo_ddr_addr fifo_rd_addr_inst(
       .rst(sys_rst_i),
       .wr_clk(sys_clk_i),
       .wr_en(),
       .din(),
       .full(),
       .rd_clk(ui_clk),
       .rd_en(rd_fifo_re),
       .dout(rd_fifo_addr),
       .empty(rd_fifo_addr_empty)
);

fifo_ddr_len fifo_rd_len_inst(
       .rst(sys_rst_i),
       .wr_clk(sys_clk_i),
       .wr_en(),
       .din(),
       .full(),
       .rd_clk(ui_clk),
       .rd_en(rd_fifo_re),
       .dout(rd_fifo_len),
       .empty(rd_fifo_len_empty)
);

fifo_ddr_data fifo_rd_data_inst(
       .rst(ui_rst),
       .wr_clk(ui_clk),
       .wr_en(rd_fifo_we),
       .din(rd_fifo_data),
       .almost_full(rd_fifo_almost_full),
       .full(),
       .rd_clk(sys_clk_i),
       .rd_en(),
       .dout(),
       .empty()
);

fifo_ddr_info fifo_rd_info_inst(
       .srst(sys_rst_i),
       .clk(sys_clk_i),
       .wr_en(),
       .din(),
       .full(),
       .rd_en(),
       .dout(),
       .empty()
);

// Instance of axi_m_wr
axi_m_wr u_axi_m_wr (
       .ui_clk_i(ui_clk),
       .ui_rst_i(ui_rst),

       // Connect m_axi to s_axi
       .m_axi_awid_o(s_axi_awid),
       .m_axi_awaddr_o(s_axi_awaddr),
       .m_axi_awlen_o(s_axi_awlen),
       .m_axi_awsize_o(s_axi_awsize),
       .m_axi_awburst_o(s_axi_awburst),
       .m_axi_awlock_o(s_axi_awlock),
       .m_axi_awcache_o(s_axi_awcache),
       .m_axi_awprot_o(s_axi_awprot),
       .m_axi_awvalid_o(s_axi_awvalid),
       .m_axi_awready_i(s_axi_awready),
       .m_axi_wdata_o(s_axi_wdata),
       .m_axi_wstrb_o(s_axi_wstrb),
       .m_axi_wlast_o(s_axi_wlast),
       .m_axi_wvalid_o(s_axi_wvalid),
       .m_axi_wready_i(s_axi_wready),
       .m_axi_bready_o(s_axi_bready),
       .m_axi_bid_i(s_axi_bid),
       .m_axi_bresp_i(s_axi_bresp),
       .m_axi_bvalid_i(s_axi_bvalid),

       // Remaining ports
       .wr_fifo_empty_i(wr_fifo_addr_empty && wr_fifo_data_empty && wr_fifo_mask_empty), 
       .wr_fifo_re_o(wr_fifo_re),        
       .wr_fifo_addr_i(wr_fifo_addr), 
       .wr_fifo_len_i(1'b1),   
       .wr_fifo_data_i(wr_fifo_data),
       .wr_fifo_mask_i(wr_fifo_mask)  
    );

fifo_ddr_addr fifo_wr_addr_inst(
       .rst(sys_rst_i),
       .wr_clk(sys_clk_i),
       .wr_en(),
       .din(),
       .full(),
       .rd_clk(ui_clk),
       .rd_en(wr_fifo_re),
       .dout(wr_fifo_addr),
       .empty(wr_fifo_addr_empty)
);

fifo_ddr_data fifo_wr_data_inst(
       .rst(sys_rst_i),
       .wr_clk(sys_clk_i),
       .wr_en(),
       .din(),
       .full(),
       .rd_clk(ui_clk),
       .rd_en(wr_fifo_re),
       .dout(wr_fifo_data),
       .empty(wr_fifo_data_empty)
);

fifo_ddr_mask fifo_wr_mask_inst(
       .rst(sys_rst_i),
       .wr_clk(sys_clk_i),
       .wr_en(),
       .din(),
       .full(),
       .rd_clk(ui_clk),
       .rd_en(wr_fifo_re),
       .dout(wr_fifo_mask),
       .empty(wr_fifo_mask_empty)
);

endmodule
