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

📄 pci_arb.tf

📁 VHDLVERILOG语言实现的CARDBUS的IP源码,已经实现现场应用
💻 TF
字号:
//------------------------------------------------------------------------------
//
// File : pci_arb.tf
// Last Modification: 06/26/2001
//
// Created In SpDE Version: SpDE 8.22
// Author :	Richard Yuan, QuickLogic Corporation
// Copyright (C) 2001, Licensed customers of QuickLogic may copy and modify
// this file for use in designing with QuickLogic devices only.
//	
// Description :
//	This is a PCI arbiter model.
//	Please see "The QL5064 PCI Bus Simulation Environment" for detailed informaiton.
//
// Hierarchy:
//	This file is to be included by pci5(3/4)32_208.tf.
//
// History:	
//	Date	        Author					Version
//  06/26/01		Richard Yuan			1.0
//		- Header reorganized to conform to coding standard.
//
//------------------------------------------------------------------------------


module pci_arbiter(pci_clk,request_n,grant_n,busy,reset_n);

parameter PCI_MASTER_DEVICES = 1; //The number of pci master devices attached to the bus

input pci_clk;
inout [PCI_MASTER_DEVICES-1:0] request_n;
output [PCI_MASTER_DEVICES-1:0] grant_n;
input busy;
input reset_n;

reg [1:0] ARBITRATION_STYLE; //See below
reg [31:0] TIMESLICE_LENGTH; //Number of pci_clk cycles granted to each device in round robin
reg [31:0] timeslice;
//00 = Give grant until it is no longer requested, then go to next device in round robin fashion
//01 = Give grant until device does first access, then remove and give to next device in round robin fashion
//10 = Give grant for a fixed timeslice, then give to next in round robin fashion (classic round robin)
//11 = Unused

wire [PCI_MASTER_DEVICES-1:0] request_n;
wire [PCI_MASTER_DEVICES-1:0] grant_n;
wire busy;
wire reset_n;

wire reset;
assign reset = ~reset_n;

//pullup (request_n);

// grant to everyone on reset, just to try and break things
reg [PCI_MASTER_DEVICES-1:0] grant_reg;
assign grant_n[PCI_MASTER_DEVICES-1:0] = (reset) ? 'b0 : ~grant_reg[PCI_MASTER_DEVICES-1:0];

wire [PCI_MASTER_DEVICES-1:0] request;
assign request[PCI_MASTER_DEVICES-1:0] = (reset) ? 'bz : ~request_n[PCI_MASTER_DEVICES-1:0];

reg [15:0] grant_device; //who has the grant
integer search_device; 
reg idle;                //flags that the grant is in the process of changing
reg NEXT_DEVICE;         //flags that it is time to move to the next requesting device
reg done_access;         //flags that a new access will have completed when busy is deasserted
reg seen_idle;           //flags that idle state has been since since last grant change

initial begin
    //Set all grants to zero
    for (grant_device=0; grant_device<PCI_MASTER_DEVICES; grant_device=grant_device+1)
      grant_reg[grant_device] <= 0;
end

initial begin
    //Set Arbitration Style to default
    ARBITRATION_STYLE = 2'b00;
    //Set Timeslice to default
    TIMESLICE_LENGTH = 40;
    timeslice = 0;
    NEXT_DEVICE = 0;
    done_access = 0;
    seen_idle = 0;
end


always @(posedge pci_clk or posedge reset)
begin
  if (reset) begin
    //initialize the grant registers
    grant_device <= 0;
    idle <= 0;
    grant_reg <= 'b0 | 1'b1;
  end
  else begin
    if (idle) begin
        grant_reg[grant_device] <= 1'b1;
        idle = 1'b0;
    end
    else begin
      //Do Arbitration
      case (ARBITRATION_STYLE) 
          2'b00: begin
              if (!(request[grant_device])) begin 
                  //The device with the grant is not requesting it!
                  NEXT_DEVICE = 1;
              end
          end
          
          2'b01: begin
              if (!NEXT_DEVICE) begin
                  if (busy && seen_idle) begin
                      done_access = 1;
                  end
                  if (!busy) begin
                      if (seen_idle && done_access) begin
                          done_access = 0;
                          seen_idle = 0;
                          NEXT_DEVICE = 1;
                      end
                      else seen_idle = 1;
                  end
              end
          end

          2'b10: begin
              if (!NEXT_DEVICE) begin
                  if (timeslice == 0) begin
                      timeslice = TIMESLICE_LENGTH;
                      NEXT_DEVICE = 1;
                  end
                  else begin
                      timeslice = timeslice - 1;
                  end
              end
          end 

          2'b11: begin
              $display("ARBITER ERROR: ILLEGAL VALUE FOR ARBITRATION_STYLE: %0d, time %0t",
                        ARBITRATION_STYLE,$time);
			  $stop;
          end

          default: begin
              $display("ARBITER ERROR: ILLEGAL VALUE FOR ARBITRATION_STYLE: %0d, time %0t",
                        ARBITRATION_STYLE,$time);
			  $stop;
          end
      endcase

      //Give grant to the next requesting device
      if (NEXT_DEVICE) begin
        if (grant_device == (PCI_MASTER_DEVICES - 1)) begin
          search_device = 0;
        end
        else begin
          search_device = grant_device+1;  
        end
       
        //Search for a device that is requesting the grant.
        while (!(request[search_device]) && !(search_device == grant_device)) begin
          //Device with grant is not requesting it- if someone else is requesting, give them the grant
          if (search_device == (PCI_MASTER_DEVICES - 1)) begin
            search_device = 0;
          end
          else begin
            search_device = search_device + 1;
          end
        end
        //$display("ARBITER: Granting Next Device: current device: %d, new device: %d, req:%x, time %0t",
        //          grant_device,search_device,request_n,$time);
        if (search_device == grant_device) begin end
        else begin
          NEXT_DEVICE = 0;
          //Give the Requesting Device the Grant
          grant_reg[grant_device] <= 1'b0;  //Remove the grant from the current device
          grant_device <= search_device;  //Select the new device
          if (busy) begin
            grant_reg[search_device] <= 1'b1;  //If bus is busy, immediately give grant to new device
          end
          else begin
            idle <= 1'b1;             //else let an idle cycle pass before giving grant to new device
          end
        end
      end
    end
  end
end

endmodule //pci_arbiter

⌨️ 快捷键说明

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