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