以下資料的整理主要是做備忘錄,避免以後忘了,順便留給需要的人。
==========================================
本文主要是參考友晶科技的DE2i-150光碟裡面的PCie_Fundmental範例,再重新打造一個新的範例程式。
// ============================================================================
// Copyright (c) 2012 by Terasic Technologies Inc.
// Copyright (c) 2013 by TKU ICLAB.
// ============================================================================
//
//
// ============================================================================
//Date: Wed Jun 27 19:19:53 2012
// ============================================================================
//
// Revision History :
// --------------------------------------------------------------------
// Ver :| Author :| Mod. Date :| Changes Made:
// V1.0 :| Shih-An Li :| 10/10/2013 :| Initial Revision, add SW14
// to control 7-seg lights
// -------------------------------------------------------------------- `define ENABLE_PCIE
module de2i_pci_top( ///////////CLOCK2/////////////
iCLOCK2_50, /////////CLOCK3/////////
iCLOCK3_50, /////////CLOCK/////////
iCLOCK_50, /////////DRAM/////////
oDRAM_ADDR,
oDRAM_BA,
oDRAM_CAS_N,
oDRAM_CKE,
oDRAM_CLK,
oDRAM_CS_N,
DRAM_DQ,
oDRAM_DQM,
oDRAM_RAS_N,
oDRAM_WE_N, /////////EEP/////////
oEEP_I2C_SCLK,
EEP_I2C_SDAT, /////////ENET/////////
oENET_GTX_CLK,
iENET_INT_N,
iENET_LINK100,
oENET_MDC,
ENET_MDIO,
oENET_RST_N,
iENET_RX_CLK,
iENET_RX_COL,
iENET_RX_CRS,
iENET_RX_DATA,
iENET_RX_DV,
iENET_RX_ER,
iENET_TX_CLK,
oENET_TX_DATA,
oENET_TX_EN,
oENET_TX_ER, /////////FAN/////////
FAN_CTRL, /////////FL/////////
oFL_CE_N,
oFL_OE_N,
iFL_RY,
oFL_WE_N,
oFL_WP_N,
oFL_RESET_N,
/////////FS/////////
FS_DQ,
oFS_ADDR,
/////////GPIO/////////
GPIO, /////////G/////////
iG_SENSOR_INT1,
oG_SENSOR_SCLK,
G_SENSOR_SDAT, /////////HEX/////////
oHEX0,
oHEX1,
oHEX2,
oHEX3,
oHEX4,
oHEX5,
oHEX6,
oHEX7, /////////HSMC/////////
iHSMC_CLKIN0,
iHSMC_CLKIN_N1,
iHSMC_CLKIN_N2,
iHSMC_CLKIN_P1,
iHSMC_CLKIN_P2,
oHSMC_CLKOUT0,
HSMC_CLKOUT_N1,
HSMC_CLKOUT_N2,
HSMC_CLKOUT_P1,
HSMC_CLKOUT_P2,
HSMC_D,
oHSMC_I2C_SCLK,
HSMC_I2C_SDAT,
HSMC_RX_D_N,
HSMC_RX_D_P,
HSMC_TX_D_N,
HSMC_TX_D_P, /////////I2C/////////
oI2C_SCLK,
I2C_SDAT, /////////IRDA/////////
iIRDA_RXD, /////////KEY/////////
iKEY, /////////LCD/////////
LCD_DATA,
oLCD_EN,
oLCD_ON,
oLCD_RS,
oLCD_RW, /////////LEDG/////////
oLEDG, /////////LEDR/////////
oLEDR, /////////PCIE/////////
`ifdef ENABLE_PCIE iPCIE_PERST_N,
iPCIE_REFCLK_P,
iPCIE_RX_P,
oPCIE_TX_P,
oPCIE_WAKE_N,
`endif
/////////SD/////////
oSD_CLK,
SD_CMD,
SD_DAT,
iSD_WP_N, /////////SMA/////////
iSMA_CLKIN,
oSMA_CLKOUT, /////////SSRAM/////////
oSSRAM_ADSC_N,
oSSRAM_ADSP_N,
oSSRAM_ADV_N,
oSSRAM_BE,
oSSRAM_CLK,
oSSRAM_GW_N,
oSSRAM_OE_N,
oSSRAM_WE_N,
oSSRAM0_CE_N,
oSSRAM1_CE_N,
/////////SW/////////
iSW, /////////TD/////////
iTD_CLK27,
iTD_DATA,
iTD_HS,
oTD_RESET_N,
iTD_VS, /////////UART/////////
iUART_CTS,
oUART_RTS,
iUART_RXD,
oUART_TXD, /////////VGA/////////
oVGA_B,
oVGA_BLANK_N,
oVGA_CLK,
oVGA_G,
oVGA_HS,
oVGA_R,
oVGA_SYNC_N,
oVGA_VS,
); //=======================================================
// PORT declarations
//======================================================= ///////////CLOCK2///////////// input iCLOCK2_50; ///////// CLOCK3 /////////
input iCLOCK3_50; ///////// CLOCK /////////
input iCLOCK_50; ///////// DRAM /////////
output [:] oDRAM_ADDR;
output [:] oDRAM_BA;
output oDRAM_CAS_N;
output oDRAM_CKE;
output oDRAM_CLK;
output oDRAM_CS_N;
inout [:] DRAM_DQ;
output [:] oDRAM_DQM;
output oDRAM_RAS_N;
output oDRAM_WE_N; ///////// EEP /////////
output oEEP_I2C_SCLK;
inout EEP_I2C_SDAT; ///////// ENET /////////
output oENET_GTX_CLK;
input iENET_INT_N;
input iENET_LINK100;
output oENET_MDC;
inout ENET_MDIO;
output oENET_RST_N;
input iENET_RX_CLK;
input iENET_RX_COL;
input iENET_RX_CRS;
input [:] iENET_RX_DATA;
input iENET_RX_DV;
input iENET_RX_ER;
input iENET_TX_CLK;
output [:] oENET_TX_DATA;
output oENET_TX_EN;
output oENET_TX_ER; ///////// FAN /////////
inout FAN_CTRL; ///////// FL /////////
output oFL_CE_N;
output oFL_OE_N;
input iFL_RY;
output oFL_WE_N;
output oFL_WP_N;
output oFL_RESET_N;
///////// FS /////////
inout [:] FS_DQ;
output [:] oFS_ADDR;
///////// GPIO /////////
inout [:] GPIO; ///////// G /////////
input iG_SENSOR_INT1;
output oG_SENSOR_SCLK;
inout G_SENSOR_SDAT; ///////// HEX /////////
output [:] oHEX0;
output [:] oHEX1;
output [:] oHEX2;
output [:] oHEX3;
output [:] oHEX4;
output [:] oHEX5;
output [:] oHEX6;
output [:] oHEX7; ///////// HSMC /////////
input iHSMC_CLKIN0;
input iHSMC_CLKIN_N1;
input iHSMC_CLKIN_N2;
input iHSMC_CLKIN_P1;
input iHSMC_CLKIN_P2;
output oHSMC_CLKOUT0;
inout HSMC_CLKOUT_N1;
inout HSMC_CLKOUT_N2;
inout HSMC_CLKOUT_P1;
inout HSMC_CLKOUT_P2;
inout [:] HSMC_D;
output oHSMC_I2C_SCLK;
inout HSMC_I2C_SDAT;
inout [:] HSMC_RX_D_N;
inout [:] HSMC_RX_D_P;
inout [:] HSMC_TX_D_N;
inout [:] HSMC_TX_D_P; ///////// I2C /////////
output oI2C_SCLK;
inout I2C_SDAT; ///////// IRDA /////////
input iIRDA_RXD; ///////// KEY /////////
input [:] iKEY; ///////// LCD /////////
inout [:] LCD_DATA;
output oLCD_EN;
output oLCD_ON;
output oLCD_RS;
output oLCD_RW; ///////// LEDG /////////
output [:] oLEDG; ///////// LEDR /////////
output [:] oLEDR; ///////// PCIE /////////
`ifdef ENABLE_PCIE
input iPCIE_PERST_N;
input iPCIE_REFCLK_P;
input [:] iPCIE_RX_P;
output [:] oPCIE_TX_P;
output oPCIE_WAKE_N;
`endif
///////// SD /////////
output oSD_CLK;
inout SD_CMD;
inout [:] SD_DAT;
input iSD_WP_N; ///////// SMA /////////
input iSMA_CLKIN;
output oSMA_CLKOUT; ///////// SSRAM /////////
output oSSRAM_ADSC_N;
output oSSRAM_ADSP_N;
output oSSRAM_ADV_N;
output [:] oSSRAM_BE;
output oSSRAM_CLK;
output oSSRAM_GW_N;
output oSSRAM_OE_N;
output oSSRAM_WE_N;
output oSSRAM0_CE_N;
output oSSRAM1_CE_N; ///////// SW /////////
input [:] iSW; ///////// TD /////////
input iTD_CLK27;
input [:] iTD_DATA;
input iTD_HS;
output oTD_RESET_N;
input iTD_VS; ///////// UART /////////
input iUART_CTS;
output oUART_RTS;
input iUART_RXD;
output oUART_TXD; ///////// VGA /////////
output [:] oVGA_B;
output oVGA_BLANK_N;
output oVGA_CLK;
output [:] oVGA_G;
output oVGA_HS;
output [:] oVGA_R;
output oVGA_SYNC_N;
output oVGA_VS; //=======================================================
// REG/WIRE declarations
//======================================================= wire [:] hexbus;
wire [:] inbus; //=======================================================
// Structural coding
//======================================================= pcihellocore u0 (
.clk_clk(iCLOCK_50),
.reset_reset_n(iKEY[]),
.pcie_ip_rx_in_rx_datain_0 (iPCIE_RX_P[]), // pcie_hard_ip_0_rx_in.rx_datain_0
.pcie_ip_rx_in_rx_datain_1 (iPCIE_RX_P[]),
.pcie_ip_tx_out_tx_dataout_0 (oPCIE_TX_P[]), // pcie_hard_ip_0_tx_out.tx_dataout_0
.pcie_ip_tx_out_tx_dataout_1 (oPCIE_TX_P[]),
// .pcie_hard_ip_0_powerdown_pll_powerdown (oPCIE_WAKE_N), // pcie_hard_ip_0_powerdown.pll_powerdown
// .pcie_hard_ip_0_powerdown_gxb_powerdown (oPCIE_WAKE_N), // .gxb_powerdown
.pcie_ip_refclk_export (iPCIE_REFCLK_P), // pcie_hard_ip_0_refclk.export
.pcie_ip_pcie_rstn_export (iPCIE_PERST_N),
// .hexport_external_connection_export (hexbus), // hexport_external_connection.export
// .inport_external_connection_export (inbus), // inport_external_connection.export
.led_external_connection_export(oLEDG),
.button_external_connection_export(iKEY)
); assign oPCIE_WAKE_N = 'b1; // for ubuntu poweroff instruction using, if set to 0, the poweroff cant be used //////////// FAN Control //////////
//assign FAN_CTRL = 1'b1; // turn on FAN
//iSW close the 7-segment led, add by 2013/10/10
assign oHEX0 = (iSW[])? hexbus[ : ] : 'h7f;
assign oHEX1 = (iSW[])? hexbus[: ] : 'h7f;
assign oHEX2 = (iSW[])? hexbus[:] : 'h7f;
assign oHEX3 = (iSW[])? hexbus[:] : 'h7f;
assign oHEX4 = (iSW[])? hexbus[ : ] : 'h7f;
assign oHEX5 = (iSW[])? hexbus[: ] : 'h7f;
assign oHEX6 = (iSW[])? hexbus[:] : 'h7f;
assign oHEX7 = (iSW[])? hexbus[:] : 'h7f; assign inbus = iSW[:]; // Fan Control,
wire [:] wDuty;
assign wDuty = (iSW[:]=='b000) ? 8'd0 :
(iSW[:]=='b001) ? 8'd10 :
(iSW[:]=='b010) ? 8'd20 :
(iSW[:]=='b011) ? 8'd30 :
(iSW[:]=='b100) ? 8'd40 :
(iSW[:]=='b101) ? 8'd50 :
(iSW[:]=='b110) ? 8'd60 : 'd100 ;
pwmgen pwm(
.iClk50M(iCLOCK_50), // 50Mhz clock
.iRst_n('b1), // reset, low active
.iDuty(wDuty), // Range is 0~100
.oPWM(FAN_CTRL),
// .oSampClk,
// .oErrorValue
); wire hb_50;
heart_beat heart_beat_clk50(
.clk(iCLOCK_50),
.led(oLEDR[])
); endmodule
程式碼說明:
Line 384~399是Qsys模組的腳位連接。因為是選用PCIe Gen1 x2所以會用到兩個PCIe訊號。
Line 428~435是風扇控制程式,由於風扇太吵了,所以寫了一個PWM程式用SW[17:15]來控制風扇轉速。
=================================================================
以下來介紹Qsys系統的設定。
Fig.1 Qsys系統圖
其中pcie_ip模組的設定如Fig.2所示。
Fig.2 PCIe_ip模組設定
SGDMA模組設定如下:
Fig.3 SGDMA設定
接下來是Nios設定
Fig.4 Nios設定
LED模組設定
Fig.5 LED模組
Button模組設定:
Fig. 6 Button模組設定
FIFO_memory模組設定:
Fig.7 FIFO_memory模組設定
Onchip_memory模組設定:
Fig. 8 On_Chip Memory模組設定
設定完成後就可以按下generate產生Qsys系統。
Fig.9 Generate Qsys
經由以上設定後,Quartus硬體也都設定完成。
接下來就可以用Quartus 編譯 de2i_pci_top專案了。
等編譯完成後,按照下面步驟執行。
Step 1: 下載 de2i_pci_top.sof 檔至DE2i-150 的FPGA晶片內。
Step 2: 安裝PCIe_DriverInstall目錄下的驅動程式。(如果之前有裝過,就可以跳過)
Step 3: windwos重新開機,讓作業系統重新抓PCIe的新硬體。
Step 4: 執行專案目錄下的\windows_app_bcb6\output\app.exe
就可以按[0]控制LED,[1]讀取按鈕。
但是按[2]和[3]就會出現錯誤,這是由於FIFO跟onchip_memory內沒有資料,因此需要事先把FIFO與onchip_memory的初始檔放到
.\pcihellocore\synthesis\submodules 目錄下,本人已經把檔案放在附件的code中,有需要的人就去下載吧。
再重新編譯Qsys和Quartus專案後,執行步驟Step1~step4後就可以順利執行[2]和[3]功能了。
==================================================================================
以上是整個PCIe_Fundmental範例硬體檔的設定部分,下次再來研究講解VC程式部分,PC如何跟FPGA用PCIe做溝通。
附件下載URL: http://files.cnblogs.com/files/lishyhan/PCIe_Fundmental.zip