⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmd_ep_mem.v

📁 已经在xilinx的ML555开发板上实现的PCIEx4的设计
💻 V
字号:
//--------------------------------------------------------------------------------
//--
//-- This file is owned and controlled by Xilinx and must be used solely
//-- for design, simulation, implementation and creation of design files
//-- limited to Xilinx devices or technologies. Use with non-Xilinx
//-- devices or technologies is expressly prohibited and immediately
//-- terminates your license.
//--
//-- Xilinx products are not intended for use in life support
//-- appliances, devices, or systems. Use in such applications is
//-- expressly prohibited.
//--
//--            **************************************
//--            ** Copyright (C) 2005, Xilinx, Inc. **
//--            ** All Rights Reserved.             **
//--            **************************************
//--
//--------------------------------------------------------------------------------
//-- Filename: BMD_EP_MEM.v
//--
//-- Description: Endpoint Memory: 128B/32 registers
//--
//--------------------------------------------------------------------------------

`timescale 1ns/1ns

module BMD_EP_MEM (
                      clk,                   // I
                      rst_n,                 // I

                      cfg_max_rd_req_size,   // I [2:0]
                      cfg_max_payload_size,  // I [2:0]

                      a_i,                   // I [8:0]
                      wr_en_i,               // I
                      rd_d_o,                // O [31:0]
                      wr_d_i,                // I [31:0]

                      init_rst_o,            // O

                      mrd_start_o,           // O
                      mrd_done_o,            // O
                      mrd_addr_o,            // O [31:0]
                      mrd_len_o,             // O [31:0]
                      mrd_count_o,           // O [31:0]

                      mwr_start_o,           // O
                      mwr_done_i,            // I
                      mwr_addr_o,            // O [31:0]
                      mwr_len_o,             // O [31:0]
                      mwr_count_o,           // O [31:0]
                      mwr_data_o,            // O [31:0]

                      cpl_ur_found_i,        // I [7:0]
                      cpl_ur_tag_i,          // I [7:0]

                      cpld_found_i,          // I [31:0]
                      cpld_data_size_i,      // I [31:0]
                      cpld_malformed_i,      // I

                      int_src_rd_i,      // I
                      int_src_wr_i,      // I
                      int_clear_o        // O


                      );

    input             clk;
    input             rst_n;

    input [2:0]       cfg_max_rd_req_size;
    input [2:0]       cfg_max_payload_size;

    input [6:0]       a_i;
    input             wr_en_i;
    output [31:0]     rd_d_o;
    input  [31:0]     wr_d_i;

    // CSR bits

    output            init_rst_o;

    output            mrd_start_o;
    output            mrd_done_o;
    output [31:0]     mrd_addr_o;
    output [31:0]     mrd_len_o;
    output [31:0]     mrd_count_o;

    output            mwr_start_o;
    input             mwr_done_i;
    output [31:0]     mwr_addr_o;
    output [31:0]     mwr_len_o;
    output [31:0]     mwr_count_o;
    output [31:0]     mwr_data_o;

    input  [7:0]      cpl_ur_found_i;
    input  [7:0]      cpl_ur_tag_i;

    input  [31:0]     cpld_found_i;
    input  [31:0]     cpld_data_size_i;
    input             cpld_malformed_i;

    input             int_src_rd_i;
    input             int_src_wr_i;
    output            int_clear_o;

    // Local Regs

    reg [31:0]        rd_d_o;

    reg               init_rst_o;

    reg               mrd_start_o;
    reg [31:0]        mrd_addr_o;
    reg [31:0]        mrd_len_o;
    reg [31:0]        mrd_count_o;

    reg               mwr_start_o;
    reg [31:0]        mwr_addr_o;
    reg [31:0]        mwr_len_o;
    reg [31:0]        mwr_count_o;
    reg [31:0]        mwr_data_o;

    reg [31:0]        mrd_perf;
    reg [31:0]        mwr_perf;

    reg               mrd_done_o;

    reg [20:0]        expect_cpld_data_size;  // 2 GB max
    reg [20:0]        expect_cpld_data_size_reg;  // 2 GB max
        
    reg [20:0]        cpld_data_size;         // 2 GB max
    reg               cpld_done;

    wire              int_clear_o;


    assign int_asserted = int_src_wr_i | int_src_rd_i;
    assign int_clear_o = (( a_i[6:0] == 7'b001111 ) && (wr_en_i == 1'b1)) ? 1'b1:1'b0;

    always @(posedge clk or negedge rst_n) begin

        if ( !rst_n ) begin

          init_rst_o  <= 1'b0;

          mrd_start_o <= 1'b0;
          mrd_addr_o  <= 32'b0;
          mrd_len_o   <= 32'b0;
          mrd_count_o <= 32'b0;

          mwr_start_o <= 1'b0;
          mwr_addr_o  <= 32'b0;
          mwr_len_o   <= 32'b0;
          mwr_count_o <= 32'b0;
          mwr_data_o  <= 32'b0;

//          int_clear_o  <= 1'b0;

        end else begin

          case (a_i[6:0])

            // 00-03H : Reg # 0
            // Byte0[0]: Initiator Reset (RW) 0= no reset 1=reset.
            7'b0000000: begin

              if (wr_en_i)
                init_rst_o  <= wr_d_i[0];

              rd_d_o <= {{31'b0}, init_rst_o};

              if (init_rst_o) begin

                mwr_start_o <= 1'b0;
                mrd_start_o <= 1'b0;

              end

            end

            // 04-07H :  Reg # 1
            // Byte0[0]: Memory Write Start (RW) 0=no start, 1=start
            // Byte1[0]: Memory Write Done  (RO) 0=not done, 1=done
            // Byte2[0]: Memory Read Start (RW) 0=no start, 1=start
            // Byte3[0]: Memory Read Done  (RO) 0=not done, 1=done
            7'b0000001: begin

              if (wr_en_i) begin
                mwr_start_o  <= wr_d_i[0];
                mrd_start_o  <= wr_d_i[16];
              end

              rd_d_o <= {7'b0,mrd_done_o,7'b0,mrd_start_o,
                         7'b0,mwr_done_i,7'b0,mwr_start_o};

            end

            // 08-0BH : Reg # 2
            // Memory Write DMA Address (RW)
            7'b0000010: begin

              if (wr_en_i)
                mwr_addr_o  <= wr_d_i;

              rd_d_o <= mwr_addr_o;

            end

            // 0C-0FH : Reg # 3
            // Memory Write length in DWORDs (RW)
            7'b0000011: begin

              if (wr_en_i)
                mwr_len_o  <= wr_d_i[15:0];

              rd_d_o <= {{13'b0}, cfg_max_payload_size, mwr_len_o[15:0]};

            end

            // 10-13H : Reg # 4
            // Memory Write Packet Count (RW)
            7'b0000100: begin

              if (wr_en_i)
                mwr_count_o  <= wr_d_i;

              rd_d_o <= mwr_count_o;

            end

            // 14-17H : Reg # 5
            // Memory Write Packet DWORD Data (RW)
            7'b000101: begin

              if (wr_en_i)
                mwr_data_o  <= wr_d_i;

              rd_d_o <= mwr_data_o;

            end

            // 18-1BH : Reg # 6
            // Reserved for future use
            7'b000110: begin

              rd_d_o <= 32'hFFFFFFFF;

            end

            // 1C-1FH : Reg # 7
            // Read DMA Address (RW)
            7'b000111: begin

              if (wr_en_i)
                mrd_addr_o  <= wr_d_i;

              rd_d_o <= mrd_addr_o;

            end

            // 20-23H : Reg # 8
            // Read length in DWORDs (RW)
            7'b001000: begin

              if (wr_en_i)
                mrd_len_o  <= wr_d_i[15:0];

              rd_d_o <= {{13'b0}, cfg_max_rd_req_size, mrd_len_o[15:0]};

            end

            // 24-27H : Reg # 9
            // Read Packet Count (RW)
            7'b001001: begin

              if (wr_en_i)
                mrd_count_o  <= wr_d_i;

              rd_d_o <= mrd_count_o;

            end

            // 28-2BH : Reg # 10
            // Memory Write Performance (RO)
            7'b001010: begin

              rd_d_o <= mwr_perf;

            end

            // 2C-2FH  : Reg # 11
            // Memory Read  Performance (RO)
            7'b001011: begin

              rd_d_o <= mrd_perf;

            end

            // 30-33H  : Reg # 12
            // Memory Read Completion Status (RO)
            7'b001100: begin

              rd_d_o <= {{15'b0}, cpld_malformed_i, cpl_ur_tag_i, cpl_ur_found_i};

            end

            // 34-37H  : Reg # 13
            // Memory Read Completion with Data Detected (RO)
            7'b001101: begin

              rd_d_o <= {cpld_found_i};

            end

            // 38-3BH  : Reg # 14
            // Memory Read Completion with Data Size (RO)
            7'b001110: begin

              rd_d_o <= {cpld_data_size_i};

            end

            // 3C-3FH  : Reg # 15
            // Interrupt status and interrupt clear (RW)
            7'b001111: begin
//              if (wr_en_i)
//                int_clear_o  <= 1'b1;
              rd_d_o <= {int_asserted,{29'b0},int_src_wr_i,int_src_rd_i};
            end

            // 3C-7FH : Reserved
            default: begin

              rd_d_o <= 32'b0;

            end

          endcase

        end

    end

    /*
     * Memory Write Performance Instrumentation
     */

    always @(posedge clk or negedge rst_n) begin

        if ( !rst_n ) begin

          mwr_perf <= 32'b0;

        end else begin

          if (init_rst_o)
            mwr_perf <= 32'b0;
          else if (mwr_start_o && !mwr_done_i)
            mwr_perf <= mwr_perf + 1'b1;

        end

    end

    /*
     * Memory Read Performance Instrumentation
     */

    always @(posedge clk or negedge rst_n) begin

        if ( !rst_n ) begin

          mrd_perf <= 32'b0;

        end else begin

          if (init_rst_o)
            mrd_perf <= 32'b0;
          else if (mrd_start_o && !mrd_done_o)
            mrd_perf <= mrd_perf + 1'b1;

        end

    end

    always @(posedge clk) begin
            expect_cpld_data_size_reg <= mrd_len_o[15:0] * mrd_count_o[15:0];
            expect_cpld_data_size <= expect_cpld_data_size_reg;
		end

    always @(posedge clk or negedge rst_n) begin
        if ( !rst_n ) begin

//          expect_cpld_data_size  <=  21'b0;
          cpld_data_size         <=  21'b0;
          cpld_done              <=  1'b0;

        end else begin

          if (init_rst_o) begin

//            expect_cpld_data_size <=  21'b0;
            cpld_data_size        <=  21'b0;
            cpld_done             <=  1'b0;

          end else begin
          
//            expect_cpld_data_size <= mrd_len_o[15:0] * mrd_count_o[15:0];          
            cpld_data_size        <= cpld_data_size_i[20:0];
            cpld_done             <= (expect_cpld_data_size == cpld_data_size);

          end

        end

    end

    always @(posedge clk or negedge rst_n) begin

        if ( !rst_n )
          mrd_done_o <= 1'b0;
        else
          if (init_rst_o)
            mrd_done_o <= 1'b0;
          else if ( (mrd_start_o) && (!mrd_done_o) && (cpld_done) )
            mrd_done_o <= 1'b1;
    end

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -