📄 pcicore.v
字号:
/*
**********************************************************************************
**********************************************************************************
// Interface Studio PCI IP Core
// ----Reference Design of 33MHz 32bit PCI Target Device
//
//
//File name:pci_core.v
//Designor: duoduo
//Date: 15,Mar,2004
//Ver: 1.0
*********************************NOTE*********************************************
// ALL COPY RIGHTS IS RESERVED BY INTERFACE STUDIO
**********************************************************************************
*/
// Tis Reference Design is implementated using ALTERA's EPF10K10A device. It may
//be implemented in other device by modification or not.
// This design contains follow modules:
// --pci_top.v
// --pci_core.v
//This PCI Target IP Core support following features:
// 33MHz 32bit PCI and Intel 8051 back end interface
// Support one IO base address regions (16 bytes)
// Support one memory base address regions (256K bytes)
// Support one interrupt signal from the back end device to the PCI bus
// Implementation of all required PCI configuration registers
// Parity generation for all read cycles
// Compliance with PCI 2.2 requirements
// A fully wave simulation is supplied use MAXPLUSII for verification
//This PCI Target IP Core does not support following features:
// PERR and SERR
// Expansion ROM
// Built-in Self Test (BIST)
// Burst Access
`timescale 1ns/10ps
`define DEVICE_ID 16'H1125
`define VENDOR_ID 16'H1172 //altera PCI SIG VENDOR_ID
`define CLASS_CODE 24'H068000 //other PCI brige device class
`define REVISION_ID 8'H01 //Rev. 01
`define DEVSEL_TIMING 2'B10 //devsel timing is slow
`define INTERRUPT_PIN 8'H01 //use PCI INTA#
`define BASE_ADDRESS0_SIZE 4 //16 byte IO space
`define BASE_ADDRESS0_LENGTH 28 //Note: for convenient for this IP Core,should:
//BASE_ADDRESS0_LENGTH + BASE_ADDRESS0_SIZE = 32
`define BASE_ADDRESS1_SIZE 18 //64K byte memory,is implemented as 64k*4 byte memory space
`define BASE_ADDRESS1_LENGTH 14 //Note: for convenient for this IP Core,should:
////BASE_ADDRESS1_LENGTH + BASE_ADDRESS1_SIZE = 32
//PCI BUS command
`define CONFIG_READ 4'B1010 //A
`define CONFIG_WRITE 4'B1011 //B
`define IO_READ 4'B0010 //2
`define IO_WRITE 4'B0011 //3
`define MEMORY_READ 4'B0110 //6
`define MEMORY_WRITE 4'B0111 //7
`define MEMORY_READ_MULTIPLE 4'B1100 //C
`define MEMORY_READ_LINE 4'B1110 //E
`define MEMORY_WRITE_AND_INVALIDATE 4'B1111 //F
//state machine state define
`define IDLE 4'B0000 //0
`define CONFIG_ACCESS1 4'B0001 //1
`define CONFIG_ACCESS2 4'B0011 //3
`define CONFIG_ACCESS3 4'B0111 //7
`define CONFIG_ACCESS4 4'B1111 //f
`define IO_MEMORY_ACCESS1 4'B1000 //8
`define IO_MEMORY_ACCESS2 4'B1100 //c
`define IO_MEMORY_ACCESS3 4'B1110 //e
`define IO_MEMORY_ACCESS4 4'B0110 //6
`define IO_MEMORY_ACCESS5 4'B0010 //2
`define IO_MEMORY_ACCESS6 4'B1010 //a
`define ACCESS_FINISH 4'B1011 //b
`define IO_MEMORY_WAIT1 4'B0100 //4
`define IO_MEMORY_WAIT2 4'B0101 //5
`define IO_MEMORY_WAIT3 4'B1001 //9
`define IO_MEMORY_WAIT4 4'B1101 //d
/////////////////////////////////
`define FUNCTION0 3'B000
`define TYPE0 2'B00
`define PCI_READ_CONFIG 2'B00
`define PCI_READ_INNER_IO 2'B01
`define PCI_READ_E8051 2'B10
`define PCI_READ_UNKNOWN 2'B11
module pcicore
(
//PCI signal
PciReset_, //PCI reset
PciClk, //PCI clock
PciFrame_, //PCI frame
PciIdsel, //PCI idsel
PciIrdy_ , //PCI irdy
PciDevsel_, //PCI devsel
PciTrdy_, //PCI trdy
PciStop_, //PCI stop
PciPar, //PCI par
PciCbe_, //PCI cbe
PciAdIn, //PCI AD bus input
PciAdOut, //PCI AD bus output
PciIntA_,
//internal control signal
PciAdOutEnable, //high aceive,when aceive,output data to PCI AD bus
PciParOutEnable, //high aceive,when aceive,par output to PCI PAR
PciDevselTrdyStopOutEnable, //high aceive,when aceive,output devsel/trdy/stop to PCI bus
E8051P0OutEnable,
//local signal:
E8051Ale, //8051 signal: ALE
E8051Al, //8051 low 8bit address latch
E8051P2, //8051 signal: P2(as address bus)
E8051P0In, //8051 signal: P0(input,multiplexed data/address bus)
E8051P0Out, //8051 signal: P0(output,multiplexed data/address bus)
E8051Wr_, //8051 signal: WR
E8051Rd_, //8051 signal: RD
E8051IoWr_, //8051 expanded signal: IOWR
E8051IoRd_, //8051 expanded signal: IORD
LocalReset_, //local reset output
LocalInt_ //local interrupt input
);
//port define
input PciReset_;
input PciClk;
input PciFrame_;
input PciIdsel;
input PciIrdy_ ;
output PciDevsel_ ;
output PciTrdy_ ;
output PciStop_ ;
output PciPar ;
input [3:0] PciCbe_;
input [31:0] PciAdIn;
output [31:0] PciAdOut;
output PciIntA_;
output PciAdOutEnable;
output PciParOutEnable;
output PciDevselTrdyStopOutEnable;
output E8051P0OutEnable;
output [7:0] E8051P2;
output [7:0] E8051Al;
output [7:0] E8051P0Out;
input [7:0] E8051P0In;
output E8051Ale;
output E8051Wr_;
output E8051Rd_;
output E8051IoWr_;
output E8051IoRd_;
output LocalReset_;
input LocalInt_;
//register type port
reg [31:0] PciAdOut;
reg PciDevsel_ ;
reg PciTrdy_ ;
reg PciStop_ ;
reg PciPar;
reg PciAdOutEnable;
reg PciParOutEnable;
reg PciDevselTrdyStopOutEnable;
reg [7:0] E8051P2;
reg [7:0] E8051Al;
reg E8051Ale;
reg E8051Wr_;
reg E8051Rd_;
reg E8051IoWr_;
reg E8051IoRd_;
reg E8051P0OutEnable;
//////////////////////////////////////////////////////
//internal signal define:
reg [31:0] PciAdressReg;
reg [3:0] PciCbeReg;
reg PciAdLatchEnable;
reg ConfigDataChange;
reg [31:0] ConfigDataOut;
reg [1:0] PciAdOutSelect;
reg [1:0] Com;
reg [7:0] InterruptLine;
reg IoWriteEnable;
reg LiLatchEnable;
reg ConfigWriteEnable;
reg [31:`BASE_ADDRESS0_SIZE] BaseAddress0;
reg [31:`BASE_ADDRESS1_SIZE] BaseAddress1;
wire HitBaseAddress0;
wire HitBaseAddress1;
reg [3:0] PciStateMachine;
wire Par0;
wire Par1;
wire Par2;
wire Par3;
wire ParCbe;
wire ParReg;
reg PciCycleBegin;
reg PciCycleBeginClear_;
reg P2LatchStrobe;
reg [6:0] InnerIoReg;
reg BUTTON_INT_;
reg E8051P0DataAddressSelect;
reg InnerIoWriteStrobe;
wire IoMemReadInnerIo;
wire IoMemWriteInnerIo;
wire IoMemReadExternalIo;
wire IoMemWriteExternalIo;
wire IoMenReadMemory;
wire IoMenWriteMemory;
assign IoMemReadInnerIo = ((PciCbeReg == `IO_READ) && (PciAdressReg[3] == 1'b1))? 1'B1 : 1'B0;
assign IoMemWriteInnerIo = ((PciCbeReg == `IO_WRITE) && (PciAdressReg[3] == 1'b1))? 1'B1 : 1'B0;
assign IoMemReadExternalIo = ((PciCbeReg == `IO_READ) && (PciAdressReg[3] == 1'b0))? 1'B1 : 1'B0;
assign IoMemWriteExternalIo = ((PciCbeReg == `IO_WRITE) && (PciAdressReg[3] == 1'b0))? 1'B1 : 1'B0;
assign IoMenReadMemory = ((PciCbeReg == `MEMORY_READ) || (PciCbeReg == `MEMORY_READ_MULTIPLE) || (PciCbeReg == `MEMORY_READ_LINE)) ? 1'B1 : 1'B0;
assign IoMenWriteMemory = ((PciCbeReg == `MEMORY_WRITE) || (PciCbeReg == `MEMORY_WRITE_AND_INVALIDATE)) ? 1'B1 : 1'B0;
wire AddressPhaseConfig;
wire AddressPhaseIoMemory;
assign AddressPhaseConfig = ((PciCbe_ == `CONFIG_READ) || (PciCbe_ == `CONFIG_WRITE)) ? 1'B1 : 1'B0;
assign AddressPhaseIoMemory = ((((PciCbe_ == `IO_READ) || (PciCbe_ == `IO_WRITE))&& (Com[0]==1'B1)) ||
(((PciCbe_ == `MEMORY_READ) || (PciCbe_ == `MEMORY_WRITE) ||
(PciCbe_ == `MEMORY_READ_MULTIPLE) || (PciCbe_ == `MEMORY_READ_LINE)||
(PciCbeReg == `MEMORY_WRITE_AND_INVALIDATE))&& (Com[1]==1'B1))) ? 1'B1 : 1'B0;
//PCI state machine:
always @(negedge PciReset_ or posedge PciClk)
begin
if (!PciReset_)
begin
PciDevsel_ = 1'B1;
PciTrdy_ = 1'B1;
PciStop_ = 1'B1;
PciAdOutEnable = 1'B0;
PciParOutEnable = 1'B0;
PciDevselTrdyStopOutEnable = 1'B0;
ConfigWriteEnable = 1'B0;
PciStateMachine = `IDLE;
ConfigDataChange = 1'B0;
E8051Ale = 1'B1;
E8051P0OutEnable = 1'B0;
E8051Wr_ = 1'B1;
E8051Rd_ = 1'B1;
E8051IoWr_ = 1'B1;
E8051IoRd_ = 1'B1;
E8051P0DataAddressSelect = 1'B1;
InnerIoWriteStrobe = 1'B1;
PciAdOutSelect = `PCI_READ_CONFIG;
P2LatchStrobe = 1'b0;
end
else
begin
case(PciStateMachine)
`IDLE:
begin
if ((PciAdIn[10:8] == `FUNCTION0) &&(PciAdIn[1:0] == `TYPE0) && (!PciFrame_) && (PciIdsel) && (AddressPhaseConfig))
//if it is a config access
begin
PciStateMachine = `CONFIG_ACCESS1;
ConfigDataChange = 1'B1;
PciAdOutSelect = `PCI_READ_CONFIG;
end
else if (PciCycleBegin && (!PciIdsel) && AddressPhaseIoMemory)
//else if it may be a IO or memory access to our device
begin
PciStateMachine = `IO_MEMORY_ACCESS1;
end
else
//else it is not a valid PCI bus cycle
begin
PciStateMachine = `IDLE;
end
end
`CONFIG_ACCESS1:
//devsel,trdy and stop signal will be otuput enabled:
begin
PciDevselTrdyStopOutEnable = 1'B1;
PciStateMachine = `CONFIG_ACCESS2;
end
`CONFIG_ACCESS2:
//devsel will be active:
begin
PciStateMachine = `CONFIG_ACCESS3;
PciDevsel_ = 1'B0;
end
`CONFIG_ACCESS3:
begin
//if it is a config read command,we will output config space register data to PCI AD bus
if (PciCbeReg == `CONFIG_READ) PciAdOutEnable = 1'b1;
//wait for irdy is active
if (!PciIrdy_)
begin
//if irdy is aceive,activate trdy to show master that we are ready for complete this command
PciTrdy_ = 1'B0;
//if it is a config write command,we will accept data and latch it to config space register
if (PciCbeReg == `CONFIG_WRITE) ConfigWriteEnable = 1'B1;
//if frame is 0,it means PCI master want a burst config read,because we don't support bust access
//so stop it
if (!PciFrame_) PciStop_ = 1'B0;
PciStateMachine = `CONFIG_ACCESS4;
end
else PciStateMachine = `CONFIG_ACCESS3;
end
`CONFIG_ACCESS4:
begin
//after complete data phase of this PCI cycle,trdy is inavtice
PciTrdy_ = 1'B1;
//no matter it is read or write cycle,ConfigWriteEnable should inactive now
ConfigWriteEnable = 1'B0;
//if it is a PCI read cycle,we should output parity signal
if (PciCbeReg == `CONFIG_READ) PciParOutEnable = 1'b1;
//whatever read or write,we should release PCI AD bus now
PciAdOutEnable = 1'B0;
//if master request a burst access,we will stop it and wait until master
//release frame signal to flag this cycle is complete
if (!PciFrame_)
begin
PciStateMachine = `CONFIG_ACCESS4;
end
else
begin
PciStateMachine = `ACCESS_FINISH;
PciDevsel_ = 1'B1;
PciStop_ = 1'B1;
end
end
`IO_MEMORY_ACCESS1:
begin
//judge whether this cycle is a IO or memory access to our device
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -