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

📄 config_mux.v

📁 ---简化版
💻 V
字号:
//	Module  config_mux
// This block implements the PCI target configuration registers, and
// the PCI data output MUX.  It controls when data gets written into the
// configuration registers, and what data gets presented onto the output
// data bus (pci_dat_out) during reads.
//
// Note:  The read values for the base address registers are set in this
//        block.  BA0 & BA1 always return the size of the memory block for the
//        backend app. when read. 
//

module config_mux 
 (
    input pci_clk,              // system clock
    input pci_rst_l,            // async reset
    input pci_irdy_l,           // master device is ready;
    input [3:0]  pci_cbe,       // byte enables in
    input [31:0] pci_data,      // pci data
    input [7:0]  pci_addr_reg,	// from: glue; pci address
    input [3:0]  pci_cbe_reg,   // from: glue; config cycle ID
    input        pci_idsel_reg, // from: glue;
    input [31:4] ba0_reg, 	    // from: base_addr_chk; The address space required for ba0
    input [31:4] ba1_reg, 	    // from: base_addr_chk; The address space required for ba1
    input [31:0] bk_data,     // back end data in
    output reg [31:0] pci_dat_out, // the pci output data bus
    output reg [1:0] com,       // The Mem - I/O enable bits of the command reg
    output reg ba0_en,          // base address 0 clock enable
    output reg ba1_en           // base address 1 clock enable
 );
    
//--------------------reg declarations-------------------------------
    reg [7:0]  int_line; 	// r/w interupt line register
    reg [31:0] cfg_dat_out; // output data bus
    reg  stat_com_en;
    reg  int_line_en;
    reg  cfg_out_en;        // config read
    wire cfg_en;            // config write
//-------------------------------------------------------------------


// The following parameters set the values for the read only 
// configuration registers.

/******************************************************************/
/************    Start Reg 00h Section              ***************/
/******************************************************************/
// reg 00h (DevID/VendorID)
    parameter	DEVICE_ID     = 16'h0120; // User Defined
    parameter	VENDOR_ID     = 16'h1022; // Set to AMD
/******************************************************************/
/************    End Reg 00h Section              *****************/
/******************************************************************/




/******************************************************************/
/************    Start Reg 04h Section              ***************/
/******************************************************************/
//reg 04h (status/command) : default value: 0400_0000
/*	BYTE: 07~06h (status reg)
	BYTE: 05~04h (command reg)
	  --- bit0 : I/O space enabled
	  --- bit1 : memory space enabled */

// The only bits used in this section are status[11:9]/Command[1:0];
// The rest are all disabled to 0 at the Mux inputs

// `defines used for devsel
    `define spd_fast    2'b00
    `define spd_medium  2'b01
    `define spd_slow    2'b10
    parameter DEV_SEL = 2'b01; // medium devsel timing

// The creation of the status and Command Registers
    always @ (posedge pci_clk or negedge pci_rst_l)
    begin
        if (pci_rst_l == 1'b0) begin 
            com <= 2'b00;   // disable I/O and MEM space accesses.
        end
        else if (stat_com_en == 1'b1) begin 
            if (!pci_cbe[0])  // check to see if byte lane is enabled
                com <= pci_data[1:0]; 
            else
                com <= com;
        end 
        else begin 
            com <= com;
        end
    end
/******************************************************************/
/************    End Reg 04h Section              *****************/
/******************************************************************/





/******************************************************************/
/************    Start Reg 08h Section              ***************/
/******************************************************************/
// reg 08h (Class/revision)
/*
	OBh : = 00 --- old device; 
			01 --- large memory device
			02 --- net controller
			03 --- display controller
			04 --- multimedia device
			05 --- memory controller
			06 --- birdge device
			07~ef --- reserved
			ff --- other device
	0Ah : subclass code
	09h : program interface
	08h : Revision
*/
    parameter	CLASS_CODE    = 24'h058000;	// Memory Controller 
    parameter	REVISION_ID   =  8'h01;		// Rev. 01
/******************************************************************/
/************    End Reg 08h Section              *****************/
/******************************************************************/





/******************************************************************/
/************    Start Reg 0Ch Section              ***************/
/******************************************************************/
// reg 0Ch (Misc Functions)
/*
	0fh : self test;
	0eh : header type;
		  bit7 == 1 --- multifunction device
	0dh : delay timer;
	0ch : cache size.
*/
// No BIST, Type 00 header, Ignore Cachelinesize, No Latency Set,
    parameter MISC_FUNCTIONS = 32'h00000000;
/******************************************************************/
/************    End Reg 0Ch Section              *****************/
/******************************************************************/





/******************************************************************/
/************  Start Base Address Defines Section   ***************/
/******************************************************************/
// Base address registers. 
// The Following `defines are used in the Base Address Parameters
// To set if the Back End Device is:
//   -User I/O or Memory
//   -Where it is locatated in the address map
//   -If the backend device is prefetchable
//   -How much address space it requires

    `define MEM_ON         1'b0
    `define IO_ON          1'b1

    `define ANYWHERE_IN_32 2'b00
    `define BELOW_1M       2'b01
    `define ANYWHERE_IN_64 2'b10

    `define PREFETCH_ON    1'b1
    `define PREFETCH_OFF   1'b0

/******************************************************************/
/************  End Base Address Defines Section   ***************/
/******************************************************************/
/******************************************************************/
/************    Start Reg 10h Section           ***************/
/******************************************************************/
// reg 10h (Base Address 0) BA0 Using `defines from above
    wire [31:0] BA0 = {ba0_reg,`PREFETCH_OFF,`ANYWHERE_IN_32,`MEM_ON};
/******************************************************************/
/************    End Reg 10h Section              *****************/
/******************************************************************/
/******************************************************************/
/*************    Start Reg 14h Section             ***************/
/******************************************************************/
// reg 14h (Base Address 1) BA1 Using `defines from above
    wire [31:0] BA1 = {ba1_reg,`PREFETCH_OFF,`ANYWHERE_IN_32,`IO_ON};
/******************************************************************/
/************    End Reg 14h Section              *****************/
/******************************************************************/





/******************************************************************/
/************    Start Reg 2C Section               ***************/
/******************************************************************/
// reg 2Ch (SubsystemID/Subsystem VendorID)
parameter	SUB_SYSTEM_ID = 16'h0120; // User Defined Could be anything
parameter	SUB_VENDOR_ID = 16'h1022; // Set to AMD
/******************************************************************/
/************    End Reg 2Ch Section              *****************/
/******************************************************************/





/******************************************************************/
/************    Start Reg 3C Section               ***************/
/******************************************************************/
// reg 3C (Max_Lat/Min_Gnt/Interrupt Pin/ Interupt Line)
// Interupt Pin is set to 1 corresponding to inta_l
/*
	Interupter line reg : IRQ0~15;
	Interrupt Pin : connect to INTA# or INTB# or INTC# or INTD#
								==1		==2		  ==3      ==4
*/
    parameter INT_PIN = 8'h01;

// The int_line reg is defined here
// The software will write to this register
// to set the system IRQ used for the interrupt
    always @ (posedge pci_clk or negedge pci_rst_l)
    begin
        if (pci_rst_l == 1'b0) begin 
            int_line <= 8'h00;
        end 
        else if (int_line_en && !pci_cbe[0] ) begin // check byte enables
            int_line <= pci_data[7:0];
        end
        else begin 
            int_line <= int_line;    
        end
    end
// Max_Lat & Min_Gnt are not implemented so they are 0's in Mux
/******************************************************************/
/************    End Reg 3Ch Section              *****************/
/******************************************************************/




/******************************************************************/
/************    Start Write Enable section         ***************/
/******************************************************************/
    `define write_04 (pci_addr_reg[7:0] == 8'h04)
    `define write_10 (pci_addr_reg[7:0] == 8'h10)
    `define write_14 (pci_addr_reg[7:0] == 8'h14)
    `define write_3C (pci_addr_reg[7:0] == 8'h3C)

    assign cfg_en = ((pci_cbe_reg == 4'b1011) && (pci_idsel_reg == 1'b1)) ? 1'b1 : 1'b0;
 
    always @ (cfg_en or pci_irdy_l or pci_addr_reg[7:0])
    begin 
        if (cfg_en && !pci_irdy_l) begin 
            if (`write_04) begin 
                stat_com_en <= #1 1;
                ba0_en      <= #1 0;
                ba1_en      <= #1 0;
                int_line_en <= #1 0;
                end
            else if (`write_10) begin 
                ba0_en      <= #1 1;
                stat_com_en <= #1 0;
                ba1_en      <= #1 0;
                int_line_en <= #1 0;
                end
            else if (`write_14) begin 
                ba1_en      <= #1 1;
                stat_com_en <= #1 0;
                ba0_en      <= #1 0;
                int_line_en <= #1 0;
                end
            else if (`write_3C) begin 
                int_line_en <= #1 1;
                stat_com_en <= #1 0;
                ba0_en      <= #1 0;
                ba1_en      <= #1 0;
                end
            else begin 
                stat_com_en <= #1 0;
                ba0_en      <= #1 0;
                ba1_en      <= #1 0;
                int_line_en <= #1 0;
            end
        end
        else begin 
            stat_com_en <= #1 0;
            ba0_en      <= #1 0;
            ba1_en      <= #1 0;
            int_line_en <= #1 0;
        end
    end
/******************************************************************/
/************      End Write Enable section         ***************/
/******************************************************************/
  
  
  
  
  
/******************************************************************/
/************    Start Output Mux Section           ***************/
/******************************************************************/
    always @ (posedge pci_clk or negedge pci_rst_l)
    begin 
        if (!pci_rst_l) begin 
            cfg_out_en <= #1 1'b0;
        end
        else if (pci_cbe_reg == 4'b1010) begin 
            cfg_out_en <= #1 1'b1;
        end
        else begin
            cfg_out_en <= #1 1'b0;
        end
    end

    always @ (cfg_dat_out or bk_data or cfg_out_en)
    begin 
        if (cfg_out_en) 
            pci_dat_out <= #1 cfg_dat_out;
        else 
            pci_dat_out <= #1 bk_data;    
    end

/*	Read the Config Space */
    always @ (posedge pci_clk or negedge pci_rst_l)
    begin 
        if (!pci_rst_l) begin 
            cfg_dat_out <= #1 32'b0; // zero at reset
        end
        else begin 
            case (pci_addr_reg [5:2])
                4'b00_00: cfg_dat_out <= #1 {DEVICE_ID,VENDOR_ID};                  // reg 00h (DevID/VendorID)
                4'b00_01: cfg_dat_out <= #1 {4'b0,1'b0,DEV_SEL,9'b0,14'b0,com};     // reg 04h (status/command)
                4'b00_10: cfg_dat_out <= #1 {CLASS_CODE,REVISION_ID};               // reg 08h (Class/revision)
                4'b00_11: cfg_dat_out <= #1 MISC_FUNCTIONS;                         // reg 0Ch (Misc Functions);
                4'b01_00: cfg_dat_out <= #1 BA0;                                    // reg 10h (Base Address 0);
                4'b01_01: cfg_dat_out <= #1 BA1;                                    // reg 14h (Base Address 1);
                4'b10_11: cfg_dat_out <= #1 {SUB_SYSTEM_ID,SUB_VENDOR_ID};          // reg 2Ch (SubsystemID/Subsystem VendorID);
                4'b11_11: cfg_dat_out <= #1 {16'b0,INT_PIN,int_line};               // reg 3C (Max_Lat/Min_Gnt/Interrupt Pin/ Interupt Line);
                default:  cfg_dat_out <= #1 32'b0;                                  // unimplemented return 0's;
            endcase
        end
    end
/******************************************************************/
/************    End Output Mux Section           ***************/
/******************************************************************/
    
endmodule //end of config_mux

						


⌨️ 快捷键说明

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