在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 23731|回复: 94

斑竹编写的PCI Slave 源代码

[复制链接]
发表于 2003-8-4 10:11:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
[这个贴子最后由jackzhang在 2004/01/03 09:01pm 第 4 次编辑]

这是斑竹编写的用于cpld的PCI Slave 源代码(包括pci slave和一个8位的测试寄存器),可以装到 Xilinx XC9572XL,XC95144XL .. Altera 的 7128(也有可能装入7064)等cpld之中。可以算得上是最小的pci core了吧。
该pci core只被仿真验证过,但没有做成板卡测试,因此希望大家仅仅作为参考。
[fly]有效期限1月4日~2月4日[/fly]
(代码版权归亿涛工作室所有,未经同意任何人不得转载!)
[post=30]
/***********************************************************************
Little PCI Core

***********************************************************************/
`define  VID   16'H1234
`define  DID   16'HABCD

module pci (
// PCI ports -- do not modify names!
                AD,
                CBE,
           //     PAR,
                FRAME_N,
                TRDY_N,
                IRDY_N,
                STOP_N,
                DEVSEL_N,
                IDSEL,
                RST_N,
                PCLK,
                INTR_N,     //PCI Interrupt output Low level active
            //LOCAL Signals
                RD_EN,
        WR_EN,
                ADDR,
                P_L_DA,
                L_P_DA,
                INT      //local Interrupt, high level active
                );

inout[31:0]AD;
input   [3:0]CBE; //inout   [3:0] CBE;
input        FRAME_N; //inout        FRAME_N;
output        TRDY_N;
inputIRDY_N;
output        STOP_N;
output         DEVSEL_N;
input         IDSEL;
input         RST_N;
input         PCLK;
output         INTR_N;

output         RD_EN;
output        WR_EN;
output [4:0]   ADDR;
input  [31:0]  L_P_DA;
output [31:0]  P_L_DA;
input          INT;

`define state parameter  
`state    S_IDLE_S = 2'B00;
`state    S_BUSY_S = 2'B01;
`state    S_DATA_S = 2'B10;
`state    S_STOP_S = 2'B11;

reg  [1:0]    current_state,next_state;
reg           CFG_EN;       //CFG_EN = 1 : PCI config read/write, CFG_EN = 0: PCI Mem Read/Write
reg           S_DATA_REG;
reg           HIT;
reg           S_RD,S_WR;
reg [11:0]    BAR0_REG;     //{BAR0_REG,20'h00}: 1M PCI MEM Space,last 20 bit is hardware as 0
reg  [4:0]    ADDR;
reg           S_DATA;
reg [31:0]    AD_D;
wire          TRDY,STOP;
//State Machine
always @(posedge PCLK or negedge RST_N)
begin
if (~RST_N) current_state <= 2'b0;
else  current_state <= next_state;
end
always @(FRAME_N or TRDY_N or IRDY_N or current_state)
begin
   next_state = current_state;
       case (current_state)
       S_IDLE_S: if (!FRAME_N & !HIT) next_state = S_BUSY_S;
       S_BUSY_S: begin
                 if (FRAME_N & !HIT) next_state = S_IDLE_S;
                 else if ((!FRAME_N || !IRDY_N) & HIT) next_state = S_DATA_S;
                 end
       S_DATA_S: if (FRAME_N & !TRDY) next_state = S_IDLE_S;
             else if (~STOP) next_state = S_STOP_S;
       S_STOP_S: if (FRAME_N) next_state = S_IDLE_S;
        default: next_state = S_IDLE_S;
       endcase
end

//address compare with BAR0
wire #1 AD_EQ = (AD[31:20] == BAR0_REG);   //BAR0 Support 1M MEM Space (but littlr PCI CORE only support
                                            //                            5bit (32byte) Mem Space)
always @(posedge PCLK or negedge RST_N)
begin
      if (~RST_N) begin
                 S_WR <= 1'B0;
                 S_RD <= 1'B0;
                 CFG_EN <= 1'B0;
                 HIT <= 1'B0;  //BASE HIT, CFG HIT
                 ADDR <= 5'H0;
                 end
      else if (!FRAME_N && (current_state == S_IDLE_S)) begin
           ADDR <= AD[4:0];        //littlr PCI CORE only support 5bit (32byte) Mem Space
               casex ({CBE,IDSEL})
               5'B0110X: begin
S_WR <= 1'B0;  
S_RD <= 1'B1;  //PCI MEM Read
                         CFG_EN <= 1'B0;
if (AD_EQ) begin
    HIT <= 1'B1;
   end
end
               5'B0111X: begin
                         CFG_EN <= 1'B0;
                         S_WR <= 1'B1;  //PCI MEM Write
         S_RD <= 1'B0;
if (AD_EQ) HIT <= 1'B1;
end
               5'B10101: begin
                         CFG_EN <= 1'B1;
S_RD <= 1'B1;    //PCI CFG Read
S_WR <= 1'B0;
HIT <= 1'B1;
end
               5'B10111: begin
                         CFG_EN <= 1'B1;
S_RD <= 1'B0;    //PCI CFG Write
S_WR <= 1'B1;
HIT <= 1'B1;
end
                default: begin
S_WR <= 1'B0;
S_RD <= 1'B0;
HIT <= 1'B0;
end
endcase
end
  else if (current_state == S_BUSY_S)
                         HIT <= 1'B0;
end  

//S_DATA: is register output, in order to mach CLK to PAD delay <7.8ns
always @(posedge PCLK or negedge RST_N)
begin
      if (~RST_N) S_DATA <= 1'B0;
      else S_DATA <= (next_state == S_DATA_S);
end
always @(posedge PCLK or negedge RST_N)
begin
      if (~RST_N) S_DATA_REG <= 1'B0;
      else S_DATA_REG <= S_DATA;
end
//TAR_DLY: delete 1 clock
wire #1 TAR_DLY = S_DATA_REG;
//Address Decode
wire #1 ad_00 = (ADDR == 5'h00);
wire #1 ad_10 = (ADDR == 5'h10);
wire #1 we_en = S_DATA & S_WR;
wire #1 rd_en = S_DATA & S_RD;
wire S_TERM = 1'B0;
wire S_READY = 1'B1;

wire #1 RD_WR = S_DATA & (S_WR || (S_RD & TAR_DLY));
//assign #1 TRDY = !(RD_WR & (CFG_EN || S_READY));
assign #1 TRDY = ~RD_WR;  //a optimize , add at 15/01/2002
//assign #1 STOP = ~(RD_WR & (CFG_EN || S_TERM));//1'B1;
assign #1 STOP = ~(RD_WR & CFG_EN);//a optimize , add at 15/01/2002
wire #1 OE = S_DATA || TAR_DLY;
wire #1 DEVSEL = ~S_DATA;
assign TRDY_N = OE ? TRDY : 1'BZ;       //tri gate output: is more slower
assign STOP_N = OE ? STOP : 1'BZ;
assign DEVSEL_N = OE ? DEVSEL : 1'BZ;
//CFG
//CFG Address Decode
wire #1 RD_ID   = rd_en &  CFG_EN & TAR_DLY & ad_00;//(ADDR == 5'h00);
wire #1 RD_BAR0 = rd_en &  CFG_EN & TAR_DLY & ad_10;//(ADDR == 5'h10);
wire #1 WE_BAR0 = we_en &  CFG_EN & ad_10;//(ADDR == 5'h10);
//CFG Write : BAR0
always @(posedge PCLK or negedge RST_N)
begin
      if (~RST_N) BAR0_REG <= 12'B0;
  else if (WE_BAR0) BAR0_REG <= AD[31:20];//ADIO[31:20];
end

wire #1 WR_EN = we_en &  ~CFG_EN ;
wire #1 RD_EN = rd_en &  ~CFG_EN & TAR_DLY ;
      
//PCI read data
always @(RD_ID or RD_BAR0 or RD_EN)
begin
       case ({RD_ID,RD_BAR0,RD_EN})
       3'b001: AD_D[31:0] = L_P_DA;          //Read Data from local
       3'B010: AD_D = {BAR0_REG,20'h0};      //Config Read BAR0
       3'B100: AD_D = {`DID,`VID};           //Config Read VID DID
       default:AD_D = 32'B00;
       endcase
end   
      
assign AD = rd_en ? AD_D : 32'BZZ;   
assign P_L_DA = AD;
//PCI Interrupt Output
assign INTR_N = INT ? 1'B0 : 1'BZ;   //Tri gate output, need outside pullup res
endmodule
[/post]






[fly]有效期限1月4日~2月4日[/fly]
发表于 2003-8-4 15:45:10 | 显示全部楼层

斑竹编写的PCI Slave 源代码

可以公开不,我是新手,看不到文件,但是我很想现在要,可以给我发一份不?老肖我先谢了
发表于 2003-8-4 15:46:21 | 显示全部楼层

斑竹编写的PCI Slave 源代码

我的信箱是:esunnydayy@yahoo.com.cn
 楼主| 发表于 2003-8-4 15:50:17 | 显示全部楼层

斑竹编写的PCI Slave 源代码

大家只要发贴数达到30篇既可以看到了。
发表于 2003-8-4 15:51:49 | 显示全部楼层

斑竹编写的PCI Slave 源代码

努力吧!
发表于 2003-8-5 12:05:25 | 显示全部楼层

斑竹编写的PCI Slave 源代码

非常感谢坛主。
回去好好研究。
发表于 2003-8-5 14:07:14 | 显示全部楼层

斑竹编写的PCI Slave 源代码

晕哦,我现在看不到啊,55555555555
发表于 2003-8-5 14:22:54 | 显示全部楼层

斑竹编写的PCI Slave 源代码

我也努力一下
发表于 2003-8-5 14:56:33 | 显示全部楼层

斑竹编写的PCI Slave 源代码

努力,为了看到版主的代码
发表于 2003-8-5 15:22:39 | 显示全部楼层

斑竹编写的PCI Slave 源代码

55555555555555555555555555!!!
看不见啊!
哎!何时能发到30片啊!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /3 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-18 23:13 , Processed in 0.031601 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表