📄 config_mux.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 + -