//===========================================================================
|
//===========================================================================
|
// $Id: pci_behaviorial_target.v,v 1.1 2002-02-01 15:07:51 mihad Exp $
|
// $Id: pci_behaviorial_target.v,v 1.2 2002-02-19 16:32:29 mihad Exp $
|
//
|
//
|
// Copyright 2001 Blue Beaver. All Rights Reserved.
|
// Copyright 2001 Blue Beaver. All Rights Reserved.
|
//
|
//
|
// Summary: A PCI Behaviorial Target. This module receives commands over
|
// Summary: A PCI Behaviorial Target. This module receives commands over
|
// the PCI Bus. The PCI Master encodes commands in the middle
|
// the PCI Bus. The PCI Master encodes commands in the middle
|
// 16 bits of the PCI Address. This Target contains Config
|
// 16 bits of the PCI Address. This Target contains Config
|
// registers and a 256 byte scratch SRAM. It responds with data
|
// registers and a 256 byte scratch SRAM. It responds with data
|
// when it is given a Read command, and checks data when it is
|
// when it is given a Read command, and checks data when it is
|
// given a Write command.
|
// given a Write command.
|
// This interface does implement a very simple Delayed Read
|
// This interface does implement a very simple Delayed Read
|
// facility which is enough to let the user manually make the
|
// facility which is enough to let the user manually make the
|
// PCI Bus look like a Delayed Read is begin done. This will
|
// PCI Bus look like a Delayed Read is begin done. This will
|
// probably not work when a synthesizable PCI Interface tries
|
// probably not work when a synthesizable PCI Interface tries
|
// to cause Delayed Reads. But by then, a second synthesizable
|
// to cause Delayed Reads. But by then, a second synthesizable
|
// PCI Core will be the more useful test target.
|
// PCI Core will be the more useful test target.
|
//
|
//
|
// This library is free software; you can distribute it and/or modify it
|
// This library is free software; you can distribute it and/or modify it
|
// under the terms of the GNU Lesser General Public License as published
|
// under the terms of the GNU Lesser General Public License as published
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
// (at your option) any later version.
|
// (at your option) any later version.
|
//
|
//
|
// This library is distributed in the hope that it will be useful, but
|
// This library is distributed in the hope that it will be useful, but
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
// See the GNU Lesser General Public License for more details.
|
// See the GNU Lesser General Public License for more details.
|
//
|
//
|
// You should have received a copy of the GNU Lesser General Public License
|
// You should have received a copy of the GNU Lesser General Public License
|
// along with this library. If not, write to
|
// along with this library. If not, write to
|
// Free Software Foundation, Inc.
|
// Free Software Foundation, Inc.
|
// 59 Temple Place, Suite 330
|
// 59 Temple Place, Suite 330
|
// Boston, MA 02111-1307 USA
|
// Boston, MA 02111-1307 USA
|
//
|
//
|
// Author's note about this license: The intention of the Author and of
|
// Author's note about this license: The intention of the Author and of
|
// the Gnu Lesser General Public License is that users should be able to
|
// the Gnu Lesser General Public License is that users should be able to
|
// use this code for any purpose, including combining it with other source
|
// use this code for any purpose, including combining it with other source
|
// code, combining it with other logic, translated it into a gate-level
|
// code, combining it with other logic, translated it into a gate-level
|
// representation, or projected it into gates in a programmable or
|
// representation, or projected it into gates in a programmable or
|
// hardwired chip, as long as the users of the resulting source, compiled
|
// hardwired chip, as long as the users of the resulting source, compiled
|
// source, or chip are given the means to get a copy of this source code
|
// source, or chip are given the means to get a copy of this source code
|
// with no new restrictions on redistribution of this source.
|
// with no new restrictions on redistribution of this source.
|
//
|
//
|
// If you make changes, even substantial changes, to this code, or use
|
// If you make changes, even substantial changes, to this code, or use
|
// substantial parts of this code as an inseparable part of another work
|
// substantial parts of this code as an inseparable part of another work
|
// of authorship, the users of the resulting IP must be given the means
|
// of authorship, the users of the resulting IP must be given the means
|
// to get a copy of the modified or combined source code, with no new
|
// to get a copy of the modified or combined source code, with no new
|
// restrictions on redistribution of the resulting source.
|
// restrictions on redistribution of the resulting source.
|
//
|
//
|
// Separate parts of the combined source code, compiled code, or chip,
|
// Separate parts of the combined source code, compiled code, or chip,
|
// which are NOT derived from this source code do NOT need to be offered
|
// which are NOT derived from this source code do NOT need to be offered
|
// to the final user of the chip merely because they are used in
|
// to the final user of the chip merely because they are used in
|
// combination with this code. Other code is not forced to fall under
|
// combination with this code. Other code is not forced to fall under
|
// the GNU Lesser General Public License when it is linked to this code.
|
// the GNU Lesser General Public License when it is linked to this code.
|
// The license terms of other source code linked to this code might require
|
// The license terms of other source code linked to this code might require
|
// that it NOT be made available to users. The GNU Lesser General Public
|
// that it NOT be made available to users. The GNU Lesser General Public
|
// License does not prevent this code from being used in such a situation,
|
// License does not prevent this code from being used in such a situation,
|
// as long as the user of the resulting IP is given the means to get a
|
// as long as the user of the resulting IP is given the means to get a
|
// copy of this component of the IP with no new restrictions on
|
// copy of this component of the IP with no new restrictions on
|
// redistribution of this source.
|
// redistribution of this source.
|
//
|
//
|
// This code was developed using VeriLogger Pro, by Synapticad.
|
// This code was developed using VeriLogger Pro, by Synapticad.
|
// Their support is greatly appreciated.
|
// Their support is greatly appreciated.
|
//
|
//
|
// NOTE: This Test Chip instantiates one PCI interface and connects it
|
// NOTE: This Test Chip instantiates one PCI interface and connects it
|
// to its IO pads and to logic representing a real application.
|
// to its IO pads and to logic representing a real application.
|
//
|
//
|
// NOTE TODO: Horrible. Tasks can't depend on their Arguments being safe
|
// NOTE TODO: Horrible. Tasks can't depend on their Arguments being safe
|
// if there are several instances ofthe tasl running at once.
|
// if there are several instances ofthe tasl running at once.
|
// NOTE TODO: need to check parity on writes, and report if error status wrong
|
// NOTE TODO: need to check parity on writes, and report if error status wrong
|
// NOTE TODO: need to drive PERR and SERR lines
|
// NOTE TODO: need to drive PERR and SERR lines
|
// NOTE TODO: need to start setting error bits in Config Register
|
// NOTE TODO: need to start setting error bits in Config Register
|
// Need to detect Address Parity Errors, and report them 3.7.3
|
// Need to detect Address Parity Errors, and report them 3.7.3
|
// Need to allow bad parity address decodes if Parity Error Response not set 3.7.3
|
// Need to allow bad parity address decodes if Parity Error Response not set 3.7.3
|
// Need to act on Delayed Read commands
|
// Need to act on Delayed Read commands
|
// Need to do retries on other READ commands when delayed read in progress
|
// Need to do retries on other READ commands when delayed read in progress
|
// Need to clear delayed read in progress bit when Config Register says to
|
// Need to clear delayed read in progress bit when Config Register says to
|
// Need to consider holding PERR if asserted without regards to TRDY and IRDY
|
// Need to consider holding PERR if asserted without regards to TRDY and IRDY
|
// See 3.7.4.1 for details. If done as now, no need to hold.
|
// See 3.7.4.1 for details. If done as now, no need to hold.
|
// Need to assert SERR on address parity errors 3.7.4.2
|
// Need to assert SERR on address parity errors 3.7.4.2
|
// Need to record errors. 3.7.4.3, 3.7.4.4
|
// Need to record errors. 3.7.4.3, 3.7.4.4
|
// Complain if address parity error not seen when expected
|
// Complain if address parity error not seen when expected
|
// Complain if data parity error not seen when expected
|
// Complain if data parity error not seen when expected
|
//
|
//
|
//===========================================================================
|
//===========================================================================
|
|
|
`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
|
|
module pci_behaviorial_target (
|
module pci_behaviorial_target (
|
ad_now, ad_prev, target_ad_out, target_ad_oe,
|
ad_now, ad_prev, target_ad_out, target_ad_oe,
|
cbe_l_now, cbe_l_prev, calc_input_parity_prev, par_now, par_prev,
|
cbe_l_now, cbe_l_prev, calc_input_parity_prev, par_now, par_prev,
|
frame_now, frame_prev, irdy_now, irdy_prev,
|
frame_now, frame_prev, irdy_now, irdy_prev,
|
target_devsel_out, target_d_t_s_oe, target_trdy_out, target_stop_out,
|
target_devsel_out, target_d_t_s_oe, target_trdy_out, target_stop_out,
|
target_perr_out, target_perr_oe, target_serr_oe,
|
target_perr_out, target_perr_oe, target_serr_oe,
|
idsel_now, idsel_prev,
|
idsel_now, idsel_prev,
|
pci_reset_comb, pci_ext_clk,
|
pci_reset_comb, pci_ext_clk,
|
// Signals from the master to the target to set bits in the Status Register
|
// Signals from the master to the target to set bits in the Status Register
|
master_got_parity_error, master_asserted_serr, master_got_master_abort,
|
master_got_parity_error, master_asserted_serr, master_got_master_abort,
|
master_got_target_abort, master_caused_parity_error,
|
master_got_target_abort, master_caused_parity_error,
|
master_enable, master_fast_b2b_en, master_perr_enable, master_serr_enable,
|
master_enable, master_fast_b2b_en, master_perr_enable, master_serr_enable,
|
master_latency_value,
|
master_latency_value,
|
// Signals used by the test bench instead of using "." notation
|
// Signals used by the test bench instead of using "." notation
|
target_debug_force_bad_par,
|
target_debug_force_bad_par,
|
test_error_event, test_device_id,
|
test_error_event, test_device_id,
|
test_response
|
test_response
|
);
|
);
|
|
|
`include "pci_blue_options.vh"
|
`include "pci_blue_options.vh"
|
`include "pci_blue_constants.vh"
|
`include "pci_blue_constants.vh"
|
|
|
input [PCI_BUS_DATA_RANGE:0] ad_now;
|
input [PCI_BUS_DATA_RANGE:0] ad_now;
|
input [PCI_BUS_DATA_RANGE:0] ad_prev;
|
input [PCI_BUS_DATA_RANGE:0] ad_prev;
|
output [PCI_BUS_DATA_RANGE:0] target_ad_out;
|
output [PCI_BUS_DATA_RANGE:0] target_ad_out;
|
output target_ad_oe;
|
output target_ad_oe;
|
input [PCI_BUS_CBE_RANGE:0] cbe_l_now;
|
input [PCI_BUS_CBE_RANGE:0] cbe_l_now;
|
input [PCI_BUS_CBE_RANGE:0] cbe_l_prev;
|
input [PCI_BUS_CBE_RANGE:0] cbe_l_prev;
|
input calc_input_parity_prev;
|
input calc_input_parity_prev;
|
input par_now, par_prev;
|
input par_now, par_prev;
|
input frame_now, frame_prev, irdy_now, irdy_prev;
|
input frame_now, frame_prev, irdy_now, irdy_prev;
|
output target_devsel_out, target_d_t_s_oe, target_trdy_out, target_stop_out;
|
output target_devsel_out, target_d_t_s_oe, target_trdy_out, target_stop_out;
|
output target_perr_out, target_perr_oe, target_serr_oe;
|
output target_perr_out, target_perr_oe, target_serr_oe;
|
input idsel_now, idsel_prev;
|
input idsel_now, idsel_prev;
|
input pci_reset_comb, pci_ext_clk;
|
input pci_reset_comb, pci_ext_clk;
|
// Signals from the master to the target to set bits in the Status Register
|
// Signals from the master to the target to set bits in the Status Register
|
input master_got_parity_error, master_asserted_serr, master_got_master_abort;
|
input master_got_parity_error, master_asserted_serr, master_got_master_abort;
|
input master_got_target_abort, master_caused_parity_error;
|
input master_got_target_abort, master_caused_parity_error;
|
output master_enable, master_fast_b2b_en, master_perr_enable, master_serr_enable;
|
output master_enable, master_fast_b2b_en, master_perr_enable, master_serr_enable;
|
output [7:0] master_latency_value;
|
output [7:0] master_latency_value;
|
// Signals used by the test bench instead of using "." notation
|
// Signals used by the test bench instead of using "." notation
|
output target_debug_force_bad_par;
|
output target_debug_force_bad_par;
|
output test_error_event;
|
output test_error_event;
|
input [2:0] test_device_id;
|
input [2:0] test_device_id;
|
input [25:0] test_response ;
|
input [25:0] test_response ;
|
|
|
reg [PCI_BUS_DATA_RANGE:0] target_ad_out;
|
reg [PCI_BUS_DATA_RANGE:0] target_ad_out;
|
reg target_ad_oe;
|
reg target_ad_oe;
|
reg target_devsel_out, target_trdy_out, target_stop_out;
|
reg target_devsel_out, target_trdy_out, target_stop_out;
|
wire target_d_t_s_oe, target_perr_oe;
|
wire target_d_t_s_oe, target_perr_oe;
|
reg target_perr_out, target_serr_oe;
|
reg target_perr_out, target_serr_oe;
|
reg target_debug_force_bad_par;
|
reg target_debug_force_bad_par;
|
reg test_error_event;
|
reg test_error_event;
|
|
|
// Make temporary Bip every time an error is detected
|
// Make temporary Bip every time an error is detected
|
initial test_error_event <= 1'bZ;
|
initial test_error_event <= 1'bZ;
|
reg error_detected;
|
reg error_detected;
|
initial error_detected <= 1'b0;
|
initial error_detected <= 1'b0;
|
always @(error_detected)
|
always @(error_detected)
|
begin
|
begin
|
test_error_event <= 1'b0;
|
test_error_event <= 1'b0;
|
#2;
|
#2;
|
test_error_event <= 1'bZ;
|
test_error_event <= 1'bZ;
|
end
|
end
|
|
|
// Target Interface:
|
// Target Interface:
|
// This will have just enough memory to make debugging exciting.
|
// This will have just enough memory to make debugging exciting.
|
// It will have 256 Bytes of SRAM. The memory will be available
|
// It will have 256 Bytes of SRAM. The memory will be available
|
// BOTH as Config memory and as regular memory.
|
// BOTH as Config memory and as regular memory.
|
// Special regions of the memory will have special characteristics.
|
// Special regions of the memory will have special characteristics.
|
// Locations 0, 4, 8, A, 10, and 14 will be implemented as Control
|
// Locations 0, 4, 8, A, 10, and 14 will be implemented as Control
|
// registers.
|
// registers.
|
// Locations 18 and 1C will be used for memory debugging (somehow!)
|
// Locations 18 and 1C will be used for memory debugging (somehow!)
|
// All other locations will act as simple memory.
|
// All other locations will act as simple memory.
|
|
|
// Config Register Area consists of:
|
// Config Register Area consists of:
|
// 31 24 23 16 15 8 7 0
|
// 31 24 23 16 15 8 7 0
|
// | Device ID | Vendor ID | 0x00
|
// | Device ID | Vendor ID | 0x00
|
// | Status | Command | 0x04
|
// | Status | Command | 0x04
|
// | Class Code | Rev | 0x08
|
// | Class Code | Rev | 0x08
|
// | BIST | HEAD | LTCY | CSize| 0x0A
|
// | BIST | HEAD | LTCY | CSize| 0x0A
|
// | Base Address 0 | 0x10
|
// | Base Address 0 | 0x10
|
// | Base Address 1 | 0x14
|
// | Base Address 1 | 0x14
|
// | Unused | 0x18
|
// | Unused | 0x18
|
// | Unused | 0x1C
|
// | Unused | 0x1C
|
// | Unused | 0x20
|
// | Unused | 0x20
|
// | Unused | 0x24
|
// | Unused | 0x24
|
// | Cardbus Pointer | 0x28
|
// | Cardbus Pointer | 0x28
|
// | SubSys ID | SubVnd ID | 0x2C
|
// | SubSys ID | SubVnd ID | 0x2C
|
// | Expansion ROM Pointer | 0x30
|
// | Expansion ROM Pointer | 0x30
|
// | Reserved | Cap | 0x34
|
// | Reserved | Cap | 0x34
|
// | Reserved | 0x38
|
// | Reserved | 0x38
|
// | MLat | MGnt | IPin | ILine| 0x3C
|
// | MLat | MGnt | IPin | ILine| 0x3C
|
//
|
//
|
// Command resets to 0 or maybe 0x80. It consists of:
|
// Command resets to 0 or maybe 0x80. It consists of:
|
// {6'h00, FB2B_En, SERR_En,
|
// {6'h00, FB2B_En, SERR_En,
|
// Step_En, Par_Err_En, VGA_En, Mem_Write_Inv_En,
|
// Step_En, Par_Err_En, VGA_En, Mem_Write_Inv_En,
|
// Special_En, Master_En, Target_En, IO_En}
|
// Special_En, Master_En, Target_En, IO_En}
|
//
|
//
|
// Status consists of:
|
// Status consists of:
|
// {Detected_Perr, Signaled_Serr, Got_Master_Abort, Got_Target_Abort,
|
// {Detected_Perr, Signaled_Serr, Got_Master_Abort, Got_Target_Abort,
|
// Signaled_Target_Abort, Devsel_Timing[1:0], Master_Got_Perr,
|
// Signaled_Target_Abort, Devsel_Timing[1:0], Master_Got_Perr,
|
// FB2B_Capable, 1'b0, 66MHz_Capable, New_Capabilities,
|
// FB2B_Capable, 1'b0, 66MHz_Capable, New_Capabilities,
|
// 4'h0}
|
// 4'h0}
|
//
|
//
|
// Got_Master_Abort is not set for Special Cycles.
|
// Got_Master_Abort is not set for Special Cycles.
|
// Devsel will be 2'h01 in this design. New_Capabilities is 1'b0.
|
// Devsel will be 2'h01 in this design. New_Capabilities is 1'b0.
|
// All clearable bits in this register are cleared whenever the
|
// All clearable bits in this register are cleared whenever the
|
// register is written with the corresponding bit being 1'b1.
|
// register is written with the corresponding bit being 1'b1.
|
// See the PCI Local Bus Spec Revision 2.2 section 6.2.3.
|
// See the PCI Local Bus Spec Revision 2.2 section 6.2.3.
|
|
|
reg FB2B_En, SERR_En, Par_Err_En, Master_En, Target_En;
|
reg FB2B_En, SERR_En, Par_Err_En, Master_En, Target_En;
|
reg Detected_PERR, Signaled_SERR, Received_Master_Abort, Received_Target_Abort;
|
reg Detected_PERR, Signaled_SERR, Received_Master_Abort, Received_Target_Abort;
|
reg Signaled_Target_Abort, Master_Caused_PERR;
|
reg Signaled_Target_Abort, Master_Caused_PERR;
|
reg [7:0] Latency_Timer;
|
reg [7:0] Latency_Timer;
|
reg [7:0] Cache_Line_Size;
|
reg [7:0] Cache_Line_Size;
|
reg [7:0] Interrupt_Line;
|
reg [7:0] Interrupt_Line;
|
reg [`PCI_BASE_ADDR0_MATCH_RANGE] BAR0; // Base Address Registers, used to match addresses
|
reg [`PCI_BASE_ADDR0_MATCH_RANGE] BAR0; // Base Address Registers, used to match addresses
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
reg [`PCI_BASE_ADDR1_MATCH_RANGE] BAR1;
|
reg [`PCI_BASE_ADDR1_MATCH_RANGE] BAR1;
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
|
|
wire [15:0] Target_Command =
|
wire [15:0] Target_Command =
|
{4'b0000,
|
{4'b0000,
|
2'b00, FB2B_En, SERR_En,
|
2'b00, FB2B_En, SERR_En,
|
1'b1, Par_Err_En, 2'b00,
|
1'b1, Par_Err_En, 2'b00,
|
1'b0, Master_En, Target_En, 1'b0};
|
1'b0, Master_En, Target_En, 1'b0};
|
`ifdef PCI_CLK_66
|
`ifdef PCI_CLK_66
|
wire [15:0] Target_Status =
|
wire [15:0] Target_Status =
|
{Detected_PERR, Signaled_SERR, Received_Master_Abort,
|
{Detected_PERR, Signaled_SERR, Received_Master_Abort,
|
Received_Target_Abort,
|
Received_Target_Abort,
|
Signaled_Target_Abort, 2'b01, Master_Caused_PERR,
|
Signaled_Target_Abort, 2'b01, Master_Caused_PERR,
|
1'b1, 1'b0, 1'b1, 1'b0,
|
1'b1, 1'b0, 1'b1, 1'b0,
|
4'b0000};
|
4'b0000};
|
`else // PCI_CLK_66
|
`else // PCI_CLK_66
|
wire [15:0] Target_Status =
|
wire [15:0] Target_Status =
|
{Detected_PERR, Signaled_SERR, Received_Master_Abort,
|
{Detected_PERR, Signaled_SERR, Received_Master_Abort,
|
Received_Target_Abort,
|
Received_Target_Abort,
|
Signaled_Target_Abort, 2'b01, Master_Caused_PERR,
|
Signaled_Target_Abort, 2'b01, Master_Caused_PERR,
|
1'b1, 1'b0, 1'b0, 1'b0,
|
1'b1, 1'b0, 1'b0, 1'b0,
|
4'b0000};
|
4'b0000};
|
`endif // PCI_CLK_66
|
`endif // PCI_CLK_66
|
|
|
assign master_enable = Master_En;
|
assign master_enable = Master_En;
|
assign master_fast_b2b_en = FB2B_En;
|
assign master_fast_b2b_en = FB2B_En;
|
assign master_perr_enable = Par_Err_En;
|
assign master_perr_enable = Par_Err_En;
|
assign master_serr_enable = SERR_En;
|
assign master_serr_enable = SERR_En;
|
assign master_latency_value[7:0] = Latency_Timer[7:0];
|
assign master_latency_value[7:0] = Latency_Timer[7:0];
|
|
|
task Read_Test_Device_Config_Regs;
|
task Read_Test_Device_Config_Regs;
|
input [7:2] reg_number;
|
input [7:2] reg_number;
|
output [PCI_BUS_DATA_RANGE:0] Read_Config_Reg;
|
output [PCI_BUS_DATA_RANGE:0] Read_Config_Reg;
|
begin // Addresses except 0, 4, 8, A, 10, 14, 3C all return 0x00
|
begin // Addresses except 0, 4, 8, A, 10, 14, 3C all return 0x00
|
case (reg_number[7:2])
|
case (reg_number[7:2])
|
6'h00: Read_Config_Reg = 32'h8000AAAA
|
6'h00: Read_Config_Reg = 32'h8000AAAA
|
| {13'h0000, test_device_id[2:0], 16'h0000};
|
| {13'h0000, test_device_id[2:0], 16'h0000};
|
6'h01: Read_Config_Reg = {Target_Status[15:0], Target_Command[15:0]};
|
6'h01: Read_Config_Reg = {Target_Status[15:0], Target_Command[15:0]};
|
6'h02: Read_Config_Reg = 32'hFF000000;
|
6'h02: Read_Config_Reg = 32'hFF000000;
|
6'h03: Read_Config_Reg = {16'h0000, Latency_Timer[7:0], Cache_Line_Size[7:0]};
|
6'h03: Read_Config_Reg = {16'h0000, Latency_Timer[7:0], Cache_Line_Size[7:0]};
|
6'h04: Read_Config_Reg = {BAR0[`PCI_BASE_ADDR0_MATCH_RANGE],
|
6'h04: Read_Config_Reg = {BAR0[`PCI_BASE_ADDR0_MATCH_RANGE],
|
`PCI_BASE_ADDR0_FILL, `PCI_BASE_ADDR0_MAP_QUAL};
|
`PCI_BASE_ADDR0_FILL, `PCI_BASE_ADDR0_MAP_QUAL};
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
6'h05: Read_Config_Reg = {BAR1[`PCI_BASE_ADDR1_MATCH_RANGE],
|
6'h05: Read_Config_Reg = {BAR1[`PCI_BASE_ADDR1_MATCH_RANGE],
|
`PCI_BASE_ADDR1_FILL, `PCI_BASE_ADDR1_MAP_QUAL};
|
`PCI_BASE_ADDR1_FILL, `PCI_BASE_ADDR1_MAP_QUAL};
|
`else // PCI_BASE_ADDR1_MATCH_ENABLE
|
`else // PCI_BASE_ADDR1_MATCH_ENABLE
|
6'h05: Read_Config_Reg = 32'h00000000;
|
6'h05: Read_Config_Reg = 32'h00000000;
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
6'h0F: Read_Config_Reg = {16'h0000, 8'h01, Interrupt_Line[7:0]};
|
6'h0F: Read_Config_Reg = {16'h0000, 8'h01, Interrupt_Line[7:0]};
|
default: Read_Config_Reg = 32'h00000000;
|
default: Read_Config_Reg = 32'h00000000;
|
endcase
|
endcase
|
end
|
end
|
endtask
|
endtask
|
|
|
// store info away so Config Register code can update register correctly
|
// store info away so Config Register code can update register correctly
|
reg [7:2] pending_config_reg_write_address;
|
reg [7:2] pending_config_reg_write_address;
|
reg [PCI_BUS_CBE_RANGE:0] pending_config_reg_write_byte_enables;
|
reg [PCI_BUS_CBE_RANGE:0] pending_config_reg_write_byte_enables;
|
reg [PCI_BUS_DATA_RANGE:0] pending_config_reg_write_data;
|
reg [PCI_BUS_DATA_RANGE:0] pending_config_reg_write_data;
|
reg pending_config_write_request;
|
reg pending_config_write_request;
|
task Write_Test_Device_Config_Regs;
|
task Write_Test_Device_Config_Regs;
|
input [7:2] reg_number;
|
input [7:2] reg_number;
|
input [PCI_BUS_DATA_RANGE:0] data;
|
input [PCI_BUS_DATA_RANGE:0] data;
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
begin
|
begin
|
if (~pci_reset_comb)
|
if (~pci_reset_comb)
|
begin
|
begin
|
pending_config_reg_write_address[7:2] <= reg_number[7:2];
|
pending_config_reg_write_address[7:2] <= reg_number[7:2];
|
pending_config_reg_write_byte_enables[PCI_BUS_CBE_RANGE:0] <= master_mask_l[PCI_BUS_CBE_RANGE:0];
|
pending_config_reg_write_byte_enables[PCI_BUS_CBE_RANGE:0] <= master_mask_l[PCI_BUS_CBE_RANGE:0];
|
pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] <= data[PCI_BUS_DATA_RANGE:0];
|
pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] <= data[PCI_BUS_DATA_RANGE:0];
|
pending_config_write_request <= 1'b1;
|
pending_config_write_request <= 1'b1;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
end
|
end
|
endtask
|
endtask
|
|
|
wire target_got_parity_error;
|
wire target_got_parity_error;
|
wire target_asserted_serr;
|
wire target_asserted_serr;
|
reg target_signaling_target_abort;
|
reg target_signaling_target_abort;
|
|
|
// Make a register transfer style Configuration Register, so it is easier to handle
|
// Make a register transfer style Configuration Register, so it is easier to handle
|
// simultaneous updates from the master and the target.
|
// simultaneous updates from the master and the target.
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
begin
|
begin
|
if (pci_reset_comb)
|
if (pci_reset_comb)
|
begin
|
begin
|
FB2B_En <= 1'b0;
|
FB2B_En <= 1'b0;
|
SERR_En <= 1'b0; Par_Err_En <= 1'b0;
|
SERR_En <= 1'b0; Par_Err_En <= 1'b0;
|
Master_En <= 1'b0; Target_En <= 1'b0;
|
Master_En <= 1'b0; Target_En <= 1'b0;
|
Detected_PERR <= 1'b0; Signaled_SERR <= 1'b0;
|
Detected_PERR <= 1'b0; Signaled_SERR <= 1'b0;
|
Received_Master_Abort <= 1'b0; Received_Target_Abort <= 1'b0;
|
Received_Master_Abort <= 1'b0; Received_Target_Abort <= 1'b0;
|
Signaled_Target_Abort <= 1'b0;
|
Signaled_Target_Abort <= 1'b0;
|
Master_Caused_PERR <= 1'b0;
|
Master_Caused_PERR <= 1'b0;
|
Latency_Timer <= 8'h00; Cache_Line_Size <= 8'h00;
|
Latency_Timer <= 8'h00; Cache_Line_Size <= 8'h00;
|
Interrupt_Line <= 8'h00;
|
Interrupt_Line <= 8'h00;
|
BAR0 <= 8'hXX;
|
BAR0 <= 8'hXX;
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
BAR1 <= 8'hXX;
|
BAR1 <= 8'hXX;
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
pending_config_write_request <= 1'b0;
|
pending_config_write_request <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (pending_config_write_request)
|
if (pending_config_write_request)
|
begin
|
begin
|
// Words 0 and 2 are not writable. Only certain bits in word 1 are writable.
|
// Words 0 and 2 are not writable. Only certain bits in word 1 are writable.
|
FB2B_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
FB2B_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[1])
|
& ~pending_config_reg_write_byte_enables[1])
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_FB2B_EN)
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_FB2B_EN)
|
!= `PCI_BUS_DATA_ZERO) : FB2B_En;
|
!= `PCI_BUS_DATA_ZERO) : FB2B_En;
|
SERR_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
SERR_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[1])
|
& ~pending_config_reg_write_byte_enables[1])
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_SERR_EN)
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_SERR_EN)
|
!= `PCI_BUS_DATA_ZERO) : SERR_En;
|
!= `PCI_BUS_DATA_ZERO) : SERR_En;
|
Par_Err_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
Par_Err_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[0])
|
& ~pending_config_reg_write_byte_enables[0])
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_PAR_ERR_EN)
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_PAR_ERR_EN)
|
!= `PCI_BUS_DATA_ZERO) : Par_Err_En;
|
!= `PCI_BUS_DATA_ZERO) : Par_Err_En;
|
Master_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
Master_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[0])
|
& ~pending_config_reg_write_byte_enables[0])
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_MASTER_EN)
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_MASTER_EN)
|
!= `PCI_BUS_DATA_ZERO) : Master_En;
|
!= `PCI_BUS_DATA_ZERO) : Master_En;
|
Target_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
Target_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[0])
|
& ~pending_config_reg_write_byte_enables[0])
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_TARGET_EN)
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_TARGET_EN)
|
!= `PCI_BUS_DATA_ZERO) : Target_En;
|
!= `PCI_BUS_DATA_ZERO) : Target_En;
|
// Certain bits in word 1 are only clearable, not writable.
|
// Certain bits in word 1 are only clearable, not writable.
|
Detected_PERR <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
Detected_PERR <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[3]
|
& ~pending_config_reg_write_byte_enables[3]
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_DETECTED_PERR) != `PCI_BUS_DATA_ZERO))
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_DETECTED_PERR) != `PCI_BUS_DATA_ZERO))
|
? 1'b0 : Detected_PERR | master_got_parity_error | target_got_parity_error;
|
? 1'b0 : Detected_PERR | master_got_parity_error | target_got_parity_error;
|
Signaled_SERR <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
Signaled_SERR <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[3]
|
& ~pending_config_reg_write_byte_enables[3]
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_DETECTED_SERR) != `PCI_BUS_DATA_ZERO))
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_DETECTED_SERR) != `PCI_BUS_DATA_ZERO))
|
? 1'b0 : Signaled_SERR | master_asserted_serr | target_asserted_serr;
|
? 1'b0 : Signaled_SERR | master_asserted_serr | target_asserted_serr;
|
Received_Master_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
Received_Master_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[3]
|
& ~pending_config_reg_write_byte_enables[3]
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_GOT_MABORT) != `PCI_BUS_DATA_ZERO))
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_GOT_MABORT) != `PCI_BUS_DATA_ZERO))
|
? 1'b0 : Received_Master_Abort | master_got_master_abort;
|
? 1'b0 : Received_Master_Abort | master_got_master_abort;
|
Received_Target_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
Received_Target_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[3]
|
& ~pending_config_reg_write_byte_enables[3]
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_GOT_TABORT) != `PCI_BUS_DATA_ZERO))
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_GOT_TABORT) != `PCI_BUS_DATA_ZERO))
|
? 1'b0 : Received_Target_Abort | master_got_target_abort;
|
? 1'b0 : Received_Target_Abort | master_got_target_abort;
|
Signaled_Target_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
Signaled_Target_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[3]
|
& ~pending_config_reg_write_byte_enables[3]
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_CAUSED_TABORT) != `PCI_BUS_DATA_ZERO))
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_CAUSED_TABORT) != `PCI_BUS_DATA_ZERO))
|
? 1'b0 : Signaled_Target_Abort | target_signaling_target_abort;
|
? 1'b0 : Signaled_Target_Abort | target_signaling_target_abort;
|
Master_Caused_PERR <= ( (pending_config_reg_write_address[7:2] == 6'h01)
|
Master_Caused_PERR <= ( (pending_config_reg_write_address[7:2] == 6'h01)
|
& ~pending_config_reg_write_byte_enables[3]
|
& ~pending_config_reg_write_byte_enables[3]
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_CAUSED_PERR) != `PCI_BUS_DATA_ZERO))
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_CAUSED_PERR) != `PCI_BUS_DATA_ZERO))
|
? 1'b0 : Master_Caused_PERR | master_caused_parity_error;
|
? 1'b0 : Master_Caused_PERR | master_caused_parity_error;
|
// Certain bytes in higher words are writable
|
// Certain bytes in higher words are writable
|
Latency_Timer <= ( (pending_config_reg_write_address[7:2] == 6'h03)
|
Latency_Timer <= ( (pending_config_reg_write_address[7:2] == 6'h03)
|
& ~pending_config_reg_write_byte_enables[1])
|
& ~pending_config_reg_write_byte_enables[1])
|
? pending_config_reg_write_data[15:8] : Latency_Timer;
|
? pending_config_reg_write_data[15:8] : Latency_Timer;
|
Cache_Line_Size <= ( (pending_config_reg_write_address[7:2] == 6'h03)
|
Cache_Line_Size <= ( (pending_config_reg_write_address[7:2] == 6'h03)
|
& ~pending_config_reg_write_byte_enables[0])
|
& ~pending_config_reg_write_byte_enables[0])
|
? pending_config_reg_write_data[7:0] : Cache_Line_Size;
|
? pending_config_reg_write_data[7:0] : Cache_Line_Size;
|
|
|
BAR0 <= ( (pending_config_reg_write_address[7:2] == 6'h04)
|
BAR0 <= ( (pending_config_reg_write_address[7:2] == 6'h04)
|
& ~pending_config_reg_write_byte_enables[3])
|
& ~pending_config_reg_write_byte_enables[3])
|
? pending_config_reg_write_data[`PCI_BASE_ADDR0_MATCH_RANGE] : BAR0;
|
? pending_config_reg_write_data[`PCI_BASE_ADDR0_MATCH_RANGE] : BAR0;
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
BAR1 <= ( (pending_config_reg_write_address[7:2] == 6'h05)
|
BAR1 <= ( (pending_config_reg_write_address[7:2] == 6'h05)
|
& ~pending_config_reg_write_byte_enables[3])
|
& ~pending_config_reg_write_byte_enables[3])
|
? pending_config_reg_write_data[`PCI_BASE_ADDR1_MATCH_RANGE] : BAR1;
|
? pending_config_reg_write_data[`PCI_BASE_ADDR1_MATCH_RANGE] : BAR1;
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
Interrupt_Line <= ( (pending_config_reg_write_address[7:2] == 6'h0F)
|
Interrupt_Line <= ( (pending_config_reg_write_address[7:2] == 6'h0F)
|
& ~pending_config_reg_write_byte_enables[0])
|
& ~pending_config_reg_write_byte_enables[0])
|
? pending_config_reg_write_data[7:0] : Interrupt_Line;
|
? pending_config_reg_write_data[7:0] : Interrupt_Line;
|
pending_config_write_request <= 1'b0; // NOTE this seems to prevent back-to-back writes.
|
pending_config_write_request <= 1'b0; // NOTE this seems to prevent back-to-back writes.
|
end
|
end
|
else
|
else
|
begin // not writing from PCI side
|
begin // not writing from PCI side
|
// Words 0 and 2 are not writable. Only certain bits in word 1 are writable.
|
// Words 0 and 2 are not writable. Only certain bits in word 1 are writable.
|
FB2B_En <= FB2B_En;
|
FB2B_En <= FB2B_En;
|
SERR_En <= SERR_En;
|
SERR_En <= SERR_En;
|
Par_Err_En <= Par_Err_En;
|
Par_Err_En <= Par_Err_En;
|
Master_En <= Master_En;
|
Master_En <= Master_En;
|
Target_En <= Target_En;
|
Target_En <= Target_En;
|
// Certain bits in word 1 are only clearable, not writable.
|
// Certain bits in word 1 are only clearable, not writable.
|
Detected_PERR <= Detected_PERR | master_got_parity_error | target_got_parity_error;
|
Detected_PERR <= Detected_PERR | master_got_parity_error | target_got_parity_error;
|
Signaled_SERR <= Signaled_SERR | master_asserted_serr | target_asserted_serr;
|
Signaled_SERR <= Signaled_SERR | master_asserted_serr | target_asserted_serr;
|
Received_Master_Abort <= Received_Master_Abort | master_got_master_abort;
|
Received_Master_Abort <= Received_Master_Abort | master_got_master_abort;
|
Received_Target_Abort <= Received_Target_Abort | master_got_target_abort;
|
Received_Target_Abort <= Received_Target_Abort | master_got_target_abort;
|
Signaled_Target_Abort <= Signaled_Target_Abort | target_signaling_target_abort;
|
Signaled_Target_Abort <= Signaled_Target_Abort | target_signaling_target_abort;
|
Master_Caused_PERR <= Master_Caused_PERR | master_caused_parity_error;
|
Master_Caused_PERR <= Master_Caused_PERR | master_caused_parity_error;
|
// Certain bytes in higher words are writable
|
// Certain bytes in higher words are writable
|
Latency_Timer <= Latency_Timer;
|
Latency_Timer <= Latency_Timer;
|
Cache_Line_Size <= Cache_Line_Size;
|
Cache_Line_Size <= Cache_Line_Size;
|
BAR0 <= BAR0;
|
BAR0 <= BAR0;
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
BAR1 <= BAR1;
|
BAR1 <= BAR1;
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
Interrupt_Line <= Interrupt_Line;
|
Interrupt_Line <= Interrupt_Line;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// Tasks to manage the small SRAM visible in Memory Space
|
// Tasks to manage the small SRAM visible in Memory Space
|
reg [PCI_BUS_DATA_RANGE:0] Test_Device_Mem [0:255]; // address limits, not bits in address
|
reg [PCI_BUS_DATA_RANGE:0] Test_Device_Mem [0:1023]; // address limits, not bits in address
|
// Tasks can't have local storage! have to be module global
|
// Tasks can't have local storage! have to be module global
|
reg [7:0] sram_addr;
|
reg [9:0] sram_addr;
|
task Init_Test_Device_SRAM;
|
task Init_Test_Device_SRAM;
|
begin
|
begin
|
for (sram_addr = 8'h00; sram_addr < 8'hFF; sram_addr = sram_addr + 8'h01)
|
for (sram_addr = 10'h000; sram_addr < 10'h3FF; sram_addr = sram_addr + 10'h001)
|
begin
|
begin
|
Test_Device_Mem[sram_addr] = `BUS_IMPOSSIBLE_VALUE;
|
Test_Device_Mem[sram_addr] = `BUS_IMPOSSIBLE_VALUE;
|
end
|
end
|
|
sram_addr = 10'h3FF; // maximum value must also be written!
|
|
Test_Device_Mem[sram_addr] = `BUS_IMPOSSIBLE_VALUE;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Read_Test_Device_SRAM;
|
task Read_Test_Device_SRAM;
|
input [9:2] sram_address;
|
input [11:2] sram_address;
|
input [PCI_BUS_CBE_RANGE:0] byte_sel ;
|
input [PCI_BUS_CBE_RANGE:0] byte_sel ;
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
reg [PCI_BUS_DATA_RANGE:0] temp_val ;
|
reg [PCI_BUS_DATA_RANGE:0] temp_val ;
|
begin
|
begin
|
temp_val = Test_Device_Mem[sram_address] ;
|
temp_val = Test_Device_Mem[sram_address] ;
|
target_read_data[7:0] = byte_sel[0] ? temp_val[7:0] : 0 ;
|
target_read_data[7:0] = byte_sel[0] ? temp_val[7:0] : 0 ;
|
target_read_data[15:8] = byte_sel[1] ? temp_val[15:8] : 0 ;
|
target_read_data[15:8] = byte_sel[1] ? temp_val[15:8] : 0 ;
|
target_read_data[23:16] = byte_sel[2] ? temp_val[23:16] : 0 ;
|
target_read_data[23:16] = byte_sel[2] ? temp_val[23:16] : 0 ;
|
target_read_data[31:24] = byte_sel[3] ? temp_val[31:24] : 0 ;
|
target_read_data[31:24] = byte_sel[3] ? temp_val[31:24] : 0 ;
|
end
|
end
|
endtask
|
endtask
|
|
|
// Tasks can't have local storage! have to be module global
|
// Tasks can't have local storage! have to be module global
|
reg [PCI_BUS_DATA_RANGE:0] sram_temp;
|
reg [PCI_BUS_DATA_RANGE:0] sram_temp;
|
task Write_Test_Device_SRAM;
|
task Write_Test_Device_SRAM;
|
input [9:2] sram_address;
|
input [11:2] sram_address;
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
begin
|
begin
|
sram_temp = Test_Device_Mem[sram_address];
|
sram_temp = Test_Device_Mem[sram_address];
|
sram_temp[7:0] = (~master_mask_l[0]) ? master_write_data[7:0] : sram_temp[7:0];
|
sram_temp[7:0] = (~master_mask_l[0]) ? master_write_data[7:0] : sram_temp[7:0];
|
sram_temp[15:8] = (~master_mask_l[1]) ? master_write_data[15:8] : sram_temp[15:8];
|
sram_temp[15:8] = (~master_mask_l[1]) ? master_write_data[15:8] : sram_temp[15:8];
|
sram_temp[23:16] = (~master_mask_l[2]) ? master_write_data[23:16] : sram_temp[23:16];
|
sram_temp[23:16] = (~master_mask_l[2]) ? master_write_data[23:16] : sram_temp[23:16];
|
sram_temp[31:24] = (~master_mask_l[3]) ? master_write_data[31:24] : sram_temp[31:24];
|
sram_temp[31:24] = (~master_mask_l[3]) ? master_write_data[31:24] : sram_temp[31:24];
|
Test_Device_Mem[sram_address] = sram_temp[PCI_BUS_DATA_RANGE:0];
|
Test_Device_Mem[sram_address] = sram_temp[PCI_BUS_DATA_RANGE:0];
|
end
|
end
|
endtask
|
endtask
|
|
|
// Make the DEVSEL_TRDY_STOP_OE output enable signal. It must become
|
// Make the DEVSEL_TRDY_STOP_OE output enable signal. It must become
|
// asserted as soon as one of those signals become asserted, and
|
// asserted as soon as one of those signals become asserted, and
|
// must stay asserted one clock after the last one becomes deasserted.
|
// must stay asserted one clock after the last one becomes deasserted.
|
reg prev_d_t_s_asserted;
|
reg prev_d_t_s_asserted;
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
begin
|
begin
|
if (pci_reset_comb)
|
if (pci_reset_comb)
|
begin
|
begin
|
prev_d_t_s_asserted <= 1'b0;
|
prev_d_t_s_asserted <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
prev_d_t_s_asserted <= target_devsel_out | target_trdy_out | target_stop_out;
|
prev_d_t_s_asserted <= target_devsel_out | target_trdy_out | target_stop_out;
|
end
|
end
|
end
|
end
|
assign target_d_t_s_oe = target_devsel_out | target_trdy_out | target_stop_out
|
assign target_d_t_s_oe = target_devsel_out | target_trdy_out | target_stop_out
|
| prev_d_t_s_asserted;
|
| prev_d_t_s_asserted;
|
|
|
// Make the PERR_OE signal.
|
// Make the PERR_OE signal.
|
// See the PCI Local Bus Spec Revision 2.2 section 3.7.4.1
|
// See the PCI Local Bus Spec Revision 2.2 section 3.7.4.1
|
// At time N, target_perr_check_next is set
|
// At time N, target_perr_check_next is set
|
// At time N+1, external data is latched, and irdy is also latched
|
// At time N+1, external data is latched, and irdy is also latched
|
// At time N+1, target_perr_check is latched
|
// At time N+1, target_perr_check is latched
|
// At time N+2, calc_input_parity_prev is valid
|
// At time N+2, calc_input_parity_prev is valid
|
// Also at N+2, external parity is valid
|
// Also at N+2, external parity is valid
|
reg target_perr_prev, target_perr_check_next, target_perr_check;
|
reg target_perr_prev, target_perr_check_next, target_perr_check;
|
reg target_perr_detected;
|
reg target_perr_detected;
|
reg target_debug_force_bad_perr ;
|
reg target_debug_force_bad_perr ;
|
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
begin
|
begin
|
if (pci_reset_comb)
|
if (pci_reset_comb)
|
target_debug_force_bad_perr <= 1'b0 ;
|
target_debug_force_bad_perr <= 1'b0 ;
|
else
|
else
|
target_debug_force_bad_perr <= target_debug_force_bad_par ;
|
target_debug_force_bad_perr <= target_debug_force_bad_par ;
|
end
|
end
|
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
begin
|
begin
|
if (pci_reset_comb)
|
if (pci_reset_comb)
|
begin
|
begin
|
target_perr_check <= 1'b0;
|
target_perr_check <= 1'b0;
|
target_perr_detected <= 1'b0;
|
target_perr_detected <= 1'b0;
|
target_perr_out <= 1'b0;
|
target_perr_out <= 1'b0;
|
target_perr_prev <= 1'b0;
|
target_perr_prev <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
target_perr_check <= target_perr_check_next;
|
target_perr_check <= target_perr_check_next;
|
target_perr_detected <= target_perr_check & irdy_prev
|
target_perr_detected <= target_perr_check & irdy_prev
|
& (calc_input_parity_prev != par_now);
|
& (calc_input_parity_prev != par_now);
|
target_perr_out <= target_perr_check & irdy_prev & Par_Err_En
|
target_perr_out <= target_perr_check & irdy_prev & Par_Err_En
|
// mihad - bad perr generation
|
// mihad - bad perr generation
|
& (calc_input_parity_prev != (par_now ^ target_debug_force_bad_perr));
|
& (calc_input_parity_prev != (par_now ^ target_debug_force_bad_perr));
|
target_perr_prev <= target_perr_out;
|
target_perr_prev <= target_perr_out;
|
end
|
end
|
end
|
end
|
assign target_perr_oe = target_perr_out | target_perr_prev;
|
assign target_perr_oe = target_perr_out | target_perr_prev;
|
|
|
// Make the SERR_OE signal
|
// Make the SERR_OE signal
|
// See the PCI Local Bus Spec Revision 2.2 section 6.2.3.
|
// See the PCI Local Bus Spec Revision 2.2 section 6.2.3.
|
reg prev_prev_frame;
|
reg prev_prev_frame;
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
begin
|
begin
|
if (pci_reset_comb)
|
if (pci_reset_comb)
|
begin
|
begin
|
prev_prev_frame <= 1'b0;
|
prev_prev_frame <= 1'b0;
|
target_serr_oe <= 1'b0;
|
target_serr_oe <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
prev_prev_frame <= frame_prev;
|
prev_prev_frame <= frame_prev;
|
target_serr_oe <= ~prev_prev_frame & frame_prev
|
target_serr_oe <= ~prev_prev_frame & frame_prev
|
& SERR_En & Par_Err_En
|
& SERR_En & Par_Err_En
|
& (calc_input_parity_prev != par_now);
|
& (calc_input_parity_prev != par_now);
|
end
|
end
|
end
|
end
|
assign target_asserted_serr = target_serr_oe;
|
assign target_asserted_serr = target_serr_oe;
|
assign target_got_parity_error = target_perr_detected | target_serr_oe;
|
assign target_got_parity_error = target_perr_detected | target_serr_oe;
|
|
|
// Remember whether this device drove DEVSEL last clock, which allows
|
// Remember whether this device drove DEVSEL last clock, which allows
|
// Zero-Wait-State Back-to-Back references
|
// Zero-Wait-State Back-to-Back references
|
wire This_Target_Drove_DEVSEL_Last_Clock = target_d_t_s_oe;
|
wire This_Target_Drove_DEVSEL_Last_Clock = target_d_t_s_oe;
|
|
|
// Remember whether the bus has correct parity.
|
// Remember whether the bus has correct parity.
|
// Used by Medium, slower Address Decode to prevent DEVSEL on bad Address Parity
|
// Used by Medium, slower Address Decode to prevent DEVSEL on bad Address Parity
|
reg prev_bus_par_ok, prev_prev_bus_par_ok;
|
reg prev_bus_par_ok, prev_prev_bus_par_ok;
|
always @(posedge pci_ext_clk)
|
always @(posedge pci_ext_clk)
|
begin
|
begin
|
prev_bus_par_ok <= (calc_input_parity_prev == par_now);
|
prev_bus_par_ok <= (calc_input_parity_prev == par_now);
|
prev_prev_bus_par_ok <= prev_bus_par_ok;
|
prev_prev_bus_par_ok <= prev_bus_par_ok;
|
end
|
end
|
|
|
// We want the Target to do certain behavior to let us test the interface.
|
// We want the Target to do certain behavior to let us test the interface.
|
// See the note in the Master section about the use of Address Bits to
|
// See the note in the Master section about the use of Address Bits to
|
// encode Target Wait State, Target Completion, and Target Error info.
|
// encode Target Wait State, Target Completion, and Target Error info.
|
|
|
// signals used by Target test code to apply correct info to the PCI bus
|
// signals used by Target test code to apply correct info to the PCI bus
|
reg [PCI_BUS_DATA_RANGE:0] hold_target_address;
|
reg [PCI_BUS_DATA_RANGE:0] hold_target_address;
|
reg [PCI_BUS_CBE_RANGE:0] hold_target_command;
|
reg [PCI_BUS_CBE_RANGE:0] hold_target_command;
|
reg [3:0] hold_target_initial_waitstates;
|
reg [3:0] hold_target_initial_waitstates;
|
reg [3:0] hold_target_subsequent_waitstates;
|
reg [3:0] hold_target_subsequent_waitstates;
|
reg [2:0] hold_target_termination;
|
reg [2:0] hold_target_termination;
|
reg [1:0] hold_target_devsel_speed;
|
reg [1:0] hold_target_devsel_speed;
|
reg [9:0] hold_target_terminate_on ;
|
reg [9:0] hold_target_terminate_on ;
|
reg hold_target_data_par_err;
|
reg hold_target_data_par_err;
|
reg hold_target_addr_par_err;
|
reg hold_target_addr_par_err;
|
|
|
// Tasks which use the held PCI address to access internal info. These tasks
|
// Tasks which use the held PCI address to access internal info. These tasks
|
// update the address counter, emulating the target address counter during bursts.
|
// update the address counter, emulating the target address counter during bursts.
|
// Store data from PCI bus into Config Register, and increment Write Pointer
|
// Store data from PCI bus into Config Register, and increment Write Pointer
|
task Capture_Config_Reg_Data_From_AD_Bus;
|
task Capture_Config_Reg_Data_From_AD_Bus;
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
begin
|
begin
|
Write_Test_Device_Config_Regs (hold_target_address[7:2],
|
Write_Test_Device_Config_Regs (hold_target_address[7:2],
|
master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
hold_target_address[7:2] = hold_target_address[7:2] + 6'h01; // addr++
|
hold_target_address[7:2] = hold_target_address[7:2] + 6'h01; // addr++
|
end
|
end
|
endtask
|
endtask
|
|
|
// Drive Config Register Data onto AD bus, and increment Read Pointer
|
// Drive Config Register Data onto AD bus, and increment Read Pointer
|
task Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus;
|
task Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus;
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
begin
|
begin
|
Read_Test_Device_Config_Regs (hold_target_address[7:2], target_read_data[PCI_BUS_DATA_RANGE:0]);
|
Read_Test_Device_Config_Regs (hold_target_address[7:2], target_read_data[PCI_BUS_DATA_RANGE:0]);
|
hold_target_address[7:2] = hold_target_address[7:2] + 6'h01; // addr++
|
hold_target_address[7:2] = hold_target_address[7:2] + 6'h01; // addr++
|
end
|
end
|
endtask
|
endtask
|
|
|
// Store data from PCI bus into SRAM, and increment Write Pointer
|
// Store data from PCI bus into SRAM, and increment Write Pointer
|
task Capture_SRAM_Data_From_AD_Bus;
|
task Capture_SRAM_Data_From_AD_Bus;
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
begin
|
begin
|
Write_Test_Device_SRAM (hold_target_address[9:2],
|
Write_Test_Device_SRAM (hold_target_address[11:2],
|
master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
hold_target_address[9:2] = hold_target_address[9:2] + 8'h01; // addr++
|
hold_target_address[11:2] = hold_target_address[11:2] + 10'h001; // addr++
|
end
|
end
|
endtask
|
endtask
|
|
|
// Drive SRAM Data onto AD bus, and increment Read Pointer
|
// Drive SRAM Data onto AD bus, and increment Read Pointer
|
task Fetch_SRAM_Data_For_Read_Onto_AD_Bus;
|
task Fetch_SRAM_Data_For_Read_Onto_AD_Bus;
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
begin
|
begin
|
Read_Test_Device_SRAM (hold_target_address[9:2], ~cbe_l_now, target_read_data[PCI_BUS_DATA_RANGE:0]);
|
Read_Test_Device_SRAM (hold_target_address[11:2], ~cbe_l_now, target_read_data[PCI_BUS_DATA_RANGE:0]);
|
hold_target_address[9:2] = hold_target_address[9:2] + 8'h01; // addr++
|
hold_target_address[11:2] = hold_target_address[11:2] + 10'h001; // addr++
|
end
|
end
|
endtask
|
endtask
|
|
|
// The target is able to execute Delayed Reads,
|
// The target is able to execute Delayed Reads,
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.3.3
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.3.3
|
// To allow a delayed read to complete, read data must be available.
|
// To allow a delayed read to complete, read data must be available.
|
// Also a PCI command matching in Address, Command, Byte Enables,
|
// Also a PCI command matching in Address, Command, Byte Enables,
|
// and parity on address.
|
// and parity on address.
|
// If the region of memory is prefetchable and always returns all
|
// If the region of memory is prefetchable and always returns all
|
// bytes, it is OK to disregard the Byte Enables.
|
// bytes, it is OK to disregard the Byte Enables.
|
reg Delayed_Read_Started, Delayed_Read_Pending, Delayed_Read_Finished;
|
reg Delayed_Read_Started, Delayed_Read_Pending, Delayed_Read_Finished;
|
reg [PCI_BUS_DATA_RANGE:0] Delayed_Read_Address;
|
reg [PCI_BUS_DATA_RANGE:0] Delayed_Read_Address;
|
reg [PCI_BUS_CBE_RANGE:0] Delayed_Read_Command;
|
reg [PCI_BUS_CBE_RANGE:0] Delayed_Read_Command;
|
reg [PCI_BUS_CBE_RANGE:0] Delayed_Read_Mask_L;
|
reg [PCI_BUS_CBE_RANGE:0] Delayed_Read_Mask_L;
|
reg [14:0] Delayed_Read_Discard_Counter;
|
reg [14:0] Delayed_Read_Discard_Counter;
|
wire [14:0] Delayed_Read_Discard_Limit = 15'h7FFF; // change for debugging
|
wire [14:0] Delayed_Read_Discard_Limit = 15'h7FFF; // change for debugging
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
begin
|
begin
|
if (pci_reset_comb)
|
if (pci_reset_comb)
|
begin
|
begin
|
Delayed_Read_Pending <= 1'b0;
|
Delayed_Read_Pending <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
Delayed_Read_Pending <= Delayed_Read_Started
|
Delayed_Read_Pending <= Delayed_Read_Started
|
| (Delayed_Read_Pending & ~Delayed_Read_Finished
|
| (Delayed_Read_Pending & ~Delayed_Read_Finished
|
& (Delayed_Read_Discard_Counter[14:0] < Delayed_Read_Discard_Limit[14:0]));
|
& (Delayed_Read_Discard_Counter[14:0] < Delayed_Read_Discard_Limit[14:0]));
|
end
|
end
|
end
|
end
|
|
|
always @(posedge pci_ext_clk)
|
always @(posedge pci_ext_clk)
|
begin
|
begin
|
Delayed_Read_Discard_Counter[14:0] <= Delayed_Read_Started
|
Delayed_Read_Discard_Counter[14:0] <= Delayed_Read_Started
|
? 15'h0000 : Delayed_Read_Discard_Counter[14:0] + 15'h0001;
|
? 15'h0000 : Delayed_Read_Discard_Counter[14:0] + 15'h0001;
|
`ifdef VERBOSE_TEST_DEVICE
|
`ifdef VERBOSE_TEST_DEVICE
|
if (Delayed_Read_Pending & (Delayed_Read_Discard_Counter[14:0]
|
if (Delayed_Read_Pending & (Delayed_Read_Discard_Counter[14:0]
|
>= Delayed_Read_Discard_Limit[14:0]))
|
>= Delayed_Read_Discard_Limit[14:0]))
|
begin
|
begin
|
$display (" test target %h - Delayed Read Discarded, at %t",
|
$display (" test target %h - Delayed Read Discarded, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // VERBOSE_TEST_DEVICE
|
`endif // VERBOSE_TEST_DEVICE
|
end
|
end
|
|
|
// Target tasks. These know how to respond to the external masters.
|
// Target tasks. These know how to respond to the external masters.
|
// NOTE all tasks end with an @(posedge pci_ext_clk) statement
|
// NOTE all tasks end with an @(posedge pci_ext_clk) statement
|
// to let any signals asserted during that task settle out.
|
// to let any signals asserted during that task settle out.
|
// If a task DOESN'T end with @(posedge pci_ext_clk), then it must
|
// If a task DOESN'T end with @(posedge pci_ext_clk), then it must
|
// be called just before some other task which does.
|
// be called just before some other task which does.
|
|
|
parameter TEST_TARGET_SPINLOOP_MAX = 20;
|
parameter TEST_TARGET_SPINLOOP_MAX = 20;
|
|
|
task Clock_Wait_Unless_Reset;
|
task Clock_Wait_Unless_Reset;
|
begin
|
begin
|
if (~pci_reset_comb)
|
if (~pci_reset_comb)
|
begin
|
begin
|
@ (posedge pci_ext_clk or posedge pci_reset_comb) ;
|
@ (posedge pci_ext_clk or posedge pci_reset_comb) ;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Assert_DEVSEL;
|
task Assert_DEVSEL;
|
begin
|
begin
|
target_devsel_out <= 1'b1;
|
target_devsel_out <= 1'b1;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Assert_TRDY;
|
task Assert_TRDY;
|
begin
|
begin
|
target_trdy_out <= 1'b1;
|
target_trdy_out <= 1'b1;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Assert_STOP;
|
task Assert_STOP;
|
begin
|
begin
|
target_stop_out <= 1'b1;
|
target_stop_out <= 1'b1;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Deassert_DEVSEL;
|
task Deassert_DEVSEL;
|
begin
|
begin
|
target_devsel_out <= 1'b0;
|
target_devsel_out <= 1'b0;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Deassert_TRDY;
|
task Deassert_TRDY;
|
begin
|
begin
|
target_trdy_out <= 1'b0;
|
target_trdy_out <= 1'b0;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Deassert_STOP;
|
task Deassert_STOP;
|
begin
|
begin
|
target_stop_out <= 1'b0;
|
target_stop_out <= 1'b0;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Assert_Target_Continue_Or_Disconnect;
|
task Assert_Target_Continue_Or_Disconnect;
|
input do_target_disconnect;
|
input do_target_disconnect;
|
begin
|
begin
|
if (do_target_disconnect)
|
if (do_target_disconnect)
|
begin
|
begin
|
Assert_DEVSEL; Assert_TRDY; Assert_STOP;
|
Assert_DEVSEL; Assert_TRDY; Assert_STOP;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
Assert_DEVSEL; Assert_TRDY; Deassert_STOP;
|
Assert_DEVSEL; Assert_TRDY; Deassert_STOP;
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
// Execute_Target_Retry is called with nothing or DEVSEL asserted
|
// Execute_Target_Retry is called with nothing or DEVSEL asserted
|
// tasks can't have local storage! have to be module global
|
// tasks can't have local storage! have to be module global
|
integer iiii;
|
integer iiii;
|
task Execute_Target_Retry_Undrive_DEVSEL;
|
task Execute_Target_Retry_Undrive_DEVSEL;
|
input drive_ad_bus;
|
input drive_ad_bus;
|
input signal_starting_delayed_read;
|
input signal_starting_delayed_read;
|
input signal_satisfied_delayed_read;
|
input signal_satisfied_delayed_read;
|
begin
|
begin
|
for (iiii = 0; iiii < TEST_TARGET_SPINLOOP_MAX; iiii = iiii + 1)
|
for (iiii = 0; iiii < TEST_TARGET_SPINLOOP_MAX; iiii = iiii + 1)
|
begin
|
begin
|
if ((iiii == 0) | frame_now | ~irdy_now) // At least one stop, then Not Finished
|
if ((iiii == 0) | frame_now | ~irdy_now) // At least one stop, then Not Finished
|
begin
|
begin
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= drive_ad_bus;
|
target_ad_oe <= drive_ad_bus;
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= ~drive_ad_bus;
|
target_perr_check_next <= ~drive_ad_bus;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= signal_starting_delayed_read;
|
Delayed_Read_Started <= signal_starting_delayed_read;
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
Assert_DEVSEL; // signal DEVSEL and Stop, indicating Retry
|
Assert_DEVSEL; // signal DEVSEL and Stop, indicating Retry
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Assert_STOP;
|
Assert_STOP;
|
if (signal_starting_delayed_read)
|
if (signal_starting_delayed_read)
|
begin
|
begin
|
Delayed_Read_Address[PCI_BUS_DATA_RANGE:0] = hold_target_address[PCI_BUS_DATA_RANGE:0];
|
Delayed_Read_Address[PCI_BUS_DATA_RANGE:0] = hold_target_address[PCI_BUS_DATA_RANGE:0];
|
Delayed_Read_Command[PCI_BUS_CBE_RANGE:0] = hold_target_command[PCI_BUS_CBE_RANGE:0];
|
Delayed_Read_Command[PCI_BUS_CBE_RANGE:0] = hold_target_command[PCI_BUS_CBE_RANGE:0];
|
Delayed_Read_Mask_L[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
Delayed_Read_Mask_L[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Deassert_DEVSEL; // Master saw us, so leave
|
Deassert_DEVSEL; // Master saw us, so leave
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Deassert_STOP;
|
Deassert_STOP;
|
iiii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
iiii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
end
|
end
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
signal_satisfied_delayed_read = 1'b0;
|
signal_satisfied_delayed_read = 1'b0;
|
end
|
end
|
`ifdef NORMAL_PCI_CHECKS
|
`ifdef NORMAL_PCI_CHECKS
|
if (~pci_reset_comb & (iiii == TEST_TARGET_SPINLOOP_MAX))
|
if (~pci_reset_comb & (iiii == TEST_TARGET_SPINLOOP_MAX))
|
begin
|
begin
|
$display ("*** test target %h - Bus didn't go Idle during Target Retry, at %t",
|
$display ("*** test target %h - Bus didn't go Idle during Target Retry, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
if (~pci_reset_comb & irdy_now)
|
if (~pci_reset_comb & irdy_now)
|
begin
|
begin
|
$display ("*** test target %h - IRDY didn't deassert at end of Target Retry, at %t",
|
$display ("*** test target %h - IRDY didn't deassert at end of Target Retry, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // NORMAL_PCI_CHECKS
|
`endif // NORMAL_PCI_CHECKS
|
end
|
end
|
endtask
|
endtask
|
|
|
// This Test Device is capable of doing Fast Decode. To do this,
|
// This Test Device is capable of doing Fast Decode. To do this,
|
// it must make sure not to cause conflicts on DEVSEL, IRDY,
|
// it must make sure not to cause conflicts on DEVSEL, IRDY,
|
// STOP, or PERR. To achieve this, the task must hold off on
|
// STOP, or PERR. To achieve this, the task must hold off on
|
// making DEVSEL unless either
|
// making DEVSEL unless either
|
// 1) the bus was just Idle
|
// 1) the bus was just Idle
|
// 2) this device also drove DEVSEL the previous clock (I presume this
|
// 2) this device also drove DEVSEL the previous clock (I presume this
|
// means that DEVSEL was driven LOW!! Would HIGH be an idle cycle?)
|
// means that DEVSEL was driven LOW!! Would HIGH be an idle cycle?)
|
// See the PCI Local Bus Spec Revision 2.2 section 3.4.2
|
// See the PCI Local Bus Spec Revision 2.2 section 3.4.2
|
//
|
//
|
// See the PCI Local Bus Spec Revision 2.2 section 3.7.3 for what
|
// See the PCI Local Bus Spec Revision 2.2 section 3.7.3 for what
|
// to do if an Address Parity Error is detected.
|
// to do if an Address Parity Error is detected.
|
// Since this behaviorial test knows that an address parity error is
|
// Since this behaviorial test knows that an address parity error is
|
// comming, it holds off fast decode parity errors, and always
|
// comming, it holds off fast decode parity errors, and always
|
// allows a master abort to happen. This would not be possible in
|
// allows a master abort to happen. This would not be possible in
|
// a gate-level PCI interface. For FAST decode, that interface would
|
// a gate-level PCI interface. For FAST decode, that interface would
|
// have to continue on as if there was no error. It would be nice
|
// have to continue on as if there was no error. It would be nice
|
// if it prevented any writes of data, or reads with side-effects.
|
// if it prevented any writes of data, or reads with side-effects.
|
task Wait_Till_DEVSEL_Possible;
|
task Wait_Till_DEVSEL_Possible;
|
output devsel_asserted;
|
output devsel_asserted;
|
output fast_devsel_asserted;
|
output fast_devsel_asserted;
|
output signal_satisfied_delayed_read;
|
output signal_satisfied_delayed_read;
|
begin
|
begin
|
if ((hold_target_devsel_speed[1:0] == `Test_Devsel_Fast) & ~Delayed_Read_Pending
|
if ((hold_target_devsel_speed[1:0] == `Test_Devsel_Fast) & ~Delayed_Read_Pending
|
& ( (~frame_prev & ~irdy_prev)
|
& ( (~frame_prev & ~irdy_prev)
|
| (~frame_prev & irdy_prev & This_Target_Drove_DEVSEL_Last_Clock) )
|
| (~frame_prev & irdy_prev & This_Target_Drove_DEVSEL_Last_Clock) )
|
& ~(hold_target_addr_par_err & Par_Err_En))
|
& ~(hold_target_addr_par_err & Par_Err_En))
|
begin
|
begin
|
`ifdef VERBOSE_TEST_DEVICE
|
`ifdef VERBOSE_TEST_DEVICE
|
$display (" test target %h - doing fast DEVSEL, at %t",
|
$display (" test target %h - doing fast DEVSEL, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
`endif // VERBOSE_TEST_DEVICE
|
`endif // VERBOSE_TEST_DEVICE
|
devsel_asserted = 1'b1; // fast decode
|
devsel_asserted = 1'b1; // fast decode
|
fast_devsel_asserted = 1'b1; // fast decode
|
fast_devsel_asserted = 1'b1; // fast decode
|
signal_satisfied_delayed_read = 1'b0;
|
signal_satisfied_delayed_read = 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Deassert_DEVSEL;
|
Deassert_DEVSEL;
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Deassert_STOP;
|
Deassert_STOP;
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
if (Delayed_Read_Pending
|
if (Delayed_Read_Pending
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) )
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) )
|
& ( ( (hold_target_address[PCI_BUS_DATA_RANGE:0] & 32'hFF0000FF) // partial test address match
|
& ( ( (hold_target_address[PCI_BUS_DATA_RANGE:0] & 32'hFF0000FF) // partial test address match
|
!= (Delayed_Read_Address[PCI_BUS_DATA_RANGE:0] & 32'hFF0000FF))
|
!= (Delayed_Read_Address[PCI_BUS_DATA_RANGE:0] & 32'hFF0000FF))
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] != Delayed_Read_Command[PCI_BUS_CBE_RANGE:0])
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] != Delayed_Read_Command[PCI_BUS_CBE_RANGE:0])
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] != Delayed_Read_Mask_L[PCI_BUS_CBE_RANGE:0]) ) )
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] != Delayed_Read_Mask_L[PCI_BUS_CBE_RANGE:0]) ) )
|
begin
|
begin
|
Execute_Target_Retry_Undrive_DEVSEL (1'b1, 1'b0, 1'b0);
|
Execute_Target_Retry_Undrive_DEVSEL (1'b1, 1'b0, 1'b0);
|
devsel_asserted = 1'b0; // tell calling routine to not claim DEVSEL.
|
devsel_asserted = 1'b0; // tell calling routine to not claim DEVSEL.
|
fast_devsel_asserted = 1'b0;
|
fast_devsel_asserted = 1'b0;
|
signal_satisfied_delayed_read = 1'b0;
|
signal_satisfied_delayed_read = 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if /*(*/( (hold_target_devsel_speed[1:0] == `Test_Devsel_Fast)
|
if /*(*/( (hold_target_devsel_speed[1:0] == `Test_Devsel_Fast)
|
| (hold_target_devsel_speed[1:0] == `Test_Devsel_Medium) )
|
| (hold_target_devsel_speed[1:0] == `Test_Devsel_Medium) )
|
/* & ((calc_input_parity_prev == par_now) | ~Par_Err_En))*/
|
/* & ((calc_input_parity_prev == par_now) | ~Par_Err_En))*/
|
begin
|
begin
|
devsel_asserted = 1'b1; // medium decode
|
devsel_asserted = 1'b1; // medium decode
|
fast_devsel_asserted = 1'b0; // medium decode
|
fast_devsel_asserted = 1'b0; // medium decode
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
end
|
end
|
else
|
else
|
begin
|
begin
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Deassert_DEVSEL;
|
Deassert_DEVSEL;
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Deassert_STOP;
|
Deassert_STOP;
|
Clock_Wait_Unless_Reset;
|
Clock_Wait_Unless_Reset;
|
if /*(*/(hold_target_devsel_speed[1:0] == `Test_Devsel_Slow)
|
if /*(*/(hold_target_devsel_speed[1:0] == `Test_Devsel_Slow)
|
/*& (prev_bus_par_ok | ~Par_Err_En))*/
|
/*& (prev_bus_par_ok | ~Par_Err_En))*/
|
begin
|
begin
|
devsel_asserted = 1'b1; // slow decode
|
devsel_asserted = 1'b1; // slow decode
|
fast_devsel_asserted = 1'b0; // slow decode
|
fast_devsel_asserted = 1'b0; // slow decode
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
end
|
end
|
else
|
else
|
begin
|
begin
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Deassert_DEVSEL;
|
Deassert_DEVSEL;
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Deassert_STOP;
|
Deassert_STOP;
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
if (/*(*/hold_target_devsel_speed[1:0] == `Test_Devsel_Subtractive)
|
if (/*(*/hold_target_devsel_speed[1:0] == `Test_Devsel_Subtractive)
|
/*& (prev_prev_bus_par_ok | ~Par_Err_En))*/
|
/*& (prev_prev_bus_par_ok | ~Par_Err_En))*/
|
begin
|
begin
|
devsel_asserted = 1'b1; // subtractive decode
|
devsel_asserted = 1'b1; // subtractive decode
|
fast_devsel_asserted = 1'b0; // subtractive decode
|
fast_devsel_asserted = 1'b0; // subtractive decode
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
|
|
end
|
end
|
else
|
else
|
begin
|
begin
|
devsel_asserted = 1'b0; // must have had bad parity
|
devsel_asserted = 1'b0; // must have had bad parity
|
fast_devsel_asserted = 1'b0;
|
fast_devsel_asserted = 1'b0;
|
signal_satisfied_delayed_read = 1'b0;
|
signal_satisfied_delayed_read = 1'b0;
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
`ifdef NORMAL_PCI_CHECKS
|
`ifdef NORMAL_PCI_CHECKS
|
if (~pci_reset_comb & (devsel_asserted == 1'b1)
|
if (~pci_reset_comb & (devsel_asserted == 1'b1)
|
& (hold_target_addr_par_err == 1'b1))
|
& (hold_target_addr_par_err == 1'b1))
|
begin
|
begin
|
$display ("*** test target %h - DEVSEL Asserted when Address Parity Error expected, at %t",
|
$display ("*** test target %h - DEVSEL Asserted when Address Parity Error expected, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // NORMAL_PCI_CHECKS
|
`endif // NORMAL_PCI_CHECKS
|
end
|
end
|
endtask
|
endtask
|
|
|
// While asserting DEVSEL, wait zero or more clocks as commanded by master
|
// While asserting DEVSEL, wait zero or more clocks as commanded by master
|
// This might be called with 1 waitstate before the read data can be OE'd
|
// This might be called with 1 waitstate before the read data can be OE'd
|
// or before the Master Parity can be checked.
|
// or before the Master Parity can be checked.
|
// Tasks can't have local storage! have to be module global
|
// Tasks can't have local storage! have to be module global
|
reg [3:0] cnt1;
|
reg [3:0] cnt1;
|
task Execute_Target_Waitstates;
|
task Execute_Target_Waitstates;
|
input drive_ad_bus;
|
input drive_ad_bus;
|
input enable_parity_check;
|
input enable_parity_check;
|
input [3:0] num_waitstates;
|
input [3:0] num_waitstates;
|
begin
|
begin
|
for (cnt1 = 4'h0; cnt1 < num_waitstates[3:0]; cnt1 = cnt1 + 4'h1)
|
for (cnt1 = 4'h0; cnt1 < num_waitstates[3:0]; cnt1 = cnt1 + 4'h1)
|
begin
|
begin
|
`ifdef NORMAL_PCI_CHECKS
|
`ifdef NORMAL_PCI_CHECKS
|
if (!pci_reset_comb & ~frame_now & ~irdy_now)
|
if (!pci_reset_comb & ~frame_now & ~irdy_now)
|
begin
|
begin
|
$display ("*** test target %h - Execute Target Waitstates Wait States called when no Master, at %t",
|
$display ("*** test target %h - Execute Target Waitstates Wait States called when no Master, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // NORMAL_PCI_CHECKS
|
`endif // NORMAL_PCI_CHECKS
|
target_ad_out <= `BUS_WAIT_STATE_VALUE;
|
target_ad_out <= `BUS_WAIT_STATE_VALUE;
|
target_ad_oe <= drive_ad_bus;
|
target_ad_oe <= drive_ad_bus;
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= enable_parity_check;
|
target_perr_check_next <= enable_parity_check;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Assert_DEVSEL;
|
Assert_DEVSEL;
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Deassert_STOP;
|
Deassert_STOP;
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
// DEVSEL already asserted upon entry to this task. OK to watch Parity
|
// DEVSEL already asserted upon entry to this task. OK to watch Parity
|
// Tasks can't have local storage! have to be module global
|
// Tasks can't have local storage! have to be module global
|
integer ii;
|
integer ii;
|
task Linger_Until_Master_Waitstates_Done;
|
task Linger_Until_Master_Waitstates_Done;
|
input drive_ad_bus;
|
input drive_ad_bus;
|
input [PCI_BUS_DATA_RANGE:0] target_read_data;
|
input [PCI_BUS_DATA_RANGE:0] target_read_data;
|
input do_target_disconnect;
|
input do_target_disconnect;
|
begin
|
begin
|
for (ii = 0; ii < TEST_TARGET_SPINLOOP_MAX; ii = ii + 1)
|
for (ii = 0; ii < TEST_TARGET_SPINLOOP_MAX; ii = ii + 1)
|
begin
|
begin
|
if (frame_now & ~irdy_now) // master executing wait states
|
if (frame_now & ~irdy_now) // master executing wait states
|
begin
|
begin
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= target_read_data[PCI_BUS_DATA_RANGE:0];
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= target_read_data[PCI_BUS_DATA_RANGE:0];
|
target_ad_oe <= drive_ad_bus;
|
target_ad_oe <= drive_ad_bus;
|
target_debug_force_bad_par <= hold_target_data_par_err;
|
target_debug_force_bad_par <= hold_target_data_par_err;
|
target_perr_check_next <= ~drive_ad_bus;
|
target_perr_check_next <= ~drive_ad_bus;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Assert_Target_Continue_Or_Disconnect (do_target_disconnect);
|
Assert_Target_Continue_Or_Disconnect (do_target_disconnect);
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
end
|
end
|
else
|
else
|
begin
|
begin
|
ii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
ii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
end
|
end
|
end
|
end
|
`ifdef NORMAL_PCI_CHECKS
|
`ifdef NORMAL_PCI_CHECKS
|
if (~pci_reset_comb & ~frame_now & ~irdy_now)
|
if (~pci_reset_comb & ~frame_now & ~irdy_now)
|
begin
|
begin
|
$display ("*** test target %h - Linger during Master Wait States called when no Master, at %t",
|
$display ("*** test target %h - Linger during Master Wait States called when no Master, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
if (~pci_reset_comb & (ii == TEST_TARGET_SPINLOOP_MAX))
|
if (~pci_reset_comb & (ii == TEST_TARGET_SPINLOOP_MAX))
|
begin
|
begin
|
$display ("*** test target %h - Bus stuck in Master Wait States during Target ref, at %t",
|
$display ("*** test target %h - Bus stuck in Master Wait States during Target ref, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // NORMAL_PCI_CHECKS
|
`endif // NORMAL_PCI_CHECKS
|
end
|
end
|
endtask
|
endtask
|
|
|
// Execute_Target_Abort. This must be called with DEVSEL asserted
|
// Execute_Target_Abort. This must be called with DEVSEL asserted
|
// Tasks can't have local storage! have to be module global
|
// Tasks can't have local storage! have to be module global
|
integer iii;
|
integer iii;
|
task Execute_Target_Abort_Undrive_DEVSEL;
|
task Execute_Target_Abort_Undrive_DEVSEL;
|
input drive_ad_bus;
|
input drive_ad_bus;
|
input signal_satisfied_delayed_read;
|
input signal_satisfied_delayed_read;
|
begin
|
begin
|
`ifdef NORMAL_PCI_CHECKS
|
`ifdef NORMAL_PCI_CHECKS
|
if (~pci_reset_comb & (target_devsel_out == 1'b0))
|
if (~pci_reset_comb & (target_devsel_out == 1'b0))
|
begin
|
begin
|
$display ("*** test target %h - DEVSEL not asserted when starting Target Abort, at %t",
|
$display ("*** test target %h - DEVSEL not asserted when starting Target Abort, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // NORMAL_PCI_CHECKS
|
`endif // NORMAL_PCI_CHECKS
|
for (iii = 0; iii < TEST_TARGET_SPINLOOP_MAX; iii = iii + 1)
|
for (iii = 0; iii < TEST_TARGET_SPINLOOP_MAX; iii = iii + 1)
|
begin
|
begin
|
if ((iii == 0) | frame_now | ~irdy_now) // At least one stop, Master Not Finished
|
if ((iii == 0) | frame_now | ~irdy_now) // At least one stop, Master Not Finished
|
begin
|
begin
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_signaling_target_abort <= 1'b1;
|
target_signaling_target_abort <= 1'b1;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
Deassert_DEVSEL; // Signal Target Abort
|
Deassert_DEVSEL; // Signal Target Abort
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Assert_STOP;
|
Assert_STOP;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Deassert_DEVSEL; // Signal Target Abort
|
Deassert_DEVSEL; // Signal Target Abort
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Deassert_STOP; // Master saw us, so leave
|
Deassert_STOP; // Master saw us, so leave
|
iii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
iii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
end
|
end
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
signal_satisfied_delayed_read = 1'b0;
|
signal_satisfied_delayed_read = 1'b0;
|
end
|
end
|
`ifdef NORMAL_PCI_CHECKS
|
`ifdef NORMAL_PCI_CHECKS
|
if (~pci_reset_comb & irdy_now)
|
if (~pci_reset_comb & irdy_now)
|
begin
|
begin
|
$display ("*** test target %h - Master didn't deassert IRDY at end of Target Abort, at %t",
|
$display ("*** test target %h - Master didn't deassert IRDY at end of Target Abort, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
if (~pci_reset_comb & (iii == TEST_TARGET_SPINLOOP_MAX))
|
if (~pci_reset_comb & (iii == TEST_TARGET_SPINLOOP_MAX))
|
begin
|
begin
|
$display ("*** test target %h - Bus didn't go Idle during Target Abort, at %t",
|
$display ("*** test target %h - Bus didn't go Idle during Target Abort, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // NORMAL_PCI_CHECKS
|
`endif // NORMAL_PCI_CHECKS
|
end
|
end
|
endtask
|
endtask
|
|
|
// Transfer a word with or without target termination, and act on Master Termination
|
// Transfer a word with or without target termination, and act on Master Termination
|
task Execute_Target_Ref_Undrive_DEVSEL_On_Any_Termination;
|
task Execute_Target_Ref_Undrive_DEVSEL_On_Any_Termination;
|
input drive_ad_bus;
|
input drive_ad_bus;
|
input do_target_disconnect;
|
input do_target_disconnect;
|
input signal_satisfied_delayed_read;
|
input signal_satisfied_delayed_read;
|
input [PCI_BUS_DATA_RANGE:0] target_read_data;
|
input [PCI_BUS_DATA_RANGE:0] target_read_data;
|
output [PCI_BUS_DATA_RANGE:0] master_write_data;
|
output [PCI_BUS_DATA_RANGE:0] master_write_data;
|
output [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
output [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
output target_was_terminated;
|
output target_was_terminated;
|
begin
|
begin
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= target_read_data[PCI_BUS_DATA_RANGE:0];
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= target_read_data[PCI_BUS_DATA_RANGE:0];
|
target_ad_oe <= drive_ad_bus;
|
target_ad_oe <= drive_ad_bus;
|
target_debug_force_bad_par <= hold_target_data_par_err;
|
target_debug_force_bad_par <= hold_target_data_par_err;
|
target_perr_check_next <= ~drive_ad_bus;
|
target_perr_check_next <= ~drive_ad_bus;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
Assert_Target_Continue_Or_Disconnect (do_target_disconnect);
|
Assert_Target_Continue_Or_Disconnect (do_target_disconnect);
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
Linger_Until_Master_Waitstates_Done (drive_ad_bus,
|
Linger_Until_Master_Waitstates_Done (drive_ad_bus,
|
target_read_data[PCI_BUS_DATA_RANGE:0], do_target_disconnect);
|
target_read_data[PCI_BUS_DATA_RANGE:0], do_target_disconnect);
|
master_write_data[PCI_BUS_DATA_RANGE:0] = ad_now[PCI_BUS_DATA_RANGE:0]; // unconditionally grab.
|
master_write_data[PCI_BUS_DATA_RANGE:0] = ad_now[PCI_BUS_DATA_RANGE:0]; // unconditionally grab.
|
master_mask_l[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
master_mask_l[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
if (frame_now & irdy_now & ~do_target_disconnect)
|
if (frame_now & irdy_now & ~do_target_disconnect)
|
begin
|
begin
|
target_was_terminated = 1'b0;
|
target_was_terminated = 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
if (frame_now & irdy_now & do_target_disconnect) // doing Target Termination
|
if (frame_now & irdy_now & do_target_disconnect) // doing Target Termination
|
begin
|
begin
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= drive_ad_bus;
|
target_ad_oe <= drive_ad_bus;
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= ~drive_ad_bus;
|
target_perr_check_next <= ~drive_ad_bus;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Assert_DEVSEL;
|
Assert_DEVSEL;
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Assert_STOP;
|
Assert_STOP;
|
Clock_Wait_Unless_Reset; // give master a chance to turn FRAME around
|
Clock_Wait_Unless_Reset; // give master a chance to turn FRAME around
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`ifdef NORMAL_PCI_CHECKS
|
`ifdef NORMAL_PCI_CHECKS
|
if (~pci_reset_comb & ~(~frame_now & irdy_now)) // error if not last master data phase
|
if (~pci_reset_comb & ~(~frame_now & irdy_now)) // error if not last master data phase
|
begin
|
begin
|
$display ("*** test target %h - Master entered fatally odd state in Target Ref, at %t",
|
$display ("*** test target %h - Master entered fatally odd state in Target Ref, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // NORMAL_PCI_CHECKS
|
`endif // NORMAL_PCI_CHECKS
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
target_debug_force_bad_par <= 1'b0;
|
target_debug_force_bad_par <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Deassert_DEVSEL;
|
Deassert_DEVSEL;
|
Deassert_TRDY;
|
Deassert_TRDY;
|
Deassert_STOP;
|
Deassert_STOP;
|
Clock_Wait_Unless_Reset;
|
Clock_Wait_Unless_Reset;
|
`ifdef NORMAL_PCI_CHECKS
|
`ifdef NORMAL_PCI_CHECKS
|
if (~pci_reset_comb & irdy_now)
|
if (~pci_reset_comb & irdy_now)
|
begin
|
begin
|
$display ("*** test target %h - IRDY didn't deassert at end of Master Termination, at %t",
|
$display ("*** test target %h - IRDY didn't deassert at end of Master Termination, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
error_detected <= ~error_detected;
|
error_detected <= ~error_detected;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
`endif // NORMAL_PCI_CHECKS
|
`endif // NORMAL_PCI_CHECKS
|
target_was_terminated = 1'b1;
|
target_was_terminated = 1'b1;
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
`define TEST_TARGET_DOING_CONFIG_READ 2'b00
|
`define TEST_TARGET_DOING_CONFIG_READ 2'b00
|
`define TEST_TARGET_DOING_CONFIG_WRITE 2'b01
|
`define TEST_TARGET_DOING_CONFIG_WRITE 2'b01
|
`define TEST_TARGET_DOING_SRAM_READ 2'b10
|
`define TEST_TARGET_DOING_SRAM_READ 2'b10
|
`define TEST_TARGET_DOING_SRAM_WRITE 2'b11
|
`define TEST_TARGET_DOING_SRAM_WRITE 2'b11
|
|
|
task Report_On_Target_PCI_Ref_Start;
|
task Report_On_Target_PCI_Ref_Start;
|
input [1:0] reference_type;
|
input [1:0] reference_type;
|
begin
|
begin
|
case (reference_type[1:0])
|
case (reference_type[1:0])
|
`TEST_TARGET_DOING_CONFIG_READ:
|
`TEST_TARGET_DOING_CONFIG_READ:
|
$display (" test target %h - Starting Config Read, at %t",
|
$display (" test target %h - Starting Config Read, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
`TEST_TARGET_DOING_CONFIG_WRITE:
|
`TEST_TARGET_DOING_CONFIG_WRITE:
|
$display (" test target %h - Starting Config Write, at %t",
|
$display (" test target %h - Starting Config Write, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
`TEST_TARGET_DOING_SRAM_READ:
|
`TEST_TARGET_DOING_SRAM_READ:
|
$display (" test target %h - Starting Memory Read, at %t",
|
$display (" test target %h - Starting Memory Read, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
`TEST_TARGET_DOING_SRAM_WRITE:
|
`TEST_TARGET_DOING_SRAM_WRITE:
|
$display (" test target %h - Starting Memory Write, at %t",
|
$display (" test target %h - Starting Memory Write, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
default:
|
default:
|
$display ("*** test target %h - Doing Unknown Reference, at %t",
|
$display ("*** test target %h - Doing Unknown Reference, at %t",
|
test_device_id[2:0], $time);
|
test_device_id[2:0], $time);
|
endcase
|
endcase
|
`ifdef VERBOSE_TEST_DEVICE
|
`ifdef VERBOSE_TEST_DEVICE
|
Report_Target_Reference_Paramaters;
|
Report_Target_Reference_Paramaters;
|
`endif // VERBOSE_TEST_DEVICE
|
`endif // VERBOSE_TEST_DEVICE
|
end
|
end
|
endtask
|
endtask
|
|
|
// Transfer either a burst of Config Registers or SRAM Contents across the PCI Bus
|
// Transfer either a burst of Config Registers or SRAM Contents across the PCI Bus
|
// Tasks can't have local storage! have to be module global
|
// Tasks can't have local storage! have to be module global
|
reg devsel_asserted, fast_devsel_asserted, target_was_terminated;
|
reg devsel_asserted, fast_devsel_asserted, target_was_terminated;
|
reg [3:0] wait_states_this_time;
|
reg [3:0] wait_states_this_time;
|
reg do_abort_this_time, do_retry_this_time, do_disconnect_this_time;
|
reg do_abort_this_time, do_retry_this_time, do_disconnect_this_time;
|
reg abort_needs_waitstate;
|
reg abort_needs_waitstate;
|
reg [PCI_BUS_DATA_RANGE:0] master_write_data;
|
reg [PCI_BUS_DATA_RANGE:0] master_write_data;
|
reg [PCI_BUS_DATA_RANGE:0] target_read_data;
|
reg [PCI_BUS_DATA_RANGE:0] target_read_data;
|
reg [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
reg [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
reg drive_ad_bus;
|
reg drive_ad_bus;
|
reg signal_satisfied_delayed_read;
|
reg signal_satisfied_delayed_read;
|
task Execute_Target_PCI_Ref;
|
task Execute_Target_PCI_Ref;
|
input [1:0] reference_type;
|
input [1:0] reference_type;
|
output saw_fast_back_to_back;
|
output saw_fast_back_to_back;
|
reg [9:0] number_of_transfers ;
|
reg [9:0] number_of_transfers ;
|
begin
|
begin
|
|
|
number_of_transfers = 0 ;
|
number_of_transfers = 0 ;
|
`ifdef REPORT_TEST_DEVICE
|
`ifdef REPORT_TEST_DEVICE
|
Report_On_Target_PCI_Ref_Start (reference_type[1:0]);
|
Report_On_Target_PCI_Ref_Start (reference_type[1:0]);
|
`endif // REPORT_TEST_DEVICE
|
`endif // REPORT_TEST_DEVICE
|
Wait_Till_DEVSEL_Possible (devsel_asserted, fast_devsel_asserted,
|
Wait_Till_DEVSEL_Possible (devsel_asserted, fast_devsel_asserted,
|
signal_satisfied_delayed_read);
|
signal_satisfied_delayed_read);
|
if (devsel_asserted == 1'b1)
|
if (devsel_asserted == 1'b1)
|
begin
|
begin
|
// Target must drive AD bus even if it is going to do an abort or retry.
|
// Target must drive AD bus even if it is going to do an abort or retry.
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.1
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.1
|
drive_ad_bus = (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_READ)
|
drive_ad_bus = (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_READ)
|
| (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_READ);
|
| (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_READ);
|
wait_states_this_time[3:0] = hold_target_initial_waitstates[3:0];
|
wait_states_this_time[3:0] = hold_target_initial_waitstates[3:0];
|
abort_needs_waitstate = (hold_target_initial_waitstates[3:0] == 4'h0);
|
abort_needs_waitstate = (hold_target_initial_waitstates[3:0] == 4'h0);
|
|
|
do_abort_this_time = ( (hold_target_termination[2:0] == `Test_Target_Abort) && (hold_target_terminate_on == 1) );
|
do_abort_this_time = ( (hold_target_termination[2:0] == `Test_Target_Abort) && (hold_target_terminate_on == 1) );
|
|
|
do_retry_this_time = ( (hold_target_termination[2:0] == `Test_Target_Retry_Before) && (hold_target_terminate_on == 1) ) |
|
do_retry_this_time = ( (hold_target_termination[2:0] == `Test_Target_Retry_Before) && (hold_target_terminate_on == 1) ) |
|
(hold_target_termination[2:0] == `Test_Target_Start_Delayed_Read) ;
|
(hold_target_termination[2:0] == `Test_Target_Start_Delayed_Read) ;
|
|
|
do_disconnect_this_time = ( (hold_target_termination[2:0] == `Test_Target_Disc_With) && (hold_target_terminate_on == 1) ) ;
|
do_disconnect_this_time = ( (hold_target_termination[2:0] == `Test_Target_Disc_With) && (hold_target_terminate_on == 1) ) ;
|
|
|
// If the bottom 2 bits of the Address aren't 2'b00, only transfer 1 word.
|
// If the bottom 2 bits of the Address aren't 2'b00, only transfer 1 word.
|
// See the PCI Local Bus Spec Revision 2.2 section 3.2.2.2
|
// See the PCI Local Bus Spec Revision 2.2 section 3.2.2.2
|
do_disconnect_this_time = do_disconnect_this_time
|
do_disconnect_this_time = do_disconnect_this_time
|
| (hold_target_address[1:0] != 2'b00);
|
| (hold_target_address[1:0] != 2'b00);
|
// If Fast Decode and it's a read, don't drive data for 1 clock to avoid AD bus fight
|
// If Fast Decode and it's a read, don't drive data for 1 clock to avoid AD bus fight
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.1
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.1
|
if (fast_devsel_asserted & drive_ad_bus)
|
if (fast_devsel_asserted & drive_ad_bus)
|
begin
|
begin
|
Execute_Target_Waitstates (1'b0, 1'b0, 4'h1); // avoid collisions on AD bus
|
Execute_Target_Waitstates (1'b0, 1'b0, 4'h1); // avoid collisions on AD bus
|
if (wait_states_this_time[3:0] != 4'h0)
|
if (wait_states_this_time[3:0] != 4'h0)
|
begin
|
begin
|
wait_states_this_time[3:0] = wait_states_this_time[3:0] - 4'h1;
|
wait_states_this_time[3:0] = wait_states_this_time[3:0] - 4'h1;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
target_was_terminated = 1'b0;
|
target_was_terminated = 1'b0;
|
while (target_was_terminated == 1'b0)
|
while (target_was_terminated == 1'b0)
|
begin
|
begin
|
Execute_Target_Waitstates (drive_ad_bus, ~drive_ad_bus,
|
Execute_Target_Waitstates (drive_ad_bus, ~drive_ad_bus,
|
wait_states_this_time[3:0]);
|
wait_states_this_time[3:0]);
|
if (do_abort_this_time)
|
if (do_abort_this_time)
|
begin
|
begin
|
if (abort_needs_waitstate)
|
if (abort_needs_waitstate)
|
begin
|
begin
|
Execute_Target_Waitstates (drive_ad_bus, ~drive_ad_bus, 4'h1);
|
Execute_Target_Waitstates (drive_ad_bus, ~drive_ad_bus, 4'h1);
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
Execute_Target_Abort_Undrive_DEVSEL (drive_ad_bus,
|
Execute_Target_Abort_Undrive_DEVSEL (drive_ad_bus,
|
signal_satisfied_delayed_read);
|
signal_satisfied_delayed_read);
|
target_was_terminated = 1'b1;
|
target_was_terminated = 1'b1;
|
end
|
end
|
else if (do_retry_this_time)
|
else if (do_retry_this_time)
|
begin
|
begin
|
Execute_Target_Retry_Undrive_DEVSEL (drive_ad_bus,
|
Execute_Target_Retry_Undrive_DEVSEL (drive_ad_bus,
|
(hold_target_termination[2:0] == `Test_Target_Start_Delayed_Read)
|
(hold_target_termination[2:0] == `Test_Target_Start_Delayed_Read)
|
& ( (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
& ( (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
PCI_COMMAND_MEMORY_READ)
|
PCI_COMMAND_MEMORY_READ)
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
PCI_COMMAND_MEMORY_READ_LINE)
|
PCI_COMMAND_MEMORY_READ_LINE)
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
PCI_COMMAND_CONFIG_READ) ),
|
PCI_COMMAND_CONFIG_READ) ),
|
signal_satisfied_delayed_read);
|
signal_satisfied_delayed_read);
|
target_was_terminated = 1'b1;
|
target_was_terminated = 1'b1;
|
end
|
end
|
else // at least one data item should be read out of this device
|
else // at least one data item should be read out of this device
|
begin
|
begin
|
// do_disconnect_this_time = do_disconnect_this_time // prevent address roll-over
|
// do_disconnect_this_time = do_disconnect_this_time // prevent address roll-over
|
// | (hold_target_address[7:2] == 6'h3F);
|
// | (hold_target_address[7:2] == 6'h3F);
|
if (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_READ)
|
if (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_READ)
|
begin
|
begin
|
Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus (target_read_data[PCI_BUS_DATA_RANGE:0]);
|
Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus (target_read_data[PCI_BUS_DATA_RANGE:0]);
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
if (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_READ)
|
if (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_READ)
|
begin
|
begin
|
Fetch_SRAM_Data_For_Read_Onto_AD_Bus (target_read_data[PCI_BUS_DATA_RANGE:0]);
|
Fetch_SRAM_Data_For_Read_Onto_AD_Bus (target_read_data[PCI_BUS_DATA_RANGE:0]);
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
Execute_Target_Ref_Undrive_DEVSEL_On_Any_Termination
|
Execute_Target_Ref_Undrive_DEVSEL_On_Any_Termination
|
(drive_ad_bus, do_disconnect_this_time,
|
(drive_ad_bus, do_disconnect_this_time,
|
signal_satisfied_delayed_read,
|
signal_satisfied_delayed_read,
|
target_read_data[PCI_BUS_DATA_RANGE:0],
|
target_read_data[PCI_BUS_DATA_RANGE:0],
|
master_write_data[PCI_BUS_DATA_RANGE:0],
|
master_write_data[PCI_BUS_DATA_RANGE:0],
|
master_mask_l[PCI_BUS_CBE_RANGE:0],
|
master_mask_l[PCI_BUS_CBE_RANGE:0],
|
target_was_terminated);
|
target_was_terminated);
|
number_of_transfers = number_of_transfers + 1 ;
|
number_of_transfers = number_of_transfers + 1 ;
|
|
|
if (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_WRITE)
|
if (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_WRITE)
|
begin
|
begin
|
Capture_Config_Reg_Data_From_AD_Bus (master_write_data[PCI_BUS_DATA_RANGE:0],
|
Capture_Config_Reg_Data_From_AD_Bus (master_write_data[PCI_BUS_DATA_RANGE:0],
|
master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
if (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_WRITE)
|
if (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_WRITE)
|
begin
|
begin
|
Capture_SRAM_Data_From_AD_Bus (master_write_data[PCI_BUS_DATA_RANGE:0],
|
Capture_SRAM_Data_From_AD_Bus (master_write_data[PCI_BUS_DATA_RANGE:0],
|
master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
end
|
end
|
|
|
`NO_ELSE;
|
`NO_ELSE;
|
// set up for the next transfer
|
// set up for the next transfer
|
wait_states_this_time[3:0] = hold_target_subsequent_waitstates[3:0];
|
wait_states_this_time[3:0] = hold_target_subsequent_waitstates[3:0];
|
abort_needs_waitstate = 1'b0;
|
abort_needs_waitstate = 1'b0;
|
/*do_abort_this_time = (hold_target_termination[2:0]
|
/*do_abort_this_time = (hold_target_termination[2:0]
|
== `Test_Target_Abort_Before_Second);
|
== `Test_Target_Abort_Before_Second);
|
do_retry_this_time = (hold_target_termination[2:0]
|
do_retry_this_time = (hold_target_termination[2:0]
|
== `Test_Target_Retry_Before_Second);
|
== `Test_Target_Retry_Before_Second);
|
do_disconnect_this_time = (hold_target_termination[2:0]
|
do_disconnect_this_time = (hold_target_termination[2:0]
|
== `Test_Target_Disc_With_Second);*/
|
== `Test_Target_Disc_With_Second);*/
|
|
|
do_abort_this_time = ( (hold_target_termination[2:0] == `Test_Target_Abort) && (hold_target_terminate_on == (number_of_transfers + 1)) );
|
do_abort_this_time = ( (hold_target_termination[2:0] == `Test_Target_Abort) && (hold_target_terminate_on == (number_of_transfers + 1)) );
|
|
|
do_retry_this_time = ( (hold_target_termination[2:0] == `Test_Target_Retry_Before) && (hold_target_terminate_on == (number_of_transfers + 1)) ) ;
|
do_retry_this_time = ( (hold_target_termination[2:0] == `Test_Target_Retry_Before) && (hold_target_terminate_on == (number_of_transfers + 1)) ) ;
|
|
|
do_disconnect_this_time = ( (hold_target_termination[2:0] == `Test_Target_Disc_With) && (hold_target_terminate_on == (number_of_transfers + 1)) ) ;
|
do_disconnect_this_time = ( (hold_target_termination[2:0] == `Test_Target_Disc_With) && (hold_target_terminate_on == (number_of_transfers + 1)) ) ;
|
|
|
signal_satisfied_delayed_read = 1'b0;
|
signal_satisfied_delayed_read = 1'b0;
|
end
|
end
|
end
|
end
|
// Watch for Fast Back-to-Back reference. If seen, do not go to the top
|
// Watch for Fast Back-to-Back reference. If seen, do not go to the top
|
// of the Target Idle Loop, which automatically waits for one clock.
|
// of the Target Idle Loop, which automatically waits for one clock.
|
// Instead go directly to see if this device is addressed.
|
// Instead go directly to see if this device is addressed.
|
// This transition is manditory even if the device can't do
|
// This transition is manditory even if the device can't do
|
// fast-back-to-back transfers!
|
// fast-back-to-back transfers!
|
// See the PCI Local Bus Spec Revision 2.2 section 3.4.2.
|
// See the PCI Local Bus Spec Revision 2.2 section 3.4.2.
|
saw_fast_back_to_back = frame_now & ~irdy_now;
|
saw_fast_back_to_back = frame_now & ~irdy_now;
|
// No clock here to let this dovetail with the next reference?
|
// No clock here to let this dovetail with the next reference?
|
end
|
end
|
else
|
else
|
begin // no devsel, so it must have been an address parity error
|
begin // no devsel, so it must have been an address parity error
|
saw_fast_back_to_back = 1'b0;
|
saw_fast_back_to_back = 1'b0;
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
// Task to print debug info
|
// Task to print debug info
|
// NOTE This must change if bit allocation changes
|
// NOTE This must change if bit allocation changes
|
task Report_Target_Reference_Paramaters;
|
task Report_Target_Reference_Paramaters;
|
begin
|
begin
|
if (hold_target_address[23:9] != 15'h0000)
|
if (hold_target_address[23:9] != 15'h0000)
|
begin
|
begin
|
$display (" Target Devsel Speed %h, Target Termination %h,",
|
$display (" Target Devsel Speed %h, Target Termination %h,",
|
hold_target_devsel_speed[1:0], hold_target_termination[2:0]);
|
hold_target_devsel_speed[1:0], hold_target_termination[2:0]);
|
$display (" First Target Data Wait States %h, Subsequent Target Data Wait States %h",
|
$display (" First Target Data Wait States %h, Subsequent Target Data Wait States %h",
|
hold_target_initial_waitstates[3:0],
|
hold_target_initial_waitstates[3:0],
|
hold_target_subsequent_waitstates[3:0]);
|
hold_target_subsequent_waitstates[3:0]);
|
$display (" Addr Par Error %h, Data Par Error %h",
|
$display (" Addr Par Error %h, Data Par Error %h",
|
hold_target_addr_par_err, hold_target_data_par_err);
|
hold_target_addr_par_err, hold_target_data_par_err);
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
end
|
end
|
endtask
|
endtask
|
|
|
task Reset_Target_To_Idle;
|
task Reset_Target_To_Idle;
|
begin
|
begin
|
Init_Test_Device_SRAM;
|
Init_Test_Device_SRAM;
|
target_ad_oe <= 1'b0;
|
target_ad_oe <= 1'b0;
|
target_devsel_out <= 1'b0;
|
target_devsel_out <= 1'b0;
|
target_trdy_out <= 1'b0;
|
target_trdy_out <= 1'b0;
|
target_stop_out <= 1'b0;
|
target_stop_out <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_perr_check_next <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
target_signaling_target_abort <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Started <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
Delayed_Read_Finished <= 1'b0;
|
end
|
end
|
endtask
|
endtask
|
|
|
// Config References are described in PCI Local Bus Spec
|
// Config References are described in PCI Local Bus Spec
|
// Revision 2.2 section 3.2.2.3.4
|
// Revision 2.2 section 3.2.2.3.4
|
// The idea is that a Config command must be seen, IDSEL must be LOW,
|
// The idea is that a Config command must be seen, IDSEL must be LOW,
|
// AD[1:0] must be 2'b00, and either AD[10:8] should be ignored
|
// AD[1:0] must be 2'b00, and either AD[10:8] should be ignored
|
// for a single function device, or only implemented devices should
|
// for a single function device, or only implemented devices should
|
// respond. Function 0 is required to be detected.
|
// respond. Function 0 is required to be detected.
|
|
|
// Make a fake version just to make the charts pop:
|
// Make a fake version just to make the charts pop:
|
|
|
// Fire off Target tasks in response to PCI Bus Activity
|
// Fire off Target tasks in response to PCI Bus Activity
|
reg saw_fast_back_to_back;
|
reg saw_fast_back_to_back;
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
begin
|
begin
|
if (~pci_reset_comb)
|
if (~pci_reset_comb)
|
begin
|
begin
|
saw_fast_back_to_back = 1'b1;
|
saw_fast_back_to_back = 1'b1;
|
while (saw_fast_back_to_back == 1'b1) // whats the value of this loop? Does it reset correctly?
|
while (saw_fast_back_to_back == 1'b1) // whats the value of this loop? Does it reset correctly?
|
begin
|
begin
|
hold_target_address[PCI_BUS_DATA_RANGE:0] = ad_now[PCI_BUS_DATA_RANGE:0]; // intentionally use "="
|
hold_target_address[PCI_BUS_DATA_RANGE:0] = ad_now[PCI_BUS_DATA_RANGE:0]; // intentionally use "="
|
hold_target_command[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
hold_target_command[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
if (test_response[`TARGET_ENCODED_PARAMATERS_ENABLE] != 1'b0)
|
if (test_response[`TARGET_ENCODED_PARAMATERS_ENABLE] != 1'b0)
|
begin
|
begin
|
hold_target_initial_waitstates = test_response[`TARGET_ENCODED_INIT_WAITSTATES];
|
hold_target_initial_waitstates = test_response[`TARGET_ENCODED_INIT_WAITSTATES];
|
hold_target_subsequent_waitstates = test_response[`TARGET_ENCODED_SUBS_WAITSTATES];
|
hold_target_subsequent_waitstates = test_response[`TARGET_ENCODED_SUBS_WAITSTATES];
|
hold_target_termination = test_response[`TARGET_ENCODED_TERMINATION];
|
hold_target_termination = test_response[`TARGET_ENCODED_TERMINATION];
|
hold_target_devsel_speed = test_response[`TARGET_ENCODED_DEVSEL_SPEED];
|
hold_target_devsel_speed = test_response[`TARGET_ENCODED_DEVSEL_SPEED];
|
hold_target_data_par_err = test_response[`TARGET_ENCODED_DATA_PAR_ERR];
|
hold_target_data_par_err = test_response[`TARGET_ENCODED_DATA_PAR_ERR];
|
hold_target_addr_par_err = test_response[`TARGET_ENCODED_ADDR_PAR_ERR];
|
hold_target_addr_par_err = test_response[`TARGET_ENCODED_ADDR_PAR_ERR];
|
hold_target_terminate_on = test_response[`TARGET_ENCODED_TERMINATE_ON];
|
hold_target_terminate_on = test_response[`TARGET_ENCODED_TERMINATE_ON];
|
end
|
end
|
else
|
else
|
begin
|
begin
|
hold_target_initial_waitstates = 4'h0;
|
hold_target_initial_waitstates = 4'h0;
|
hold_target_subsequent_waitstates = 4'h0;
|
hold_target_subsequent_waitstates = 4'h0;
|
hold_target_termination = `Test_Target_Normal_Completion;
|
hold_target_termination = `Test_Target_Normal_Completion;
|
hold_target_devsel_speed = `Test_Devsel_Medium;
|
hold_target_devsel_speed = `Test_Devsel_Medium;
|
hold_target_data_par_err = `Test_No_Data_Perr;
|
hold_target_data_par_err = `Test_No_Data_Perr;
|
hold_target_addr_par_err = `Test_No_Addr_Perr;
|
hold_target_addr_par_err = `Test_No_Addr_Perr;
|
hold_target_terminate_on = 0 ;
|
hold_target_terminate_on = 0 ;
|
end
|
end
|
|
|
if (~frame_prev & frame_now & Target_En
|
if (~frame_prev & frame_now & Target_En
|
`ifdef SIMULTANEOUS_MASTER_TARGET
|
`ifdef SIMULTANEOUS_MASTER_TARGET
|
// don't check for reads to self
|
// don't check for reads to self
|
`else // SIMULTANEOUS_MASTER_TARGET
|
`else // SIMULTANEOUS_MASTER_TARGET
|
// check for, and don't respond to, reads to self
|
// check for, and don't respond to, reads to self
|
`endif //SIMULTANEOUS_MASTER_TARGET
|
`endif //SIMULTANEOUS_MASTER_TARGET
|
& ( (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_WRITE)
|
& ( (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_WRITE)
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_WRITE_INVALIDATE) )
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_WRITE_INVALIDATE) )
|
& ( (ad_now[`PCI_BASE_ADDR0_MATCH_RANGE] == BAR0[`PCI_BASE_ADDR0_MATCH_RANGE])
|
& ( (ad_now[`PCI_BASE_ADDR0_MATCH_RANGE] == BAR0[`PCI_BASE_ADDR0_MATCH_RANGE])
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
| (ad_now[`PCI_BASE_ADDR1_MATCH_RANGE] == BAR1[`PCI_BASE_ADDR1_MATCH_RANGE])
|
| (ad_now[`PCI_BASE_ADDR1_MATCH_RANGE] == BAR1[`PCI_BASE_ADDR1_MATCH_RANGE])
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
) )
|
) )
|
begin
|
begin
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_SRAM_WRITE,
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_SRAM_WRITE,
|
saw_fast_back_to_back);
|
saw_fast_back_to_back);
|
end
|
end
|
else if (~frame_prev & frame_now & (idsel_now == 1'b1)
|
else if (~frame_prev & frame_now & (idsel_now == 1'b1)
|
& (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_WRITE)
|
& (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_WRITE)
|
& (ad_now[1:0] == 2'b00) )
|
& (ad_now[1:0] == 2'b00) )
|
begin
|
begin
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_CONFIG_WRITE,
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_CONFIG_WRITE,
|
saw_fast_back_to_back);
|
saw_fast_back_to_back);
|
end
|
end
|
else if (~frame_prev & frame_now & Target_En
|
else if (~frame_prev & frame_now & Target_En
|
`ifdef SIMULTANEOUS_MASTER_TARGET
|
`ifdef SIMULTANEOUS_MASTER_TARGET
|
// Don't check for reads to self
|
// Don't check for reads to self
|
`else // SIMULTANEOUS_MASTER_TARGET
|
`else // SIMULTANEOUS_MASTER_TARGET
|
// Check for, and don't respond to, reads to self
|
// Check for, and don't respond to, reads to self
|
`endif //SIMULTANEOUS_MASTER_TARGET
|
`endif //SIMULTANEOUS_MASTER_TARGET
|
& ( (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ)
|
& ( (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ)
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ_LINE) )
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ_LINE) )
|
& ( (ad_now[`PCI_BASE_ADDR0_MATCH_RANGE] == BAR0[`PCI_BASE_ADDR0_MATCH_RANGE])
|
& ( (ad_now[`PCI_BASE_ADDR0_MATCH_RANGE] == BAR0[`PCI_BASE_ADDR0_MATCH_RANGE])
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
| (ad_now[`PCI_BASE_ADDR1_MATCH_RANGE] == BAR1[`PCI_BASE_ADDR1_MATCH_RANGE])
|
| (ad_now[`PCI_BASE_ADDR1_MATCH_RANGE] == BAR1[`PCI_BASE_ADDR1_MATCH_RANGE])
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
) )
|
) )
|
begin
|
begin
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_SRAM_READ,
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_SRAM_READ,
|
saw_fast_back_to_back);
|
saw_fast_back_to_back);
|
end
|
end
|
else if (~frame_prev & frame_now & (idsel_now == 1'b1)
|
else if (~frame_prev & frame_now & (idsel_now == 1'b1)
|
& (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_READ)
|
& (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_READ)
|
& (ad_now[1:0] == 2'b00) )
|
& (ad_now[1:0] == 2'b00) )
|
begin
|
begin
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_CONFIG_READ,
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_CONFIG_READ,
|
saw_fast_back_to_back);
|
saw_fast_back_to_back);
|
end
|
end
|
else
|
else
|
begin
|
begin
|
saw_fast_back_to_back = 1'b0;
|
saw_fast_back_to_back = 1'b0;
|
end
|
end
|
if (pci_reset_comb)
|
if (pci_reset_comb)
|
begin
|
begin
|
saw_fast_back_to_back = 1'b0;
|
saw_fast_back_to_back = 1'b0;
|
end
|
end
|
end // saw_fast_back_to_back
|
end // saw_fast_back_to_back
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
// Because this is sequential code, have to reset all regs if the above falls
|
// Because this is sequential code, have to reset all regs if the above falls
|
// through due to a reset. This would not be needed in synthesizable code.
|
// through due to a reset. This would not be needed in synthesizable code.
|
if (pci_reset_comb)
|
if (pci_reset_comb)
|
begin
|
begin
|
Reset_Target_To_Idle;
|
Reset_Target_To_Idle;
|
end
|
end
|
`NO_ELSE;
|
`NO_ELSE;
|
end
|
end
|
endmodule
|
endmodule
|
|
|
|
|