head 1.10; access; symbols initial_import:1.1.1.1 pci_blue_interface:1.1.1; locks; strict; comment @# @; 1.10 date 2001.08.15.10.31.46; author bbeaver; state Exp; branches; next 1.9; 1.9 date 2001.08.05.06.35.42; author bbeaver; state Exp; branches; next 1.8; 1.8 date 2001.07.06.10.51.01; author bbeaver; state Exp; branches; next 1.7; 1.7 date 2001.07.03.09.20.44; author bbeaver; state Exp; branches; next 1.6; 1.6 date 2001.06.20.11.25.04; author bbeaver; state Exp; branches; next 1.5; 1.5 date 2001.06.08.08.40.36; author bbeaver; state Exp; branches; next 1.4; 1.4 date 2001.03.05.09.54.50; author bbeaver; state Exp; branches; next 1.3; 1.3 date 2001.02.26.11.50.08; author bbeaver; state Exp; branches; next 1.2; 1.2 date 2001.02.23.13.18.34; author bbeaver; state Exp; branches; next 1.1; 1.1 date 2001.02.21.15.28.49; author bbeaver; state Exp; branches 1.1.1.1; next ; 1.1.1.1 date 2001.02.21.15.28.49; author bbeaver; state Exp; branches; next ; desc @@ 1.10 log @Added two-words-of-room flag to FIFO. (Not sure it is needed. Synthesis will remove it if not.) Started stubbing in the Target. @ text @//=========================================================================== // $Id: pci_behaviorial_target.v,v 1.7 2001/07/06 10:43:37 Blue Beaver Exp $ // // Copyright 2001 Blue Beaver. All Rights Reserved. // // Summary: A PCI Behaviorial Target. This module receives commands over // the PCI Bus. The PCI Master encodes commands in the middle // 16 bits of the PCI Address. This Target contains Config // registers and a 256 byte scratch SRAM. It responds with data // when it is given a Read command, and checks data when it is // given a Write command. // This interface does implement a very simple Delayed Read // facility which is enough to let the user manually make the // PCI Bus look like a Delayed Read is begin done. This will // probably not work when a synthesizable PCI Interface tries // to cause Delayed Reads. But by then, a second synthesizable // PCI Core will be the more useful test target. // // 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 // by the Free Software Foundation; either version 2.1 of the License, or // (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this library. If not, write to // Free Software Foundation, Inc. // 59 Temple Place, Suite 330 // Boston, MA 02111-1307 USA // // 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 // use this code for any purpose, including combining it with other source // code, combining it with other logic, translated it into a gate-level // representation, or projected it into gates in a programmable or // 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 // with no new restrictions on redistribution of this source. // // If you make changes, even substantial changes, to this code, or use // 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 // to get a copy of the modified or combined source code, with no new // restrictions on redistribution of the resulting source. // // 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 // 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 // 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 // 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, // 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 // redistribution of this source. // // This code was developed using VeriLogger Pro, by Synapticad. // Their support is greatly appreciated. // // NOTE: This Test Chip instantiates one PCI interface and connects it // to its IO pads and to logic representing a real application. // // NOTE TODO: Horrible. Tasks can't depend on their Arguments being safe // 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 drive PERR and SERR lines // 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 allow bad parity address decodes if Parity Error Response not set 3.7.3 // Need to act on Delayed Read commands // 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 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. // Need to assert SERR on address parity errors 3.7.4.2 // Need to record errors. 3.7.4.3, 3.7.4.4 // Complain if address parity error not seen when expected // Complain if data parity error not seen when expected // //=========================================================================== `timescale 1ns/1ps module pci_behaviorial_target ( ad_now, ad_prev, target_ad_out, target_ad_oe, cbe_l_now, cbe_l_prev, calc_input_parity_prev, par_now, par_prev, frame_now, frame_prev, irdy_now, irdy_prev, target_devsel_out, target_d_t_s_oe, target_trdy_out, target_stop_out, target_perr_out, target_perr_oe, target_serr_oe, idsel_now, idsel_prev, pci_reset_comb, pci_ext_clk, // 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_target_abort, master_caused_parity_error, master_enable, master_fast_b2b_en, master_perr_enable, master_serr_enable, master_latency_value, // Signals used by the test bench instead of using "." notation target_debug_force_bad_par, test_error_event, test_device_id ); `include "pci_blue_options.vh" `include "pci_blue_constants.vh" input [PCI_BUS_DATA_RANGE:0] ad_now; input [PCI_BUS_DATA_RANGE:0] ad_prev; output [PCI_BUS_DATA_RANGE:0] target_ad_out; output target_ad_oe; input [PCI_BUS_CBE_RANGE:0] cbe_l_now; input [PCI_BUS_CBE_RANGE:0] cbe_l_prev; input calc_input_parity_prev; input par_now, par_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_perr_out, target_perr_oe, target_serr_oe; input idsel_now, idsel_prev; input pci_reset_comb, pci_ext_clk; // 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_target_abort, master_caused_parity_error; output master_enable, master_fast_b2b_en, master_perr_enable, master_serr_enable; output [7:0] master_latency_value; // Signals used by the test bench instead of using "." notation output target_debug_force_bad_par; output test_error_event; input [2:0] test_device_id; reg [PCI_BUS_DATA_RANGE:0] target_ad_out; reg target_ad_oe; reg target_devsel_out, target_trdy_out, target_stop_out; wire target_d_t_s_oe, target_perr_oe; reg target_perr_out, target_serr_oe; reg target_debug_force_bad_par; reg test_error_event; // Make temporary Bip every time an error is detected initial test_error_event <= 1'bZ; reg error_detected; initial error_detected <= 1'b0; always @@(error_detected) begin test_error_event <= 1'b0; #2; test_error_event <= 1'bZ; end // Target Interface: // This will have just enough memory to make debugging exciting. // It will have 256 Bytes of SRAM. The memory will be available // BOTH as Config memory and as regular memory. // Special regions of the memory will have special characteristics. // Locations 0, 4, 8, A, 10, and 14 will be implemented as Control // registers. // Locations 18 and 1C will be used for memory debugging (somehow!) // All other locations will act as simple memory. // Config Register Area consists of: // 31 24 23 16 15 8 7 0 // | Device ID | Vendor ID | 0x00 // | Status | Command | 0x04 // | Class Code | Rev | 0x08 // | BIST | HEAD | LTCY | CSize| 0x0A // | Base Address 0 | 0x10 // | Base Address 1 | 0x14 // | Unused | 0x18 // | Unused | 0x1C // | Unused | 0x20 // | Unused | 0x24 // | Cardbus Pointer | 0x28 // | SubSys ID | SubVnd ID | 0x2C // | Expansion ROM Pointer | 0x30 // | Reserved | Cap | 0x34 // | Reserved | 0x38 // | MLat | MGnt | IPin | ILine| 0x3C // // Command resets to 0 or maybe 0x80. It consists of: // {6'h00, FB2B_En, SERR_En, // Step_En, Par_Err_En, VGA_En, Mem_Write_Inv_En, // Special_En, Master_En, Target_En, IO_En} // // Status consists of: // {Detected_Perr, Signaled_Serr, Got_Master_Abort, Got_Target_Abort, // Signaled_Target_Abort, Devsel_Timing[1:0], Master_Got_Perr, // FB2B_Capable, 1'b0, 66MHz_Capable, New_Capabilities, // 4'h0} // // Got_Master_Abort is not set for Special Cycles. // Devsel will be 2'h01 in this design. New_Capabilities is 1'b0. // All clearable bits in this register are cleared whenever the // register is written with the corresponding bit being 1'b1. // 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 Detected_PERR, Signaled_SERR, Received_Master_Abort, Received_Target_Abort; reg Signaled_Target_Abort, Master_Caused_PERR; reg [7:0] Latency_Timer; reg [7:0] Cache_Line_Size; reg [7:0] Interrupt_Line; reg [`PCI_BASE_ADDR0_MATCH_RANGE] BAR0; // Base Address Registers, used to match addresses `ifdef PCI_BASE_ADDR1_MATCH_ENABLE reg [`PCI_BASE_ADDR1_MATCH_RANGE] BAR1; `endif // PCI_BASE_ADDR1_MATCH_ENABLE wire [15:0] Target_Command = {4'b0000, 2'b00, FB2B_En, SERR_En, 1'b1, Par_Err_En, 2'b00, 1'b0, Master_En, Target_En, 1'b0}; `ifdef PCI_CLK_66 wire [15:0] Target_Status = {Detected_PERR, Signaled_SERR, Received_Master_Abort, Received_Target_Abort, Signaled_Target_Abort, 2'b01, Master_Caused_PERR, 1'b1, 1'b0, 1'b1, 1'b0, 4'b0000}; `else // PCI_CLK_66 wire [15:0] Target_Status = {Detected_PERR, Signaled_SERR, Received_Master_Abort, Received_Target_Abort, Signaled_Target_Abort, 2'b01, Master_Caused_PERR, 1'b1, 1'b0, 1'b0, 1'b0, 4'b0000}; `endif // PCI_CLK_66 assign master_enable = Master_En; assign master_fast_b2b_en = FB2B_En; assign master_perr_enable = Par_Err_En; assign master_serr_enable = SERR_En; assign master_latency_value[7:0] = Latency_Timer[7:0]; task Read_Test_Device_Config_Regs; input [7:2] reg_number; output [PCI_BUS_DATA_RANGE:0] Read_Config_Reg; begin // Addresses except 0, 4, 8, A, 10, 14, 3C all return 0x00 case (reg_number[7:2]) 6'h00: Read_Config_Reg = 32'h8000AAAA | {13'h0000, test_device_id[2:0], 16'h0000}; 6'h01: Read_Config_Reg = {Target_Status[15:0], Target_Command[15:0]}; 6'h02: Read_Config_Reg = 32'hFF000000; 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], `PCI_BASE_ADDR0_FILL, `PCI_BASE_ADDR0_MAP_QUAL}; `ifdef PCI_BASE_ADDR1_MATCH_ENABLE 6'h05: Read_Config_Reg = {BAR1[`PCI_BASE_ADDR1_MATCH_RANGE], `PCI_BASE_ADDR1_FILL, `PCI_BASE_ADDR1_MAP_QUAL}; `else // PCI_BASE_ADDR1_MATCH_ENABLE 6'h05: Read_Config_Reg = 32'h00000000; `endif // PCI_BASE_ADDR1_MATCH_ENABLE 6'h0F: Read_Config_Reg = {16'h0000, 8'h01, Interrupt_Line[7:0]}; default: Read_Config_Reg = 32'h00000000; endcase end endtask // store info away so Config Register code can update register correctly reg [7:2] pending_config_reg_write_address; reg [PCI_BUS_CBE_RANGE:0] pending_config_reg_write_byte_enables; reg [PCI_BUS_DATA_RANGE:0] pending_config_reg_write_data; reg pending_config_write_request; task Write_Test_Device_Config_Regs; input [7:2] reg_number; input [PCI_BUS_DATA_RANGE:0] data; input [PCI_BUS_CBE_RANGE:0] master_mask_l; begin if (~pci_reset_comb) begin 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_data[PCI_BUS_DATA_RANGE:0] <= data[PCI_BUS_DATA_RANGE:0]; pending_config_write_request <= 1'b1; end `NO_ELSE; end endtask wire target_got_parity_error; wire target_asserted_serr; reg target_signaling_target_abort; // Make a register transfer style Configuration Register, so it is easier to handle // simultaneous updates from the master and the target. always @@(posedge pci_ext_clk or posedge pci_reset_comb) begin if (pci_reset_comb) begin FB2B_En <= 1'b0; SERR_En <= 1'b0; Par_Err_En <= 1'b0; Master_En <= 1'b0; Target_En <= 1'b0; Detected_PERR <= 1'b0; Signaled_SERR <= 1'b0; Received_Master_Abort <= 1'b0; Received_Target_Abort <= 1'b0; Signaled_Target_Abort <= 1'b0; Master_Caused_PERR <= 1'b0; Latency_Timer <= 8'h00; Cache_Line_Size <= 8'h00; Interrupt_Line <= 8'h00; BAR0 <= 8'hXX; `ifdef PCI_BASE_ADDR1_MATCH_ENABLE BAR1 <= 8'hXX; `endif // PCI_BASE_ADDR1_MATCH_ENABLE pending_config_write_request <= 1'b0; end else begin if (pending_config_write_request) begin // 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) & ~pending_config_reg_write_byte_enables[1]) ? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_FB2B_EN) != `PCI_BUS_DATA_ZERO) : FB2B_En; SERR_En <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~pending_config_reg_write_byte_enables[1]) ? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_SERR_EN) != `PCI_BUS_DATA_ZERO) : SERR_En; Par_Err_En <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~pending_config_reg_write_byte_enables[0]) ? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_PAR_ERR_EN) != `PCI_BUS_DATA_ZERO) : Par_Err_En; Master_En <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~pending_config_reg_write_byte_enables[0]) ? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_MASTER_EN) != `PCI_BUS_DATA_ZERO) : Master_En; Target_En <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~pending_config_reg_write_byte_enables[0]) ? ((pending_config_reg_write_data[PCI_BUS_DATA_RANGE:0] & CONFIG_CMD_TARGET_EN) != `PCI_BUS_DATA_ZERO) : Target_En; // Certain bits in word 1 are only clearable, not writable. Detected_PERR <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~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)) ? 1'b0 : Detected_PERR | master_got_parity_error | target_got_parity_error; Signaled_SERR <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~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)) ? 1'b0 : Signaled_SERR | master_asserted_serr | target_asserted_serr; Received_Master_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~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)) ? 1'b0 : Received_Master_Abort | master_got_master_abort; Received_Target_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~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)) ? 1'b0 : Received_Target_Abort | master_got_target_abort; Signaled_Target_Abort <= ((pending_config_reg_write_address[7:2] == 6'h01) & ~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)) ? 1'b0 : Signaled_Target_Abort | target_signaling_target_abort; Master_Caused_PERR <= ( (pending_config_reg_write_address[7:2] == 6'h01) & ~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)) ? 1'b0 : Master_Caused_PERR | master_caused_parity_error; // Certain bytes in higher words are writable Latency_Timer <= ( (pending_config_reg_write_address[7:2] == 6'h03) & ~pending_config_reg_write_byte_enables[1]) ? pending_config_reg_write_data[15:8] : Latency_Timer; Cache_Line_Size <= ( (pending_config_reg_write_address[7:2] == 6'h03) & ~pending_config_reg_write_byte_enables[0]) ? pending_config_reg_write_data[7:0] : Cache_Line_Size; BAR0 <= ( (pending_config_reg_write_address[7:2] == 6'h04) & ~pending_config_reg_write_byte_enables[3]) ? pending_config_reg_write_data[`PCI_BASE_ADDR0_MATCH_RANGE] : BAR0; `ifdef PCI_BASE_ADDR1_MATCH_ENABLE BAR1 <= ( (pending_config_reg_write_address[7:2] == 6'h05) & ~pending_config_reg_write_byte_enables[3]) ? pending_config_reg_write_data[`PCI_BASE_ADDR1_MATCH_RANGE] : BAR1; `endif // PCI_BASE_ADDR1_MATCH_ENABLE Interrupt_Line <= ( (pending_config_reg_write_address[7:2] == 6'h0F) & ~pending_config_reg_write_byte_enables[0]) ? pending_config_reg_write_data[7:0] : Interrupt_Line; pending_config_write_request <= 1'b0; // NOTE this seems to prevent back-to-back writes. end else begin // not writing from PCI side // Words 0 and 2 are not writable. Only certain bits in word 1 are writable. FB2B_En <= FB2B_En; SERR_En <= SERR_En; Par_Err_En <= Par_Err_En; Master_En <= Master_En; Target_En <= Target_En; // Certain bits in word 1 are only clearable, not writable. Detected_PERR <= Detected_PERR | master_got_parity_error | target_got_parity_error; Signaled_SERR <= Signaled_SERR | master_asserted_serr | target_asserted_serr; Received_Master_Abort <= Received_Master_Abort | master_got_master_abort; Received_Target_Abort <= Received_Target_Abort | master_got_target_abort; Signaled_Target_Abort <= Signaled_Target_Abort | target_signaling_target_abort; Master_Caused_PERR <= Master_Caused_PERR | master_caused_parity_error; // Certain bytes in higher words are writable Latency_Timer <= Latency_Timer; Cache_Line_Size <= Cache_Line_Size; BAR0 <= BAR0; `ifdef PCI_BASE_ADDR1_MATCH_ENABLE BAR1 <= BAR1; `endif // PCI_BASE_ADDR1_MATCH_ENABLE Interrupt_Line <= Interrupt_Line; end end end // Tasks to manage the small SRAM visible in Memory Space reg [PCI_BUS_DATA_RANGE:0] Test_Device_Mem [0:63]; // address limits, not bits in address // Tasks can't have local storage! have to be module global reg [6:0] sram_addr; task Init_Test_Device_SRAM; begin for (sram_addr = 7'h00; sram_addr < 7'h40; sram_addr = sram_addr + 7'h01) begin Test_Device_Mem[sram_addr] = `PCI_BUS_DATA_X; end end endtask task Read_Test_Device_SRAM; input [7:2] sram_address; output [PCI_BUS_DATA_RANGE:0] target_read_data; begin target_read_data = Test_Device_Mem[sram_address[7:2]]; end endtask // Tasks can't have local storage! have to be module global reg [PCI_BUS_DATA_RANGE:0] sram_temp; task Write_Test_Device_SRAM; input [7:2] sram_address; input [PCI_BUS_DATA_RANGE:0] master_write_data; input [PCI_BUS_CBE_RANGE:0] master_mask_l; begin sram_temp = Test_Device_Mem[sram_address[7:2]]; 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[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]; Test_Device_Mem[sram_address[7:2]] = sram_temp[PCI_BUS_DATA_RANGE:0]; end endtask // Make the DEVSEL_TRDY_STOP_OE output enable signal. It must become // asserted as soon as one of those signals become asserted, and // must stay asserted one clock after the last one becomes deasserted. reg prev_d_t_s_asserted; always @@(posedge pci_ext_clk or posedge pci_reset_comb) begin if (pci_reset_comb) begin prev_d_t_s_asserted <= 1'b0; end else begin prev_d_t_s_asserted <= target_devsel_out | target_trdy_out | target_stop_out; end end assign target_d_t_s_oe = target_devsel_out | target_trdy_out | target_stop_out | prev_d_t_s_asserted; // Make the PERR_OE signal. // 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+1, external data is latched, and irdy is also latched // At time N+1, target_perr_check is latched // At time N+2, calc_input_parity_prev is valid // Also at N+2, external parity is valid reg target_perr_prev, target_perr_check_next, target_perr_check; reg target_perr_detected; always @@(posedge pci_ext_clk or posedge pci_reset_comb) begin if (pci_reset_comb) begin target_perr_check <= 1'b0; target_perr_detected <= 1'b0; target_perr_out <= 1'b0; target_perr_prev <= 1'b0; end else begin target_perr_check <= target_perr_check_next; target_perr_detected <= target_perr_check & irdy_prev & (calc_input_parity_prev != par_now); target_perr_out <= target_perr_check & irdy_prev & Par_Err_En & (calc_input_parity_prev != par_now); target_perr_prev <= target_perr_out; end end assign target_perr_oe = target_perr_out | target_perr_prev; // Make the SERR_OE signal // See the PCI Local Bus Spec Revision 2.2 section 6.2.3. reg prev_prev_frame; always @@(posedge pci_ext_clk or posedge pci_reset_comb) begin if (pci_reset_comb) begin prev_prev_frame <= 1'b0; target_serr_oe <= 1'b0; end else begin prev_prev_frame <= frame_prev; target_serr_oe <= ~prev_prev_frame & frame_prev & SERR_En & Par_Err_En & (calc_input_parity_prev != par_now); end end assign target_asserted_serr = target_serr_oe; assign target_got_parity_error = target_perr_detected | target_serr_oe; // Remember whether this device drove DEVSEL last clock, which allows // Zero-Wait-State Back-to-Back references wire This_Target_Drove_DEVSEL_Last_Clock = target_d_t_s_oe; // Remember whether the bus has correct parity. // Used by Medium, slower Address Decode to prevent DEVSEL on bad Address Parity reg prev_bus_par_ok, prev_prev_bus_par_ok; always @@(posedge pci_ext_clk) begin prev_bus_par_ok <= (calc_input_parity_prev == par_now); prev_prev_bus_par_ok <= prev_bus_par_ok; end // 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 // encode Target Wait State, Target Completion, and Target Error info. // 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_CBE_RANGE:0] hold_target_command; reg [3:0] hold_target_initial_waitstates; reg [3:0] hold_target_subsequent_waitstates; reg [2:0] hold_target_termination; reg [1:0] hold_target_devsel_speed; reg hold_target_data_par_err; reg hold_target_addr_par_err; // Tasks which use the held PCI address to access internal info. These tasks // update the address counter, emulating the target address counter during bursts. // Store data from PCI bus into Config Register, and increment Write Pointer task Capture_Config_Reg_Data_From_AD_Bus; input [PCI_BUS_DATA_RANGE:0] master_write_data; input [PCI_BUS_CBE_RANGE:0] master_mask_l; begin 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]); hold_target_address[7:2] = hold_target_address[7:2] + 6'h01; // addr++ end endtask // Drive Config Register Data onto AD bus, and increment Read Pointer task Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus; output [PCI_BUS_DATA_RANGE:0] target_read_data; begin 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++ end endtask // Store data from PCI bus into SRAM, and increment Write Pointer task Capture_SRAM_Data_From_AD_Bus; input [PCI_BUS_DATA_RANGE:0] master_write_data; input [PCI_BUS_CBE_RANGE:0] master_mask_l; begin Write_Test_Device_SRAM (hold_target_address[7:2], 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++ end endtask // Drive SRAM Data onto AD bus, and increment Read Pointer task Fetch_SRAM_Data_For_Read_Onto_AD_Bus; output [PCI_BUS_DATA_RANGE:0] target_read_data; begin Read_Test_Device_SRAM (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++ end endtask // The target is able to execute Delayed Reads, // 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. // Also a PCI command matching in Address, Command, Byte Enables, // and parity on address. // If the region of memory is prefetchable and always returns all // bytes, it is OK to disregard the Byte Enables. reg Delayed_Read_Started, Delayed_Read_Pending, Delayed_Read_Finished; 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_Mask_L; reg [14:0] Delayed_Read_Discard_Counter; wire [14:0] Delayed_Read_Discard_Limit = 15'h7FFF; // change for debugging always @@(posedge pci_ext_clk or posedge pci_reset_comb) begin if (pci_reset_comb) begin Delayed_Read_Pending <= 1'b0; end else begin Delayed_Read_Pending <= Delayed_Read_Started | (Delayed_Read_Pending & ~Delayed_Read_Finished & (Delayed_Read_Discard_Counter[14:0] < Delayed_Read_Discard_Limit[14:0])); end end always @@(posedge pci_ext_clk) begin Delayed_Read_Discard_Counter[14:0] <= Delayed_Read_Started ? 15'h0000 : Delayed_Read_Discard_Counter[14:0] + 15'h0001; `ifdef VERBOSE_TEST_DEVICE if (Delayed_Read_Pending & (Delayed_Read_Discard_Counter[14:0] >= Delayed_Read_Discard_Limit[14:0])) begin $display (" test target %h - Delayed Read Discarded, at %t", test_device_id[2:0], $time); end `NO_ELSE; `endif // VERBOSE_TEST_DEVICE end // Target tasks. These know how to respond to the external masters. // NOTE all tasks end with an @@(posedge pci_ext_clk) statement // to let any signals asserted during that task settle out. // If a task DOESN'T end with @@(posedge pci_ext_clk), then it must // be called just before some other task which does. parameter TEST_TARGET_SPINLOOP_MAX = 20; task Clock_Wait_Unless_Reset; begin if (~pci_reset_comb) begin @@ (posedge pci_ext_clk or posedge pci_reset_comb) ; end `NO_ELSE; end endtask task Assert_DEVSEL; begin target_devsel_out <= 1'b1; end endtask task Assert_TRDY; begin target_trdy_out <= 1'b1; end endtask task Assert_STOP; begin target_stop_out <= 1'b1; end endtask task Deassert_DEVSEL; begin target_devsel_out <= 1'b0; end endtask task Deassert_TRDY; begin target_trdy_out <= 1'b0; end endtask task Deassert_STOP; begin target_stop_out <= 1'b0; end endtask task Assert_Target_Continue_Or_Disconnect; input do_target_disconnect; begin if (do_target_disconnect) begin Assert_DEVSEL; Assert_TRDY; Assert_STOP; end else begin Assert_DEVSEL; Assert_TRDY; Deassert_STOP; end end endtask // Execute_Target_Retry is called with nothing or DEVSEL asserted // tasks can't have local storage! have to be module global integer iiii; task Execute_Target_Retry_Undrive_DEVSEL; input drive_ad_bus; input signal_starting_delayed_read; input signal_satisfied_delayed_read; begin for (iiii = 0; iiii < TEST_TARGET_SPINLOOP_MAX; iiii = iiii + 1) begin if ((iiii == 0) | frame_now | ~irdy_now) // At least one stop, then Not Finished begin target_ad_out <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= drive_ad_bus; target_debug_force_bad_par <= 1'b0; target_perr_check_next <= ~drive_ad_bus; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= signal_starting_delayed_read; Delayed_Read_Finished <= signal_satisfied_delayed_read; Assert_DEVSEL; // signal DEVSEL and Stop, indicating Retry Deassert_TRDY; Assert_STOP; if (signal_starting_delayed_read) begin 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_Mask_L[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0]; end `NO_ELSE; end else begin target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= 1'b0; // unconditionally undrive ad bus target_debug_force_bad_par <= 1'b0; target_perr_check_next <= 1'b0; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Deassert_DEVSEL; // Master saw us, so leave Deassert_TRDY; Deassert_STOP; iiii = TEST_TARGET_SPINLOOP_MAX + 1; // break end Clock_Wait_Unless_Reset; // wait for outputs to settle signal_satisfied_delayed_read = 1'b0; end `ifdef NORMAL_PCI_CHECKS if (~pci_reset_comb & (iiii == TEST_TARGET_SPINLOOP_MAX)) begin $display ("*** test target %h - Bus didn't go Idle during Target Retry, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; if (~pci_reset_comb & irdy_now) begin $display ("*** test target %h - IRDY didn't deassert at end of Target Retry, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; `endif // NORMAL_PCI_CHECKS end endtask // This Test Device is capable of doing Fast Decode. To do this, // it must make sure not to cause conflicts on DEVSEL, IRDY, // STOP, or PERR. To achieve this, the task must hold off on // making DEVSEL unless either // 1) the bus was just Idle // 2) this device also drove DEVSEL the previous clock (I presume this // 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.7.3 for what // to do if an Address Parity Error is detected. // Since this behaviorial test knows that an address parity error is // comming, it holds off fast decode parity errors, and always // allows a master abort to happen. This would not be possible in // 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 // if it prevented any writes of data, or reads with side-effects. task Wait_Till_DEVSEL_Possible; output devsel_asserted; output fast_devsel_asserted; output signal_satisfied_delayed_read; begin if ((hold_target_devsel_speed[1:0] == `Test_Devsel_Fast) & ~Delayed_Read_Pending & ( (~frame_prev & ~irdy_prev) | (~frame_prev & irdy_prev & This_Target_Drove_DEVSEL_Last_Clock) ) & ~(hold_target_addr_par_err & Par_Err_En)) begin `ifdef VERBOSE_TEST_DEVICE $display (" test target %h - doing fast DEVSEL, at %t", test_device_id[2:0], $time); `endif // VERBOSE_TEST_DEVICE devsel_asserted = 1'b1; // fast decode fast_devsel_asserted = 1'b1; // fast decode signal_satisfied_delayed_read = 1'b0; end else begin target_ad_out <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL? target_debug_force_bad_par <= 1'b0; target_perr_check_next <= 1'b0; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Deassert_DEVSEL; Deassert_TRDY; Deassert_STOP; Clock_Wait_Unless_Reset; // wait for outputs to settle if (Delayed_Read_Pending & ( (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_LINE) | (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) ) & ( ( (hold_target_address[PCI_BUS_DATA_RANGE:0] & 32'hFF0000FF) // partial test address match != (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]) | (cbe_l_now[PCI_BUS_CBE_RANGE:0] != Delayed_Read_Mask_L[PCI_BUS_CBE_RANGE:0]) ) ) begin Execute_Target_Retry_Undrive_DEVSEL (1'b1, 1'b0, 1'b0); devsel_asserted = 1'b0; // tell calling routine to not claim DEVSEL. fast_devsel_asserted = 1'b0; signal_satisfied_delayed_read = 1'b0; end else begin if (( (hold_target_devsel_speed[1:0] == `Test_Devsel_Fast) | (hold_target_devsel_speed[1:0] == `Test_Devsel_Medium) ) & ((calc_input_parity_prev == par_now) | ~Par_Err_En)) begin devsel_asserted = 1'b1; // medium decode fast_devsel_asserted = 1'b0; // medium decode 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_MULTIPLE) | (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE) | (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) ); end else begin target_ad_out <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL? target_debug_force_bad_par <= 1'b0; target_perr_check_next <= 1'b0; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Deassert_DEVSEL; Deassert_TRDY; Deassert_STOP; Clock_Wait_Unless_Reset; if ((hold_target_devsel_speed[1:0] == `Test_Devsel_Slow) & prev_bus_par_ok) begin devsel_asserted = 1'b1; // slow decode fast_devsel_asserted = 1'b0; // slow decode 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_MULTIPLE) | (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE) | (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) ); end else begin target_ad_out <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL? target_debug_force_bad_par <= 1'b0; target_perr_check_next <= 1'b0; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Deassert_DEVSEL; Deassert_TRDY; Deassert_STOP; Clock_Wait_Unless_Reset; // wait for outputs to settle if ((hold_target_devsel_speed[1:0] == `Test_Devsel_Subtractive) & (prev_prev_bus_par_ok | ~Par_Err_En)) begin devsel_asserted = 1'b1; // subtractive decode fast_devsel_asserted = 1'b0; // subtractive decode 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_MULTIPLE) | (hold_target_command[3:0] == PCI_COMMAND_MEMORY_READ_LINE) | (hold_target_command[3:0] == PCI_COMMAND_CONFIG_READ) ); end else begin devsel_asserted = 1'b0; // must have had bad parity fast_devsel_asserted = 1'b0; signal_satisfied_delayed_read = 1'b0; end end end end end `ifdef NORMAL_PCI_CHECKS if (~pci_reset_comb & (devsel_asserted == 1'b1) & (hold_target_addr_par_err == 1'b1)) begin $display ("*** test target %h - DEVSEL Asserted when Address Parity Error expected, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; `endif // NORMAL_PCI_CHECKS end endtask // 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 // or before the Master Parity can be checked. // Tasks can't have local storage! have to be module global reg [3:0] cnt1; task Execute_Target_Waitstates; input drive_ad_bus; input enable_parity_check; input [3:0] num_waitstates; begin for (cnt1 = 4'h0; cnt1 < num_waitstates[3:0]; cnt1 = cnt1 + 4'h1) begin `ifdef NORMAL_PCI_CHECKS if (!pci_reset_comb & ~frame_now & ~irdy_now) begin $display ("*** test target %h - Execute Target Waitstates Wait States called when no Master, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; `endif // NORMAL_PCI_CHECKS target_ad_out <= `BUS_WAIT_STATE_VALUE; target_ad_oe <= drive_ad_bus; target_debug_force_bad_par <= 1'b0; target_perr_check_next <= enable_parity_check; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Assert_DEVSEL; Deassert_TRDY; Deassert_STOP; Clock_Wait_Unless_Reset; // wait for outputs to settle end end endtask // DEVSEL already asserted upon entry to this task. OK to watch Parity // Tasks can't have local storage! have to be module global integer ii; task Linger_Until_Master_Waitstates_Done; input drive_ad_bus; input [PCI_BUS_DATA_RANGE:0] target_read_data; input do_target_disconnect; begin for (ii = 0; ii < TEST_TARGET_SPINLOOP_MAX; ii = ii + 1) begin if (frame_now & ~irdy_now) // master executing wait states begin target_ad_out[PCI_BUS_DATA_RANGE:0] <= target_read_data[PCI_BUS_DATA_RANGE:0]; target_ad_oe <= drive_ad_bus; target_debug_force_bad_par <= hold_target_data_par_err; target_perr_check_next <= ~drive_ad_bus; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Assert_Target_Continue_Or_Disconnect (do_target_disconnect); Clock_Wait_Unless_Reset; // wait for outputs to settle end else begin ii = TEST_TARGET_SPINLOOP_MAX + 1; // break end end `ifdef NORMAL_PCI_CHECKS if (~pci_reset_comb & ~frame_now & ~irdy_now) begin $display ("*** test target %h - Linger during Master Wait States called when no Master, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; if (~pci_reset_comb & (ii == TEST_TARGET_SPINLOOP_MAX)) begin $display ("*** test target %h - Bus stuck in Master Wait States during Target ref, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; `endif // NORMAL_PCI_CHECKS end endtask // Execute_Target_Abort. This must be called with DEVSEL asserted // Tasks can't have local storage! have to be module global integer iii; task Execute_Target_Abort_Undrive_DEVSEL; input drive_ad_bus; input signal_satisfied_delayed_read; begin `ifdef NORMAL_PCI_CHECKS if (~pci_reset_comb & (target_devsel_out == 1'b0)) begin $display ("*** test target %h - DEVSEL not asserted when starting Target Abort, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; `endif // NORMAL_PCI_CHECKS for (iii = 0; iii < TEST_TARGET_SPINLOOP_MAX; iii = iii + 1) begin if ((iii == 0) | frame_now | ~irdy_now) // At least one stop, Master Not Finished begin target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= 1'b0; // Should this drive AD when not DEVSEL? target_debug_force_bad_par <= 1'b0; target_perr_check_next <= 1'b0; target_signaling_target_abort <= 1'b1; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= signal_satisfied_delayed_read; Deassert_DEVSEL; // Signal Target Abort Deassert_TRDY; Assert_STOP; end else begin target_ad_out[PCI_BUS_DATA_RANGE:0] <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= 1'b0; // unconditionally undrive ad bus target_debug_force_bad_par <= 1'b0; target_perr_check_next <= 1'b0; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Deassert_DEVSEL; // Signal Target Abort Deassert_TRDY; Deassert_STOP; // Master saw us, so leave iii = TEST_TARGET_SPINLOOP_MAX + 1; // break end Clock_Wait_Unless_Reset; // wait for outputs to settle signal_satisfied_delayed_read = 1'b0; end `ifdef NORMAL_PCI_CHECKS if (~pci_reset_comb & irdy_now) begin $display ("*** test target %h - Master didn't deassert IRDY at end of Target Abort, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; if (~pci_reset_comb & (iii == TEST_TARGET_SPINLOOP_MAX)) begin $display ("*** test target %h - Bus didn't go Idle during Target Abort, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; `endif // NORMAL_PCI_CHECKS end endtask // Transfer a word with or without target termination, and act on Master Termination task Execute_Target_Ref_Undrive_DEVSEL_On_Any_Termination; input drive_ad_bus; input do_target_disconnect; input signal_satisfied_delayed_read; input [PCI_BUS_DATA_RANGE:0] target_read_data; output [PCI_BUS_DATA_RANGE:0] master_write_data; output [PCI_BUS_CBE_RANGE:0] master_mask_l; output target_was_terminated; begin target_ad_out[PCI_BUS_DATA_RANGE:0] <= target_read_data[PCI_BUS_DATA_RANGE:0]; target_ad_oe <= drive_ad_bus; target_debug_force_bad_par <= hold_target_data_par_err; target_perr_check_next <= ~drive_ad_bus; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= signal_satisfied_delayed_read; Assert_Target_Continue_Or_Disconnect (do_target_disconnect); Clock_Wait_Unless_Reset; // wait for outputs to settle Linger_Until_Master_Waitstates_Done (drive_ad_bus, 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_mask_l[PCI_BUS_CBE_RANGE:0] = cbe_l_now[PCI_BUS_CBE_RANGE:0]; if (frame_now & irdy_now & ~do_target_disconnect) begin target_was_terminated = 1'b0; end else begin if (frame_now & irdy_now & do_target_disconnect) // doing Target Termination begin target_ad_out <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= drive_ad_bus; target_debug_force_bad_par <= 1'b0; target_perr_check_next <= ~drive_ad_bus; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Assert_DEVSEL; Deassert_TRDY; Assert_STOP; Clock_Wait_Unless_Reset; // give master a chance to turn FRAME around end `NO_ELSE; `ifdef NORMAL_PCI_CHECKS if (~pci_reset_comb & ~(~frame_now & irdy_now)) // error if not last master data phase begin $display ("*** test target %h - Master entered fatally odd state in Target Ref, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; `endif // NORMAL_PCI_CHECKS target_ad_out <= `BUS_IMPOSSIBLE_VALUE; target_ad_oe <= 1'b0; // unconditionally undrive ad bus target_debug_force_bad_par <= 1'b0; target_perr_check_next <= 1'b0; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; Deassert_DEVSEL; Deassert_TRDY; Deassert_STOP; Clock_Wait_Unless_Reset; `ifdef NORMAL_PCI_CHECKS if (~pci_reset_comb & irdy_now) begin $display ("*** test target %h - IRDY didn't deassert at end of Master Termination, at %t", test_device_id[2:0], $time); error_detected <= ~error_detected; end `NO_ELSE; `endif // NORMAL_PCI_CHECKS target_was_terminated = 1'b1; end end endtask `define TEST_TARGET_DOING_CONFIG_READ 2'b00 `define TEST_TARGET_DOING_CONFIG_WRITE 2'b01 `define TEST_TARGET_DOING_SRAM_READ 2'b10 `define TEST_TARGET_DOING_SRAM_WRITE 2'b11 task Report_On_Target_PCI_Ref_Start; input [1:0] reference_type; begin case (reference_type[1:0]) `TEST_TARGET_DOING_CONFIG_READ: $display (" test target %h - Starting Config Read, at %t", test_device_id[2:0], $time); `TEST_TARGET_DOING_CONFIG_WRITE: $display (" test target %h - Starting Config Write, at %t", test_device_id[2:0], $time); `TEST_TARGET_DOING_SRAM_READ: $display (" test target %h - Starting Memory Read, at %t", test_device_id[2:0], $time); `TEST_TARGET_DOING_SRAM_WRITE: $display (" test target %h - Starting Memory Write, at %t", test_device_id[2:0], $time); default: $display ("*** test target %h - Doing Unknown Reference, at %t", test_device_id[2:0], $time); endcase `ifdef VERBOSE_TEST_DEVICE Report_Target_Reference_Paramaters; `endif // VERBOSE_TEST_DEVICE end endtask // 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 reg devsel_asserted, fast_devsel_asserted, target_was_terminated; reg [3:0] wait_states_this_time; reg do_abort_this_time, do_retry_this_time, do_disconnect_this_time; reg abort_needs_waitstate; reg [PCI_BUS_DATA_RANGE:0] master_write_data; reg [PCI_BUS_DATA_RANGE:0] target_read_data; reg [PCI_BUS_CBE_RANGE:0] master_mask_l; reg drive_ad_bus; reg signal_satisfied_delayed_read; task Execute_Target_PCI_Ref; input [1:0] reference_type; output saw_fast_back_to_back; begin `ifdef REPORT_TEST_DEVICE Report_On_Target_PCI_Ref_Start (reference_type[1:0]); `endif // REPORT_TEST_DEVICE Wait_Till_DEVSEL_Possible (devsel_asserted, fast_devsel_asserted, signal_satisfied_delayed_read); if (devsel_asserted == 1'b1) begin // 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 drive_ad_bus = (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_READ) | (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_READ); wait_states_this_time[3:0] = hold_target_initial_waitstates[3:0]; abort_needs_waitstate = (hold_target_initial_waitstates[3:0] == 4'h0); do_abort_this_time = (hold_target_termination[2:0] == `Test_Target_Abort_Before_First); do_retry_this_time = (hold_target_termination[2:0] == `Test_Target_Retry_Before_First) | (hold_target_termination[2:0] == `Test_Target_Start_Delayed_Read); do_disconnect_this_time = (hold_target_termination[2:0] == `Test_Target_Disc_With_First); // 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 do_disconnect_this_time = do_disconnect_this_time | (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 // See the PCI Local Bus Spec Revision 2.2 section 3.3.1 if (fast_devsel_asserted & drive_ad_bus) begin Execute_Target_Waitstates (1'b0, 1'b0, 4'h1); // avoid collisions on AD bus if (wait_states_this_time[3:0] != 4'h0) begin wait_states_this_time[3:0] = wait_states_this_time[3:0] - 4'h1; end `NO_ELSE; end `NO_ELSE; target_was_terminated = 1'b0; while (target_was_terminated == 1'b0) begin Execute_Target_Waitstates (drive_ad_bus, ~drive_ad_bus, wait_states_this_time[3:0]); if (do_abort_this_time) begin if (abort_needs_waitstate) begin Execute_Target_Waitstates (drive_ad_bus, ~drive_ad_bus, 4'h1); end `NO_ELSE; Execute_Target_Abort_Undrive_DEVSEL (drive_ad_bus, signal_satisfied_delayed_read); target_was_terminated = 1'b1; end else if (do_retry_this_time) begin Execute_Target_Retry_Undrive_DEVSEL (drive_ad_bus, (hold_target_termination[2:0] == `Test_Target_Start_Delayed_Read) & ( (hold_target_command[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ) | (hold_target_command[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ_MULTIPLE) | (hold_target_command[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_MEMORY_READ_LINE) | (hold_target_command[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_READ) ), signal_satisfied_delayed_read); target_was_terminated = 1'b1; end else // at least one data item should be read out of this device begin // do_disconnect_this_time = do_disconnect_this_time // prevent address roll-over // | (hold_target_address[7:2] == 6'h3F); if (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_READ) begin Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus (target_read_data[PCI_BUS_DATA_RANGE:0]); end `NO_ELSE; if (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_READ) begin Fetch_SRAM_Data_For_Read_Onto_AD_Bus (target_read_data[PCI_BUS_DATA_RANGE:0]); end `NO_ELSE; Execute_Target_Ref_Undrive_DEVSEL_On_Any_Termination (drive_ad_bus, do_disconnect_this_time, signal_satisfied_delayed_read, target_read_data[PCI_BUS_DATA_RANGE:0], master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0], target_was_terminated); if (reference_type[1:0] == `TEST_TARGET_DOING_CONFIG_WRITE) begin Capture_Config_Reg_Data_From_AD_Bus (master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0]); end `NO_ELSE; if (reference_type[1:0] == `TEST_TARGET_DOING_SRAM_WRITE) begin Capture_SRAM_Data_From_AD_Bus (master_write_data[PCI_BUS_DATA_RANGE:0], master_mask_l[PCI_BUS_CBE_RANGE:0]); end `NO_ELSE; // set up for the next transfer wait_states_this_time[3:0] = hold_target_subsequent_waitstates[3:0]; abort_needs_waitstate = 1'b0; do_abort_this_time = (hold_target_termination[2:0] == `Test_Target_Abort_Before_Second); do_retry_this_time = (hold_target_termination[2:0] == `Test_Target_Retry_Before_Second); do_disconnect_this_time = (hold_target_termination[2:0] == `Test_Target_Disc_With_Second); signal_satisfied_delayed_read = 1'b0; end end // 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. // Instead go directly to see if this device is addressed. // This transition is manditory even if the device can't do // fast-back-to-back transfers! // See the PCI Local Bus Spec Revision 2.2 section 3.4.2. saw_fast_back_to_back = frame_now & ~irdy_now; // No clock here to let this dovetail with the next reference? end else begin // no devsel, so it must have been an address parity error saw_fast_back_to_back = 1'b0; end end endtask // Task to print debug info // NOTE This must change if bit allocation changes task Report_Target_Reference_Paramaters; begin if (hold_target_address[23:9] != 15'h0000) begin $display (" Target Devsel Speed %h, Target Termination %h,", hold_target_devsel_speed[1:0], hold_target_termination[2:0]); $display (" First Target Data Wait States %h, Subsequent Target Data Wait States %h", hold_target_initial_waitstates[3:0], hold_target_subsequent_waitstates[3:0]); $display (" Addr Par Error %h, Data Par Error %h", hold_target_addr_par_err, hold_target_data_par_err); end `NO_ELSE; end endtask task Reset_Target_To_Idle; begin Init_Test_Device_SRAM; target_ad_oe <= 1'b0; target_devsel_out <= 1'b0; target_trdy_out <= 1'b0; target_stop_out <= 1'b0; target_perr_check_next <= 1'b0; target_signaling_target_abort <= 1'b0; Delayed_Read_Started <= 1'b0; Delayed_Read_Finished <= 1'b0; end endtask // Config References are described in PCI Local Bus Spec // Revision 2.2 section 3.2.2.3.4 // 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 // for a single function device, or only implemented devices should // respond. Function 0 is required to be detected. // Make a fake version just to make the charts pop: // Fire off Target tasks in response to PCI Bus Activity reg saw_fast_back_to_back; always @@(posedge pci_ext_clk or posedge pci_reset_comb) begin if (~pci_reset_comb) begin 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? begin 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]; if (ad_now[`TARGET_ENCODED_PARAMATERS_ENABLE] != 1'b0) begin hold_target_initial_waitstates = ad_now[`TARGET_ENCODED_INIT_WAITSTATES]; hold_target_subsequent_waitstates = ad_now[`TARGET_ENCODED_SUBS_WAITSTATES]; hold_target_termination = ad_now[`TARGET_ENCODED_TERMINATION]; hold_target_devsel_speed = ad_now[`TARGET_ENCODED_DEVSEL_SPEED]; hold_target_data_par_err = ad_now[`TARGET_ENCODED_DATA_PAR_ERR]; hold_target_addr_par_err = ad_now[`TARGET_ENCODED_ADDR_PAR_ERR]; end else begin hold_target_initial_waitstates = 4'h0; hold_target_subsequent_waitstates = 4'h0; hold_target_termination = `Test_Target_Normal_Completion; hold_target_devsel_speed = `Test_Devsel_Medium; hold_target_data_par_err = `Test_No_Data_Perr; hold_target_addr_par_err = `Test_No_Addr_Perr; end if (~frame_prev & frame_now & Target_En `ifdef SIMULTANEOUS_MASTER_TARGET // don't check for reads to self `else // SIMULTANEOUS_MASTER_TARGET // check for, and don't respond to, reads to self `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_INVALIDATE) ) & ( (ad_now[`PCI_BASE_ADDR0_MATCH_RANGE] == BAR0[`PCI_BASE_ADDR0_MATCH_RANGE]) `ifdef PCI_BASE_ADDR1_MATCH_ENABLE | (ad_now[`PCI_BASE_ADDR1_MATCH_RANGE] == BAR1[`PCI_BASE_ADDR1_MATCH_RANGE]) `endif // PCI_BASE_ADDR1_MATCH_ENABLE ) ) begin Execute_Target_PCI_Ref (`TEST_TARGET_DOING_SRAM_WRITE, saw_fast_back_to_back); end else if (~frame_prev & frame_now & (idsel_now == 1'b1) & (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_WRITE) & (ad_now[1:0] == 2'b00) ) begin Execute_Target_PCI_Ref (`TEST_TARGET_DOING_CONFIG_WRITE, saw_fast_back_to_back); end else if (~frame_prev & frame_now & Target_En `ifdef SIMULTANEOUS_MASTER_TARGET // Don't check for reads to self `else // SIMULTANEOUS_MASTER_TARGET // Check for, and don't respond to, reads to self `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_MULTIPLE) | (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]) `ifdef PCI_BASE_ADDR1_MATCH_ENABLE | (ad_now[`PCI_BASE_ADDR1_MATCH_RANGE] == BAR1[`PCI_BASE_ADDR1_MATCH_RANGE]) `endif // PCI_BASE_ADDR1_MATCH_ENABLE ) ) begin Execute_Target_PCI_Ref (`TEST_TARGET_DOING_SRAM_READ, saw_fast_back_to_back); end else if (~frame_prev & frame_now & (idsel_now == 1'b1) & (cbe_l_now[PCI_BUS_CBE_RANGE:0] == PCI_COMMAND_CONFIG_READ) & (ad_now[1:0] == 2'b00) ) begin Execute_Target_PCI_Ref (`TEST_TARGET_DOING_CONFIG_READ, saw_fast_back_to_back); end else begin saw_fast_back_to_back = 1'b0; end if (pci_reset_comb) begin saw_fast_back_to_back = 1'b0; end end // saw_fast_back_to_back end `NO_ELSE; // 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. if (pci_reset_comb) begin Reset_Target_To_Idle; end `NO_ELSE; end endmodule @ 1.9 log @Made the compromise that the FIFOs and the PCI Bus will be the same width. No 32/64 combinations. Working on Master. @ text @@ 1.8 log @Massive edit to start changing many `defines into Parameters. This MIGHT (?) make it possible to have more than 1 PCI interface, but with different bus sizes. On the other hand, it might be an idiotic change in style. @ text @@ 1.7 log @Made giant pass through files to try to paramaterize the FIFO and PCI Bus size. Probably broke everything. In pci_blue_master, made many changes to handle FIFO unloads In pci_fifos, simplified FIFOs. All the tricky stuff is now in the reader and writer @ text @d2 1 a2 1 // $Id: pci_behaviorial_target.v,v 1.6 2001/07/03 09:09:38 Blue Beaver Exp $ a86 2 `include "pci_blue_options.vh" `include "pci_blue_constants.vh" d106 7 a112 3 input [`PCI_BUS_DATA_RANGE] ad_now; input [`PCI_BUS_DATA_RANGE] ad_prev; output [`PCI_BUS_DATA_RANGE] target_ad_out; d114 2 a115 2 input [`PCI_BUS_CBE_RANGE] cbe_l_now; input [`PCI_BUS_CBE_RANGE] cbe_l_prev; d133 1 a133 1 reg [`PCI_BUS_DATA_RANGE] target_ad_out; d238 1 a238 1 output [`PCI_BUS_DATA_RANGE] Read_Config_Reg; d262 2 a263 2 reg [`PCI_BUS_CBE_RANGE] pending_config_reg_write_byte_enables; reg [`PCI_BUS_DATA_RANGE] pending_config_reg_write_data; d267 2 a268 2 input [`PCI_BUS_DATA_RANGE] data; input [`PCI_BUS_CBE_RANGE] master_mask_l; d273 2 a274 2 pending_config_reg_write_byte_enables[`PCI_BUS_CBE_RANGE] <= master_mask_l[`PCI_BUS_CBE_RANGE]; pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] <= data[`PCI_BUS_DATA_RANGE]; d313 1 a313 1 ? ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_CMD_FB2B_EN) d317 1 a317 1 ? ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_CMD_SERR_EN) d321 1 a321 1 ? ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_CMD_PAR_ERR_EN) d325 1 a325 1 ? ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_CMD_MASTER_EN) d329 1 a329 1 ? ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_CMD_TARGET_EN) d334 1 a334 1 & ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_STAT_DETECTED_PERR) != `PCI_BUS_DATA_ZERO)) d338 1 a338 1 & ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_STAT_DETECTED_SERR) != `PCI_BUS_DATA_ZERO)) d342 1 a342 1 & ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_STAT_GOT_MABORT) != `PCI_BUS_DATA_ZERO)) d346 1 a346 1 & ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_STAT_GOT_TABORT) != `PCI_BUS_DATA_ZERO)) d350 1 a350 1 & ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_STAT_CAUSED_TABORT) != `PCI_BUS_DATA_ZERO)) d354 1 a354 1 & ((pending_config_reg_write_data[`PCI_BUS_DATA_RANGE] & `CONFIG_STAT_CAUSED_PERR) != `PCI_BUS_DATA_ZERO)) d405 1 a405 1 reg [`PCI_BUS_DATA_RANGE] Test_Device_Mem [0:63]; // address limits, not bits in address d419 1 a419 1 output [`PCI_BUS_DATA_RANGE] target_read_data; d426 1 a426 1 reg [`PCI_BUS_DATA_RANGE] sram_temp; d429 2 a430 2 input [`PCI_BUS_DATA_RANGE] master_write_data; input [`PCI_BUS_CBE_RANGE] master_mask_l; d437 1 a437 1 Test_Device_Mem[sram_address[7:2]] = sram_temp[`PCI_BUS_DATA_RANGE]; d528 2 a529 2 reg [`PCI_BUS_DATA_RANGE] hold_target_address; reg [`PCI_BUS_CBE_RANGE] hold_target_command; d541 2 a542 2 input [`PCI_BUS_DATA_RANGE] master_write_data; input [`PCI_BUS_CBE_RANGE] master_mask_l; d545 1 a545 1 master_write_data[`PCI_BUS_DATA_RANGE], master_mask_l[`PCI_BUS_CBE_RANGE]); d552 1 a552 1 output [`PCI_BUS_DATA_RANGE] target_read_data; d554 1 a554 1 Read_Test_Device_Config_Regs (hold_target_address[7:2], target_read_data[`PCI_BUS_DATA_RANGE]); d561 2 a562 2 input [`PCI_BUS_DATA_RANGE] master_write_data; input [`PCI_BUS_CBE_RANGE] master_mask_l; d565 1 a565 1 master_write_data[`PCI_BUS_DATA_RANGE], master_mask_l[`PCI_BUS_CBE_RANGE]); d572 1 a572 1 output [`PCI_BUS_DATA_RANGE] target_read_data; d574 1 a574 1 Read_Test_Device_SRAM (hold_target_address[7:2], target_read_data[`PCI_BUS_DATA_RANGE]); d587 3 a589 3 reg [`PCI_BUS_DATA_RANGE] Delayed_Read_Address; reg [`PCI_BUS_CBE_RANGE] Delayed_Read_Command; reg [`PCI_BUS_CBE_RANGE] Delayed_Read_Mask_L; d713 3 a715 3 Delayed_Read_Address[`PCI_BUS_DATA_RANGE] = hold_target_address[`PCI_BUS_DATA_RANGE]; Delayed_Read_Command[`PCI_BUS_CBE_RANGE] = hold_target_command[`PCI_BUS_CBE_RANGE]; Delayed_Read_Mask_L[`PCI_BUS_CBE_RANGE] = cbe_l_now[`PCI_BUS_CBE_RANGE]; d721 1 a721 1 target_ad_out[`PCI_BUS_DATA_RANGE] <= `BUS_IMPOSSIBLE_VALUE; d804 8 a811 8 & ( (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_LINE) | (hold_target_command[3:0] == `PCI_COMMAND_CONFIG_READ) ) & ( ( (hold_target_address[`PCI_BUS_DATA_RANGE] & 32'hFF0000FF) // partial test address match != (Delayed_Read_Address[`PCI_BUS_DATA_RANGE] & 32'hFF0000FF)) | (hold_target_command[`PCI_BUS_CBE_RANGE] != Delayed_Read_Command[`PCI_BUS_CBE_RANGE]) | (cbe_l_now[`PCI_BUS_CBE_RANGE] != Delayed_Read_Mask_L[`PCI_BUS_CBE_RANGE]) ) ) d827 4 a830 4 & ( (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_LINE) | (hold_target_command[3:0] == `PCI_COMMAND_CONFIG_READ) ); d851 4 a854 4 & ( (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_LINE) | (hold_target_command[3:0] == `PCI_COMMAND_CONFIG_READ) ); d875 4 a878 4 & ( (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_LINE) | (hold_target_command[3:0] == `PCI_COMMAND_CONFIG_READ) ); d945 1 a945 1 input [`PCI_BUS_DATA_RANGE] target_read_data; d952 1 a952 1 target_ad_out[`PCI_BUS_DATA_RANGE] <= target_read_data[`PCI_BUS_DATA_RANGE]; d1006 1 a1006 1 target_ad_out[`PCI_BUS_DATA_RANGE] <= `BUS_IMPOSSIBLE_VALUE; d1019 1 a1019 1 target_ad_out[`PCI_BUS_DATA_RANGE] <= `BUS_IMPOSSIBLE_VALUE; d1058 3 a1060 3 input [`PCI_BUS_DATA_RANGE] target_read_data; output [`PCI_BUS_DATA_RANGE] master_write_data; output [`PCI_BUS_CBE_RANGE] master_mask_l; d1063 1 a1063 1 target_ad_out[`PCI_BUS_DATA_RANGE] <= target_read_data[`PCI_BUS_DATA_RANGE]; d1073 3 a1075 3 target_read_data[`PCI_BUS_DATA_RANGE], do_target_disconnect); master_write_data[`PCI_BUS_DATA_RANGE] = ad_now[`PCI_BUS_DATA_RANGE]; // unconditionally grab. master_mask_l[`PCI_BUS_CBE_RANGE] = cbe_l_now[`PCI_BUS_CBE_RANGE]; d1168 3 a1170 3 reg [`PCI_BUS_DATA_RANGE] master_write_data; reg [`PCI_BUS_DATA_RANGE] target_read_data; reg [`PCI_BUS_CBE_RANGE] master_mask_l; d1234 8 a1241 8 & ( (hold_target_command[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_MEMORY_READ) | (hold_target_command[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_MEMORY_READ_MULTIPLE) | (hold_target_command[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_MEMORY_READ_LINE) | (hold_target_command[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_CONFIG_READ) ), d1251 1 a1251 1 Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus (target_read_data[`PCI_BUS_DATA_RANGE]); d1256 1 a1256 1 Fetch_SRAM_Data_For_Read_Onto_AD_Bus (target_read_data[`PCI_BUS_DATA_RANGE]); d1262 3 a1264 3 target_read_data[`PCI_BUS_DATA_RANGE], master_write_data[`PCI_BUS_DATA_RANGE], master_mask_l[`PCI_BUS_CBE_RANGE], d1268 2 a1269 2 Capture_Config_Reg_Data_From_AD_Bus (master_write_data[`PCI_BUS_DATA_RANGE], master_mask_l[`PCI_BUS_CBE_RANGE]); d1274 2 a1275 2 Capture_SRAM_Data_From_AD_Bus (master_write_data[`PCI_BUS_DATA_RANGE], master_mask_l[`PCI_BUS_CBE_RANGE]); d1356 2 a1357 2 hold_target_address[`PCI_BUS_DATA_RANGE] = ad_now[`PCI_BUS_DATA_RANGE]; // intentionally use "=" hold_target_command[`PCI_BUS_CBE_RANGE] = cbe_l_now[`PCI_BUS_CBE_RANGE]; d1383 2 a1384 2 & ( (cbe_l_now[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_MEMORY_WRITE) | (cbe_l_now[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_MEMORY_WRITE_INVALIDATE) ) d1395 1 a1395 1 & (cbe_l_now[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_CONFIG_WRITE) d1407 3 a1409 3 & ( (cbe_l_now[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_MEMORY_READ) | (cbe_l_now[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_MEMORY_READ_MULTIPLE) | (cbe_l_now[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_MEMORY_READ_LINE) ) d1420 1 a1420 1 & (cbe_l_now[`PCI_BUS_CBE_RANGE] == `PCI_COMMAND_CONFIG_READ) @ 1.6 log @Working on Synthesizable PCI Master @ text @d2 1 a2 1 // $Id: pci_behaviorial_target.v,v 1.4 2001/02/22 10:19:17 Blue Beaver Exp $ d108 3 a110 3 input [31:0] ad_now; input [31:0] ad_prev; output [31:0] target_ad_out; d112 2 a113 2 input [3:0] cbe_l_now; input [3:0] cbe_l_prev; d131 1 a131 1 reg [31:0] target_ad_out; d236 1 a236 1 output [31:0] Read_Config_Reg; d260 2 a261 2 reg [3:0] pending_config_reg_write_byte_enables; reg [31:0] pending_config_reg_write_data; d265 2 a266 2 input [31:0] data; input [3:0] master_mask_l; d271 2 a272 2 pending_config_reg_write_byte_enables[3:0] <= master_mask_l[3:0]; pending_config_reg_write_data[31:0] <= data[31:0]; d311 2 a312 2 ? ((pending_config_reg_write_data[31:0] & `CONFIG_CMD_FB2B_EN) != 32'h00000000) : FB2B_En; d315 2 a316 2 ? ((pending_config_reg_write_data[31:0] & `CONFIG_CMD_SERR_EN) != 32'h00000000) : SERR_En; d319 2 a320 2 ? ((pending_config_reg_write_data[31:0] & `CONFIG_CMD_PAR_ERR_EN) != 32'h00000000) : Par_Err_En; d323 2 a324 2 ? ((pending_config_reg_write_data[31:0] & `CONFIG_CMD_MASTER_EN) != 32'h00000000) : Master_En; d327 2 a328 2 ? ((pending_config_reg_write_data[31:0] & `CONFIG_CMD_TARGET_EN) != 32'h00000000) : Target_En; d332 1 a332 1 & ((pending_config_reg_write_data[31:0] & `CONFIG_STAT_DETECTED_PERR) != 32'h00000000)) d336 1 a336 1 & ((pending_config_reg_write_data[31:0] & `CONFIG_STAT_DETECTED_SERR) != 32'h00000000)) d340 1 a340 1 & ((pending_config_reg_write_data[31:0] & `CONFIG_STAT_GOT_MABORT) != 32'h00000000)) d344 1 a344 1 & ((pending_config_reg_write_data[31:0] & `CONFIG_STAT_GOT_TABORT) != 32'h00000000)) d348 1 a348 1 & ((pending_config_reg_write_data[31:0] & `CONFIG_STAT_CAUSED_TABORT) != 32'h00000000)) d352 1 a352 1 & ((pending_config_reg_write_data[31:0] & `CONFIG_STAT_CAUSED_PERR) != 32'h00000000)) d403 1 a403 1 reg [31:0] Test_Device_Mem [0:63]; // address limits, not bits in address d410 1 a410 1 Test_Device_Mem[sram_addr] = 32'hXXXXXXXX; d417 1 a417 1 output [31:0] target_read_data; d424 1 a424 1 reg [31:0] sram_temp; d427 2 a428 2 input [31:0] master_write_data; input [3:0] master_mask_l; d435 1 a435 1 Test_Device_Mem[sram_address[7:2]] = sram_temp[31:0]; d526 2 a527 2 reg [31:0] hold_target_address; reg [3:0] hold_target_command; d539 2 a540 2 input [31:0] master_write_data; input [3:0] master_mask_l; d543 1 a543 1 master_write_data[31:0], master_mask_l[3:0]); d550 1 a550 1 output [31:0] target_read_data; d552 1 a552 1 Read_Test_Device_Config_Regs (hold_target_address[7:2], target_read_data[31:0]); d559 2 a560 2 input [31:0] master_write_data; input [3:0] master_mask_l; d563 1 a563 1 master_write_data[31:0], master_mask_l[3:0]); d570 1 a570 1 output [31:0] target_read_data; d572 1 a572 1 Read_Test_Device_SRAM (hold_target_address[7:2], target_read_data[31:0]); d585 3 a587 3 reg [31:0] Delayed_Read_Address; reg [3:0] Delayed_Read_Command; reg [3:0] Delayed_Read_Mask_L; d711 3 a713 3 Delayed_Read_Address = hold_target_address[31:0]; Delayed_Read_Command = hold_target_command[3:0]; Delayed_Read_Mask_L = cbe_l_now[3:0]; d719 1 a719 1 target_ad_out <= `BUS_IMPOSSIBLE_VALUE; d806 4 a809 4 & ( ( (hold_target_address[31:0] & 32'hFF0000FF) // partial test address match != (Delayed_Read_Address[31:0] & 32'hFF0000FF)) | (hold_target_command[3:0] != Delayed_Read_Command[3:0]) | (cbe_l_now[3:0] != Delayed_Read_Mask_L[3:0]) ) ) d943 1 a943 1 input [31:0] target_read_data; d950 1 a950 1 target_ad_out <= target_read_data[31:0]; d1004 1 a1004 1 target_ad_out <= `BUS_IMPOSSIBLE_VALUE; d1017 1 a1017 1 target_ad_out <= `BUS_IMPOSSIBLE_VALUE; d1056 3 a1058 3 input [31:0] target_read_data; output [31:0] master_write_data; output [3:0] master_mask_l; d1061 1 a1061 1 target_ad_out <= target_read_data[31:0]; d1071 3 a1073 3 target_read_data[31:0], do_target_disconnect); master_write_data = ad_now[31:0]; // unconditionally grab. master_mask_l = cbe_l_now[3:0]; d1166 3 a1168 3 reg [31:0] master_write_data; reg [31:0] target_read_data; reg [3:0] master_mask_l; d1232 8 a1239 4 & ( (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_LINE) | (hold_target_command[3:0] == `PCI_COMMAND_CONFIG_READ) ), d1249 1 a1249 1 Fetch_Config_Reg_Data_For_Read_Onto_AD_Bus (target_read_data[31:0]); d1254 1 a1254 1 Fetch_SRAM_Data_For_Read_Onto_AD_Bus (target_read_data[31:0]); d1259 4 a1262 2 signal_satisfied_delayed_read, target_read_data[31:0], master_write_data[31:0], master_mask_l[3:0], d1266 2 a1267 2 Capture_Config_Reg_Data_From_AD_Bus (master_write_data[31:0], master_mask_l[3:0]); d1272 2 a1273 2 Capture_SRAM_Data_From_AD_Bus (master_write_data[31:0], master_mask_l[3:0]); d1354 2 a1355 2 hold_target_address = ad_now[31:0]; // intentionally use "=" hold_target_command = cbe_l_now[3:0]; d1381 2 a1382 2 & ( (cbe_l_now[3:0] == `PCI_COMMAND_MEMORY_WRITE) | (cbe_l_now[3:0] == `PCI_COMMAND_MEMORY_WRITE_INVALIDATE) ) d1393 1 a1393 1 & (cbe_l_now[3:0] == `PCI_COMMAND_CONFIG_WRITE) d1405 3 a1407 3 & ( (cbe_l_now[3:0] == `PCI_COMMAND_MEMORY_READ) | (cbe_l_now[3:0] == `PCI_COMMAND_MEMORY_READ_MULTIPLE) | (cbe_l_now[3:0] == `PCI_COMMAND_MEMORY_READ_LINE) ) d1418 1 a1418 1 & (cbe_l_now[3:0] == `PCI_COMMAND_CONFIG_READ) @ 1.5 log @Working on pci_blue_master Adding state machine and carefully crafted FRAME and IRDY next value function This code compiles, but does not function at all The previous version should be used when exploring the test framework. @ text @@ 1.4 log @working on example host interface @ text @@ 1.3 log @working on the example host interface @ text @@ 1.2 log @Various cosmetic changes, No functional changes. @ text @@ 1.1 log @Initial revision @ text @d2 1 a2 1 // $Id: pci_behaviorial_target.v,v 1.3 2001/02/20 17:21:38 Blue Beaver Exp $ d275 1 d625 1 a625 1 `define TEST_TARGET_SPINLOOP_MAX 20 d630 1 d632 2 d695 1 a695 1 for (iiii = 0; iiii < `TEST_TARGET_SPINLOOP_MAX; iiii = iiii + 1) d715 1 d729 1 a729 1 iiii = `TEST_TARGET_SPINLOOP_MAX + 1; // break d735 1 a735 1 if (~pci_reset_comb & (iiii == `TEST_TARGET_SPINLOOP_MAX)) d946 1 a946 1 for (ii = 0; ii < `TEST_TARGET_SPINLOOP_MAX; ii = ii + 1) d962 1 a962 1 ii = `TEST_TARGET_SPINLOOP_MAX + 1; // break d973 1 a973 1 if (~pci_reset_comb & (ii == `TEST_TARGET_SPINLOOP_MAX)) d1000 1 a1000 1 for (iii = 0; iii < `TEST_TARGET_SPINLOOP_MAX; iii = iii + 1) d1027 1 a1027 1 iii = `TEST_TARGET_SPINLOOP_MAX + 1; // break d1040 1 a1040 1 if (~pci_reset_comb & (iii == `TEST_TARGET_SPINLOOP_MAX)) d1094 1 d1206 1 d1208 2 d1211 1 d1220 1 d1222 2 d1244 1 d1246 2 d1249 1 d1251 2 d1259 1 d1262 2 d1265 1 d1268 2 d1423 1 d1425 1 d1428 1 d1435 1 @ 1.1.1.1 log @Initial Import of pci_blue_interface Only the behaviorial code works There is no synthesizable code in this initial source import @ text @@