1 |
19 |
mihad |
//===========================================================================
|
2 |
|
|
// $Id: pci_behaviorial_target.v,v 1.1 2002-02-01 15:07:51 mihad Exp $
|
3 |
|
|
//
|
4 |
|
|
// Copyright 2001 Blue Beaver. All Rights Reserved.
|
5 |
|
|
//
|
6 |
|
|
// Summary: A PCI Behaviorial Target. This module receives commands over
|
7 |
|
|
// the PCI Bus. The PCI Master encodes commands in the middle
|
8 |
|
|
// 16 bits of the PCI Address. This Target contains Config
|
9 |
|
|
// registers and a 256 byte scratch SRAM. It responds with data
|
10 |
|
|
// when it is given a Read command, and checks data when it is
|
11 |
|
|
// given a Write command.
|
12 |
|
|
// This interface does implement a very simple Delayed Read
|
13 |
|
|
// facility which is enough to let the user manually make the
|
14 |
|
|
// PCI Bus look like a Delayed Read is begin done. This will
|
15 |
|
|
// probably not work when a synthesizable PCI Interface tries
|
16 |
|
|
// to cause Delayed Reads. But by then, a second synthesizable
|
17 |
|
|
// PCI Core will be the more useful test target.
|
18 |
|
|
//
|
19 |
|
|
// This library is free software; you can distribute it and/or modify it
|
20 |
|
|
// under the terms of the GNU Lesser General Public License as published
|
21 |
|
|
// by the Free Software Foundation; either version 2.1 of the License, or
|
22 |
|
|
// (at your option) any later version.
|
23 |
|
|
//
|
24 |
|
|
// This library is distributed in the hope that it will be useful, but
|
25 |
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
26 |
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
27 |
|
|
// See the GNU Lesser General Public License for more details.
|
28 |
|
|
//
|
29 |
|
|
// You should have received a copy of the GNU Lesser General Public License
|
30 |
|
|
// along with this library. If not, write to
|
31 |
|
|
// Free Software Foundation, Inc.
|
32 |
|
|
// 59 Temple Place, Suite 330
|
33 |
|
|
// Boston, MA 02111-1307 USA
|
34 |
|
|
//
|
35 |
|
|
// Author's note about this license: The intention of the Author and of
|
36 |
|
|
// the Gnu Lesser General Public License is that users should be able to
|
37 |
|
|
// use this code for any purpose, including combining it with other source
|
38 |
|
|
// code, combining it with other logic, translated it into a gate-level
|
39 |
|
|
// representation, or projected it into gates in a programmable or
|
40 |
|
|
// hardwired chip, as long as the users of the resulting source, compiled
|
41 |
|
|
// source, or chip are given the means to get a copy of this source code
|
42 |
|
|
// with no new restrictions on redistribution of this source.
|
43 |
|
|
//
|
44 |
|
|
// If you make changes, even substantial changes, to this code, or use
|
45 |
|
|
// substantial parts of this code as an inseparable part of another work
|
46 |
|
|
// of authorship, the users of the resulting IP must be given the means
|
47 |
|
|
// to get a copy of the modified or combined source code, with no new
|
48 |
|
|
// restrictions on redistribution of the resulting source.
|
49 |
|
|
//
|
50 |
|
|
// Separate parts of the combined source code, compiled code, or chip,
|
51 |
|
|
// which are NOT derived from this source code do NOT need to be offered
|
52 |
|
|
// to the final user of the chip merely because they are used in
|
53 |
|
|
// combination with this code. Other code is not forced to fall under
|
54 |
|
|
// the GNU Lesser General Public License when it is linked to this code.
|
55 |
|
|
// The license terms of other source code linked to this code might require
|
56 |
|
|
// that it NOT be made available to users. The GNU Lesser General Public
|
57 |
|
|
// License does not prevent this code from being used in such a situation,
|
58 |
|
|
// as long as the user of the resulting IP is given the means to get a
|
59 |
|
|
// copy of this component of the IP with no new restrictions on
|
60 |
|
|
// redistribution of this source.
|
61 |
|
|
//
|
62 |
|
|
// This code was developed using VeriLogger Pro, by Synapticad.
|
63 |
|
|
// Their support is greatly appreciated.
|
64 |
|
|
//
|
65 |
|
|
// NOTE: This Test Chip instantiates one PCI interface and connects it
|
66 |
|
|
// to its IO pads and to logic representing a real application.
|
67 |
|
|
//
|
68 |
|
|
// NOTE TODO: Horrible. Tasks can't depend on their Arguments being safe
|
69 |
|
|
// if there are several instances ofthe tasl running at once.
|
70 |
|
|
// NOTE TODO: need to check parity on writes, and report if error status wrong
|
71 |
|
|
// NOTE TODO: need to drive PERR and SERR lines
|
72 |
|
|
// NOTE TODO: need to start setting error bits in Config Register
|
73 |
|
|
// Need to detect Address Parity Errors, and report them 3.7.3
|
74 |
|
|
// Need to allow bad parity address decodes if Parity Error Response not set 3.7.3
|
75 |
|
|
// Need to act on Delayed Read commands
|
76 |
|
|
// Need to do retries on other READ commands when delayed read in progress
|
77 |
|
|
// Need to clear delayed read in progress bit when Config Register says to
|
78 |
|
|
// Need to consider holding PERR if asserted without regards to TRDY and IRDY
|
79 |
|
|
// See 3.7.4.1 for details. If done as now, no need to hold.
|
80 |
|
|
// Need to assert SERR on address parity errors 3.7.4.2
|
81 |
|
|
// Need to record errors. 3.7.4.3, 3.7.4.4
|
82 |
|
|
// Complain if address parity error not seen when expected
|
83 |
|
|
// Complain if data parity error not seen when expected
|
84 |
|
|
//
|
85 |
|
|
//===========================================================================
|
86 |
|
|
|
87 |
|
|
`timescale 1ns/1ps
|
88 |
|
|
|
89 |
|
|
module pci_behaviorial_target (
|
90 |
|
|
ad_now, ad_prev, target_ad_out, target_ad_oe,
|
91 |
|
|
cbe_l_now, cbe_l_prev, calc_input_parity_prev, par_now, par_prev,
|
92 |
|
|
frame_now, frame_prev, irdy_now, irdy_prev,
|
93 |
|
|
target_devsel_out, target_d_t_s_oe, target_trdy_out, target_stop_out,
|
94 |
|
|
target_perr_out, target_perr_oe, target_serr_oe,
|
95 |
|
|
idsel_now, idsel_prev,
|
96 |
|
|
pci_reset_comb, pci_ext_clk,
|
97 |
|
|
// Signals from the master to the target to set bits in the Status Register
|
98 |
|
|
master_got_parity_error, master_asserted_serr, master_got_master_abort,
|
99 |
|
|
master_got_target_abort, master_caused_parity_error,
|
100 |
|
|
master_enable, master_fast_b2b_en, master_perr_enable, master_serr_enable,
|
101 |
|
|
master_latency_value,
|
102 |
|
|
// Signals used by the test bench instead of using "." notation
|
103 |
|
|
target_debug_force_bad_par,
|
104 |
|
|
test_error_event, test_device_id,
|
105 |
|
|
test_response
|
106 |
|
|
);
|
107 |
|
|
|
108 |
|
|
`include "pci_blue_options.vh"
|
109 |
|
|
`include "pci_blue_constants.vh"
|
110 |
|
|
|
111 |
|
|
input [PCI_BUS_DATA_RANGE:0] ad_now;
|
112 |
|
|
input [PCI_BUS_DATA_RANGE:0] ad_prev;
|
113 |
|
|
output [PCI_BUS_DATA_RANGE:0] target_ad_out;
|
114 |
|
|
output target_ad_oe;
|
115 |
|
|
input [PCI_BUS_CBE_RANGE:0] cbe_l_now;
|
116 |
|
|
input [PCI_BUS_CBE_RANGE:0] cbe_l_prev;
|
117 |
|
|
input calc_input_parity_prev;
|
118 |
|
|
input par_now, par_prev;
|
119 |
|
|
input frame_now, frame_prev, irdy_now, irdy_prev;
|
120 |
|
|
output target_devsel_out, target_d_t_s_oe, target_trdy_out, target_stop_out;
|
121 |
|
|
output target_perr_out, target_perr_oe, target_serr_oe;
|
122 |
|
|
input idsel_now, idsel_prev;
|
123 |
|
|
input pci_reset_comb, pci_ext_clk;
|
124 |
|
|
// Signals from the master to the target to set bits in the Status Register
|
125 |
|
|
input master_got_parity_error, master_asserted_serr, master_got_master_abort;
|
126 |
|
|
input master_got_target_abort, master_caused_parity_error;
|
127 |
|
|
output master_enable, master_fast_b2b_en, master_perr_enable, master_serr_enable;
|
128 |
|
|
output [7:0] master_latency_value;
|
129 |
|
|
// Signals used by the test bench instead of using "." notation
|
130 |
|
|
output target_debug_force_bad_par;
|
131 |
|
|
output test_error_event;
|
132 |
|
|
input [2:0] test_device_id;
|
133 |
|
|
input [25:0] test_response ;
|
134 |
|
|
|
135 |
|
|
reg [PCI_BUS_DATA_RANGE:0] target_ad_out;
|
136 |
|
|
reg target_ad_oe;
|
137 |
|
|
reg target_devsel_out, target_trdy_out, target_stop_out;
|
138 |
|
|
wire target_d_t_s_oe, target_perr_oe;
|
139 |
|
|
reg target_perr_out, target_serr_oe;
|
140 |
|
|
reg target_debug_force_bad_par;
|
141 |
|
|
reg test_error_event;
|
142 |
|
|
|
143 |
|
|
// Make temporary Bip every time an error is detected
|
144 |
|
|
initial test_error_event <= 1'bZ;
|
145 |
|
|
reg error_detected;
|
146 |
|
|
initial error_detected <= 1'b0;
|
147 |
|
|
always @(error_detected)
|
148 |
|
|
begin
|
149 |
|
|
test_error_event <= 1'b0;
|
150 |
|
|
#2;
|
151 |
|
|
test_error_event <= 1'bZ;
|
152 |
|
|
end
|
153 |
|
|
|
154 |
|
|
// Target Interface:
|
155 |
|
|
// This will have just enough memory to make debugging exciting.
|
156 |
|
|
// It will have 256 Bytes of SRAM. The memory will be available
|
157 |
|
|
// BOTH as Config memory and as regular memory.
|
158 |
|
|
// Special regions of the memory will have special characteristics.
|
159 |
|
|
// Locations 0, 4, 8, A, 10, and 14 will be implemented as Control
|
160 |
|
|
// registers.
|
161 |
|
|
// Locations 18 and 1C will be used for memory debugging (somehow!)
|
162 |
|
|
// All other locations will act as simple memory.
|
163 |
|
|
|
164 |
|
|
// Config Register Area consists of:
|
165 |
|
|
// 31 24 23 16 15 8 7 0
|
166 |
|
|
// | Device ID | Vendor ID | 0x00
|
167 |
|
|
// | Status | Command | 0x04
|
168 |
|
|
// | Class Code | Rev | 0x08
|
169 |
|
|
// | BIST | HEAD | LTCY | CSize| 0x0A
|
170 |
|
|
// | Base Address 0 | 0x10
|
171 |
|
|
// | Base Address 1 | 0x14
|
172 |
|
|
// | Unused | 0x18
|
173 |
|
|
// | Unused | 0x1C
|
174 |
|
|
// | Unused | 0x20
|
175 |
|
|
// | Unused | 0x24
|
176 |
|
|
// | Cardbus Pointer | 0x28
|
177 |
|
|
// | SubSys ID | SubVnd ID | 0x2C
|
178 |
|
|
// | Expansion ROM Pointer | 0x30
|
179 |
|
|
// | Reserved | Cap | 0x34
|
180 |
|
|
// | Reserved | 0x38
|
181 |
|
|
// | MLat | MGnt | IPin | ILine| 0x3C
|
182 |
|
|
//
|
183 |
|
|
// Command resets to 0 or maybe 0x80. It consists of:
|
184 |
|
|
// {6'h00, FB2B_En, SERR_En,
|
185 |
|
|
// Step_En, Par_Err_En, VGA_En, Mem_Write_Inv_En,
|
186 |
|
|
// Special_En, Master_En, Target_En, IO_En}
|
187 |
|
|
//
|
188 |
|
|
// Status consists of:
|
189 |
|
|
// {Detected_Perr, Signaled_Serr, Got_Master_Abort, Got_Target_Abort,
|
190 |
|
|
// Signaled_Target_Abort, Devsel_Timing[1:0], Master_Got_Perr,
|
191 |
|
|
// FB2B_Capable, 1'b0, 66MHz_Capable, New_Capabilities,
|
192 |
|
|
// 4'h0}
|
193 |
|
|
//
|
194 |
|
|
// Got_Master_Abort is not set for Special Cycles.
|
195 |
|
|
// Devsel will be 2'h01 in this design. New_Capabilities is 1'b0.
|
196 |
|
|
// All clearable bits in this register are cleared whenever the
|
197 |
|
|
// register is written with the corresponding bit being 1'b1.
|
198 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 6.2.3.
|
199 |
|
|
|
200 |
|
|
reg FB2B_En, SERR_En, Par_Err_En, Master_En, Target_En;
|
201 |
|
|
reg Detected_PERR, Signaled_SERR, Received_Master_Abort, Received_Target_Abort;
|
202 |
|
|
reg Signaled_Target_Abort, Master_Caused_PERR;
|
203 |
|
|
reg [7:0] Latency_Timer;
|
204 |
|
|
reg [7:0] Cache_Line_Size;
|
205 |
|
|
reg [7:0] Interrupt_Line;
|
206 |
|
|
reg [`PCI_BASE_ADDR0_MATCH_RANGE] BAR0; // Base Address Registers, used to match addresses
|
207 |
|
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
208 |
|
|
reg [`PCI_BASE_ADDR1_MATCH_RANGE] BAR1;
|
209 |
|
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
210 |
|
|
|
211 |
|
|
wire [15:0] Target_Command =
|
212 |
|
|
{4'b0000,
|
213 |
|
|
2'b00, FB2B_En, SERR_En,
|
214 |
|
|
1'b1, Par_Err_En, 2'b00,
|
215 |
|
|
1'b0, Master_En, Target_En, 1'b0};
|
216 |
|
|
`ifdef PCI_CLK_66
|
217 |
|
|
wire [15:0] Target_Status =
|
218 |
|
|
{Detected_PERR, Signaled_SERR, Received_Master_Abort,
|
219 |
|
|
Received_Target_Abort,
|
220 |
|
|
Signaled_Target_Abort, 2'b01, Master_Caused_PERR,
|
221 |
|
|
1'b1, 1'b0, 1'b1, 1'b0,
|
222 |
|
|
4'b0000};
|
223 |
|
|
`else // PCI_CLK_66
|
224 |
|
|
wire [15:0] Target_Status =
|
225 |
|
|
{Detected_PERR, Signaled_SERR, Received_Master_Abort,
|
226 |
|
|
Received_Target_Abort,
|
227 |
|
|
Signaled_Target_Abort, 2'b01, Master_Caused_PERR,
|
228 |
|
|
1'b1, 1'b0, 1'b0, 1'b0,
|
229 |
|
|
4'b0000};
|
230 |
|
|
`endif // PCI_CLK_66
|
231 |
|
|
|
232 |
|
|
assign master_enable = Master_En;
|
233 |
|
|
assign master_fast_b2b_en = FB2B_En;
|
234 |
|
|
assign master_perr_enable = Par_Err_En;
|
235 |
|
|
assign master_serr_enable = SERR_En;
|
236 |
|
|
assign master_latency_value[7:0] = Latency_Timer[7:0];
|
237 |
|
|
|
238 |
|
|
task Read_Test_Device_Config_Regs;
|
239 |
|
|
input [7:2] reg_number;
|
240 |
|
|
output [PCI_BUS_DATA_RANGE:0] Read_Config_Reg;
|
241 |
|
|
begin // Addresses except 0, 4, 8, A, 10, 14, 3C all return 0x00
|
242 |
|
|
case (reg_number[7:2])
|
243 |
|
|
6'h00: Read_Config_Reg = 32'h8000AAAA
|
244 |
|
|
| {13'h0000, test_device_id[2:0], 16'h0000};
|
245 |
|
|
6'h01: Read_Config_Reg = {Target_Status[15:0], Target_Command[15:0]};
|
246 |
|
|
6'h02: Read_Config_Reg = 32'hFF000000;
|
247 |
|
|
6'h03: Read_Config_Reg = {16'h0000, Latency_Timer[7:0], Cache_Line_Size[7:0]};
|
248 |
|
|
6'h04: Read_Config_Reg = {BAR0[`PCI_BASE_ADDR0_MATCH_RANGE],
|
249 |
|
|
`PCI_BASE_ADDR0_FILL, `PCI_BASE_ADDR0_MAP_QUAL};
|
250 |
|
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
251 |
|
|
6'h05: Read_Config_Reg = {BAR1[`PCI_BASE_ADDR1_MATCH_RANGE],
|
252 |
|
|
`PCI_BASE_ADDR1_FILL, `PCI_BASE_ADDR1_MAP_QUAL};
|
253 |
|
|
`else // PCI_BASE_ADDR1_MATCH_ENABLE
|
254 |
|
|
6'h05: Read_Config_Reg = 32'h00000000;
|
255 |
|
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
256 |
|
|
6'h0F: Read_Config_Reg = {16'h0000, 8'h01, Interrupt_Line[7:0]};
|
257 |
|
|
default: Read_Config_Reg = 32'h00000000;
|
258 |
|
|
endcase
|
259 |
|
|
end
|
260 |
|
|
endtask
|
261 |
|
|
|
262 |
|
|
// store info away so Config Register code can update register correctly
|
263 |
|
|
reg [7:2] pending_config_reg_write_address;
|
264 |
|
|
reg [PCI_BUS_CBE_RANGE:0] pending_config_reg_write_byte_enables;
|
265 |
|
|
reg [PCI_BUS_DATA_RANGE:0] pending_config_reg_write_data;
|
266 |
|
|
reg pending_config_write_request;
|
267 |
|
|
task Write_Test_Device_Config_Regs;
|
268 |
|
|
input [7:2] reg_number;
|
269 |
|
|
input [PCI_BUS_DATA_RANGE:0] data;
|
270 |
|
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
271 |
|
|
begin
|
272 |
|
|
if (~pci_reset_comb)
|
273 |
|
|
begin
|
274 |
|
|
pending_config_reg_write_address[7:2] <= reg_number[7:2];
|
275 |
|
|
pending_config_reg_write_byte_enables[PCI_BUS_CBE_RANGE:0] <= master_mask_l[PCI_BUS_CBE_RANGE:0];
|
276 |
|
|
pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] <= data[PCI_BUS_DATA_RANGE:0];
|
277 |
|
|
pending_config_write_request <= 1'b1;
|
278 |
|
|
end
|
279 |
|
|
`NO_ELSE;
|
280 |
|
|
end
|
281 |
|
|
endtask
|
282 |
|
|
|
283 |
|
|
wire target_got_parity_error;
|
284 |
|
|
wire target_asserted_serr;
|
285 |
|
|
reg target_signaling_target_abort;
|
286 |
|
|
|
287 |
|
|
// Make a register transfer style Configuration Register, so it is easier to handle
|
288 |
|
|
// simultaneous updates from the master and the target.
|
289 |
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
290 |
|
|
begin
|
291 |
|
|
if (pci_reset_comb)
|
292 |
|
|
begin
|
293 |
|
|
FB2B_En <= 1'b0;
|
294 |
|
|
SERR_En <= 1'b0; Par_Err_En <= 1'b0;
|
295 |
|
|
Master_En <= 1'b0; Target_En <= 1'b0;
|
296 |
|
|
Detected_PERR <= 1'b0; Signaled_SERR <= 1'b0;
|
297 |
|
|
Received_Master_Abort <= 1'b0; Received_Target_Abort <= 1'b0;
|
298 |
|
|
Signaled_Target_Abort <= 1'b0;
|
299 |
|
|
Master_Caused_PERR <= 1'b0;
|
300 |
|
|
Latency_Timer <= 8'h00; Cache_Line_Size <= 8'h00;
|
301 |
|
|
Interrupt_Line <= 8'h00;
|
302 |
|
|
BAR0 <= 8'hXX;
|
303 |
|
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
304 |
|
|
BAR1 <= 8'hXX;
|
305 |
|
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
306 |
|
|
pending_config_write_request <= 1'b0;
|
307 |
|
|
end
|
308 |
|
|
else
|
309 |
|
|
begin
|
310 |
|
|
if (pending_config_write_request)
|
311 |
|
|
begin
|
312 |
|
|
// Words 0 and 2 are not writable. Only certain bits in word 1 are writable.
|
313 |
|
|
FB2B_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
314 |
|
|
& ~pending_config_reg_write_byte_enables[1])
|
315 |
|
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_FB2B_EN)
|
316 |
|
|
!= `PCI_BUS_DATA_ZERO) : FB2B_En;
|
317 |
|
|
SERR_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
318 |
|
|
& ~pending_config_reg_write_byte_enables[1])
|
319 |
|
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_SERR_EN)
|
320 |
|
|
!= `PCI_BUS_DATA_ZERO) : SERR_En;
|
321 |
|
|
Par_Err_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
322 |
|
|
& ~pending_config_reg_write_byte_enables[0])
|
323 |
|
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_PAR_ERR_EN)
|
324 |
|
|
!= `PCI_BUS_DATA_ZERO) : Par_Err_En;
|
325 |
|
|
Master_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
326 |
|
|
& ~pending_config_reg_write_byte_enables[0])
|
327 |
|
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_MASTER_EN)
|
328 |
|
|
!= `PCI_BUS_DATA_ZERO) : Master_En;
|
329 |
|
|
Target_En <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
330 |
|
|
& ~pending_config_reg_write_byte_enables[0])
|
331 |
|
|
? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_TARGET_EN)
|
332 |
|
|
!= `PCI_BUS_DATA_ZERO) : Target_En;
|
333 |
|
|
// Certain bits in word 1 are only clearable, not writable.
|
334 |
|
|
Detected_PERR <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
335 |
|
|
& ~pending_config_reg_write_byte_enables[3]
|
336 |
|
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_DETECTED_PERR) != `PCI_BUS_DATA_ZERO))
|
337 |
|
|
? 1'b0 : Detected_PERR | master_got_parity_error | target_got_parity_error;
|
338 |
|
|
Signaled_SERR <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
339 |
|
|
& ~pending_config_reg_write_byte_enables[3]
|
340 |
|
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_DETECTED_SERR) != `PCI_BUS_DATA_ZERO))
|
341 |
|
|
? 1'b0 : Signaled_SERR | master_asserted_serr | target_asserted_serr;
|
342 |
|
|
Received_Master_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
343 |
|
|
& ~pending_config_reg_write_byte_enables[3]
|
344 |
|
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_GOT_MABORT) != `PCI_BUS_DATA_ZERO))
|
345 |
|
|
? 1'b0 : Received_Master_Abort | master_got_master_abort;
|
346 |
|
|
Received_Target_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
347 |
|
|
& ~pending_config_reg_write_byte_enables[3]
|
348 |
|
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_GOT_TABORT) != `PCI_BUS_DATA_ZERO))
|
349 |
|
|
? 1'b0 : Received_Target_Abort | master_got_target_abort;
|
350 |
|
|
Signaled_Target_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01)
|
351 |
|
|
& ~pending_config_reg_write_byte_enables[3]
|
352 |
|
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_CAUSED_TABORT) != `PCI_BUS_DATA_ZERO))
|
353 |
|
|
? 1'b0 : Signaled_Target_Abort | target_signaling_target_abort;
|
354 |
|
|
Master_Caused_PERR <= ( (pending_config_reg_write_address[7:2] == 6'h01)
|
355 |
|
|
& ~pending_config_reg_write_byte_enables[3]
|
356 |
|
|
& ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_STAT_CAUSED_PERR) != `PCI_BUS_DATA_ZERO))
|
357 |
|
|
? 1'b0 : Master_Caused_PERR | master_caused_parity_error;
|
358 |
|
|
// Certain bytes in higher words are writable
|
359 |
|
|
Latency_Timer <= ( (pending_config_reg_write_address[7:2] == 6'h03)
|
360 |
|
|
& ~pending_config_reg_write_byte_enables[1])
|
361 |
|
|
? pending_config_reg_write_data[15:8] : Latency_Timer;
|
362 |
|
|
Cache_Line_Size <= ( (pending_config_reg_write_address[7:2] == 6'h03)
|
363 |
|
|
& ~pending_config_reg_write_byte_enables[0])
|
364 |
|
|
? pending_config_reg_write_data[7:0] : Cache_Line_Size;
|
365 |
|
|
|
366 |
|
|
BAR0 <= ( (pending_config_reg_write_address[7:2] == 6'h04)
|
367 |
|
|
& ~pending_config_reg_write_byte_enables[3])
|
368 |
|
|
? pending_config_reg_write_data[`PCI_BASE_ADDR0_MATCH_RANGE] : BAR0;
|
369 |
|
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
370 |
|
|
BAR1 <= ( (pending_config_reg_write_address[7:2] == 6'h05)
|
371 |
|
|
& ~pending_config_reg_write_byte_enables[3])
|
372 |
|
|
? pending_config_reg_write_data[`PCI_BASE_ADDR1_MATCH_RANGE] : BAR1;
|
373 |
|
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
374 |
|
|
Interrupt_Line <= ( (pending_config_reg_write_address[7:2] == 6'h0F)
|
375 |
|
|
& ~pending_config_reg_write_byte_enables[0])
|
376 |
|
|
? pending_config_reg_write_data[7:0] : Interrupt_Line;
|
377 |
|
|
pending_config_write_request <= 1'b0; // NOTE this seems to prevent back-to-back writes.
|
378 |
|
|
end
|
379 |
|
|
else
|
380 |
|
|
begin // not writing from PCI side
|
381 |
|
|
// Words 0 and 2 are not writable. Only certain bits in word 1 are writable.
|
382 |
|
|
FB2B_En <= FB2B_En;
|
383 |
|
|
SERR_En <= SERR_En;
|
384 |
|
|
Par_Err_En <= Par_Err_En;
|
385 |
|
|
Master_En <= Master_En;
|
386 |
|
|
Target_En <= Target_En;
|
387 |
|
|
// Certain bits in word 1 are only clearable, not writable.
|
388 |
|
|
Detected_PERR <= Detected_PERR | master_got_parity_error | target_got_parity_error;
|
389 |
|
|
Signaled_SERR <= Signaled_SERR | master_asserted_serr | target_asserted_serr;
|
390 |
|
|
Received_Master_Abort <= Received_Master_Abort | master_got_master_abort;
|
391 |
|
|
Received_Target_Abort <= Received_Target_Abort | master_got_target_abort;
|
392 |
|
|
Signaled_Target_Abort <= Signaled_Target_Abort | target_signaling_target_abort;
|
393 |
|
|
Master_Caused_PERR <= Master_Caused_PERR | master_caused_parity_error;
|
394 |
|
|
// Certain bytes in higher words are writable
|
395 |
|
|
Latency_Timer <= Latency_Timer;
|
396 |
|
|
Cache_Line_Size <= Cache_Line_Size;
|
397 |
|
|
BAR0 <= BAR0;
|
398 |
|
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
399 |
|
|
BAR1 <= BAR1;
|
400 |
|
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
401 |
|
|
Interrupt_Line <= Interrupt_Line;
|
402 |
|
|
end
|
403 |
|
|
end
|
404 |
|
|
end
|
405 |
|
|
|
406 |
|
|
// Tasks to manage the small SRAM visible in Memory Space
|
407 |
|
|
reg [PCI_BUS_DATA_RANGE:0] Test_Device_Mem [0:255]; // address limits, not bits in address
|
408 |
|
|
// Tasks can't have local storage! have to be module global
|
409 |
|
|
reg [7:0] sram_addr;
|
410 |
|
|
task Init_Test_Device_SRAM;
|
411 |
|
|
begin
|
412 |
|
|
for (sram_addr = 8'h00; sram_addr < 8'hFF; sram_addr = sram_addr + 8'h01)
|
413 |
|
|
begin
|
414 |
|
|
Test_Device_Mem[sram_addr] = `BUS_IMPOSSIBLE_VALUE;
|
415 |
|
|
end
|
416 |
|
|
end
|
417 |
|
|
endtask
|
418 |
|
|
|
419 |
|
|
task Read_Test_Device_SRAM;
|
420 |
|
|
input [9:2] sram_address;
|
421 |
|
|
input [PCI_BUS_CBE_RANGE:0] byte_sel ;
|
422 |
|
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
423 |
|
|
reg [PCI_BUS_DATA_RANGE:0] temp_val ;
|
424 |
|
|
begin
|
425 |
|
|
temp_val = Test_Device_Mem[sram_address] ;
|
426 |
|
|
target_read_data[7:0] = byte_sel[0] ? temp_val[7:0] : 0 ;
|
427 |
|
|
target_read_data[15:8] = byte_sel[1] ? temp_val[15:8] : 0 ;
|
428 |
|
|
target_read_data[23:16] = byte_sel[2] ? temp_val[23:16] : 0 ;
|
429 |
|
|
target_read_data[31:24] = byte_sel[3] ? temp_val[31:24] : 0 ;
|
430 |
|
|
end
|
431 |
|
|
endtask
|
432 |
|
|
|
433 |
|
|
// Tasks can't have local storage! have to be module global
|
434 |
|
|
reg [PCI_BUS_DATA_RANGE:0] sram_temp;
|
435 |
|
|
task Write_Test_Device_SRAM;
|
436 |
|
|
input [9:2] sram_address;
|
437 |
|
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
438 |
|
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
439 |
|
|
begin
|
440 |
|
|
sram_temp = Test_Device_Mem[sram_address];
|
441 |
|
|
sram_temp[7:0] = (~master_mask_l[0]) ? master_write_data[7:0] : sram_temp[7:0];
|
442 |
|
|
sram_temp[15:8] = (~master_mask_l[1]) ? master_write_data[15:8] : sram_temp[15:8];
|
443 |
|
|
sram_temp[23:16] = (~master_mask_l[2]) ? master_write_data[23:16] : sram_temp[23:16];
|
444 |
|
|
sram_temp[31:24] = (~master_mask_l[3]) ? master_write_data[31:24] : sram_temp[31:24];
|
445 |
|
|
Test_Device_Mem[sram_address] = sram_temp[PCI_BUS_DATA_RANGE:0];
|
446 |
|
|
end
|
447 |
|
|
endtask
|
448 |
|
|
|
449 |
|
|
// Make the DEVSEL_TRDY_STOP_OE output enable signal. It must become
|
450 |
|
|
// asserted as soon as one of those signals become asserted, and
|
451 |
|
|
// must stay asserted one clock after the last one becomes deasserted.
|
452 |
|
|
reg prev_d_t_s_asserted;
|
453 |
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
454 |
|
|
begin
|
455 |
|
|
if (pci_reset_comb)
|
456 |
|
|
begin
|
457 |
|
|
prev_d_t_s_asserted <= 1'b0;
|
458 |
|
|
end
|
459 |
|
|
else
|
460 |
|
|
begin
|
461 |
|
|
prev_d_t_s_asserted <= target_devsel_out | target_trdy_out | target_stop_out;
|
462 |
|
|
end
|
463 |
|
|
end
|
464 |
|
|
assign target_d_t_s_oe = target_devsel_out | target_trdy_out | target_stop_out
|
465 |
|
|
| prev_d_t_s_asserted;
|
466 |
|
|
|
467 |
|
|
// Make the PERR_OE signal.
|
468 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 3.7.4.1
|
469 |
|
|
// At time N, target_perr_check_next is set
|
470 |
|
|
// At time N+1, external data is latched, and irdy is also latched
|
471 |
|
|
// At time N+1, target_perr_check is latched
|
472 |
|
|
// At time N+2, calc_input_parity_prev is valid
|
473 |
|
|
// Also at N+2, external parity is valid
|
474 |
|
|
reg target_perr_prev, target_perr_check_next, target_perr_check;
|
475 |
|
|
reg target_perr_detected;
|
476 |
|
|
reg target_debug_force_bad_perr ;
|
477 |
|
|
|
478 |
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
479 |
|
|
begin
|
480 |
|
|
if (pci_reset_comb)
|
481 |
|
|
target_debug_force_bad_perr <= 1'b0 ;
|
482 |
|
|
else
|
483 |
|
|
target_debug_force_bad_perr <= target_debug_force_bad_par ;
|
484 |
|
|
end
|
485 |
|
|
|
486 |
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
487 |
|
|
begin
|
488 |
|
|
if (pci_reset_comb)
|
489 |
|
|
begin
|
490 |
|
|
target_perr_check <= 1'b0;
|
491 |
|
|
target_perr_detected <= 1'b0;
|
492 |
|
|
target_perr_out <= 1'b0;
|
493 |
|
|
target_perr_prev <= 1'b0;
|
494 |
|
|
end
|
495 |
|
|
else
|
496 |
|
|
begin
|
497 |
|
|
target_perr_check <= target_perr_check_next;
|
498 |
|
|
target_perr_detected <= target_perr_check & irdy_prev
|
499 |
|
|
& (calc_input_parity_prev != par_now);
|
500 |
|
|
target_perr_out <= target_perr_check & irdy_prev & Par_Err_En
|
501 |
|
|
// mihad - bad perr generation
|
502 |
|
|
& (calc_input_parity_prev != (par_now ^ target_debug_force_bad_perr));
|
503 |
|
|
target_perr_prev <= target_perr_out;
|
504 |
|
|
end
|
505 |
|
|
end
|
506 |
|
|
assign target_perr_oe = target_perr_out | target_perr_prev;
|
507 |
|
|
|
508 |
|
|
// Make the SERR_OE signal
|
509 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 6.2.3.
|
510 |
|
|
reg prev_prev_frame;
|
511 |
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
512 |
|
|
begin
|
513 |
|
|
if (pci_reset_comb)
|
514 |
|
|
begin
|
515 |
|
|
prev_prev_frame <= 1'b0;
|
516 |
|
|
target_serr_oe <= 1'b0;
|
517 |
|
|
end
|
518 |
|
|
else
|
519 |
|
|
begin
|
520 |
|
|
prev_prev_frame <= frame_prev;
|
521 |
|
|
target_serr_oe <= ~prev_prev_frame & frame_prev
|
522 |
|
|
& SERR_En & Par_Err_En
|
523 |
|
|
& (calc_input_parity_prev != par_now);
|
524 |
|
|
end
|
525 |
|
|
end
|
526 |
|
|
assign target_asserted_serr = target_serr_oe;
|
527 |
|
|
assign target_got_parity_error = target_perr_detected | target_serr_oe;
|
528 |
|
|
|
529 |
|
|
// Remember whether this device drove DEVSEL last clock, which allows
|
530 |
|
|
// Zero-Wait-State Back-to-Back references
|
531 |
|
|
wire This_Target_Drove_DEVSEL_Last_Clock = target_d_t_s_oe;
|
532 |
|
|
|
533 |
|
|
// Remember whether the bus has correct parity.
|
534 |
|
|
// Used by Medium, slower Address Decode to prevent DEVSEL on bad Address Parity
|
535 |
|
|
reg prev_bus_par_ok, prev_prev_bus_par_ok;
|
536 |
|
|
always @(posedge pci_ext_clk)
|
537 |
|
|
begin
|
538 |
|
|
prev_bus_par_ok <= (calc_input_parity_prev == par_now);
|
539 |
|
|
prev_prev_bus_par_ok <= prev_bus_par_ok;
|
540 |
|
|
end
|
541 |
|
|
|
542 |
|
|
// We want the Target to do certain behavior to let us test the interface.
|
543 |
|
|
// See the note in the Master section about the use of Address Bits to
|
544 |
|
|
// encode Target Wait State, Target Completion, and Target Error info.
|
545 |
|
|
|
546 |
|
|
// signals used by Target test code to apply correct info to the PCI bus
|
547 |
|
|
reg [PCI_BUS_DATA_RANGE:0] hold_target_address;
|
548 |
|
|
reg [PCI_BUS_CBE_RANGE:0] hold_target_command;
|
549 |
|
|
reg [3:0] hold_target_initial_waitstates;
|
550 |
|
|
reg [3:0] hold_target_subsequent_waitstates;
|
551 |
|
|
reg [2:0] hold_target_termination;
|
552 |
|
|
reg [1:0] hold_target_devsel_speed;
|
553 |
|
|
reg [9:0] hold_target_terminate_on ;
|
554 |
|
|
reg hold_target_data_par_err;
|
555 |
|
|
reg hold_target_addr_par_err;
|
556 |
|
|
|
557 |
|
|
// Tasks which use the held PCI address to access internal info. These tasks
|
558 |
|
|
// update the address counter, emulating the target address counter during bursts.
|
559 |
|
|
// Store data from PCI bus into Config Register, and increment Write Pointer
|
560 |
|
|
task Capture_Config_Reg_Data_From_AD_Bus;
|
561 |
|
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
562 |
|
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
563 |
|
|
begin
|
564 |
|
|
Write_Test_Device_Config_Regs (hold_target_address[7:2],
|
565 |
|
|
master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
566 |
|
|
hold_target_address[7:2] = hold_target_address[7:2] + 6'h01; // addr++
|
567 |
|
|
end
|
568 |
|
|
endtask
|
569 |
|
|
|
570 |
|
|
// Drive Config Register Data onto AD bus, and increment Read Pointer
|
571 |
|
|
task Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus;
|
572 |
|
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
573 |
|
|
begin
|
574 |
|
|
Read_Test_Device_Config_Regs (hold_target_address[7:2], target_read_data[PCI_BUS_DATA_RANGE:0]);
|
575 |
|
|
hold_target_address[7:2] = hold_target_address[7:2] + 6'h01; // addr++
|
576 |
|
|
end
|
577 |
|
|
endtask
|
578 |
|
|
|
579 |
|
|
// Store data from PCI bus into SRAM, and increment Write Pointer
|
580 |
|
|
task Capture_SRAM_Data_From_AD_Bus;
|
581 |
|
|
input [PCI_BUS_DATA_RANGE:0] master_write_data;
|
582 |
|
|
input [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
583 |
|
|
begin
|
584 |
|
|
Write_Test_Device_SRAM (hold_target_address[9:2],
|
585 |
|
|
master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
586 |
|
|
hold_target_address[9:2] = hold_target_address[9:2] + 8'h01; // addr++
|
587 |
|
|
end
|
588 |
|
|
endtask
|
589 |
|
|
|
590 |
|
|
// Drive SRAM Data onto AD bus, and increment Read Pointer
|
591 |
|
|
task Fetch_SRAM_Data_For_Read_Onto_AD_Bus;
|
592 |
|
|
output [PCI_BUS_DATA_RANGE:0] target_read_data;
|
593 |
|
|
begin
|
594 |
|
|
Read_Test_Device_SRAM (hold_target_address[9:2], ~cbe_l_now, target_read_data[PCI_BUS_DATA_RANGE:0]);
|
595 |
|
|
hold_target_address[9:2] = hold_target_address[9:2] + 8'h01; // addr++
|
596 |
|
|
end
|
597 |
|
|
endtask
|
598 |
|
|
|
599 |
|
|
// The target is able to execute Delayed Reads,
|
600 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.3.3
|
601 |
|
|
// To allow a delayed read to complete, read data must be available.
|
602 |
|
|
// Also a PCI command matching in Address, Command, Byte Enables,
|
603 |
|
|
// and parity on address.
|
604 |
|
|
// If the region of memory is prefetchable and always returns all
|
605 |
|
|
// bytes, it is OK to disregard the Byte Enables.
|
606 |
|
|
reg Delayed_Read_Started, Delayed_Read_Pending, Delayed_Read_Finished;
|
607 |
|
|
reg [PCI_BUS_DATA_RANGE:0] Delayed_Read_Address;
|
608 |
|
|
reg [PCI_BUS_CBE_RANGE:0] Delayed_Read_Command;
|
609 |
|
|
reg [PCI_BUS_CBE_RANGE:0] Delayed_Read_Mask_L;
|
610 |
|
|
reg [14:0] Delayed_Read_Discard_Counter;
|
611 |
|
|
wire [14:0] Delayed_Read_Discard_Limit = 15'h7FFF; // change for debugging
|
612 |
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
613 |
|
|
begin
|
614 |
|
|
if (pci_reset_comb)
|
615 |
|
|
begin
|
616 |
|
|
Delayed_Read_Pending <= 1'b0;
|
617 |
|
|
end
|
618 |
|
|
else
|
619 |
|
|
begin
|
620 |
|
|
Delayed_Read_Pending <= Delayed_Read_Started
|
621 |
|
|
| (Delayed_Read_Pending & ~Delayed_Read_Finished
|
622 |
|
|
& (Delayed_Read_Discard_Counter[14:0] < Delayed_Read_Discard_Limit[14:0]));
|
623 |
|
|
end
|
624 |
|
|
end
|
625 |
|
|
|
626 |
|
|
always @(posedge pci_ext_clk)
|
627 |
|
|
begin
|
628 |
|
|
Delayed_Read_Discard_Counter[14:0] <= Delayed_Read_Started
|
629 |
|
|
? 15'h0000 : Delayed_Read_Discard_Counter[14:0] + 15'h0001;
|
630 |
|
|
`ifdef VERBOSE_TEST_DEVICE
|
631 |
|
|
if (Delayed_Read_Pending & (Delayed_Read_Discard_Counter[14:0]
|
632 |
|
|
>= Delayed_Read_Discard_Limit[14:0]))
|
633 |
|
|
begin
|
634 |
|
|
$display (" test target %h - Delayed Read Discarded, at %t",
|
635 |
|
|
test_device_id[2:0], $time);
|
636 |
|
|
end
|
637 |
|
|
`NO_ELSE;
|
638 |
|
|
`endif // VERBOSE_TEST_DEVICE
|
639 |
|
|
end
|
640 |
|
|
|
641 |
|
|
// Target tasks. These know how to respond to the external masters.
|
642 |
|
|
// NOTE all tasks end with an @(posedge pci_ext_clk) statement
|
643 |
|
|
// to let any signals asserted during that task settle out.
|
644 |
|
|
// If a task DOESN'T end with @(posedge pci_ext_clk), then it must
|
645 |
|
|
// be called just before some other task which does.
|
646 |
|
|
|
647 |
|
|
parameter TEST_TARGET_SPINLOOP_MAX = 20;
|
648 |
|
|
|
649 |
|
|
task Clock_Wait_Unless_Reset;
|
650 |
|
|
begin
|
651 |
|
|
if (~pci_reset_comb)
|
652 |
|
|
begin
|
653 |
|
|
@ (posedge pci_ext_clk or posedge pci_reset_comb) ;
|
654 |
|
|
end
|
655 |
|
|
`NO_ELSE;
|
656 |
|
|
end
|
657 |
|
|
endtask
|
658 |
|
|
|
659 |
|
|
task Assert_DEVSEL;
|
660 |
|
|
begin
|
661 |
|
|
target_devsel_out <= 1'b1;
|
662 |
|
|
end
|
663 |
|
|
endtask
|
664 |
|
|
|
665 |
|
|
task Assert_TRDY;
|
666 |
|
|
begin
|
667 |
|
|
target_trdy_out <= 1'b1;
|
668 |
|
|
end
|
669 |
|
|
endtask
|
670 |
|
|
|
671 |
|
|
task Assert_STOP;
|
672 |
|
|
begin
|
673 |
|
|
target_stop_out <= 1'b1;
|
674 |
|
|
end
|
675 |
|
|
endtask
|
676 |
|
|
|
677 |
|
|
task Deassert_DEVSEL;
|
678 |
|
|
begin
|
679 |
|
|
target_devsel_out <= 1'b0;
|
680 |
|
|
end
|
681 |
|
|
endtask
|
682 |
|
|
|
683 |
|
|
task Deassert_TRDY;
|
684 |
|
|
begin
|
685 |
|
|
target_trdy_out <= 1'b0;
|
686 |
|
|
end
|
687 |
|
|
endtask
|
688 |
|
|
|
689 |
|
|
task Deassert_STOP;
|
690 |
|
|
begin
|
691 |
|
|
target_stop_out <= 1'b0;
|
692 |
|
|
end
|
693 |
|
|
endtask
|
694 |
|
|
|
695 |
|
|
task Assert_Target_Continue_Or_Disconnect;
|
696 |
|
|
input do_target_disconnect;
|
697 |
|
|
begin
|
698 |
|
|
if (do_target_disconnect)
|
699 |
|
|
begin
|
700 |
|
|
Assert_DEVSEL; Assert_TRDY; Assert_STOP;
|
701 |
|
|
end
|
702 |
|
|
else
|
703 |
|
|
begin
|
704 |
|
|
Assert_DEVSEL; Assert_TRDY; Deassert_STOP;
|
705 |
|
|
end
|
706 |
|
|
end
|
707 |
|
|
endtask
|
708 |
|
|
|
709 |
|
|
// Execute_Target_Retry is called with nothing or DEVSEL asserted
|
710 |
|
|
// tasks can't have local storage! have to be module global
|
711 |
|
|
integer iiii;
|
712 |
|
|
task Execute_Target_Retry_Undrive_DEVSEL;
|
713 |
|
|
input drive_ad_bus;
|
714 |
|
|
input signal_starting_delayed_read;
|
715 |
|
|
input signal_satisfied_delayed_read;
|
716 |
|
|
begin
|
717 |
|
|
for (iiii = 0; iiii < TEST_TARGET_SPINLOOP_MAX; iiii = iiii + 1)
|
718 |
|
|
begin
|
719 |
|
|
if ((iiii == 0) | frame_now | ~irdy_now) // At least one stop, then Not Finished
|
720 |
|
|
begin
|
721 |
|
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
722 |
|
|
target_ad_oe <= drive_ad_bus;
|
723 |
|
|
target_debug_force_bad_par <= 1'b0;
|
724 |
|
|
target_perr_check_next <= ~drive_ad_bus;
|
725 |
|
|
target_signaling_target_abort <= 1'b0;
|
726 |
|
|
Delayed_Read_Started <= signal_starting_delayed_read;
|
727 |
|
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
728 |
|
|
Assert_DEVSEL; // signal DEVSEL and Stop, indicating Retry
|
729 |
|
|
Deassert_TRDY;
|
730 |
|
|
Assert_STOP;
|
731 |
|
|
if (signal_starting_delayed_read)
|
732 |
|
|
begin
|
733 |
|
|
Delayed_Read_Address[PCI_BUS_DATA_RANGE:0] = hold_target_address[PCI_BUS_DATA_RANGE:0];
|
734 |
|
|
Delayed_Read_Command[PCI_BUS_CBE_RANGE:0] = hold_target_command[PCI_BUS_CBE_RANGE:0];
|
735 |
|
|
Delayed_Read_Mask_L[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
736 |
|
|
end
|
737 |
|
|
`NO_ELSE;
|
738 |
|
|
end
|
739 |
|
|
else
|
740 |
|
|
begin
|
741 |
|
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
742 |
|
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
743 |
|
|
target_debug_force_bad_par <= 1'b0;
|
744 |
|
|
target_perr_check_next <= 1'b0;
|
745 |
|
|
target_signaling_target_abort <= 1'b0;
|
746 |
|
|
Delayed_Read_Started <= 1'b0;
|
747 |
|
|
Delayed_Read_Finished <= 1'b0;
|
748 |
|
|
Deassert_DEVSEL; // Master saw us, so leave
|
749 |
|
|
Deassert_TRDY;
|
750 |
|
|
Deassert_STOP;
|
751 |
|
|
iiii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
752 |
|
|
end
|
753 |
|
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
754 |
|
|
signal_satisfied_delayed_read = 1'b0;
|
755 |
|
|
end
|
756 |
|
|
`ifdef NORMAL_PCI_CHECKS
|
757 |
|
|
if (~pci_reset_comb & (iiii == TEST_TARGET_SPINLOOP_MAX))
|
758 |
|
|
begin
|
759 |
|
|
$display ("*** test target %h - Bus didn't go Idle during Target Retry, at %t",
|
760 |
|
|
test_device_id[2:0], $time);
|
761 |
|
|
error_detected <= ~error_detected;
|
762 |
|
|
end
|
763 |
|
|
`NO_ELSE;
|
764 |
|
|
if (~pci_reset_comb & irdy_now)
|
765 |
|
|
begin
|
766 |
|
|
$display ("*** test target %h - IRDY didn't deassert at end of Target Retry, at %t",
|
767 |
|
|
test_device_id[2:0], $time);
|
768 |
|
|
error_detected <= ~error_detected;
|
769 |
|
|
end
|
770 |
|
|
`NO_ELSE;
|
771 |
|
|
`endif // NORMAL_PCI_CHECKS
|
772 |
|
|
end
|
773 |
|
|
endtask
|
774 |
|
|
|
775 |
|
|
// This Test Device is capable of doing Fast Decode. To do this,
|
776 |
|
|
// it must make sure not to cause conflicts on DEVSEL, IRDY,
|
777 |
|
|
// STOP, or PERR. To achieve this, the task must hold off on
|
778 |
|
|
// making DEVSEL unless either
|
779 |
|
|
// 1) the bus was just Idle
|
780 |
|
|
// 2) this device also drove DEVSEL the previous clock (I presume this
|
781 |
|
|
// means that DEVSEL was driven LOW!! Would HIGH be an idle cycle?)
|
782 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 3.4.2
|
783 |
|
|
//
|
784 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 3.7.3 for what
|
785 |
|
|
// to do if an Address Parity Error is detected.
|
786 |
|
|
// Since this behaviorial test knows that an address parity error is
|
787 |
|
|
// comming, it holds off fast decode parity errors, and always
|
788 |
|
|
// allows a master abort to happen. This would not be possible in
|
789 |
|
|
// a gate-level PCI interface. For FAST decode, that interface would
|
790 |
|
|
// have to continue on as if there was no error. It would be nice
|
791 |
|
|
// if it prevented any writes of data, or reads with side-effects.
|
792 |
|
|
task Wait_Till_DEVSEL_Possible;
|
793 |
|
|
output devsel_asserted;
|
794 |
|
|
output fast_devsel_asserted;
|
795 |
|
|
output signal_satisfied_delayed_read;
|
796 |
|
|
begin
|
797 |
|
|
if ((hold_target_devsel_speed[1:0] == `Test_Devsel_Fast) & ~Delayed_Read_Pending
|
798 |
|
|
& ( (~frame_prev & ~irdy_prev)
|
799 |
|
|
| (~frame_prev & irdy_prev & This_Target_Drove_DEVSEL_Last_Clock) )
|
800 |
|
|
& ~(hold_target_addr_par_err & Par_Err_En))
|
801 |
|
|
begin
|
802 |
|
|
`ifdef VERBOSE_TEST_DEVICE
|
803 |
|
|
$display (" test target %h - doing fast DEVSEL, at %t",
|
804 |
|
|
test_device_id[2:0], $time);
|
805 |
|
|
`endif // VERBOSE_TEST_DEVICE
|
806 |
|
|
devsel_asserted = 1'b1; // fast decode
|
807 |
|
|
fast_devsel_asserted = 1'b1; // fast decode
|
808 |
|
|
signal_satisfied_delayed_read = 1'b0;
|
809 |
|
|
end
|
810 |
|
|
else
|
811 |
|
|
begin
|
812 |
|
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
813 |
|
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
814 |
|
|
target_debug_force_bad_par <= 1'b0;
|
815 |
|
|
target_perr_check_next <= 1'b0;
|
816 |
|
|
target_signaling_target_abort <= 1'b0;
|
817 |
|
|
Delayed_Read_Started <= 1'b0;
|
818 |
|
|
Delayed_Read_Finished <= 1'b0;
|
819 |
|
|
Deassert_DEVSEL;
|
820 |
|
|
Deassert_TRDY;
|
821 |
|
|
Deassert_STOP;
|
822 |
|
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
823 |
|
|
if (Delayed_Read_Pending
|
824 |
|
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
825 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
826 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
827 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) )
|
828 |
|
|
& ( ( (hold_target_address[PCI_BUS_DATA_RANGE:0] & 32'hFF0000FF) // partial test address match
|
829 |
|
|
!= (Delayed_Read_Address[PCI_BUS_DATA_RANGE:0] & 32'hFF0000FF))
|
830 |
|
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] != Delayed_Read_Command[PCI_BUS_CBE_RANGE:0])
|
831 |
|
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] != Delayed_Read_Mask_L[PCI_BUS_CBE_RANGE:0]) ) )
|
832 |
|
|
begin
|
833 |
|
|
Execute_Target_Retry_Undrive_DEVSEL (1'b1, 1'b0, 1'b0);
|
834 |
|
|
devsel_asserted = 1'b0; // tell calling routine to not claim DEVSEL.
|
835 |
|
|
fast_devsel_asserted = 1'b0;
|
836 |
|
|
signal_satisfied_delayed_read = 1'b0;
|
837 |
|
|
end
|
838 |
|
|
else
|
839 |
|
|
begin
|
840 |
|
|
if /*(*/( (hold_target_devsel_speed[1:0] == `Test_Devsel_Fast)
|
841 |
|
|
| (hold_target_devsel_speed[1:0] == `Test_Devsel_Medium) )
|
842 |
|
|
/* & ((calc_input_parity_prev == par_now) | ~Par_Err_En))*/
|
843 |
|
|
begin
|
844 |
|
|
devsel_asserted = 1'b1; // medium decode
|
845 |
|
|
fast_devsel_asserted = 1'b0; // medium decode
|
846 |
|
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
847 |
|
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
848 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
849 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
850 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
851 |
|
|
end
|
852 |
|
|
else
|
853 |
|
|
begin
|
854 |
|
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
855 |
|
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
856 |
|
|
target_debug_force_bad_par <= 1'b0;
|
857 |
|
|
target_perr_check_next <= 1'b0;
|
858 |
|
|
target_signaling_target_abort <= 1'b0;
|
859 |
|
|
Delayed_Read_Started <= 1'b0;
|
860 |
|
|
Delayed_Read_Finished <= 1'b0;
|
861 |
|
|
Deassert_DEVSEL;
|
862 |
|
|
Deassert_TRDY;
|
863 |
|
|
Deassert_STOP;
|
864 |
|
|
Clock_Wait_Unless_Reset;
|
865 |
|
|
if /*(*/(hold_target_devsel_speed[1:0] == `Test_Devsel_Slow)
|
866 |
|
|
/*& (prev_bus_par_ok | ~Par_Err_En))*/
|
867 |
|
|
begin
|
868 |
|
|
devsel_asserted = 1'b1; // slow decode
|
869 |
|
|
fast_devsel_asserted = 1'b0; // slow decode
|
870 |
|
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
871 |
|
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
872 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
873 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
874 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
875 |
|
|
end
|
876 |
|
|
else
|
877 |
|
|
begin
|
878 |
|
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
879 |
|
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
880 |
|
|
target_debug_force_bad_par <= 1'b0;
|
881 |
|
|
target_perr_check_next <= 1'b0;
|
882 |
|
|
target_signaling_target_abort <= 1'b0;
|
883 |
|
|
Delayed_Read_Started <= 1'b0;
|
884 |
|
|
Delayed_Read_Finished <= 1'b0;
|
885 |
|
|
Deassert_DEVSEL;
|
886 |
|
|
Deassert_TRDY;
|
887 |
|
|
Deassert_STOP;
|
888 |
|
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
889 |
|
|
if (/*(*/hold_target_devsel_speed[1:0] == `Test_Devsel_Subtractive)
|
890 |
|
|
/*& (prev_prev_bus_par_ok | ~Par_Err_En))*/
|
891 |
|
|
begin
|
892 |
|
|
devsel_asserted = 1'b1; // subtractive decode
|
893 |
|
|
fast_devsel_asserted = 1'b0; // subtractive decode
|
894 |
|
|
signal_satisfied_delayed_read = Delayed_Read_Pending
|
895 |
|
|
& ( (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ)
|
896 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
897 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE)
|
898 |
|
|
| (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) );
|
899 |
|
|
|
900 |
|
|
end
|
901 |
|
|
else
|
902 |
|
|
begin
|
903 |
|
|
devsel_asserted = 1'b0; // must have had bad parity
|
904 |
|
|
fast_devsel_asserted = 1'b0;
|
905 |
|
|
signal_satisfied_delayed_read = 1'b0;
|
906 |
|
|
end
|
907 |
|
|
end
|
908 |
|
|
end
|
909 |
|
|
end
|
910 |
|
|
end
|
911 |
|
|
`ifdef NORMAL_PCI_CHECKS
|
912 |
|
|
if (~pci_reset_comb & (devsel_asserted == 1'b1)
|
913 |
|
|
& (hold_target_addr_par_err == 1'b1))
|
914 |
|
|
begin
|
915 |
|
|
$display ("*** test target %h - DEVSEL Asserted when Address Parity Error expected, at %t",
|
916 |
|
|
test_device_id[2:0], $time);
|
917 |
|
|
error_detected <= ~error_detected;
|
918 |
|
|
end
|
919 |
|
|
`NO_ELSE;
|
920 |
|
|
`endif // NORMAL_PCI_CHECKS
|
921 |
|
|
end
|
922 |
|
|
endtask
|
923 |
|
|
|
924 |
|
|
// While asserting DEVSEL, wait zero or more clocks as commanded by master
|
925 |
|
|
// This might be called with 1 waitstate before the read data can be OE'd
|
926 |
|
|
// or before the Master Parity can be checked.
|
927 |
|
|
// Tasks can't have local storage! have to be module global
|
928 |
|
|
reg [3:0] cnt1;
|
929 |
|
|
task Execute_Target_Waitstates;
|
930 |
|
|
input drive_ad_bus;
|
931 |
|
|
input enable_parity_check;
|
932 |
|
|
input [3:0] num_waitstates;
|
933 |
|
|
begin
|
934 |
|
|
for (cnt1 = 4'h0; cnt1 < num_waitstates[3:0]; cnt1 = cnt1 + 4'h1)
|
935 |
|
|
begin
|
936 |
|
|
`ifdef NORMAL_PCI_CHECKS
|
937 |
|
|
if (!pci_reset_comb & ~frame_now & ~irdy_now)
|
938 |
|
|
begin
|
939 |
|
|
$display ("*** test target %h - Execute Target Waitstates Wait States called when no Master, at %t",
|
940 |
|
|
test_device_id[2:0], $time);
|
941 |
|
|
error_detected <= ~error_detected;
|
942 |
|
|
end
|
943 |
|
|
`NO_ELSE;
|
944 |
|
|
`endif // NORMAL_PCI_CHECKS
|
945 |
|
|
target_ad_out <= `BUS_WAIT_STATE_VALUE;
|
946 |
|
|
target_ad_oe <= drive_ad_bus;
|
947 |
|
|
target_debug_force_bad_par <= 1'b0;
|
948 |
|
|
target_perr_check_next <= enable_parity_check;
|
949 |
|
|
target_signaling_target_abort <= 1'b0;
|
950 |
|
|
Delayed_Read_Started <= 1'b0;
|
951 |
|
|
Delayed_Read_Finished <= 1'b0;
|
952 |
|
|
Assert_DEVSEL;
|
953 |
|
|
Deassert_TRDY;
|
954 |
|
|
Deassert_STOP;
|
955 |
|
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
956 |
|
|
end
|
957 |
|
|
end
|
958 |
|
|
endtask
|
959 |
|
|
|
960 |
|
|
// DEVSEL already asserted upon entry to this task. OK to watch Parity
|
961 |
|
|
// Tasks can't have local storage! have to be module global
|
962 |
|
|
integer ii;
|
963 |
|
|
task Linger_Until_Master_Waitstates_Done;
|
964 |
|
|
input drive_ad_bus;
|
965 |
|
|
input [PCI_BUS_DATA_RANGE:0] target_read_data;
|
966 |
|
|
input do_target_disconnect;
|
967 |
|
|
begin
|
968 |
|
|
for (ii = 0; ii < TEST_TARGET_SPINLOOP_MAX; ii = ii + 1)
|
969 |
|
|
begin
|
970 |
|
|
if (frame_now & ~irdy_now) // master executing wait states
|
971 |
|
|
begin
|
972 |
|
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= target_read_data[PCI_BUS_DATA_RANGE:0];
|
973 |
|
|
target_ad_oe <= drive_ad_bus;
|
974 |
|
|
target_debug_force_bad_par <= hold_target_data_par_err;
|
975 |
|
|
target_perr_check_next <= ~drive_ad_bus;
|
976 |
|
|
target_signaling_target_abort <= 1'b0;
|
977 |
|
|
Delayed_Read_Started <= 1'b0;
|
978 |
|
|
Delayed_Read_Finished <= 1'b0;
|
979 |
|
|
Assert_Target_Continue_Or_Disconnect (do_target_disconnect);
|
980 |
|
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
981 |
|
|
end
|
982 |
|
|
else
|
983 |
|
|
begin
|
984 |
|
|
ii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
985 |
|
|
end
|
986 |
|
|
end
|
987 |
|
|
`ifdef NORMAL_PCI_CHECKS
|
988 |
|
|
if (~pci_reset_comb & ~frame_now & ~irdy_now)
|
989 |
|
|
begin
|
990 |
|
|
$display ("*** test target %h - Linger during Master Wait States called when no Master, at %t",
|
991 |
|
|
test_device_id[2:0], $time);
|
992 |
|
|
error_detected <= ~error_detected;
|
993 |
|
|
end
|
994 |
|
|
`NO_ELSE;
|
995 |
|
|
if (~pci_reset_comb & (ii == TEST_TARGET_SPINLOOP_MAX))
|
996 |
|
|
begin
|
997 |
|
|
$display ("*** test target %h - Bus stuck in Master Wait States during Target ref, at %t",
|
998 |
|
|
test_device_id[2:0], $time);
|
999 |
|
|
error_detected <= ~error_detected;
|
1000 |
|
|
end
|
1001 |
|
|
`NO_ELSE;
|
1002 |
|
|
`endif // NORMAL_PCI_CHECKS
|
1003 |
|
|
end
|
1004 |
|
|
endtask
|
1005 |
|
|
|
1006 |
|
|
// Execute_Target_Abort. This must be called with DEVSEL asserted
|
1007 |
|
|
// Tasks can't have local storage! have to be module global
|
1008 |
|
|
integer iii;
|
1009 |
|
|
task Execute_Target_Abort_Undrive_DEVSEL;
|
1010 |
|
|
input drive_ad_bus;
|
1011 |
|
|
input signal_satisfied_delayed_read;
|
1012 |
|
|
begin
|
1013 |
|
|
`ifdef NORMAL_PCI_CHECKS
|
1014 |
|
|
if (~pci_reset_comb & (target_devsel_out == 1'b0))
|
1015 |
|
|
begin
|
1016 |
|
|
$display ("*** test target %h - DEVSEL not asserted when starting Target Abort, at %t",
|
1017 |
|
|
test_device_id[2:0], $time);
|
1018 |
|
|
error_detected <= ~error_detected;
|
1019 |
|
|
end
|
1020 |
|
|
`NO_ELSE;
|
1021 |
|
|
`endif // NORMAL_PCI_CHECKS
|
1022 |
|
|
for (iii = 0; iii < TEST_TARGET_SPINLOOP_MAX; iii = iii + 1)
|
1023 |
|
|
begin
|
1024 |
|
|
if ((iii == 0) | frame_now | ~irdy_now) // At least one stop, Master Not Finished
|
1025 |
|
|
begin
|
1026 |
|
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
1027 |
|
|
target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL?
|
1028 |
|
|
target_debug_force_bad_par <= 1'b0;
|
1029 |
|
|
target_perr_check_next <= 1'b0;
|
1030 |
|
|
target_signaling_target_abort <= 1'b1;
|
1031 |
|
|
Delayed_Read_Started <= 1'b0;
|
1032 |
|
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
1033 |
|
|
Deassert_DEVSEL; // Signal Target Abort
|
1034 |
|
|
Deassert_TRDY;
|
1035 |
|
|
Assert_STOP;
|
1036 |
|
|
end
|
1037 |
|
|
else
|
1038 |
|
|
begin
|
1039 |
|
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE;
|
1040 |
|
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
1041 |
|
|
target_debug_force_bad_par <= 1'b0;
|
1042 |
|
|
target_perr_check_next <= 1'b0;
|
1043 |
|
|
target_signaling_target_abort <= 1'b0;
|
1044 |
|
|
Delayed_Read_Started <= 1'b0;
|
1045 |
|
|
Delayed_Read_Finished <= 1'b0;
|
1046 |
|
|
Deassert_DEVSEL; // Signal Target Abort
|
1047 |
|
|
Deassert_TRDY;
|
1048 |
|
|
Deassert_STOP; // Master saw us, so leave
|
1049 |
|
|
iii = TEST_TARGET_SPINLOOP_MAX + 1; // break
|
1050 |
|
|
end
|
1051 |
|
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
1052 |
|
|
signal_satisfied_delayed_read = 1'b0;
|
1053 |
|
|
end
|
1054 |
|
|
`ifdef NORMAL_PCI_CHECKS
|
1055 |
|
|
if (~pci_reset_comb & irdy_now)
|
1056 |
|
|
begin
|
1057 |
|
|
$display ("*** test target %h - Master didn't deassert IRDY at end of Target Abort, at %t",
|
1058 |
|
|
test_device_id[2:0], $time);
|
1059 |
|
|
error_detected <= ~error_detected;
|
1060 |
|
|
end
|
1061 |
|
|
`NO_ELSE;
|
1062 |
|
|
if (~pci_reset_comb & (iii == TEST_TARGET_SPINLOOP_MAX))
|
1063 |
|
|
begin
|
1064 |
|
|
$display ("*** test target %h - Bus didn't go Idle during Target Abort, at %t",
|
1065 |
|
|
test_device_id[2:0], $time);
|
1066 |
|
|
error_detected <= ~error_detected;
|
1067 |
|
|
end
|
1068 |
|
|
`NO_ELSE;
|
1069 |
|
|
`endif // NORMAL_PCI_CHECKS
|
1070 |
|
|
end
|
1071 |
|
|
endtask
|
1072 |
|
|
|
1073 |
|
|
// Transfer a word with or without target termination, and act on Master Termination
|
1074 |
|
|
task Execute_Target_Ref_Undrive_DEVSEL_On_Any_Termination;
|
1075 |
|
|
input drive_ad_bus;
|
1076 |
|
|
input do_target_disconnect;
|
1077 |
|
|
input signal_satisfied_delayed_read;
|
1078 |
|
|
input [PCI_BUS_DATA_RANGE:0] target_read_data;
|
1079 |
|
|
output [PCI_BUS_DATA_RANGE:0] master_write_data;
|
1080 |
|
|
output [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
1081 |
|
|
output target_was_terminated;
|
1082 |
|
|
begin
|
1083 |
|
|
target_ad_out[PCI_BUS_DATA_RANGE:0] <= target_read_data[PCI_BUS_DATA_RANGE:0];
|
1084 |
|
|
target_ad_oe <= drive_ad_bus;
|
1085 |
|
|
target_debug_force_bad_par <= hold_target_data_par_err;
|
1086 |
|
|
target_perr_check_next <= ~drive_ad_bus;
|
1087 |
|
|
target_signaling_target_abort <= 1'b0;
|
1088 |
|
|
Delayed_Read_Started <= 1'b0;
|
1089 |
|
|
Delayed_Read_Finished <= signal_satisfied_delayed_read;
|
1090 |
|
|
Assert_Target_Continue_Or_Disconnect (do_target_disconnect);
|
1091 |
|
|
Clock_Wait_Unless_Reset; // wait for outputs to settle
|
1092 |
|
|
Linger_Until_Master_Waitstates_Done (drive_ad_bus,
|
1093 |
|
|
target_read_data[PCI_BUS_DATA_RANGE:0], do_target_disconnect);
|
1094 |
|
|
master_write_data[PCI_BUS_DATA_RANGE:0] = ad_now[PCI_BUS_DATA_RANGE:0]; // unconditionally grab.
|
1095 |
|
|
master_mask_l[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
1096 |
|
|
if (frame_now & irdy_now & ~do_target_disconnect)
|
1097 |
|
|
begin
|
1098 |
|
|
target_was_terminated = 1'b0;
|
1099 |
|
|
end
|
1100 |
|
|
else
|
1101 |
|
|
begin
|
1102 |
|
|
if (frame_now & irdy_now & do_target_disconnect) // doing Target Termination
|
1103 |
|
|
begin
|
1104 |
|
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
1105 |
|
|
target_ad_oe <= drive_ad_bus;
|
1106 |
|
|
target_debug_force_bad_par <= 1'b0;
|
1107 |
|
|
target_perr_check_next <= ~drive_ad_bus;
|
1108 |
|
|
target_signaling_target_abort <= 1'b0;
|
1109 |
|
|
Delayed_Read_Started <= 1'b0;
|
1110 |
|
|
Delayed_Read_Finished <= 1'b0;
|
1111 |
|
|
Assert_DEVSEL;
|
1112 |
|
|
Deassert_TRDY;
|
1113 |
|
|
Assert_STOP;
|
1114 |
|
|
Clock_Wait_Unless_Reset; // give master a chance to turn FRAME around
|
1115 |
|
|
end
|
1116 |
|
|
`NO_ELSE;
|
1117 |
|
|
`ifdef NORMAL_PCI_CHECKS
|
1118 |
|
|
if (~pci_reset_comb & ~(~frame_now & irdy_now)) // error if not last master data phase
|
1119 |
|
|
begin
|
1120 |
|
|
$display ("*** test target %h - Master entered fatally odd state in Target Ref, at %t",
|
1121 |
|
|
test_device_id[2:0], $time);
|
1122 |
|
|
error_detected <= ~error_detected;
|
1123 |
|
|
end
|
1124 |
|
|
`NO_ELSE;
|
1125 |
|
|
`endif // NORMAL_PCI_CHECKS
|
1126 |
|
|
target_ad_out <= `BUS_IMPOSSIBLE_VALUE;
|
1127 |
|
|
target_ad_oe <= 1'b0; // unconditionally undrive ad bus
|
1128 |
|
|
target_debug_force_bad_par <= 1'b0;
|
1129 |
|
|
target_perr_check_next <= 1'b0;
|
1130 |
|
|
target_signaling_target_abort <= 1'b0;
|
1131 |
|
|
Delayed_Read_Started <= 1'b0;
|
1132 |
|
|
Delayed_Read_Finished <= 1'b0;
|
1133 |
|
|
Deassert_DEVSEL;
|
1134 |
|
|
Deassert_TRDY;
|
1135 |
|
|
Deassert_STOP;
|
1136 |
|
|
Clock_Wait_Unless_Reset;
|
1137 |
|
|
`ifdef NORMAL_PCI_CHECKS
|
1138 |
|
|
if (~pci_reset_comb & irdy_now)
|
1139 |
|
|
begin
|
1140 |
|
|
$display ("*** test target %h - IRDY didn't deassert at end of Master Termination, at %t",
|
1141 |
|
|
test_device_id[2:0], $time);
|
1142 |
|
|
error_detected <= ~error_detected;
|
1143 |
|
|
end
|
1144 |
|
|
`NO_ELSE;
|
1145 |
|
|
`endif // NORMAL_PCI_CHECKS
|
1146 |
|
|
target_was_terminated = 1'b1;
|
1147 |
|
|
end
|
1148 |
|
|
end
|
1149 |
|
|
endtask
|
1150 |
|
|
|
1151 |
|
|
`define TEST_TARGET_DOING_CONFIG_READ 2'b00
|
1152 |
|
|
`define TEST_TARGET_DOING_CONFIG_WRITE 2'b01
|
1153 |
|
|
`define TEST_TARGET_DOING_SRAM_READ 2'b10
|
1154 |
|
|
`define TEST_TARGET_DOING_SRAM_WRITE 2'b11
|
1155 |
|
|
|
1156 |
|
|
task Report_On_Target_PCI_Ref_Start;
|
1157 |
|
|
input [1:0] reference_type;
|
1158 |
|
|
begin
|
1159 |
|
|
case (reference_type[1:0])
|
1160 |
|
|
`TEST_TARGET_DOING_CONFIG_READ:
|
1161 |
|
|
$display (" test target %h - Starting Config Read, at %t",
|
1162 |
|
|
test_device_id[2:0], $time);
|
1163 |
|
|
`TEST_TARGET_DOING_CONFIG_WRITE:
|
1164 |
|
|
$display (" test target %h - Starting Config Write, at %t",
|
1165 |
|
|
test_device_id[2:0], $time);
|
1166 |
|
|
`TEST_TARGET_DOING_SRAM_READ:
|
1167 |
|
|
$display (" test target %h - Starting Memory Read, at %t",
|
1168 |
|
|
test_device_id[2:0], $time);
|
1169 |
|
|
`TEST_TARGET_DOING_SRAM_WRITE:
|
1170 |
|
|
$display (" test target %h - Starting Memory Write, at %t",
|
1171 |
|
|
test_device_id[2:0], $time);
|
1172 |
|
|
default:
|
1173 |
|
|
$display ("*** test target %h - Doing Unknown Reference, at %t",
|
1174 |
|
|
test_device_id[2:0], $time);
|
1175 |
|
|
endcase
|
1176 |
|
|
`ifdef VERBOSE_TEST_DEVICE
|
1177 |
|
|
Report_Target_Reference_Paramaters;
|
1178 |
|
|
`endif // VERBOSE_TEST_DEVICE
|
1179 |
|
|
end
|
1180 |
|
|
endtask
|
1181 |
|
|
|
1182 |
|
|
// Transfer either a burst of Config Registers or SRAM Contents across the PCI Bus
|
1183 |
|
|
// Tasks can't have local storage! have to be module global
|
1184 |
|
|
reg devsel_asserted, fast_devsel_asserted, target_was_terminated;
|
1185 |
|
|
reg [3:0] wait_states_this_time;
|
1186 |
|
|
reg do_abort_this_time, do_retry_this_time, do_disconnect_this_time;
|
1187 |
|
|
reg abort_needs_waitstate;
|
1188 |
|
|
reg [PCI_BUS_DATA_RANGE:0] master_write_data;
|
1189 |
|
|
reg [PCI_BUS_DATA_RANGE:0] target_read_data;
|
1190 |
|
|
reg [PCI_BUS_CBE_RANGE:0] master_mask_l;
|
1191 |
|
|
reg drive_ad_bus;
|
1192 |
|
|
reg signal_satisfied_delayed_read;
|
1193 |
|
|
task Execute_Target_PCI_Ref;
|
1194 |
|
|
input [1:0] reference_type;
|
1195 |
|
|
output saw_fast_back_to_back;
|
1196 |
|
|
reg [9:0] number_of_transfers ;
|
1197 |
|
|
begin
|
1198 |
|
|
|
1199 |
|
|
number_of_transfers = 0 ;
|
1200 |
|
|
`ifdef REPORT_TEST_DEVICE
|
1201 |
|
|
Report_On_Target_PCI_Ref_Start (reference_type[1:0]);
|
1202 |
|
|
`endif // REPORT_TEST_DEVICE
|
1203 |
|
|
Wait_Till_DEVSEL_Possible (devsel_asserted, fast_devsel_asserted,
|
1204 |
|
|
signal_satisfied_delayed_read);
|
1205 |
|
|
if (devsel_asserted == 1'b1)
|
1206 |
|
|
begin
|
1207 |
|
|
// Target must drive AD bus even if it is going to do an abort or retry.
|
1208 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.1
|
1209 |
|
|
drive_ad_bus = (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_READ)
|
1210 |
|
|
| (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_READ);
|
1211 |
|
|
wait_states_this_time[3:0] = hold_target_initial_waitstates[3:0];
|
1212 |
|
|
abort_needs_waitstate = (hold_target_initial_waitstates[3:0] == 4'h0);
|
1213 |
|
|
|
1214 |
|
|
do_abort_this_time = ( (hold_target_termination[2:0] == `Test_Target_Abort) && (hold_target_terminate_on == 1) );
|
1215 |
|
|
|
1216 |
|
|
do_retry_this_time = ( (hold_target_termination[2:0] == `Test_Target_Retry_Before) && (hold_target_terminate_on == 1) ) |
|
1217 |
|
|
(hold_target_termination[2:0] == `Test_Target_Start_Delayed_Read) ;
|
1218 |
|
|
|
1219 |
|
|
do_disconnect_this_time = ( (hold_target_termination[2:0] == `Test_Target_Disc_With) && (hold_target_terminate_on == 1) ) ;
|
1220 |
|
|
|
1221 |
|
|
// If the bottom 2 bits of the Address aren't 2'b00, only transfer 1 word.
|
1222 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 3.2.2.2
|
1223 |
|
|
do_disconnect_this_time = do_disconnect_this_time
|
1224 |
|
|
| (hold_target_address[1:0] != 2'b00);
|
1225 |
|
|
// If Fast Decode and it's a read, don't drive data for 1 clock to avoid AD bus fight
|
1226 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 3.3.1
|
1227 |
|
|
if (fast_devsel_asserted & drive_ad_bus)
|
1228 |
|
|
begin
|
1229 |
|
|
Execute_Target_Waitstates (1'b0, 1'b0, 4'h1); // avoid collisions on AD bus
|
1230 |
|
|
if (wait_states_this_time[3:0] != 4'h0)
|
1231 |
|
|
begin
|
1232 |
|
|
wait_states_this_time[3:0] = wait_states_this_time[3:0] - 4'h1;
|
1233 |
|
|
end
|
1234 |
|
|
`NO_ELSE;
|
1235 |
|
|
end
|
1236 |
|
|
`NO_ELSE;
|
1237 |
|
|
target_was_terminated = 1'b0;
|
1238 |
|
|
while (target_was_terminated == 1'b0)
|
1239 |
|
|
begin
|
1240 |
|
|
Execute_Target_Waitstates (drive_ad_bus, ~drive_ad_bus,
|
1241 |
|
|
wait_states_this_time[3:0]);
|
1242 |
|
|
if (do_abort_this_time)
|
1243 |
|
|
begin
|
1244 |
|
|
if (abort_needs_waitstate)
|
1245 |
|
|
begin
|
1246 |
|
|
Execute_Target_Waitstates (drive_ad_bus, ~drive_ad_bus, 4'h1);
|
1247 |
|
|
end
|
1248 |
|
|
`NO_ELSE;
|
1249 |
|
|
Execute_Target_Abort_Undrive_DEVSEL (drive_ad_bus,
|
1250 |
|
|
signal_satisfied_delayed_read);
|
1251 |
|
|
target_was_terminated = 1'b1;
|
1252 |
|
|
end
|
1253 |
|
|
else if (do_retry_this_time)
|
1254 |
|
|
begin
|
1255 |
|
|
Execute_Target_Retry_Undrive_DEVSEL (drive_ad_bus,
|
1256 |
|
|
(hold_target_termination[2:0] == `Test_Target_Start_Delayed_Read)
|
1257 |
|
|
& ( (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
1258 |
|
|
PCI_COMMAND_MEMORY_READ)
|
1259 |
|
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
1260 |
|
|
PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
1261 |
|
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
1262 |
|
|
PCI_COMMAND_MEMORY_READ_LINE)
|
1263 |
|
|
| (hold_target_command[PCI_BUS_CBE_RANGE:0] ==
|
1264 |
|
|
PCI_COMMAND_CONFIG_READ) ),
|
1265 |
|
|
signal_satisfied_delayed_read);
|
1266 |
|
|
target_was_terminated = 1'b1;
|
1267 |
|
|
end
|
1268 |
|
|
else // at least one data item should be read out of this device
|
1269 |
|
|
begin
|
1270 |
|
|
// do_disconnect_this_time = do_disconnect_this_time // prevent address roll-over
|
1271 |
|
|
// | (hold_target_address[7:2] == 6'h3F);
|
1272 |
|
|
if (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_READ)
|
1273 |
|
|
begin
|
1274 |
|
|
Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus (target_read_data[PCI_BUS_DATA_RANGE:0]);
|
1275 |
|
|
end
|
1276 |
|
|
`NO_ELSE;
|
1277 |
|
|
if (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_READ)
|
1278 |
|
|
begin
|
1279 |
|
|
Fetch_SRAM_Data_For_Read_Onto_AD_Bus (target_read_data[PCI_BUS_DATA_RANGE:0]);
|
1280 |
|
|
end
|
1281 |
|
|
`NO_ELSE;
|
1282 |
|
|
Execute_Target_Ref_Undrive_DEVSEL_On_Any_Termination
|
1283 |
|
|
(drive_ad_bus, do_disconnect_this_time,
|
1284 |
|
|
signal_satisfied_delayed_read,
|
1285 |
|
|
target_read_data[PCI_BUS_DATA_RANGE:0],
|
1286 |
|
|
master_write_data[PCI_BUS_DATA_RANGE:0],
|
1287 |
|
|
master_mask_l[PCI_BUS_CBE_RANGE:0],
|
1288 |
|
|
target_was_terminated);
|
1289 |
|
|
number_of_transfers = number_of_transfers + 1 ;
|
1290 |
|
|
|
1291 |
|
|
if (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_WRITE)
|
1292 |
|
|
begin
|
1293 |
|
|
Capture_Config_Reg_Data_From_AD_Bus (master_write_data[PCI_BUS_DATA_RANGE:0],
|
1294 |
|
|
master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
1295 |
|
|
end
|
1296 |
|
|
`NO_ELSE;
|
1297 |
|
|
if (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_WRITE)
|
1298 |
|
|
begin
|
1299 |
|
|
Capture_SRAM_Data_From_AD_Bus (master_write_data[PCI_BUS_DATA_RANGE:0],
|
1300 |
|
|
master_mask_l[PCI_BUS_CBE_RANGE:0]);
|
1301 |
|
|
end
|
1302 |
|
|
|
1303 |
|
|
`NO_ELSE;
|
1304 |
|
|
// set up for the next transfer
|
1305 |
|
|
wait_states_this_time[3:0] = hold_target_subsequent_waitstates[3:0];
|
1306 |
|
|
abort_needs_waitstate = 1'b0;
|
1307 |
|
|
/*do_abort_this_time = (hold_target_termination[2:0]
|
1308 |
|
|
== `Test_Target_Abort_Before_Second);
|
1309 |
|
|
do_retry_this_time = (hold_target_termination[2:0]
|
1310 |
|
|
== `Test_Target_Retry_Before_Second);
|
1311 |
|
|
do_disconnect_this_time = (hold_target_termination[2:0]
|
1312 |
|
|
== `Test_Target_Disc_With_Second);*/
|
1313 |
|
|
|
1314 |
|
|
do_abort_this_time = ( (hold_target_termination[2:0] == `Test_Target_Abort) && (hold_target_terminate_on == (number_of_transfers + 1)) );
|
1315 |
|
|
|
1316 |
|
|
do_retry_this_time = ( (hold_target_termination[2:0] == `Test_Target_Retry_Before) && (hold_target_terminate_on == (number_of_transfers + 1)) ) ;
|
1317 |
|
|
|
1318 |
|
|
do_disconnect_this_time = ( (hold_target_termination[2:0] == `Test_Target_Disc_With) && (hold_target_terminate_on == (number_of_transfers + 1)) ) ;
|
1319 |
|
|
|
1320 |
|
|
signal_satisfied_delayed_read = 1'b0;
|
1321 |
|
|
end
|
1322 |
|
|
end
|
1323 |
|
|
// Watch for Fast Back-to-Back reference. If seen, do not go to the top
|
1324 |
|
|
// of the Target Idle Loop, which automatically waits for one clock.
|
1325 |
|
|
// Instead go directly to see if this device is addressed.
|
1326 |
|
|
// This transition is manditory even if the device can't do
|
1327 |
|
|
// fast-back-to-back transfers!
|
1328 |
|
|
// See the PCI Local Bus Spec Revision 2.2 section 3.4.2.
|
1329 |
|
|
saw_fast_back_to_back = frame_now & ~irdy_now;
|
1330 |
|
|
// No clock here to let this dovetail with the next reference?
|
1331 |
|
|
end
|
1332 |
|
|
else
|
1333 |
|
|
begin // no devsel, so it must have been an address parity error
|
1334 |
|
|
saw_fast_back_to_back = 1'b0;
|
1335 |
|
|
end
|
1336 |
|
|
end
|
1337 |
|
|
endtask
|
1338 |
|
|
|
1339 |
|
|
// Task to print debug info
|
1340 |
|
|
// NOTE This must change if bit allocation changes
|
1341 |
|
|
task Report_Target_Reference_Paramaters;
|
1342 |
|
|
begin
|
1343 |
|
|
if (hold_target_address[23:9] != 15'h0000)
|
1344 |
|
|
begin
|
1345 |
|
|
$display (" Target Devsel Speed %h, Target Termination %h,",
|
1346 |
|
|
hold_target_devsel_speed[1:0], hold_target_termination[2:0]);
|
1347 |
|
|
$display (" First Target Data Wait States %h, Subsequent Target Data Wait States %h",
|
1348 |
|
|
hold_target_initial_waitstates[3:0],
|
1349 |
|
|
hold_target_subsequent_waitstates[3:0]);
|
1350 |
|
|
$display (" Addr Par Error %h, Data Par Error %h",
|
1351 |
|
|
hold_target_addr_par_err, hold_target_data_par_err);
|
1352 |
|
|
end
|
1353 |
|
|
`NO_ELSE;
|
1354 |
|
|
end
|
1355 |
|
|
endtask
|
1356 |
|
|
|
1357 |
|
|
task Reset_Target_To_Idle;
|
1358 |
|
|
begin
|
1359 |
|
|
Init_Test_Device_SRAM;
|
1360 |
|
|
target_ad_oe <= 1'b0;
|
1361 |
|
|
target_devsel_out <= 1'b0;
|
1362 |
|
|
target_trdy_out <= 1'b0;
|
1363 |
|
|
target_stop_out <= 1'b0;
|
1364 |
|
|
target_perr_check_next <= 1'b0;
|
1365 |
|
|
target_signaling_target_abort <= 1'b0;
|
1366 |
|
|
Delayed_Read_Started <= 1'b0;
|
1367 |
|
|
Delayed_Read_Finished <= 1'b0;
|
1368 |
|
|
end
|
1369 |
|
|
endtask
|
1370 |
|
|
|
1371 |
|
|
// Config References are described in PCI Local Bus Spec
|
1372 |
|
|
// Revision 2.2 section 3.2.2.3.4
|
1373 |
|
|
// The idea is that a Config command must be seen, IDSEL must be LOW,
|
1374 |
|
|
// AD[1:0] must be 2'b00, and either AD[10:8] should be ignored
|
1375 |
|
|
// for a single function device, or only implemented devices should
|
1376 |
|
|
// respond. Function 0 is required to be detected.
|
1377 |
|
|
|
1378 |
|
|
// Make a fake version just to make the charts pop:
|
1379 |
|
|
|
1380 |
|
|
// Fire off Target tasks in response to PCI Bus Activity
|
1381 |
|
|
reg saw_fast_back_to_back;
|
1382 |
|
|
always @(posedge pci_ext_clk or posedge pci_reset_comb)
|
1383 |
|
|
begin
|
1384 |
|
|
if (~pci_reset_comb)
|
1385 |
|
|
begin
|
1386 |
|
|
saw_fast_back_to_back = 1'b1;
|
1387 |
|
|
while (saw_fast_back_to_back == 1'b1) // whats the value of this loop? Does it reset correctly?
|
1388 |
|
|
begin
|
1389 |
|
|
hold_target_address[PCI_BUS_DATA_RANGE:0] = ad_now[PCI_BUS_DATA_RANGE:0]; // intentionally use "="
|
1390 |
|
|
hold_target_command[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0];
|
1391 |
|
|
if (test_response[`TARGET_ENCODED_PARAMATERS_ENABLE] != 1'b0)
|
1392 |
|
|
begin
|
1393 |
|
|
hold_target_initial_waitstates = test_response[`TARGET_ENCODED_INIT_WAITSTATES];
|
1394 |
|
|
hold_target_subsequent_waitstates = test_response[`TARGET_ENCODED_SUBS_WAITSTATES];
|
1395 |
|
|
hold_target_termination = test_response[`TARGET_ENCODED_TERMINATION];
|
1396 |
|
|
hold_target_devsel_speed = test_response[`TARGET_ENCODED_DEVSEL_SPEED];
|
1397 |
|
|
hold_target_data_par_err = test_response[`TARGET_ENCODED_DATA_PAR_ERR];
|
1398 |
|
|
hold_target_addr_par_err = test_response[`TARGET_ENCODED_ADDR_PAR_ERR];
|
1399 |
|
|
hold_target_terminate_on = test_response[`TARGET_ENCODED_TERMINATE_ON];
|
1400 |
|
|
end
|
1401 |
|
|
else
|
1402 |
|
|
begin
|
1403 |
|
|
hold_target_initial_waitstates = 4'h0;
|
1404 |
|
|
hold_target_subsequent_waitstates = 4'h0;
|
1405 |
|
|
hold_target_termination = `Test_Target_Normal_Completion;
|
1406 |
|
|
hold_target_devsel_speed = `Test_Devsel_Medium;
|
1407 |
|
|
hold_target_data_par_err = `Test_No_Data_Perr;
|
1408 |
|
|
hold_target_addr_par_err = `Test_No_Addr_Perr;
|
1409 |
|
|
hold_target_terminate_on = 0 ;
|
1410 |
|
|
end
|
1411 |
|
|
|
1412 |
|
|
if (~frame_prev & frame_now & Target_En
|
1413 |
|
|
`ifdef SIMULTANEOUS_MASTER_TARGET
|
1414 |
|
|
// don't check for reads to self
|
1415 |
|
|
`else // SIMULTANEOUS_MASTER_TARGET
|
1416 |
|
|
// check for, and don't respond to, reads to self
|
1417 |
|
|
`endif //SIMULTANEOUS_MASTER_TARGET
|
1418 |
|
|
& ( (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_WRITE)
|
1419 |
|
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_WRITE_INVALIDATE) )
|
1420 |
|
|
& ( (ad_now[`PCI_BASE_ADDR0_MATCH_RANGE] == BAR0[`PCI_BASE_ADDR0_MATCH_RANGE])
|
1421 |
|
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
1422 |
|
|
| (ad_now[`PCI_BASE_ADDR1_MATCH_RANGE] == BAR1[`PCI_BASE_ADDR1_MATCH_RANGE])
|
1423 |
|
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
1424 |
|
|
) )
|
1425 |
|
|
begin
|
1426 |
|
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_SRAM_WRITE,
|
1427 |
|
|
saw_fast_back_to_back);
|
1428 |
|
|
end
|
1429 |
|
|
else if (~frame_prev & frame_now & (idsel_now == 1'b1)
|
1430 |
|
|
& (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_WRITE)
|
1431 |
|
|
& (ad_now[1:0] == 2'b00) )
|
1432 |
|
|
begin
|
1433 |
|
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_CONFIG_WRITE,
|
1434 |
|
|
saw_fast_back_to_back);
|
1435 |
|
|
end
|
1436 |
|
|
else if (~frame_prev & frame_now & Target_En
|
1437 |
|
|
`ifdef SIMULTANEOUS_MASTER_TARGET
|
1438 |
|
|
// Don't check for reads to self
|
1439 |
|
|
`else // SIMULTANEOUS_MASTER_TARGET
|
1440 |
|
|
// Check for, and don't respond to, reads to self
|
1441 |
|
|
`endif //SIMULTANEOUS_MASTER_TARGET
|
1442 |
|
|
& ( (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ)
|
1443 |
|
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE)
|
1444 |
|
|
| (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ_LINE) )
|
1445 |
|
|
& ( (ad_now[`PCI_BASE_ADDR0_MATCH_RANGE] == BAR0[`PCI_BASE_ADDR0_MATCH_RANGE])
|
1446 |
|
|
`ifdef PCI_BASE_ADDR1_MATCH_ENABLE
|
1447 |
|
|
| (ad_now[`PCI_BASE_ADDR1_MATCH_RANGE] == BAR1[`PCI_BASE_ADDR1_MATCH_RANGE])
|
1448 |
|
|
`endif // PCI_BASE_ADDR1_MATCH_ENABLE
|
1449 |
|
|
) )
|
1450 |
|
|
begin
|
1451 |
|
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_SRAM_READ,
|
1452 |
|
|
saw_fast_back_to_back);
|
1453 |
|
|
end
|
1454 |
|
|
else if (~frame_prev & frame_now & (idsel_now == 1'b1)
|
1455 |
|
|
& (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_READ)
|
1456 |
|
|
& (ad_now[1:0] == 2'b00) )
|
1457 |
|
|
begin
|
1458 |
|
|
Execute_Target_PCI_Ref (`TEST_TARGET_DOING_CONFIG_READ,
|
1459 |
|
|
saw_fast_back_to_back);
|
1460 |
|
|
end
|
1461 |
|
|
else
|
1462 |
|
|
begin
|
1463 |
|
|
saw_fast_back_to_back = 1'b0;
|
1464 |
|
|
end
|
1465 |
|
|
if (pci_reset_comb)
|
1466 |
|
|
begin
|
1467 |
|
|
saw_fast_back_to_back = 1'b0;
|
1468 |
|
|
end
|
1469 |
|
|
end // saw_fast_back_to_back
|
1470 |
|
|
end
|
1471 |
|
|
`NO_ELSE;
|
1472 |
|
|
// Because this is sequential code, have to reset all regs if the above falls
|
1473 |
|
|
// through due to a reset. This would not be needed in synthesizable code.
|
1474 |
|
|
if (pci_reset_comb)
|
1475 |
|
|
begin
|
1476 |
|
|
Reset_Target_To_Idle;
|
1477 |
|
|
end
|
1478 |
|
|
`NO_ELSE;
|
1479 |
|
|
end
|
1480 |
|
|
endmodule
|
1481 |
|
|
|