From: sithglan Date: Tue, 20 Mar 2007 17:50:56 +0000 (+0000) Subject: add shit X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/raggedstone/commitdiff_plain/40a1f26c3a09dbd1f71f4fd7f3aca74f387a09db?ds=sidebyside add shit --- diff --git a/ethernet/ethernet.prj b/ethernet/ethernet.prj index 5bd7d4e..8b9a454 100644 --- a/ethernet/ethernet.prj +++ b/ethernet/ethernet.prj @@ -1,28 +1,86 @@ -vhdl work "source/top.vhd" -verilog work "source/ethernet/eth_crc.v" -verilog work "source/ethernet/eth_cop.v" -verilog work "source/ethernet/eth_maccontrol.v" -verilog work "source/ethernet/eth_register.v" -verilog work "source/ethernet/eth_fifo.v" -verilog work "source/ethernet/eth_rxstatem.v" -verilog work "source/ethernet/eth_txcounters.v" -verilog work "source/ethernet/eth_random.v" -verilog work "source/ethernet/eth_rxcounters.v" -verilog work "source/ethernet/eth_top.v" -verilog work "source/ethernet/eth_shiftreg.v" -verilog work "source/ethernet/eth_miim.v" -verilog work "source/ethernet/eth_wishbone.v" -verilog work "source/ethernet/eth_rxaddrcheck.v" -verilog work "source/ethernet/xilinx_dist_ram_16x32.v" -verilog work "source/ethernet/eth_spram_256x32.v" -verilog work "source/ethernet/eth_txethmac.v" -verilog work "source/ethernet/timescale.v" -verilog work "source/ethernet/eth_registers.v" -verilog work "source/ethernet/eth_defines.v" -verilog work "source/ethernet/eth_rxethmac.v" -verilog work "source/ethernet/eth_receivecontrol.v" -verilog work "source/ethernet/eth_outputcontrol.v" -verilog work "source/ethernet/eth_txstatem.v" -verilog work "source/ethernet/eth_transmitcontrol.v" -verilog work "source/ethernet/eth_macstatus.v" -verilog work "source/ethernet/eth_clockgen.v" +vhdl work "source/ethernet/eth_crc.v" +vhdl work "source/ethernet/eth_cop.v" +vhdl work "source/ethernet/eth_maccontrol.v" +vhdl work "source/ethernet/eth_register.v" +vhdl work "source/ethernet/eth_fifo.v" +vhdl work "source/ethernet/eth_rxstatem.v" +vhdl work "source/ethernet/eth_txcounters.v" +vhdl work "source/ethernet/eth_random.v" +vhdl work "source/ethernet/eth_rxcounters.v" +vhdl work "source/ethernet/eth_top.v" +vhdl work "source/ethernet/eth_shiftreg.v" +vhdl work "source/ethernet/eth_miim.v" +vhdl work "source/ethernet/eth_wishbone.v" +vhdl work "source/ethernet/eth_rxaddrcheck.v" +vhdl work "source/ethernet/xilinx_dist_ram_16x32.v" +vhdl work "source/ethernet/eth_spram_256x32.v" +vhdl work "source/ethernet/eth_txethmac.v" +vhdl work "source/ethernet/timescale.v" +vhdl work "source/ethernet/eth_registers.v" +vhdl work "source/ethernet/eth_defines.v" +vhdl work "source/ethernet/eth_rxethmac.v" +vhdl work "source/ethernet/eth_receivecontrol.v" +vhdl work "source/ethernet/eth_outputcontrol.v" +vhdl work "source/ethernet/eth_txstatem.v" +vhdl work "source/ethernet/eth_transmitcontrol.v" +vhdl work "source/ethernet/eth_macstatus.v" +vhdl work "source/ethernet/eth_clockgen.v" +vhdl work "source/pci/pci_target_unit.v" +vhdl work "source/pci/pci_target32_stop_crit.v" +vhdl work "source/pci/pci_delayed_sync.v" +vhdl work "source/pci/pci_wb_slave_unit.v" +vhdl work "source/pci/pci_frame_load_crit.v" +vhdl work "source/pci/pci_mas_ad_en_crit.v" +vhdl work "source/pci/pci_constants.v" +vhdl work "source/pci/pci_wbw_wbr_fifos.v" +vhdl work "source/pci/pci_wb_slave.v" +vhdl work "source/pci/pci_target32_trdy_crit.v" +vhdl work "source/pci/pci_target32_interface.v" +vhdl work "source/pci/pci_wbw_fifo_control.v" +vhdl work "source/pci/pci_wb_tpram.v" +vhdl work "source/pci/pci_par_crit.v" +vhdl work "source/pci/pci_conf_space.v" +vhdl work "source/pci/pci_target32_sm.v" +vhdl work "source/pci/pci_pciw_pcir_fifos.v" +vhdl work "source/pci/pci_serr_en_crit.v" +vhdl work "source/pci/pci_target32_devs_crit.v" +vhdl work "source/pci/pci_out_reg.v" +vhdl work "source/pci/pci_mas_ad_load_crit.v" +vhdl work "source/pci/pci_delayed_write_reg.v" +vhdl work "source/pci/pci_wbs_wbb3_2_wbb2.v" +vhdl work "source/pci/pci_wb_master.v" +vhdl work "source/pci/bus_commands.v" +vhdl work "source/pci/pci_rst_int.v" +vhdl work "source/pci/pci_sync_module.v" +vhdl work "source/pci/pci_master32_sm_if.v" +vhdl work "source/pci/pci_frame_crit.v" +vhdl work "source/pci/pci_user_constants.v" +vhdl work "source/pci/pci_io_mux_ad_load_crit.v" +vhdl work "source/pci/pci_pciw_fifo_control.v" +vhdl work "source/pci/pci_parity_check.v" +vhdl work "source/pci/pci_irdy_out_crit.v" +vhdl work "source/pci/pci_perr_crit.v" +vhdl work "source/pci/pci_mas_ch_state_crit.v" +vhdl work "source/pci/pci_spoci_ctrl.v" +vhdl work "source/pci/pci_wb_addr_mux.v" +vhdl work "source/pci/pci_perr_en_crit.v" +vhdl work "source/pci/pci_target32_clk_en.v" +vhdl work "source/pci/timescale.v" +vhdl work "source/pci/pci_serr_crit.v" +vhdl work "source/pci/pci_frame_en_crit.v" +vhdl work "source/pci/pci_master32_sm.v" +vhdl work "source/pci/pci_pci_tpram.v" +vhdl work "source/pci/pci_cur_out_reg.v" +vhdl work "source/pci/pci_io_mux.v" +vhdl work "source/pci/pci_wbr_fifo_control.v" +vhdl work "source/pci/pci_ram_16x40d.v" +vhdl work "source/pci/pci_io_mux_ad_en_crit.v" +vhdl work "source/pci/pci_async_reset_flop.v" +vhdl work "source/pci/pci_wb_decoder.v" +vhdl work "source/pci/pci_conf_cyc_addr_dec.v" +vhdl work "source/pci/pci_bridge32.v" +vhdl work "source/pci/pci_synchronizer_flop.v" +vhdl work "source/pci/pci_pcir_fifo_control.v" +vhdl work "source/pci/pci_cbe_en_crit.v" +vhdl work "source/pci/pci_pci_decoder.v" +vhdl work "source/pci/pci_in_reg.v" diff --git a/ethernet/ethernet.ucf b/ethernet/ethernet.ucf index 3353112..3ad2942 100644 --- a/ethernet/ethernet.ucf +++ b/ethernet/ethernet.ucf @@ -1,63 +1,53 @@ -# NET "PCI_AD<0>" LOC = "A5" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<10>" LOC = "E9" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<11>" LOC = "F11" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<12>" LOC = "E10" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<13>" LOC = "A8" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<14>" LOC = "B9" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<15>" LOC = "B10" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<16>" LOC = "F17" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<17>" LOC = "F16" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<18>" LOC = "A14" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<19>" LOC = "B14" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<1>" LOC = "B5" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<20>" LOC = "B15" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<21>" LOC = "A15" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<22>" LOC = "F12" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<23>" LOC = "F13" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<24>" LOC = "D15" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<25>" LOC = "E15" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<26>" LOC = "D17" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<27>" LOC = "C17" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<28>" LOC = "B17" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<29>" LOC = "E17" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<2>" LOC = "E6" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<30>" LOC = "A18" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<31>" LOC = "B18" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<3>" LOC = "D6" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<4>" LOC = "C6" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<5>" LOC = "B6" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<6>" LOC = "D7" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<7>" LOC = "E7" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<8>" LOC = "B8" | IOSTANDARD = PCI33_3 ; -# NET "PCI_AD<9>" LOC = "F10" | IOSTANDARD = PCI33_3 ; -#NET "PCI_CLOCK" LOC = "A11" | IOSTANDARD = PCI33_3 ; -# NET "PCI_IDSEL" LOC = "D14" | IOSTANDARD = PCI33_3 ; -# NET "PCI_CBEn<0>" LOC = "F9" | IOSTANDARD = PCI33_3 ; -# NET "PCI_CBEn<1>" LOC = "C10" | IOSTANDARD = PCI33_3 ; -# NET "PCI_CBEn<2>" LOC = "D13" | IOSTANDARD = PCI33_3 ; -# NET "PCI_CBEn<3>" LOC = "E13" | IOSTANDARD = PCI33_3 ; -# NET "PCI_FRAMEn" LOC = "C13" | IOSTANDARD = PCI33_3 ; -# NET "PCI_IRDYn" LOC = "A13" | IOSTANDARD = PCI33_3 ; -# NET "PCI_RSTn" LOC = "A19" | IOSTANDARD = PCI33_3 ; -# NET "PCI_DEVSELn" LOC = "E12" | IOSTANDARD = PCI33_3 ; -# NET "PCI_INTAn" LOC = "B19" | IOSTANDARD = PCI33_3 | SLEW = FAST ; -# NET "PCI_PERRn" LOC = "D12" | IOSTANDARD = PCI33_3 | SLEW = FAST ; -# NET "PCI_SERRn" LOC = "B12" | IOSTANDARD = PCI33_3 | SLEW = FAST ; -# NET "PCI_STOPn" LOC = "A12" | IOSTANDARD = PCI33_3 | SLEW = FAST ; -# NET "PCI_TRDYn" LOC = "B13" | IOSTANDARD = PCI33_3 | SLEW = FAST ; -# NET "PCI_PAR" LOC = "A9" | IOSTANDARD = PCI33_3 | SLEW = FAST ; -# NET "PCI_REQn" LOC = "C18" | IOSTANDARD = PCI33_3 | SLEW = FAST ; -# NET "PCI_GNTn" LOC = "D18" | IOSTANDARD = PCI33_3 ; -# NET "TAST_RESn" LOC = "AA3" | IOSTANDARD = LVTTL | PULLUP ; -# NET "TAST_SETn" LOC = "Y4" | IOSTANDARD = LVTTL | PULLUP ; -# NET "LED_2" LOC = "AB5" | IOSTANDARD = LVTTL | DRIVE = 24 ; -# NET "LED_3" LOC = "AA5" | IOSTANDARD = LVTTL | DRIVE = 24 ; -# NET "LED_4" LOC = "AA4" | IOSTANDARD = LVTTL | DRIVE = 24 ; -# NET "LED_5" LOC = "AB4" | IOSTANDARD = LVTTL | DRIVE = 24 ; -# NET "KONST_1" LOC = "Y1" | IOSTANDARD = LVCMOS33 ; -# NET "TB_IDSEL" LOC = "M6" | IOSTANDARD = LVCMOS33 ; -# NET "TB_nDEVSEL" LOC = "M5" | IOSTANDARD = LVCMOS33 ; -# NET "TB_nINTA" LOC = "U2" | IOSTANDARD = LVCMOS33 ; +NET "PCI_AD<0>" LOC = "A5" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<10>" LOC = "E9" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<11>" LOC = "F11" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<12>" LOC = "E10" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<13>" LOC = "A8" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<14>" LOC = "B9" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<15>" LOC = "B10" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<16>" LOC = "F17" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<17>" LOC = "F16" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<18>" LOC = "A14" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<19>" LOC = "B14" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<1>" LOC = "B5" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<20>" LOC = "B15" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<21>" LOC = "A15" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<22>" LOC = "F12" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<23>" LOC = "F13" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<24>" LOC = "D15" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<25>" LOC = "E15" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<26>" LOC = "D17" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<27>" LOC = "C17" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<28>" LOC = "B17" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<29>" LOC = "E17" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<2>" LOC = "E6" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<30>" LOC = "A18" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<31>" LOC = "B18" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<3>" LOC = "D6" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<4>" LOC = "C6" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<5>" LOC = "B6" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<6>" LOC = "D7" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<7>" LOC = "E7" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<8>" LOC = "B8" | IOSTANDARD = PCI33_3 ; +NET "PCI_AD<9>" LOC = "F10" | IOSTANDARD = PCI33_3 ; +NET "PCI_CLOCK" LOC = "A11" | IOSTANDARD = PCI33_3 ; +NET "PCI_IDSEL" LOC = "D14" | IOSTANDARD = PCI33_3 ; +NET "PCI_CBEn<0>" LOC = "F9" | IOSTANDARD = PCI33_3 ; +NET "PCI_CBEn<1>" LOC = "C10" | IOSTANDARD = PCI33_3 ; +NET "PCI_CBEn<2>" LOC = "D13" | IOSTANDARD = PCI33_3 ; +NET "PCI_CBEn<3>" LOC = "E13" | IOSTANDARD = PCI33_3 ; +NET "PCI_FRAMEn" LOC = "C13" | IOSTANDARD = PCI33_3 ; +NET "PCI_IRDYn" LOC = "A13" | IOSTANDARD = PCI33_3 ; +NET "PCI_RSTn" LOC = "A19" | IOSTANDARD = PCI33_3 ; +NET "PCI_DEVSELn" LOC = "E12" | IOSTANDARD = PCI33_3 ; +NET "PCI_INTAn" LOC = "B19" | IOSTANDARD = PCI33_3 | SLEW = FAST ; +NET "PCI_PERRn" LOC = "D12" | IOSTANDARD = PCI33_3 | SLEW = FAST ; +NET "PCI_SERRn" LOC = "B12" | IOSTANDARD = PCI33_3 | SLEW = FAST ; +NET "PCI_STOPn" LOC = "A12" | IOSTANDARD = PCI33_3 | SLEW = FAST ; +NET "PCI_TRDYn" LOC = "B13" | IOSTANDARD = PCI33_3 | SLEW = FAST ; +NET "PCI_PAR" LOC = "A9" | IOSTANDARD = PCI33_3 | SLEW = FAST ; +NET "PCI_REQn" LOC = "C18" | IOSTANDARD = PCI33_3 | SLEW = FAST ; +NET "PCI_GNTn" LOC = "D18" | IOSTANDARD = PCI33_3 ; NET "INT_CLOCK" LOC = "AA11" | IOSTANDARD = PCI33_3 ; NET "MTX_CLK_PAD_I" LOC = "M2" | IOSTANDARD = LVCMOS33; diff --git a/ethernet/source/ethernet/BUGS b/ethernet/source/ethernet/BUGS new file mode 100644 index 0000000..2c6c412 --- /dev/null +++ b/ethernet/source/ethernet/BUGS @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// BUGS //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is available in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: BUGS,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2002/09/12 14:50:16 mohor +// CarrierSenseLost bug fixed when operating in full duplex mode. +// + + +FIXED BUGS: + +- Bug CarrierSenseLost when operating in Full duplex fixed. + + + + +KNOWN BUGS: + +- diff --git a/ethernet/source/ethernet/TODO b/ethernet/source/ethernet/TODO new file mode 100644 index 0000000..48c86fa --- /dev/null +++ b/ethernet/source/ethernet/TODO @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// TODO //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is available in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: TODO,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.3 2003/01/23 09:14:12 mohor +// Fix MTxErr or prevent sending too big frames. +// +// Revision 1.2 2002/11/21 00:33:32 mohor +// In loopback rx_clk is not looped back. Possible CRC error. Consider if usage +// of additional logic is necessery (FIFO for looping the data). +// +// Revision 1.1 2002/09/10 10:42:06 mohor +// HASH improvement needed. +// + + +- Add logic for easier use of the HASH table: First write MAC address to some + register. Then issue a command. CRC is calculated from this MAC and appropriate + bit written to the HASH register. + +- In loopback rx_clk is not looped back. Possible CRC error. Consider if usage of + additional logic is necessery (FIFO for looping the data). + +- When sending frames bigger than MaxFL, MaxFL is sent, BD marked as finished, + TxB_IRQ interrupt is set and MTxErr is set for a short period. Fix MTxErr or + prevent sending too big frames or set TxE_IRQ instead. + + + diff --git a/ethernet/source/ethernet/eth_clockgen.v b/ethernet/source/ethernet/eth_clockgen.v new file mode 100644 index 0000000..866348d --- /dev/null +++ b/ethernet/source/ethernet/eth_clockgen.v @@ -0,0 +1,137 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_clockgen.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_clockgen.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2005/02/21 12:48:05 igorm +// Warning fixes. +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.3 2001/06/01 22:28:55 mohor +// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated. +// +// + +`include "timescale.v" + +module eth_clockgen(Clk, Reset, Divider, MdcEn, MdcEn_n, Mdc); + +parameter Tp=1; + +input Clk; // Input clock (Host clock) +input Reset; // Reset signal +input [7:0] Divider; // Divider (input clock will be divided by the Divider[7:0]) + +output Mdc; // Output clock +output MdcEn; // Enable signal is asserted for one Clk period before Mdc rises. +output MdcEn_n; // Enable signal is asserted for one Clk period before Mdc falls. + +reg Mdc; +reg [7:0] Counter; + +wire CountEq0; +wire [7:0] CounterPreset; +wire [7:0] TempDivider; + + +assign TempDivider[7:0] = (Divider[7:0]<2)? 8'h02 : Divider[7:0]; // If smaller than 2 +assign CounterPreset[7:0] = (TempDivider[7:0]>>1) - 1'b1; // We are counting half of period + + +// Counter counts half period +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + Counter[7:0] <= #Tp 8'h1; + else + begin + if(CountEq0) + begin + Counter[7:0] <= #Tp CounterPreset[7:0]; + end + else + Counter[7:0] <= #Tp Counter - 8'h1; + end +end + + +// Mdc is asserted every other half period +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + Mdc <= #Tp 1'b0; + else + begin + if(CountEq0) + Mdc <= #Tp ~Mdc; + end +end + + +assign CountEq0 = Counter == 8'h0; +assign MdcEn = CountEq0 & ~Mdc; +assign MdcEn_n = CountEq0 & Mdc; + +endmodule + + diff --git a/ethernet/source/ethernet/eth_cop.v b/ethernet/source/ethernet/eth_cop.v new file mode 100644 index 0000000..6d93667 --- /dev/null +++ b/ethernet/source/ethernet/eth_cop.v @@ -0,0 +1,395 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_cop.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_cop.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2003/06/13 11:55:37 mohor +// Define file in eth_cop.v is changed to eth_defines.v. Some defines were +// moved from tb_eth_defines.v to eth_defines.v. +// +// Revision 1.3 2002/10/10 16:43:59 mohor +// Minor $display change. +// +// Revision 1.2 2002/09/09 12:54:13 mohor +// error acknowledge cycle termination added to display. +// +// Revision 1.1 2002/08/14 17:16:07 mohor +// Traffic cop with 2 wishbone master interfaces and 2 wishbona slave +// interfaces: +// - Host connects to the master interface +// - Ethernet master (DMA) connects to the second master interface +// - Memory interface connects to the slave interface +// - Ethernet slave interface (access to registers and BDs) connects to second +// slave interface +// +// +// +// +// + +`include "eth_defines.v" +`include "timescale.v" + +module eth_cop +( + // WISHBONE common + wb_clk_i, wb_rst_i, + + // WISHBONE MASTER 1 + m1_wb_adr_i, m1_wb_sel_i, m1_wb_we_i, m1_wb_dat_o, + m1_wb_dat_i, m1_wb_cyc_i, m1_wb_stb_i, m1_wb_ack_o, + m1_wb_err_o, + + // WISHBONE MASTER 2 + m2_wb_adr_i, m2_wb_sel_i, m2_wb_we_i, m2_wb_dat_o, + m2_wb_dat_i, m2_wb_cyc_i, m2_wb_stb_i, m2_wb_ack_o, + m2_wb_err_o, + + // WISHBONE slave 1 + s1_wb_adr_o, s1_wb_sel_o, s1_wb_we_o, s1_wb_cyc_o, + s1_wb_stb_o, s1_wb_ack_i, s1_wb_err_i, s1_wb_dat_i, + s1_wb_dat_o, + + // WISHBONE slave 2 + s2_wb_adr_o, s2_wb_sel_o, s2_wb_we_o, s2_wb_cyc_o, + s2_wb_stb_o, s2_wb_ack_i, s2_wb_err_i, s2_wb_dat_i, + s2_wb_dat_o +); + +parameter Tp=1; + +// WISHBONE common +input wb_clk_i, wb_rst_i; + +// WISHBONE MASTER 1 +input [31:0] m1_wb_adr_i, m1_wb_dat_i; +input [3:0] m1_wb_sel_i; +input m1_wb_cyc_i, m1_wb_stb_i, m1_wb_we_i; +output [31:0] m1_wb_dat_o; +output m1_wb_ack_o, m1_wb_err_o; + +// WISHBONE MASTER 2 +input [31:0] m2_wb_adr_i, m2_wb_dat_i; +input [3:0] m2_wb_sel_i; +input m2_wb_cyc_i, m2_wb_stb_i, m2_wb_we_i; +output [31:0] m2_wb_dat_o; +output m2_wb_ack_o, m2_wb_err_o; + +// WISHBONE slave 1 +input [31:0] s1_wb_dat_i; +input s1_wb_ack_i, s1_wb_err_i; +output [31:0] s1_wb_adr_o, s1_wb_dat_o; +output [3:0] s1_wb_sel_o; +output s1_wb_we_o, s1_wb_cyc_o, s1_wb_stb_o; + +// WISHBONE slave 2 +input [31:0] s2_wb_dat_i; +input s2_wb_ack_i, s2_wb_err_i; +output [31:0] s2_wb_adr_o, s2_wb_dat_o; +output [3:0] s2_wb_sel_o; +output s2_wb_we_o, s2_wb_cyc_o, s2_wb_stb_o; + +reg m1_in_progress; +reg m2_in_progress; +reg [31:0] s1_wb_adr_o; +reg [3:0] s1_wb_sel_o; +reg s1_wb_we_o; +reg [31:0] s1_wb_dat_o; +reg s1_wb_cyc_o; +reg s1_wb_stb_o; +reg [31:0] s2_wb_adr_o; +reg [3:0] s2_wb_sel_o; +reg s2_wb_we_o; +reg [31:0] s2_wb_dat_o; +reg s2_wb_cyc_o; +reg s2_wb_stb_o; + +reg m1_wb_ack_o; +reg [31:0] m1_wb_dat_o; +reg m2_wb_ack_o; +reg [31:0] m2_wb_dat_o; + +reg m1_wb_err_o; +reg m2_wb_err_o; + +wire m_wb_access_finished; +wire m1_req = m1_wb_cyc_i & m1_wb_stb_i & (`M1_ADDRESSED_S1 | `M1_ADDRESSED_S2); +wire m2_req = m2_wb_cyc_i & m2_wb_stb_i & (`M2_ADDRESSED_S1 | `M2_ADDRESSED_S2); + +always @ (posedge wb_clk_i or posedge wb_rst_i) +begin + if(wb_rst_i) + begin + m1_in_progress <=#Tp 0; + m2_in_progress <=#Tp 0; + s1_wb_adr_o <=#Tp 0; + s1_wb_sel_o <=#Tp 0; + s1_wb_we_o <=#Tp 0; + s1_wb_dat_o <=#Tp 0; + s1_wb_cyc_o <=#Tp 0; + s1_wb_stb_o <=#Tp 0; + s2_wb_adr_o <=#Tp 0; + s2_wb_sel_o <=#Tp 0; + s2_wb_we_o <=#Tp 0; + s2_wb_dat_o <=#Tp 0; + s2_wb_cyc_o <=#Tp 0; + s2_wb_stb_o <=#Tp 0; + end + else + begin + case({m1_in_progress, m2_in_progress, m1_req, m2_req, m_wb_access_finished}) // synopsys_full_case synopsys_paralel_case + 5'b00_10_0, 5'b00_11_0 : + begin + m1_in_progress <=#Tp 1'b1; // idle: m1 or (m1 & m2) want access: m1 -> m + if(`M1_ADDRESSED_S1) + begin + s1_wb_adr_o <=#Tp m1_wb_adr_i; + s1_wb_sel_o <=#Tp m1_wb_sel_i; + s1_wb_we_o <=#Tp m1_wb_we_i; + s1_wb_dat_o <=#Tp m1_wb_dat_i; + s1_wb_cyc_o <=#Tp 1'b1; + s1_wb_stb_o <=#Tp 1'b1; + end + else if(`M1_ADDRESSED_S2) + begin + s2_wb_adr_o <=#Tp m1_wb_adr_i; + s2_wb_sel_o <=#Tp m1_wb_sel_i; + s2_wb_we_o <=#Tp m1_wb_we_i; + s2_wb_dat_o <=#Tp m1_wb_dat_i; + s2_wb_cyc_o <=#Tp 1'b1; + s2_wb_stb_o <=#Tp 1'b1; + end + else + $display("(%t)(%m)WISHBONE ERROR: Unspecified address space accessed", $time); + end + 5'b00_01_0 : + begin + m2_in_progress <=#Tp 1'b1; // idle: m2 wants access: m2 -> m + if(`M2_ADDRESSED_S1) + begin + s1_wb_adr_o <=#Tp m2_wb_adr_i; + s1_wb_sel_o <=#Tp m2_wb_sel_i; + s1_wb_we_o <=#Tp m2_wb_we_i; + s1_wb_dat_o <=#Tp m2_wb_dat_i; + s1_wb_cyc_o <=#Tp 1'b1; + s1_wb_stb_o <=#Tp 1'b1; + end + else if(`M2_ADDRESSED_S2) + begin + s2_wb_adr_o <=#Tp m2_wb_adr_i; + s2_wb_sel_o <=#Tp m2_wb_sel_i; + s2_wb_we_o <=#Tp m2_wb_we_i; + s2_wb_dat_o <=#Tp m2_wb_dat_i; + s2_wb_cyc_o <=#Tp 1'b1; + s2_wb_stb_o <=#Tp 1'b1; + end + else + $display("(%t)(%m)WISHBONE ERROR: Unspecified address space accessed", $time); + end + 5'b10_10_1, 5'b10_11_1 : + begin + m1_in_progress <=#Tp 1'b0; // m1 in progress. Cycle is finished. Send ack or err to m1. + if(`M1_ADDRESSED_S1) + begin + s1_wb_cyc_o <=#Tp 1'b0; + s1_wb_stb_o <=#Tp 1'b0; + end + else if(`M1_ADDRESSED_S2) + begin + s2_wb_cyc_o <=#Tp 1'b0; + s2_wb_stb_o <=#Tp 1'b0; + end + end + 5'b01_01_1, 5'b01_11_1 : + begin + m2_in_progress <=#Tp 1'b0; // m2 in progress. Cycle is finished. Send ack or err to m2. + if(`M2_ADDRESSED_S1) + begin + s1_wb_cyc_o <=#Tp 1'b0; + s1_wb_stb_o <=#Tp 1'b0; + end + else if(`M2_ADDRESSED_S2) + begin + s2_wb_cyc_o <=#Tp 1'b0; + s2_wb_stb_o <=#Tp 1'b0; + end + end + endcase + end +end + +// Generating Ack for master 1 +always @ (m1_in_progress or m1_wb_adr_i or s1_wb_ack_i or s2_wb_ack_i or s1_wb_dat_i or s2_wb_dat_i or `M1_ADDRESSED_S1 or `M1_ADDRESSED_S2) +begin + if(m1_in_progress) + begin + if(`M1_ADDRESSED_S1) begin + m1_wb_ack_o <= s1_wb_ack_i; + m1_wb_dat_o <= s1_wb_dat_i; + end + else if(`M1_ADDRESSED_S2) begin + m1_wb_ack_o <= s2_wb_ack_i; + m1_wb_dat_o <= s2_wb_dat_i; + end + end + else + m1_wb_ack_o <= 0; +end + + +// Generating Ack for master 2 +always @ (m2_in_progress or m2_wb_adr_i or s1_wb_ack_i or s2_wb_ack_i or s1_wb_dat_i or s2_wb_dat_i or `M2_ADDRESSED_S1 or `M2_ADDRESSED_S2) +begin + if(m2_in_progress) + begin + if(`M2_ADDRESSED_S1) begin + m2_wb_ack_o <= s1_wb_ack_i; + m2_wb_dat_o <= s1_wb_dat_i; + end + else if(`M2_ADDRESSED_S2) begin + m2_wb_ack_o <= s2_wb_ack_i; + m2_wb_dat_o <= s2_wb_dat_i; + end + end + else + m2_wb_ack_o <= 0; +end + + +// Generating Err for master 1 +always @ (m1_in_progress or m1_wb_adr_i or s1_wb_err_i or s2_wb_err_i or `M2_ADDRESSED_S1 or `M2_ADDRESSED_S2 or + m1_wb_cyc_i or m1_wb_stb_i) +begin + if(m1_in_progress) begin + if(`M1_ADDRESSED_S1) + m1_wb_err_o <= s1_wb_err_i; + else if(`M1_ADDRESSED_S2) + m1_wb_err_o <= s2_wb_err_i; + end + else if(m1_wb_cyc_i & m1_wb_stb_i & ~`M1_ADDRESSED_S1 & ~`M1_ADDRESSED_S2) + m1_wb_err_o <= 1'b1; + else + m1_wb_err_o <= 1'b0; +end + + +// Generating Err for master 2 +always @ (m2_in_progress or m2_wb_adr_i or s1_wb_err_i or s2_wb_err_i or `M2_ADDRESSED_S1 or `M2_ADDRESSED_S2 or + m2_wb_cyc_i or m2_wb_stb_i) +begin + if(m2_in_progress) begin + if(`M2_ADDRESSED_S1) + m2_wb_err_o <= s1_wb_err_i; + else if(`M2_ADDRESSED_S2) + m2_wb_err_o <= s2_wb_err_i; + end + else if(m2_wb_cyc_i & m2_wb_stb_i & ~`M2_ADDRESSED_S1 & ~`M2_ADDRESSED_S2) + m2_wb_err_o <= 1'b1; + else + m2_wb_err_o <= 1'b0; +end + + +assign m_wb_access_finished = m1_wb_ack_o | m1_wb_err_o | m2_wb_ack_o | m2_wb_err_o; + + +// Activity monitor +integer cnt; +always @ (posedge wb_clk_i or posedge wb_rst_i) +begin + if(wb_rst_i) + cnt <=#Tp 0; + else + if(s1_wb_ack_i | s1_wb_err_i | s2_wb_ack_i | s2_wb_err_i) + cnt <=#Tp 0; + else + if(s1_wb_cyc_o | s2_wb_cyc_o) + cnt <=#Tp cnt+1; +end + +always @ (posedge wb_clk_i) +begin + if(cnt==1000) begin + $display("(%0t)(%m) ERROR: WB activity ??? ", $time); + if(s1_wb_cyc_o) begin + $display("s1_wb_dat_o = 0x%0x", s1_wb_dat_o); + $display("s1_wb_adr_o = 0x%0x", s1_wb_adr_o); + $display("s1_wb_sel_o = 0x%0x", s1_wb_sel_o); + $display("s1_wb_we_o = 0x%0x", s1_wb_we_o); + end + else if(s2_wb_cyc_o) begin + $display("s2_wb_dat_o = 0x%0x", s2_wb_dat_o); + $display("s2_wb_adr_o = 0x%0x", s2_wb_adr_o); + $display("s2_wb_sel_o = 0x%0x", s2_wb_sel_o); + $display("s2_wb_we_o = 0x%0x", s2_wb_we_o); + end + + $stop; + end +end + + +always @ (posedge wb_clk_i) +begin + if(s1_wb_err_i & s1_wb_cyc_o) begin + $display("(%0t) ERROR: WB cycle finished with error acknowledge ", $time); + $display("s1_wb_dat_o = 0x%0x", s1_wb_dat_o); + $display("s1_wb_adr_o = 0x%0x", s1_wb_adr_o); + $display("s1_wb_sel_o = 0x%0x", s1_wb_sel_o); + $display("s1_wb_we_o = 0x%0x", s1_wb_we_o); + $stop; + end + if(s2_wb_err_i & s2_wb_cyc_o) begin + $display("(%0t) ERROR: WB cycle finished with error acknowledge ", $time); + $display("s2_wb_dat_o = 0x%0x", s2_wb_dat_o); + $display("s2_wb_adr_o = 0x%0x", s2_wb_adr_o); + $display("s2_wb_sel_o = 0x%0x", s2_wb_sel_o); + $display("s2_wb_we_o = 0x%0x", s2_wb_we_o); + $stop; + end +end + + + +endmodule diff --git a/ethernet/source/ethernet/eth_crc.v b/ethernet/source/ethernet/eth_crc.v new file mode 100644 index 0000000..a16a547 --- /dev/null +++ b/ethernet/source/ethernet/eth_crc.v @@ -0,0 +1,151 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_crc.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// - Novan Hartadi (novan@vlsi.itb.ac.id) //// +//// - Mahmud Galela (mgalela@vlsi.itb.ac.id) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_crc.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.3 2001/06/19 18:16:40 mohor +// TxClk changed to MTxClk (as discribed in the documentation). +// Crc changed so only one file can be used instead of two. +// +// Revision 1.2 2001/06/19 10:38:07 mohor +// Minor changes in header. +// +// Revision 1.1 2001/06/19 10:27:57 mohor +// TxEthMAC initial release. +// +// +// + + +`include "timescale.v" + +module eth_crc (Clk, Reset, Data, Enable, Initialize, Crc, CrcError); + + +parameter Tp = 1; + +input Clk; +input Reset; +input [3:0] Data; +input Enable; +input Initialize; + +output [31:0] Crc; +output CrcError; + +reg [31:0] Crc; + +wire [31:0] CrcNext; + + +assign CrcNext[0] = Enable & (Data[0] ^ Crc[28]); +assign CrcNext[1] = Enable & (Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29]); +assign CrcNext[2] = Enable & (Data[2] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[30]); +assign CrcNext[3] = Enable & (Data[3] ^ Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30] ^ Crc[31]); +assign CrcNext[4] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[0]; +assign CrcNext[5] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[1]; +assign CrcNext[6] = (Enable & (Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30])) ^ Crc[ 2]; +assign CrcNext[7] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[3]; +assign CrcNext[8] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[4]; +assign CrcNext[9] = (Enable & (Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30])) ^ Crc[5]; +assign CrcNext[10] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[6]; +assign CrcNext[11] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[7]; +assign CrcNext[12] = (Enable & (Data[2] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[30])) ^ Crc[8]; +assign CrcNext[13] = (Enable & (Data[3] ^ Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30] ^ Crc[31])) ^ Crc[9]; +assign CrcNext[14] = (Enable & (Data[3] ^ Data[2] ^ Crc[30] ^ Crc[31])) ^ Crc[10]; +assign CrcNext[15] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[11]; +assign CrcNext[16] = (Enable & (Data[0] ^ Crc[28])) ^ Crc[12]; +assign CrcNext[17] = (Enable & (Data[1] ^ Crc[29])) ^ Crc[13]; +assign CrcNext[18] = (Enable & (Data[2] ^ Crc[30])) ^ Crc[14]; +assign CrcNext[19] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[15]; +assign CrcNext[20] = Crc[16]; +assign CrcNext[21] = Crc[17]; +assign CrcNext[22] = (Enable & (Data[0] ^ Crc[28])) ^ Crc[18]; +assign CrcNext[23] = (Enable & (Data[1] ^ Data[0] ^ Crc[29] ^ Crc[28])) ^ Crc[19]; +assign CrcNext[24] = (Enable & (Data[2] ^ Data[1] ^ Crc[30] ^ Crc[29])) ^ Crc[20]; +assign CrcNext[25] = (Enable & (Data[3] ^ Data[2] ^ Crc[31] ^ Crc[30])) ^ Crc[21]; +assign CrcNext[26] = (Enable & (Data[3] ^ Data[0] ^ Crc[31] ^ Crc[28])) ^ Crc[22]; +assign CrcNext[27] = (Enable & (Data[1] ^ Crc[29])) ^ Crc[23]; +assign CrcNext[28] = (Enable & (Data[2] ^ Crc[30])) ^ Crc[24]; +assign CrcNext[29] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[25]; +assign CrcNext[30] = Crc[26]; +assign CrcNext[31] = Crc[27]; + + +always @ (posedge Clk or posedge Reset) +begin + if (Reset) + Crc <= #1 32'hffffffff; + else + if(Initialize) + Crc <= #Tp 32'hffffffff; + else + Crc <= #Tp CrcNext; +end + +assign CrcError = Crc[31:0] != 32'hc704dd7b; // CRC not equal to magic number + +endmodule diff --git a/ethernet/source/ethernet/eth_defines.v b/ethernet/source/ethernet/eth_defines.v new file mode 100644 index 0000000..26001f5 --- /dev/null +++ b/ethernet/source/ethernet/eth_defines.v @@ -0,0 +1,351 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_defines.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is available in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_defines.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.34 2005/02/21 12:48:06 igorm +// Warning fixes. +// +// Revision 1.33 2003/11/12 18:24:58 tadejm +// WISHBONE slave changed and tested from only 32-bit accesss to byte access. +// +// Revision 1.32 2003/10/17 07:46:13 markom +// mbist signals updated according to newest convention +// +// Revision 1.31 2003/08/14 16:42:58 simons +// Artisan ram instance added. +// +// Revision 1.30 2003/06/13 11:55:37 mohor +// Define file in eth_cop.v is changed to eth_defines.v. Some defines were +// moved from tb_eth_defines.v to eth_defines.v. +// +// Revision 1.29 2002/11/19 18:13:49 mohor +// r_MiiMRst is not used for resetting the MIIM module. wb_rst used instead. +// +// Revision 1.28 2002/11/15 14:27:15 mohor +// Since r_Rst bit is not used any more, default value is changed to 0xa000. +// +// Revision 1.27 2002/11/01 18:19:34 mohor +// Defines fixed to use generic RAM by default. +// +// Revision 1.26 2002/10/24 18:53:03 mohor +// fpga define added. +// +// Revision 1.3 2002/10/11 16:57:54 igorm +// eth_defines.v tagged with rel_5 used. +// +// Revision 1.25 2002/10/10 16:47:44 mohor +// Defines changed to have ETH_ prolog. +// ETH_WISHBONE_B# define added. +// +// Revision 1.24 2002/10/10 16:33:11 mohor +// Bist added. +// +// Revision 1.23 2002/09/23 18:22:48 mohor +// Virtual Silicon RAM might be used in the ASIC implementation of the ethernet +// core. +// +// Revision 1.22 2002/09/04 18:36:49 mohor +// Defines for control registers added (ETH_TXCTRL and ETH_RXCTRL). +// +// Revision 1.21 2002/08/16 22:09:47 mohor +// Defines for register width added. mii_rst signal in MIIMODER register +// changed. +// +// Revision 1.20 2002/08/14 19:31:48 mohor +// Register TX_BD_NUM is changed so it contains value of the Tx buffer descriptors. No +// need to multiply or devide any more. +// +// Revision 1.19 2002/07/23 15:28:31 mohor +// Ram , used for BDs changed from generic_spram to eth_spram_256x32. +// +// Revision 1.18 2002/05/03 10:15:50 mohor +// Outputs registered. Reset changed for eth_wishbone module. +// +// Revision 1.17 2002/04/24 08:52:19 mohor +// Compiler directives added. Tx and Rx fifo size incremented. A "late collision" +// bug fixed. +// +// Revision 1.16 2002/03/19 12:53:29 mohor +// Some defines that are used in testbench only were moved to tb_eth_defines.v +// file. +// +// Revision 1.15 2002/02/26 16:11:32 mohor +// Number of interrupts changed +// +// Revision 1.14 2002/02/16 14:03:44 mohor +// Registered trimmed. Unused registers removed. +// +// Revision 1.13 2002/02/16 13:06:33 mohor +// EXTERNAL_DMA used instead of WISHBONE_DMA. +// +// Revision 1.12 2002/02/15 10:58:31 mohor +// Changed that were lost with last update put back to the file. +// +// Revision 1.11 2002/02/14 20:19:41 billditt +// Modified for Address Checking, +// addition of eth_addrcheck.v +// +// Revision 1.10 2002/02/12 17:01:19 mohor +// HASH0 and HASH1 registers added. + +// Revision 1.9 2002/02/08 16:21:54 mohor +// Rx status is written back to the BD. +// +// Revision 1.8 2002/02/05 16:44:38 mohor +// Both rx and tx part are finished. Tested with wb_clk_i between 10 and 200 +// MHz. Statuses, overrun, control frame transmission and reception still need +// to be fixed. +// +// Revision 1.7 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.6 2001/12/05 15:00:16 mohor +// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors +// instead of the number of RX descriptors). +// +// Revision 1.5 2001/12/05 10:21:37 mohor +// ETH_RX_BD_ADR register deleted. ETH_RX_BD_NUM is used instead. +// +// Revision 1.4 2001/11/13 14:23:56 mohor +// Generic memory model is used. Defines are changed for the same reason. +// +// Revision 1.3 2001/10/18 12:07:11 mohor +// Status signals changed, Adress decoding changed, interrupt controller +// added. +// +// Revision 1.2 2001/09/24 15:02:56 mohor +// Defines changed (All precede with ETH_). Small changes because some +// tools generate warnings when two operands are together. Synchronization +// between two clocks domains in eth_wishbonedma.v is changed (due to ASIC +// demands). +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// +// +// +// + + + +//`define ETH_BIST // Bist for usage with Virtual Silicon RAMS + +`define ETH_MBIST_CTRL_WIDTH 3 // width of MBIST control bus + +// Ethernet implemented in Xilinx Chips (uncomment following lines) +// `define ETH_FIFO_XILINX // Use Xilinx distributed ram for tx and rx fifo +// `define ETH_XILINX_RAMB4 // Selection of the used memory for Buffer descriptors + // Core is going to be implemented in Virtex FPGA and contains Virtex + // specific elements. + +// Ethernet implemented in Altera Chips (uncomment following lines) +//`define ETH_ALTERA_ALTSYNCRAM + +// Ethernet implemented in ASIC with Virtual Silicon RAMs +// `define ETH_VIRTUAL_SILICON_RAM // Virtual Silicon RAMS used storing buffer decriptors (ASIC implementation) + +// Ethernet implemented in ASIC with Artisan RAMs +// `define ETH_ARTISAN_RAM // Artisan RAMS used storing buffer decriptors (ASIC implementation) + +// Uncomment when Avalon bus is used +//`define ETH_AVALON_BUS + +`define ETH_MODER_ADR 8'h0 // 0x0 +`define ETH_INT_SOURCE_ADR 8'h1 // 0x4 +`define ETH_INT_MASK_ADR 8'h2 // 0x8 +`define ETH_IPGT_ADR 8'h3 // 0xC +`define ETH_IPGR1_ADR 8'h4 // 0x10 +`define ETH_IPGR2_ADR 8'h5 // 0x14 +`define ETH_PACKETLEN_ADR 8'h6 // 0x18 +`define ETH_COLLCONF_ADR 8'h7 // 0x1C +`define ETH_TX_BD_NUM_ADR 8'h8 // 0x20 +`define ETH_CTRLMODER_ADR 8'h9 // 0x24 +`define ETH_MIIMODER_ADR 8'hA // 0x28 +`define ETH_MIICOMMAND_ADR 8'hB // 0x2C +`define ETH_MIIADDRESS_ADR 8'hC // 0x30 +`define ETH_MIITX_DATA_ADR 8'hD // 0x34 +`define ETH_MIIRX_DATA_ADR 8'hE // 0x38 +`define ETH_MIISTATUS_ADR 8'hF // 0x3C +`define ETH_MAC_ADDR0_ADR 8'h10 // 0x40 +`define ETH_MAC_ADDR1_ADR 8'h11 // 0x44 +`define ETH_HASH0_ADR 8'h12 // 0x48 +`define ETH_HASH1_ADR 8'h13 // 0x4C +`define ETH_TX_CTRL_ADR 8'h14 // 0x50 +`define ETH_RX_CTRL_ADR 8'h15 // 0x54 + + +`define ETH_MODER_DEF_0 8'h00 +`define ETH_MODER_DEF_1 8'hA0 +`define ETH_MODER_DEF_2 1'h0 +`define ETH_INT_MASK_DEF_0 7'h0 +`define ETH_IPGT_DEF_0 7'h12 +`define ETH_IPGR1_DEF_0 7'h0C +`define ETH_IPGR2_DEF_0 7'h12 +`define ETH_PACKETLEN_DEF_0 8'h00 +`define ETH_PACKETLEN_DEF_1 8'h06 +`define ETH_PACKETLEN_DEF_2 8'h40 +`define ETH_PACKETLEN_DEF_3 8'h00 +`define ETH_COLLCONF_DEF_0 6'h3f +`define ETH_COLLCONF_DEF_2 4'hF +`define ETH_TX_BD_NUM_DEF_0 8'h40 +`define ETH_CTRLMODER_DEF_0 3'h0 +`define ETH_MIIMODER_DEF_0 8'h64 +`define ETH_MIIMODER_DEF_1 1'h0 +`define ETH_MIIADDRESS_DEF_0 5'h00 +`define ETH_MIIADDRESS_DEF_1 5'h00 +`define ETH_MIITX_DATA_DEF_0 8'h00 +`define ETH_MIITX_DATA_DEF_1 8'h00 +`define ETH_MIIRX_DATA_DEF 16'h0000 // not written from WB +`define ETH_MAC_ADDR0_DEF_0 8'h00 +`define ETH_MAC_ADDR0_DEF_1 8'h00 +`define ETH_MAC_ADDR0_DEF_2 8'h00 +`define ETH_MAC_ADDR0_DEF_3 8'h00 +`define ETH_MAC_ADDR1_DEF_0 8'h00 +`define ETH_MAC_ADDR1_DEF_1 8'h00 +`define ETH_HASH0_DEF_0 8'h00 +`define ETH_HASH0_DEF_1 8'h00 +`define ETH_HASH0_DEF_2 8'h00 +`define ETH_HASH0_DEF_3 8'h00 +`define ETH_HASH1_DEF_0 8'h00 +`define ETH_HASH1_DEF_1 8'h00 +`define ETH_HASH1_DEF_2 8'h00 +`define ETH_HASH1_DEF_3 8'h00 +`define ETH_TX_CTRL_DEF_0 8'h00 // +`define ETH_TX_CTRL_DEF_1 8'h00 // +`define ETH_TX_CTRL_DEF_2 1'h0 // +`define ETH_RX_CTRL_DEF_0 8'h00 +`define ETH_RX_CTRL_DEF_1 8'h00 + + +`define ETH_MODER_WIDTH_0 8 +`define ETH_MODER_WIDTH_1 8 +`define ETH_MODER_WIDTH_2 1 +`define ETH_INT_SOURCE_WIDTH_0 7 +`define ETH_INT_MASK_WIDTH_0 7 +`define ETH_IPGT_WIDTH_0 7 +`define ETH_IPGR1_WIDTH_0 7 +`define ETH_IPGR2_WIDTH_0 7 +`define ETH_PACKETLEN_WIDTH_0 8 +`define ETH_PACKETLEN_WIDTH_1 8 +`define ETH_PACKETLEN_WIDTH_2 8 +`define ETH_PACKETLEN_WIDTH_3 8 +`define ETH_COLLCONF_WIDTH_0 6 +`define ETH_COLLCONF_WIDTH_2 4 +`define ETH_TX_BD_NUM_WIDTH_0 8 +`define ETH_CTRLMODER_WIDTH_0 3 +`define ETH_MIIMODER_WIDTH_0 8 +`define ETH_MIIMODER_WIDTH_1 1 +`define ETH_MIICOMMAND_WIDTH_0 3 +`define ETH_MIIADDRESS_WIDTH_0 5 +`define ETH_MIIADDRESS_WIDTH_1 5 +`define ETH_MIITX_DATA_WIDTH_0 8 +`define ETH_MIITX_DATA_WIDTH_1 8 +`define ETH_MIIRX_DATA_WIDTH 16 // not written from WB +`define ETH_MIISTATUS_WIDTH 3 // not written from WB +`define ETH_MAC_ADDR0_WIDTH_0 8 +`define ETH_MAC_ADDR0_WIDTH_1 8 +`define ETH_MAC_ADDR0_WIDTH_2 8 +`define ETH_MAC_ADDR0_WIDTH_3 8 +`define ETH_MAC_ADDR1_WIDTH_0 8 +`define ETH_MAC_ADDR1_WIDTH_1 8 +`define ETH_HASH0_WIDTH_0 8 +`define ETH_HASH0_WIDTH_1 8 +`define ETH_HASH0_WIDTH_2 8 +`define ETH_HASH0_WIDTH_3 8 +`define ETH_HASH1_WIDTH_0 8 +`define ETH_HASH1_WIDTH_1 8 +`define ETH_HASH1_WIDTH_2 8 +`define ETH_HASH1_WIDTH_3 8 +`define ETH_TX_CTRL_WIDTH_0 8 +`define ETH_TX_CTRL_WIDTH_1 8 +`define ETH_TX_CTRL_WIDTH_2 1 +`define ETH_RX_CTRL_WIDTH_0 8 +`define ETH_RX_CTRL_WIDTH_1 8 + + +// Outputs are registered (uncomment when needed) +`define ETH_REGISTERED_OUTPUTS + +// Settings for TX FIFO +`define ETH_TX_FIFO_CNT_WIDTH 5 +`define ETH_TX_FIFO_DEPTH 16 +`define ETH_TX_FIFO_DATA_WIDTH 32 + +// Settings for RX FIFO +`define ETH_RX_FIFO_CNT_WIDTH 5 +`define ETH_RX_FIFO_DEPTH 16 +`define ETH_RX_FIFO_DATA_WIDTH 32 + +// Burst length +`define ETH_BURST_LENGTH 4 // Change also ETH_BURST_CNT_WIDTH +`define ETH_BURST_CNT_WIDTH 3 // The counter must be width enough to count to ETH_BURST_LENGTH + +// WISHBONE interface is Revision B3 compliant (uncomment when needed) +//`define ETH_WISHBONE_B3 + + +// Following defines are needed when eth_cop.v is used. Otherwise they may be deleted. +`define ETH_BASE 32'hd0000000 +`define ETH_WIDTH 32'h800 +`define MEMORY_BASE 32'h2000 +`define MEMORY_WIDTH 32'h10000 + +`define M1_ADDRESSED_S1 ( (m1_wb_adr_i >= `ETH_BASE) & (m1_wb_adr_i < (`ETH_BASE + `ETH_WIDTH )) ) +`define M1_ADDRESSED_S2 ( (m1_wb_adr_i >= `MEMORY_BASE) & (m1_wb_adr_i < (`MEMORY_BASE + `MEMORY_WIDTH)) ) +`define M2_ADDRESSED_S1 ( (m2_wb_adr_i >= `ETH_BASE) & (m2_wb_adr_i < (`ETH_BASE + `ETH_WIDTH )) ) +`define M2_ADDRESSED_S2 ( (m2_wb_adr_i >= `MEMORY_BASE) & (m2_wb_adr_i < (`MEMORY_BASE + `MEMORY_WIDTH)) ) +// Previous defines are only needed for eth_cop.v + diff --git a/ethernet/source/ethernet/eth_fifo.v b/ethernet/source/ethernet/eth_fifo.v new file mode 100644 index 0000000..0371112 --- /dev/null +++ b/ethernet/source/ethernet/eth_fifo.v @@ -0,0 +1,192 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_fifo.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_fifo.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2005/02/21 12:48:07 igorm +// Warning fixes. +// +// Revision 1.3 2002/04/22 13:45:52 mohor +// Generic ram or Xilinx ram can be used in fifo (selectable by setting +// ETH_FIFO_XILINX in eth_defines.v). +// +// Revision 1.2 2002/03/25 13:33:04 mohor +// When clear and read/write are active at the same time, cnt and pointers are +// set to 1. +// +// Revision 1.1 2002/02/05 16:44:39 mohor +// Both rx and tx part are finished. Tested with wb_clk_i between 10 and 200 +// MHz. Statuses, overrun, control frame transmission and reception still need +// to be fixed. +// +// + +`include "eth_defines.v" +`include "timescale.v" + +module eth_fifo (data_in, data_out, clk, reset, write, read, clear, almost_full, full, almost_empty, empty, cnt); + +parameter DATA_WIDTH = 32; +parameter DEPTH = 8; +parameter CNT_WIDTH = 4; + +parameter Tp = 1; + +input clk; +input reset; +input write; +input read; +input clear; +input [DATA_WIDTH-1:0] data_in; + +output [DATA_WIDTH-1:0] data_out; +output almost_full; +output full; +output almost_empty; +output empty; +output [CNT_WIDTH-1:0] cnt; + +`ifdef ETH_FIFO_XILINX +`else + `ifdef ETH_ALTERA_ALTSYNCRAM + `else + reg [DATA_WIDTH-1:0] fifo [0:DEPTH-1]; + reg [DATA_WIDTH-1:0] data_out; + `endif +`endif + +reg [CNT_WIDTH-1:0] cnt; +reg [CNT_WIDTH-2:0] read_pointer; +reg [CNT_WIDTH-2:0] write_pointer; + + +always @ (posedge clk or posedge reset) +begin + if(reset) + cnt <=#Tp 0; + else + if(clear) + cnt <=#Tp { {(CNT_WIDTH-1){1'b0}}, read^write}; + else + if(read ^ write) + if(read) + cnt <=#Tp cnt - 1'b1; + else + cnt <=#Tp cnt + 1'b1; +end + +always @ (posedge clk or posedge reset) +begin + if(reset) + read_pointer <=#Tp 0; + else + if(clear) + read_pointer <=#Tp { {(CNT_WIDTH-2){1'b0}}, read}; + else + if(read & ~empty) + read_pointer <=#Tp read_pointer + 1'b1; +end + +always @ (posedge clk or posedge reset) +begin + if(reset) + write_pointer <=#Tp 0; + else + if(clear) + write_pointer <=#Tp { {(CNT_WIDTH-2){1'b0}}, write}; + else + if(write & ~full) + write_pointer <=#Tp write_pointer + 1'b1; +end + +assign empty = ~(|cnt); +assign almost_empty = cnt == 1; +assign full = cnt == DEPTH; +assign almost_full = &cnt[CNT_WIDTH-2:0]; + + + +`ifdef ETH_FIFO_XILINX + xilinx_dist_ram_16x32 fifo + ( .data_out(data_out), + .we(write & ~full), + .data_in(data_in), + .read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer), + .write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer), + .wclk(clk) + ); +`else // !ETH_FIFO_XILINX +`ifdef ETH_ALTERA_ALTSYNCRAM + altera_dpram_16x32 altera_dpram_16x32_inst + ( + .data (data_in), + .wren (write & ~full), + .wraddress (clear ? {CNT_WIDTH-1{1'b0}} : write_pointer), + .rdaddress (clear ? {CNT_WIDTH-1{1'b0}} : read_pointer ), + .clock (clk), + .q (data_out) + ); //exemplar attribute altera_dpram_16x32_inst NOOPT TRUE +`else // !ETH_ALTERA_ALTSYNCRAM + always @ (posedge clk) + begin + if(write & clear) + fifo[0] <=#Tp data_in; + else + if(write & ~full) + fifo[write_pointer] <=#Tp data_in; + end + + + always @ (posedge clk) + begin + if(clear) + data_out <=#Tp fifo[0]; + else + data_out <=#Tp fifo[read_pointer]; + end +`endif // !ETH_ALTERA_ALTSYNCRAM +`endif // !ETH_FIFO_XILINX + + +endmodule diff --git a/ethernet/source/ethernet/eth_maccontrol.v b/ethernet/source/ethernet/eth_maccontrol.v new file mode 100644 index 0000000..d66842d --- /dev/null +++ b/ethernet/source/ethernet/eth_maccontrol.v @@ -0,0 +1,277 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_maccontrol.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_maccontrol.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.7 2003/01/22 13:49:26 tadejm +// When control packets were received, they were ignored in some cases. +// +// Revision 1.6 2002/11/22 01:57:06 mohor +// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort +// synchronized. +// +// Revision 1.5 2002/11/21 00:14:39 mohor +// TxDone and TxAbort changed so they're not propagated to the wishbone +// module when control frame is transmitted. +// +// Revision 1.4 2002/11/19 17:37:32 mohor +// When control frame (PAUSE) was sent, status was written in the +// eth_wishbone module and both TXB and TXC interrupts were set. Fixed. +// Only TXC interrupt is set. +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.1 2001/07/03 12:51:54 mohor +// Initial release of the MAC Control module. +// +// +// +// + + +`include "timescale.v" + + +module eth_maccontrol (MTxClk, MRxClk, TxReset, RxReset, TPauseRq, TxDataIn, TxStartFrmIn, TxUsedDataIn, + TxEndFrmIn, TxDoneIn, TxAbortIn, RxData, RxValid, RxStartFrm, RxEndFrm, ReceiveEnd, + ReceivedPacketGood, ReceivedLengthOK, TxFlow, RxFlow, DlyCrcEn, TxPauseTV, + MAC, PadIn, PadOut, CrcEnIn, CrcEnOut, TxDataOut, TxStartFrmOut, TxEndFrmOut, + TxDoneOut, TxAbortOut, TxUsedDataOut, WillSendControlFrame, TxCtrlEndFrm, + ReceivedPauseFrm, ControlFrmAddressOK, SetPauseTimer, r_PassAll, RxStatusWriteLatched_sync2 + ); + + +parameter Tp = 1; + + +input MTxClk; // Transmit clock (from PHY) +input MRxClk; // Receive clock (from PHY) +input TxReset; // Transmit reset +input RxReset; // Receive reset +input TPauseRq; // Transmit control frame (from host) +input [7:0] TxDataIn; // Transmit packet data byte (from host) +input TxStartFrmIn; // Transmit packet start frame input (from host) +input TxUsedDataIn; // Transmit packet used data (from TxEthMAC) +input TxEndFrmIn; // Transmit packet end frame input (from host) +input TxDoneIn; // Transmit packet done (from TxEthMAC) +input TxAbortIn; // Transmit packet abort (input from TxEthMAC) +input PadIn; // Padding (input from registers) +input CrcEnIn; // Crc append (input from registers) +input [7:0] RxData; // Receive Packet Data (from RxEthMAC) +input RxValid; // Received a valid packet +input RxStartFrm; // Receive packet start frame (input from RxEthMAC) +input RxEndFrm; // Receive packet end frame (input from RxEthMAC) +input ReceiveEnd; // End of receiving of the current packet (input from RxEthMAC) +input ReceivedPacketGood; // Received packet is good +input ReceivedLengthOK; // Length of the received packet is OK +input TxFlow; // Tx flow control (from registers) +input RxFlow; // Rx flow control (from registers) +input DlyCrcEn; // Delayed CRC enabled (from registers) +input [15:0] TxPauseTV; // Transmit Pause Timer Value (from registers) +input [47:0] MAC; // MAC address (from registers) +input RxStatusWriteLatched_sync2; +input r_PassAll; + +output [7:0] TxDataOut; // Transmit Packet Data (to TxEthMAC) +output TxStartFrmOut; // Transmit packet start frame (output to TxEthMAC) +output TxEndFrmOut; // Transmit packet end frame (output to TxEthMAC) +output TxDoneOut; // Transmit packet done (to host) +output TxAbortOut; // Transmit packet aborted (to host) +output TxUsedDataOut; // Transmit packet used data (to host) +output PadOut; // Padding (output to TxEthMAC) +output CrcEnOut; // Crc append (output to TxEthMAC) +output WillSendControlFrame; +output TxCtrlEndFrm; +output ReceivedPauseFrm; +output ControlFrmAddressOK; +output SetPauseTimer; + +reg TxUsedDataOutDetected; +reg TxAbortInLatched; +reg TxDoneInLatched; +reg MuxedDone; +reg MuxedAbort; + +wire Pause; +wire TxCtrlStartFrm; +wire [7:0] ControlData; +wire CtrlMux; +wire SendingCtrlFrm; // Sending Control Frame (enables padding and CRC) +wire BlockTxDone; + + +// Signal TxUsedDataOut was detected (a transfer is already in progress) +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + TxUsedDataOutDetected <= #Tp 1'b0; + else + if(TxDoneIn | TxAbortIn) + TxUsedDataOutDetected <= #Tp 1'b0; + else + if(TxUsedDataOut) + TxUsedDataOutDetected <= #Tp 1'b1; +end + + +// Latching variables +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + begin + TxAbortInLatched <= #Tp 1'b0; + TxDoneInLatched <= #Tp 1'b0; + end + else + begin + TxAbortInLatched <= #Tp TxAbortIn; + TxDoneInLatched <= #Tp TxDoneIn; + end +end + + + +// Generating muxed abort signal +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + MuxedAbort <= #Tp 1'b0; + else + if(TxStartFrmIn) + MuxedAbort <= #Tp 1'b0; + else + if(TxAbortIn & ~TxAbortInLatched & TxUsedDataOutDetected) + MuxedAbort <= #Tp 1'b1; +end + + +// Generating muxed done signal +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + MuxedDone <= #Tp 1'b0; + else + if(TxStartFrmIn) + MuxedDone <= #Tp 1'b0; + else + if(TxDoneIn & (~TxDoneInLatched) & TxUsedDataOutDetected) + MuxedDone <= #Tp 1'b1; +end + + +// TxDoneOut +assign TxDoneOut = CtrlMux? ((~TxStartFrmIn) & (~BlockTxDone) & MuxedDone) : + ((~TxStartFrmIn) & (~BlockTxDone) & TxDoneIn); + +// TxAbortOut +assign TxAbortOut = CtrlMux? ((~TxStartFrmIn) & (~BlockTxDone) & MuxedAbort) : + ((~TxStartFrmIn) & (~BlockTxDone) & TxAbortIn); + +// TxUsedDataOut +assign TxUsedDataOut = ~CtrlMux & TxUsedDataIn; + +// TxStartFrmOut +assign TxStartFrmOut = CtrlMux? TxCtrlStartFrm : (TxStartFrmIn & ~Pause); + + +// TxEndFrmOut +assign TxEndFrmOut = CtrlMux? TxCtrlEndFrm : TxEndFrmIn; + + +// TxDataOut[7:0] +assign TxDataOut[7:0] = CtrlMux? ControlData[7:0] : TxDataIn[7:0]; + + +// PadOut +assign PadOut = PadIn | SendingCtrlFrm; + + +// CrcEnOut +assign CrcEnOut = CrcEnIn | SendingCtrlFrm; + + + +// Connecting receivecontrol module +eth_receivecontrol receivecontrol1 +( + .MTxClk(MTxClk), .MRxClk(MRxClk), .TxReset(TxReset), .RxReset(RxReset), .RxData(RxData), + .RxValid(RxValid), .RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), .RxFlow(RxFlow), + .ReceiveEnd(ReceiveEnd), .MAC(MAC), .DlyCrcEn(DlyCrcEn), .TxDoneIn(TxDoneIn), + .TxAbortIn(TxAbortIn), .TxStartFrmOut(TxStartFrmOut), .ReceivedLengthOK(ReceivedLengthOK), + .ReceivedPacketGood(ReceivedPacketGood), .TxUsedDataOutDetected(TxUsedDataOutDetected), + .Pause(Pause), .ReceivedPauseFrm(ReceivedPauseFrm), .AddressOK(ControlFrmAddressOK), + .r_PassAll(r_PassAll), .RxStatusWriteLatched_sync2(RxStatusWriteLatched_sync2), .SetPauseTimer(SetPauseTimer) +); + + +eth_transmitcontrol transmitcontrol1 +( + .MTxClk(MTxClk), .TxReset(TxReset), .TxUsedDataIn(TxUsedDataIn), .TxUsedDataOut(TxUsedDataOut), + .TxDoneIn(TxDoneIn), .TxAbortIn(TxAbortIn), .TxStartFrmIn(TxStartFrmIn), .TPauseRq(TPauseRq), + .TxUsedDataOutDetected(TxUsedDataOutDetected), .TxFlow(TxFlow), .DlyCrcEn(DlyCrcEn), .TxPauseTV(TxPauseTV), + .MAC(MAC), .TxCtrlStartFrm(TxCtrlStartFrm), .TxCtrlEndFrm(TxCtrlEndFrm), .SendingCtrlFrm(SendingCtrlFrm), + .CtrlMux(CtrlMux), .ControlData(ControlData), .WillSendControlFrame(WillSendControlFrame), .BlockTxDone(BlockTxDone) +); + + + +endmodule diff --git a/ethernet/source/ethernet/eth_macstatus.v b/ethernet/source/ethernet/eth_macstatus.v new file mode 100644 index 0000000..b1d7939 --- /dev/null +++ b/ethernet/source/ethernet/eth_macstatus.v @@ -0,0 +1,431 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_macstatus.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is available in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_macstatus.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.17 2005/03/21 20:07:18 igorm +// Some small fixes + some troubles fixed. +// +// Revision 1.16 2005/02/21 10:42:11 igorm +// Defer indication fixed. +// +// Revision 1.15 2003/01/30 13:28:19 tadejm +// Defer indication changed. +// +// Revision 1.14 2002/11/22 01:57:06 mohor +// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort +// synchronized. +// +// Revision 1.13 2002/11/13 22:30:58 tadejm +// Late collision is reported only when not in the full duplex. +// Sample is taken (for status) as soon as MRxDV is not valid (regardless +// of the received byte cnt). +// +// Revision 1.12 2002/09/12 14:50:16 mohor +// CarrierSenseLost bug fixed when operating in full duplex mode. +// +// Revision 1.11 2002/09/04 18:38:03 mohor +// CarrierSenseLost status is not set when working in loopback mode. +// +// Revision 1.10 2002/07/25 18:17:46 mohor +// InvalidSymbol generation changed. +// +// Revision 1.9 2002/04/22 13:51:44 mohor +// Short frame and ReceivedLengthOK were not detected correctly. +// +// Revision 1.8 2002/02/18 10:40:17 mohor +// Small fixes. +// +// Revision 1.7 2002/02/15 17:07:39 mohor +// Status was not written correctly when frames were discarted because of +// address mismatch. +// +// Revision 1.6 2002/02/11 09:18:21 mohor +// Tx status is written back to the BD. +// +// Revision 1.5 2002/02/08 16:21:54 mohor +// Rx status is written back to the BD. +// +// Revision 1.4 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.3 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.2 2001/09/11 14:17:00 mohor +// Few little NCSIM warnings fixed. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// +// +// +// + +`include "timescale.v" + + +module eth_macstatus( + MRxClk, Reset, ReceivedLengthOK, ReceiveEnd, ReceivedPacketGood, RxCrcError, + MRxErr, MRxDV, RxStateSFD, RxStateData, RxStatePreamble, RxStateIdle, Transmitting, + RxByteCnt, RxByteCntEq0, RxByteCntGreat2, RxByteCntMaxFrame, + InvalidSymbol, MRxD, LatchedCrcError, Collision, CollValid, RxLateCollision, + r_RecSmall, r_MinFL, r_MaxFL, ShortFrame, DribbleNibble, ReceivedPacketTooBig, r_HugEn, + LoadRxStatus, StartTxDone, StartTxAbort, RetryCnt, RetryCntLatched, MTxClk, MaxCollisionOccured, + RetryLimit, LateCollision, LateCollLatched, DeferIndication, DeferLatched, RstDeferLatched, TxStartFrm, + StatePreamble, StateData, CarrierSense, CarrierSenseLost, TxUsedData, LatchedMRxErr, Loopback, + r_FullD + ); + + + +parameter Tp = 1; + + +input MRxClk; +input Reset; +input RxCrcError; +input MRxErr; +input MRxDV; + +input RxStateSFD; +input [1:0] RxStateData; +input RxStatePreamble; +input RxStateIdle; +input Transmitting; +input [15:0] RxByteCnt; +input RxByteCntEq0; +input RxByteCntGreat2; +input RxByteCntMaxFrame; +input [3:0] MRxD; +input Collision; +input [5:0] CollValid; +input r_RecSmall; +input [15:0] r_MinFL; +input [15:0] r_MaxFL; +input r_HugEn; +input StartTxDone; +input StartTxAbort; +input [3:0] RetryCnt; +input MTxClk; +input MaxCollisionOccured; +input LateCollision; +input DeferIndication; +input TxStartFrm; +input StatePreamble; +input [1:0] StateData; +input CarrierSense; +input TxUsedData; +input Loopback; +input r_FullD; + + +output ReceivedLengthOK; +output ReceiveEnd; +output ReceivedPacketGood; +output InvalidSymbol; +output LatchedCrcError; +output RxLateCollision; +output ShortFrame; +output DribbleNibble; +output ReceivedPacketTooBig; +output LoadRxStatus; +output [3:0] RetryCntLatched; +output RetryLimit; +output LateCollLatched; +output DeferLatched; +input RstDeferLatched; +output CarrierSenseLost; +output LatchedMRxErr; + + +reg ReceiveEnd; + +reg LatchedCrcError; +reg LatchedMRxErr; +reg LoadRxStatus; +reg InvalidSymbol; +reg [3:0] RetryCntLatched; +reg RetryLimit; +reg LateCollLatched; +reg DeferLatched; +reg CarrierSenseLost; + +wire TakeSample; +wire SetInvalidSymbol; // Invalid symbol was received during reception in 100Mbps + +// Crc error +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + LatchedCrcError <=#Tp 1'b0; + else + if(RxStateSFD) + LatchedCrcError <=#Tp 1'b0; + else + if(RxStateData[0]) + LatchedCrcError <=#Tp RxCrcError & ~RxByteCntEq0; +end + + +// LatchedMRxErr +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + LatchedMRxErr <=#Tp 1'b0; + else + if(MRxErr & MRxDV & (RxStatePreamble | RxStateSFD | (|RxStateData) | RxStateIdle & ~Transmitting)) + LatchedMRxErr <=#Tp 1'b1; + else + LatchedMRxErr <=#Tp 1'b0; +end + + +// ReceivedPacketGood +assign ReceivedPacketGood = ~LatchedCrcError; + + +// ReceivedLengthOK +assign ReceivedLengthOK = RxByteCnt[15:0] >= r_MinFL[15:0] & RxByteCnt[15:0] <= r_MaxFL[15:0]; + + + + + +// Time to take a sample +//assign TakeSample = |RxStateData & ~MRxDV & RxByteCntGreat2 | +assign TakeSample = (|RxStateData) & (~MRxDV) | + RxStateData[0] & MRxDV & RxByteCntMaxFrame; + + +// LoadRxStatus +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + LoadRxStatus <=#Tp 1'b0; + else + LoadRxStatus <=#Tp TakeSample; +end + + + +// ReceiveEnd +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + ReceiveEnd <=#Tp 1'b0; + else + ReceiveEnd <=#Tp LoadRxStatus; +end + + +// Invalid Symbol received during 100Mbps mode +assign SetInvalidSymbol = MRxDV & MRxErr & MRxD[3:0] == 4'he; + + +// InvalidSymbol +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + InvalidSymbol <=#Tp 1'b0; + else + if(LoadRxStatus & ~SetInvalidSymbol) + InvalidSymbol <=#Tp 1'b0; + else + if(SetInvalidSymbol) + InvalidSymbol <=#Tp 1'b1; +end + + +// Late Collision + +reg RxLateCollision; +reg RxColWindow; +// Collision Window +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxLateCollision <=#Tp 1'b0; + else + if(LoadRxStatus) + RxLateCollision <=#Tp 1'b0; + else + if(Collision & (~r_FullD) & (~RxColWindow | r_RecSmall)) + RxLateCollision <=#Tp 1'b1; +end + +// Collision Window +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxColWindow <=#Tp 1'b1; + else + if(~Collision & RxByteCnt[5:0] == CollValid[5:0] & RxStateData[1]) + RxColWindow <=#Tp 1'b0; + else + if(RxStateIdle) + RxColWindow <=#Tp 1'b1; +end + + +// ShortFrame +reg ShortFrame; +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + ShortFrame <=#Tp 1'b0; + else + if(LoadRxStatus) + ShortFrame <=#Tp 1'b0; + else + if(TakeSample) + ShortFrame <=#Tp RxByteCnt[15:0] < r_MinFL[15:0]; +end + + +// DribbleNibble +reg DribbleNibble; +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + DribbleNibble <=#Tp 1'b0; + else + if(RxStateSFD) + DribbleNibble <=#Tp 1'b0; + else + if(~MRxDV & RxStateData[1]) + DribbleNibble <=#Tp 1'b1; +end + + +reg ReceivedPacketTooBig; +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + ReceivedPacketTooBig <=#Tp 1'b0; + else + if(LoadRxStatus) + ReceivedPacketTooBig <=#Tp 1'b0; + else + if(TakeSample) + ReceivedPacketTooBig <=#Tp ~r_HugEn & RxByteCnt[15:0] > r_MaxFL[15:0]; +end + + + +// Latched Retry counter for tx status +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + RetryCntLatched <=#Tp 4'h0; + else + if(StartTxDone | StartTxAbort) + RetryCntLatched <=#Tp RetryCnt; +end + + +// Latched Retransmission limit +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + RetryLimit <=#Tp 1'h0; + else + if(StartTxDone | StartTxAbort) + RetryLimit <=#Tp MaxCollisionOccured; +end + + +// Latched Late Collision +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + LateCollLatched <=#Tp 1'b0; + else + if(StartTxDone | StartTxAbort) + LateCollLatched <=#Tp LateCollision; +end + + + +// Latched Defer state +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + DeferLatched <=#Tp 1'b0; + else + if(DeferIndication) + DeferLatched <=#Tp 1'b1; + else + if(RstDeferLatched) + DeferLatched <=#Tp 1'b0; +end + + +// CarrierSenseLost +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + CarrierSenseLost <=#Tp 1'b0; + else + if((StatePreamble | (|StateData)) & ~CarrierSense & ~Loopback & ~Collision & ~r_FullD) + CarrierSenseLost <=#Tp 1'b1; + else + if(TxStartFrm) + CarrierSenseLost <=#Tp 1'b0; +end + + +endmodule diff --git a/ethernet/source/ethernet/eth_miim.v b/ethernet/source/ethernet/eth_miim.v new file mode 100644 index 0000000..b22dfd6 --- /dev/null +++ b/ethernet/source/ethernet/eth_miim.v @@ -0,0 +1,454 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_miim.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_miim.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.7 2005/03/21 20:07:18 igorm +// Some small fixes + some troubles fixed. +// +// Revision 1.6 2005/02/21 12:48:07 igorm +// Warning fixes. +// +// Revision 1.5 2003/05/16 10:08:27 mohor +// Busy was set 2 cycles too late. Reported by Dennis Scott. +// +// Revision 1.4 2002/08/14 18:32:10 mohor +// - Busy signal was not set on time when scan status operation was performed +// and clock was divided with more than 2. +// - Nvalid remains valid two more clocks (was previously cleared too soon). +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.2 2001/08/02 09:25:31 mohor +// Unconnected signals are now connected. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.3 2001/06/01 22:28:56 mohor +// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated. +// +// + +`include "timescale.v" + + +module eth_miim +( + Clk, + Reset, + Divider, + NoPre, + CtrlData, + Rgad, + Fiad, + WCtrlData, + RStat, + ScanStat, + Mdi, + Mdo, + MdoEn, + Mdc, + Busy, + Prsd, + LinkFail, + Nvalid, + WCtrlDataStart, + RStatStart, + UpdateMIIRX_DATAReg +); + + + +input Clk; // Host Clock +input Reset; // General Reset +input [7:0] Divider; // Divider for the host clock +input [15:0] CtrlData; // Control Data (to be written to the PHY reg.) +input [4:0] Rgad; // Register Address (within the PHY) +input [4:0] Fiad; // PHY Address +input NoPre; // No Preamble (no 32-bit preamble) +input WCtrlData; // Write Control Data operation +input RStat; // Read Status operation +input ScanStat; // Scan Status operation +input Mdi; // MII Management Data In + +output Mdc; // MII Management Data Clock +output Mdo; // MII Management Data Output +output MdoEn; // MII Management Data Output Enable +output Busy; // Busy Signal +output LinkFail; // Link Integrity Signal +output Nvalid; // Invalid Status (qualifier for the valid scan result) + +output [15:0] Prsd; // Read Status Data (data read from the PHY) + +output WCtrlDataStart; // This signals resets the WCTRLDATA bit in the MIIM Command register +output RStatStart; // This signal resets the RSTAT BIT in the MIIM Command register +output UpdateMIIRX_DATAReg;// Updates MII RX_DATA register with read data + +parameter Tp = 1; + + +reg Nvalid; +reg EndBusy_d; // Pre-end Busy signal +reg EndBusy; // End Busy signal (stops the operation in progress) + +reg WCtrlData_q1; // Write Control Data operation delayed 1 Clk cycle +reg WCtrlData_q2; // Write Control Data operation delayed 2 Clk cycles +reg WCtrlData_q3; // Write Control Data operation delayed 3 Clk cycles +reg WCtrlDataStart; // Start Write Control Data Command (positive edge detected) +reg WCtrlDataStart_q; +reg WCtrlDataStart_q1; // Start Write Control Data Command delayed 1 Mdc cycle +reg WCtrlDataStart_q2; // Start Write Control Data Command delayed 2 Mdc cycles + +reg RStat_q1; // Read Status operation delayed 1 Clk cycle +reg RStat_q2; // Read Status operation delayed 2 Clk cycles +reg RStat_q3; // Read Status operation delayed 3 Clk cycles +reg RStatStart; // Start Read Status Command (positive edge detected) +reg RStatStart_q1; // Start Read Status Command delayed 1 Mdc cycle +reg RStatStart_q2; // Start Read Status Command delayed 2 Mdc cycles + +reg ScanStat_q1; // Scan Status operation delayed 1 cycle +reg ScanStat_q2; // Scan Status operation delayed 2 cycles +reg SyncStatMdcEn; // Scan Status operation delayed at least cycles and synchronized to MdcEn + +wire WriteDataOp; // Write Data Operation (positive edge detected) +wire ReadStatusOp; // Read Status Operation (positive edge detected) +wire ScanStatusOp; // Scan Status Operation (positive edge detected) +wire StartOp; // Start Operation (start of any of the preceding operations) +wire EndOp; // End of Operation + +reg InProgress; // Operation in progress +reg InProgress_q1; // Operation in progress delayed 1 Mdc cycle +reg InProgress_q2; // Operation in progress delayed 2 Mdc cycles +reg InProgress_q3; // Operation in progress delayed 3 Mdc cycles + +reg WriteOp; // Write Operation Latch (When asserted, write operation is in progress) +reg [6:0] BitCounter; // Bit Counter + + +wire [3:0] ByteSelect; // Byte Select defines which byte (preamble, data, operation, etc.) is loaded and shifted through the shift register. +wire MdcEn; // MII Management Data Clock Enable signal is asserted for one Clk period before Mdc rises. +wire ShiftedBit; // This bit is output of the shift register and is connected to the Mdo signal +wire MdcEn_n; + +wire LatchByte1_d2; +wire LatchByte0_d2; +reg LatchByte1_d; +reg LatchByte0_d; +reg [1:0] LatchByte; // Latch Byte selects which part of Read Status Data is updated from the shift register + +reg UpdateMIIRX_DATAReg;// Updates MII RX_DATA register with read data + + + + + +// Generation of the EndBusy signal. It is used for ending the MII Management operation. +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + begin + EndBusy_d <= #Tp 1'b0; + EndBusy <= #Tp 1'b0; + end + else + begin + EndBusy_d <= #Tp ~InProgress_q2 & InProgress_q3; + EndBusy <= #Tp EndBusy_d; + end +end + + +// Update MII RX_DATA register +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + UpdateMIIRX_DATAReg <= #Tp 0; + else + if(EndBusy & ~WCtrlDataStart_q) + UpdateMIIRX_DATAReg <= #Tp 1; + else + UpdateMIIRX_DATAReg <= #Tp 0; +end + + + +// Generation of the delayed signals used for positive edge triggering. +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + begin + WCtrlData_q1 <= #Tp 1'b0; + WCtrlData_q2 <= #Tp 1'b0; + WCtrlData_q3 <= #Tp 1'b0; + + RStat_q1 <= #Tp 1'b0; + RStat_q2 <= #Tp 1'b0; + RStat_q3 <= #Tp 1'b0; + + ScanStat_q1 <= #Tp 1'b0; + ScanStat_q2 <= #Tp 1'b0; + SyncStatMdcEn <= #Tp 1'b0; + end + else + begin + WCtrlData_q1 <= #Tp WCtrlData; + WCtrlData_q2 <= #Tp WCtrlData_q1; + WCtrlData_q3 <= #Tp WCtrlData_q2; + + RStat_q1 <= #Tp RStat; + RStat_q2 <= #Tp RStat_q1; + RStat_q3 <= #Tp RStat_q2; + + ScanStat_q1 <= #Tp ScanStat; + ScanStat_q2 <= #Tp ScanStat_q1; + if(MdcEn) + SyncStatMdcEn <= #Tp ScanStat_q2; + end +end + + +// Generation of the Start Commands (Write Control Data or Read Status) +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + begin + WCtrlDataStart <= #Tp 1'b0; + WCtrlDataStart_q <= #Tp 1'b0; + RStatStart <= #Tp 1'b0; + end + else + begin + if(EndBusy) + begin + WCtrlDataStart <= #Tp 1'b0; + RStatStart <= #Tp 1'b0; + end + else + begin + if(WCtrlData_q2 & ~WCtrlData_q3) + WCtrlDataStart <= #Tp 1'b1; + if(RStat_q2 & ~RStat_q3) + RStatStart <= #Tp 1'b1; + WCtrlDataStart_q <= #Tp WCtrlDataStart; + end + end +end + + +// Generation of the Nvalid signal (indicates when the status is invalid) +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + Nvalid <= #Tp 1'b0; + else + begin + if(~InProgress_q2 & InProgress_q3) + begin + Nvalid <= #Tp 1'b0; + end + else + begin + if(ScanStat_q2 & ~SyncStatMdcEn) + Nvalid <= #Tp 1'b1; + end + end +end + +// Signals used for the generation of the Operation signals (positive edge) +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + begin + WCtrlDataStart_q1 <= #Tp 1'b0; + WCtrlDataStart_q2 <= #Tp 1'b0; + + RStatStart_q1 <= #Tp 1'b0; + RStatStart_q2 <= #Tp 1'b0; + + InProgress_q1 <= #Tp 1'b0; + InProgress_q2 <= #Tp 1'b0; + InProgress_q3 <= #Tp 1'b0; + + LatchByte0_d <= #Tp 1'b0; + LatchByte1_d <= #Tp 1'b0; + + LatchByte <= #Tp 2'b00; + end + else + begin + if(MdcEn) + begin + WCtrlDataStart_q1 <= #Tp WCtrlDataStart; + WCtrlDataStart_q2 <= #Tp WCtrlDataStart_q1; + + RStatStart_q1 <= #Tp RStatStart; + RStatStart_q2 <= #Tp RStatStart_q1; + + LatchByte[0] <= #Tp LatchByte0_d; + LatchByte[1] <= #Tp LatchByte1_d; + + LatchByte0_d <= #Tp LatchByte0_d2; + LatchByte1_d <= #Tp LatchByte1_d2; + + InProgress_q1 <= #Tp InProgress; + InProgress_q2 <= #Tp InProgress_q1; + InProgress_q3 <= #Tp InProgress_q2; + end + end +end + + +// Generation of the Operation signals +assign WriteDataOp = WCtrlDataStart_q1 & ~WCtrlDataStart_q2; +assign ReadStatusOp = RStatStart_q1 & ~RStatStart_q2; +assign ScanStatusOp = SyncStatMdcEn & ~InProgress & ~InProgress_q1 & ~InProgress_q2; +assign StartOp = WriteDataOp | ReadStatusOp | ScanStatusOp; + +// Busy +assign Busy = WCtrlData | WCtrlDataStart | RStat | RStatStart | SyncStatMdcEn | EndBusy | InProgress | InProgress_q3 | Nvalid; + + +// Generation of the InProgress signal (indicates when an operation is in progress) +// Generation of the WriteOp signal (indicates when a write is in progress) +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + begin + InProgress <= #Tp 1'b0; + WriteOp <= #Tp 1'b0; + end + else + begin + if(MdcEn) + begin + if(StartOp) + begin + if(~InProgress) + WriteOp <= #Tp WriteDataOp; + InProgress <= #Tp 1'b1; + end + else + begin + if(EndOp) + begin + InProgress <= #Tp 1'b0; + WriteOp <= #Tp 1'b0; + end + end + end + end +end + + + +// Bit Counter counts from 0 to 63 (from 32 to 63 when NoPre is asserted) +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + BitCounter[6:0] <= #Tp 7'h0; + else + begin + if(MdcEn) + begin + if(InProgress) + begin + if(NoPre & ( BitCounter == 7'h0 )) + BitCounter[6:0] <= #Tp 7'h21; + else + BitCounter[6:0] <= #Tp BitCounter[6:0] + 1'b1; + end + else + BitCounter[6:0] <= #Tp 7'h0; + end + end +end + + +// Operation ends when the Bit Counter reaches 63 +assign EndOp = BitCounter==63; + +assign ByteSelect[0] = InProgress & ((NoPre & (BitCounter == 7'h0)) | (~NoPre & (BitCounter == 7'h20))); +assign ByteSelect[1] = InProgress & (BitCounter == 7'h28); +assign ByteSelect[2] = InProgress & WriteOp & (BitCounter == 7'h30); +assign ByteSelect[3] = InProgress & WriteOp & (BitCounter == 7'h38); + + +// Latch Byte selects which part of Read Status Data is updated from the shift register +assign LatchByte1_d2 = InProgress & ~WriteOp & BitCounter == 7'h37; +assign LatchByte0_d2 = InProgress & ~WriteOp & BitCounter == 7'h3F; + + +// Connecting the Clock Generator Module +eth_clockgen clkgen(.Clk(Clk), .Reset(Reset), .Divider(Divider[7:0]), .MdcEn(MdcEn), .MdcEn_n(MdcEn_n), .Mdc(Mdc) + ); + +// Connecting the Shift Register Module +eth_shiftreg shftrg(.Clk(Clk), .Reset(Reset), .MdcEn_n(MdcEn_n), .Mdi(Mdi), .Fiad(Fiad), .Rgad(Rgad), + .CtrlData(CtrlData), .WriteOp(WriteOp), .ByteSelect(ByteSelect), .LatchByte(LatchByte), + .ShiftedBit(ShiftedBit), .Prsd(Prsd), .LinkFail(LinkFail) + ); + +// Connecting the Output Control Module +eth_outputcontrol outctrl(.Clk(Clk), .Reset(Reset), .MdcEn_n(MdcEn_n), .InProgress(InProgress), + .ShiftedBit(ShiftedBit), .BitCounter(BitCounter), .WriteOp(WriteOp), .NoPre(NoPre), + .Mdo(Mdo), .MdoEn(MdoEn) + ); + +endmodule diff --git a/ethernet/source/ethernet/eth_outputcontrol.v b/ethernet/source/ethernet/eth_outputcontrol.v new file mode 100644 index 0000000..c5d3113 --- /dev/null +++ b/ethernet/source/ethernet/eth_outputcontrol.v @@ -0,0 +1,153 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_outputcontrol.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_outputcontrol.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2002/07/09 20:11:59 mohor +// Comment removed. +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.3 2001/06/01 22:28:56 mohor +// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated. +// +// + +`include "timescale.v" + +module eth_outputcontrol(Clk, Reset, InProgress, ShiftedBit, BitCounter, WriteOp, NoPre, MdcEn_n, Mdo, MdoEn); + +parameter Tp = 1; + +input Clk; // Host Clock +input Reset; // General Reset +input WriteOp; // Write Operation Latch (When asserted, write operation is in progress) +input NoPre; // No Preamble (no 32-bit preamble) +input InProgress; // Operation in progress +input ShiftedBit; // This bit is output of the shift register and is connected to the Mdo signal +input [6:0] BitCounter; // Bit Counter +input MdcEn_n; // MII Management Data Clock Enable signal is asserted for one Clk period before Mdc falls. + +output Mdo; // MII Management Data Output +output MdoEn; // MII Management Data Output Enable + +wire SerialEn; + +reg MdoEn_2d; +reg MdoEn_d; +reg MdoEn; + +reg Mdo_2d; +reg Mdo_d; +reg Mdo; // MII Management Data Output + + + +// Generation of the Serial Enable signal (enables the serialization of the data) +assign SerialEn = WriteOp & InProgress & ( BitCounter>31 | ( ( BitCounter == 0 ) & NoPre ) ) + | ~WriteOp & InProgress & (( BitCounter>31 & BitCounter<46 ) | ( ( BitCounter == 0 ) & NoPre )); + + +// Generation of the MdoEn signal +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + begin + MdoEn_2d <= #Tp 1'b0; + MdoEn_d <= #Tp 1'b0; + MdoEn <= #Tp 1'b0; + end + else + begin + if(MdcEn_n) + begin + MdoEn_2d <= #Tp SerialEn | InProgress & BitCounter<32; + MdoEn_d <= #Tp MdoEn_2d; + MdoEn <= #Tp MdoEn_d; + end + end +end + + +// Generation of the Mdo signal. +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + begin + Mdo_2d <= #Tp 1'b0; + Mdo_d <= #Tp 1'b0; + Mdo <= #Tp 1'b0; + end + else + begin + if(MdcEn_n) + begin + Mdo_2d <= #Tp ~SerialEn & BitCounter<32; + Mdo_d <= #Tp ShiftedBit | Mdo_2d; + Mdo <= #Tp Mdo_d; + end + end +end + + + +endmodule diff --git a/ethernet/source/ethernet/eth_random.v b/ethernet/source/ethernet/eth_random.v new file mode 100644 index 0000000..6d103d9 --- /dev/null +++ b/ethernet/source/ethernet/eth_random.v @@ -0,0 +1,147 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_random.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// - Novan Hartadi (novan@vlsi.itb.ac.id) //// +//// - Mahmud Galela (mgalela@vlsi.itb.ac.id) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_random.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2003/06/13 11:26:08 mohor +// Binary operator used instead of unary (xnor). +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.3 2001/06/19 18:16:40 mohor +// TxClk changed to MTxClk (as discribed in the documentation). +// Crc changed so only one file can be used instead of two. +// +// Revision 1.2 2001/06/19 10:38:07 mohor +// Minor changes in header. +// +// Revision 1.1 2001/06/19 10:27:57 mohor +// TxEthMAC initial release. +// +// +// +// + +`include "timescale.v" + +module eth_random (MTxClk, Reset, StateJam, StateJam_q, RetryCnt, NibCnt, ByteCnt, + RandomEq0, RandomEqByteCnt); + +parameter Tp = 1; + +input MTxClk; +input Reset; +input StateJam; +input StateJam_q; +input [3:0] RetryCnt; +input [15:0] NibCnt; +input [9:0] ByteCnt; +output RandomEq0; +output RandomEqByteCnt; + +wire Feedback; +reg [9:0] x; +wire [9:0] Random; +reg [9:0] RandomLatched; + + +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + x[9:0] <= #Tp 0; + else + x[9:0] <= #Tp {x[8:0], Feedback}; +end + +assign Feedback = ~(x[2] ^ x[9]); + +assign Random [0] = x[0]; +assign Random [1] = (RetryCnt > 1) ? x[1] : 1'b0; +assign Random [2] = (RetryCnt > 2) ? x[2] : 1'b0; +assign Random [3] = (RetryCnt > 3) ? x[3] : 1'b0; +assign Random [4] = (RetryCnt > 4) ? x[4] : 1'b0; +assign Random [5] = (RetryCnt > 5) ? x[5] : 1'b0; +assign Random [6] = (RetryCnt > 6) ? x[6] : 1'b0; +assign Random [7] = (RetryCnt > 7) ? x[7] : 1'b0; +assign Random [8] = (RetryCnt > 8) ? x[8] : 1'b0; +assign Random [9] = (RetryCnt > 9) ? x[9] : 1'b0; + + +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + RandomLatched <= #Tp 10'h000; + else + begin + if(StateJam & StateJam_q) + RandomLatched <= #Tp Random; + end +end + +// Random Number == 0 IEEE 802.3 page 68. If 0 we go to defer and not to backoff. +assign RandomEq0 = RandomLatched == 10'h0; + +assign RandomEqByteCnt = ByteCnt[9:0] == RandomLatched & (&NibCnt[6:0]); + +endmodule diff --git a/ethernet/source/ethernet/eth_receivecontrol.v b/ethernet/source/ethernet/eth_receivecontrol.v new file mode 100644 index 0000000..f9b9c3d --- /dev/null +++ b/ethernet/source/ethernet/eth_receivecontrol.v @@ -0,0 +1,444 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_receivecontrol.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_receivecontrol.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.5 2003/01/22 13:49:26 tadejm +// When control packets were received, they were ignored in some cases. +// +// Revision 1.4 2002/11/22 01:57:06 mohor +// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort +// synchronized. +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.1 2001/07/03 12:51:54 mohor +// Initial release of the MAC Control module. +// +// +// +// +// + + +`include "timescale.v" + + +module eth_receivecontrol (MTxClk, MRxClk, TxReset, RxReset, RxData, RxValid, RxStartFrm, + RxEndFrm, RxFlow, ReceiveEnd, MAC, DlyCrcEn, TxDoneIn, + TxAbortIn, TxStartFrmOut, ReceivedLengthOK, ReceivedPacketGood, + TxUsedDataOutDetected, Pause, ReceivedPauseFrm, AddressOK, + RxStatusWriteLatched_sync2, r_PassAll, SetPauseTimer + ); + +parameter Tp = 1; + + +input MTxClk; +input MRxClk; +input TxReset; +input RxReset; +input [7:0] RxData; +input RxValid; +input RxStartFrm; +input RxEndFrm; +input RxFlow; +input ReceiveEnd; +input [47:0]MAC; +input DlyCrcEn; +input TxDoneIn; +input TxAbortIn; +input TxStartFrmOut; +input ReceivedLengthOK; +input ReceivedPacketGood; +input TxUsedDataOutDetected; +input RxStatusWriteLatched_sync2; +input r_PassAll; + +output Pause; +output ReceivedPauseFrm; +output AddressOK; +output SetPauseTimer; + + +reg Pause; +reg AddressOK; // Multicast or unicast address detected +reg TypeLengthOK; // Type/Length field contains 0x8808 +reg DetectionWindow; // Detection of the PAUSE frame is possible within this window +reg OpCodeOK; // PAUSE opcode detected (0x0001) +reg [2:0] DlyCrcCnt; +reg [4:0] ByteCnt; +reg [15:0] AssembledTimerValue; +reg [15:0] LatchedTimerValue; +reg ReceivedPauseFrm; +reg ReceivedPauseFrmWAddr; +reg PauseTimerEq0_sync1; +reg PauseTimerEq0_sync2; +reg [15:0] PauseTimer; +reg Divider2; +reg [5:0] SlotTimer; + +wire [47:0] ReservedMulticast; // 0x0180C2000001 +wire [15:0] TypeLength; // 0x8808 +wire ResetByteCnt; // +wire IncrementByteCnt; // +wire ByteCntEq0; // ByteCnt = 0 +wire ByteCntEq1; // ByteCnt = 1 +wire ByteCntEq2; // ByteCnt = 2 +wire ByteCntEq3; // ByteCnt = 3 +wire ByteCntEq4; // ByteCnt = 4 +wire ByteCntEq5; // ByteCnt = 5 +wire ByteCntEq12; // ByteCnt = 12 +wire ByteCntEq13; // ByteCnt = 13 +wire ByteCntEq14; // ByteCnt = 14 +wire ByteCntEq15; // ByteCnt = 15 +wire ByteCntEq16; // ByteCnt = 16 +wire ByteCntEq17; // ByteCnt = 17 +wire ByteCntEq18; // ByteCnt = 18 +wire DecrementPauseTimer; // +wire PauseTimerEq0; // +wire ResetSlotTimer; // +wire IncrementSlotTimer; // +wire SlotFinished; // + + + +// Reserved multicast address and Type/Length for PAUSE control +assign ReservedMulticast = 48'h0180C2000001; +assign TypeLength = 16'h8808; + + +// Address Detection (Multicast or unicast) +always @ (posedge MRxClk or posedge RxReset) +begin + if(RxReset) + AddressOK <= #Tp 1'b0; + else + if(DetectionWindow & ByteCntEq0) + AddressOK <= #Tp RxData[7:0] == ReservedMulticast[47:40] | RxData[7:0] == MAC[47:40]; + else + if(DetectionWindow & ByteCntEq1) + AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[39:32] | RxData[7:0] == MAC[39:32]) & AddressOK; + else + if(DetectionWindow & ByteCntEq2) + AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[31:24] | RxData[7:0] == MAC[31:24]) & AddressOK; + else + if(DetectionWindow & ByteCntEq3) + AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[23:16] | RxData[7:0] == MAC[23:16]) & AddressOK; + else + if(DetectionWindow & ByteCntEq4) + AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[15:8] | RxData[7:0] == MAC[15:8]) & AddressOK; + else + if(DetectionWindow & ByteCntEq5) + AddressOK <= #Tp (RxData[7:0] == ReservedMulticast[7:0] | RxData[7:0] == MAC[7:0]) & AddressOK; + else + if(ReceiveEnd) + AddressOK <= #Tp 1'b0; +end + + + +// TypeLengthOK (Type/Length Control frame detected) +always @ (posedge MRxClk or posedge RxReset ) +begin + if(RxReset) + TypeLengthOK <= #Tp 1'b0; + else + if(DetectionWindow & ByteCntEq12) + TypeLengthOK <= #Tp ByteCntEq12 & (RxData[7:0] == TypeLength[15:8]); + else + if(DetectionWindow & ByteCntEq13) + TypeLengthOK <= #Tp ByteCntEq13 & (RxData[7:0] == TypeLength[7:0]) & TypeLengthOK; + else + if(ReceiveEnd) + TypeLengthOK <= #Tp 1'b0; +end + + + +// Latch Control Frame Opcode +always @ (posedge MRxClk or posedge RxReset ) +begin + if(RxReset) + OpCodeOK <= #Tp 1'b0; + else + if(ByteCntEq16) + OpCodeOK <= #Tp 1'b0; + else + begin + if(DetectionWindow & ByteCntEq14) + OpCodeOK <= #Tp ByteCntEq14 & RxData[7:0] == 8'h00; + + if(DetectionWindow & ByteCntEq15) + OpCodeOK <= #Tp ByteCntEq15 & RxData[7:0] == 8'h01 & OpCodeOK; + end +end + + +// ReceivedPauseFrmWAddr (+Address Check) +always @ (posedge MRxClk or posedge RxReset ) +begin + if(RxReset) + ReceivedPauseFrmWAddr <= #Tp 1'b0; + else + if(ReceiveEnd) + ReceivedPauseFrmWAddr <= #Tp 1'b0; + else + if(ByteCntEq16 & TypeLengthOK & OpCodeOK & AddressOK) + ReceivedPauseFrmWAddr <= #Tp 1'b1; +end + + + +// Assembling 16-bit timer value from two 8-bit data +always @ (posedge MRxClk or posedge RxReset ) +begin + if(RxReset) + AssembledTimerValue[15:0] <= #Tp 16'h0; + else + if(RxStartFrm) + AssembledTimerValue[15:0] <= #Tp 16'h0; + else + begin + if(DetectionWindow & ByteCntEq16) + AssembledTimerValue[15:8] <= #Tp RxData[7:0]; + if(DetectionWindow & ByteCntEq17) + AssembledTimerValue[7:0] <= #Tp RxData[7:0]; + end +end + + +// Detection window (while PAUSE detection is possible) +always @ (posedge MRxClk or posedge RxReset ) +begin + if(RxReset) + DetectionWindow <= #Tp 1'b1; + else + if(ByteCntEq18) + DetectionWindow <= #Tp 1'b0; + else + if(ReceiveEnd) + DetectionWindow <= #Tp 1'b1; +end + + + +// Latching Timer Value +always @ (posedge MRxClk or posedge RxReset ) +begin + if(RxReset) + LatchedTimerValue[15:0] <= #Tp 16'h0; + else + if(DetectionWindow & ReceivedPauseFrmWAddr & ByteCntEq18) + LatchedTimerValue[15:0] <= #Tp AssembledTimerValue[15:0]; + else + if(ReceiveEnd) + LatchedTimerValue[15:0] <= #Tp 16'h0; +end + + + +// Delayed CEC counter +always @ (posedge MRxClk or posedge RxReset) +begin + if(RxReset) + DlyCrcCnt <= #Tp 3'h0; + else + if(RxValid & RxEndFrm) + DlyCrcCnt <= #Tp 3'h0; + else + if(RxValid & ~RxEndFrm & ~DlyCrcCnt[2]) + DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1; +end + + +assign ResetByteCnt = RxEndFrm; +assign IncrementByteCnt = RxValid & DetectionWindow & ~ByteCntEq18 & (~DlyCrcEn | DlyCrcEn & DlyCrcCnt[2]); + + +// Byte counter +always @ (posedge MRxClk or posedge RxReset) +begin + if(RxReset) + ByteCnt[4:0] <= #Tp 5'h0; + else + if(ResetByteCnt) + ByteCnt[4:0] <= #Tp 5'h0; + else + if(IncrementByteCnt) + ByteCnt[4:0] <= #Tp ByteCnt[4:0] + 1'b1; +end + + +assign ByteCntEq0 = RxValid & ByteCnt[4:0] == 5'h0; +assign ByteCntEq1 = RxValid & ByteCnt[4:0] == 5'h1; +assign ByteCntEq2 = RxValid & ByteCnt[4:0] == 5'h2; +assign ByteCntEq3 = RxValid & ByteCnt[4:0] == 5'h3; +assign ByteCntEq4 = RxValid & ByteCnt[4:0] == 5'h4; +assign ByteCntEq5 = RxValid & ByteCnt[4:0] == 5'h5; +assign ByteCntEq12 = RxValid & ByteCnt[4:0] == 5'h0C; +assign ByteCntEq13 = RxValid & ByteCnt[4:0] == 5'h0D; +assign ByteCntEq14 = RxValid & ByteCnt[4:0] == 5'h0E; +assign ByteCntEq15 = RxValid & ByteCnt[4:0] == 5'h0F; +assign ByteCntEq16 = RxValid & ByteCnt[4:0] == 5'h10; +assign ByteCntEq17 = RxValid & ByteCnt[4:0] == 5'h11; +assign ByteCntEq18 = RxValid & ByteCnt[4:0] == 5'h12 & DetectionWindow; + + +assign SetPauseTimer = ReceiveEnd & ReceivedPauseFrmWAddr & ReceivedPacketGood & ReceivedLengthOK & RxFlow; +assign DecrementPauseTimer = SlotFinished & |PauseTimer; + + +// PauseTimer[15:0] +always @ (posedge MRxClk or posedge RxReset) +begin + if(RxReset) + PauseTimer[15:0] <= #Tp 16'h0; + else + if(SetPauseTimer) + PauseTimer[15:0] <= #Tp LatchedTimerValue[15:0]; + else + if(DecrementPauseTimer) + PauseTimer[15:0] <= #Tp PauseTimer[15:0] - 1'b1; +end + +assign PauseTimerEq0 = ~(|PauseTimer[15:0]); + + + +// Synchronization of the pause timer +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + begin + PauseTimerEq0_sync1 <= #Tp 1'b1; + PauseTimerEq0_sync2 <= #Tp 1'b1; + end + else + begin + PauseTimerEq0_sync1 <= #Tp PauseTimerEq0; + PauseTimerEq0_sync2 <= #Tp PauseTimerEq0_sync1; + end +end + + +// Pause signal generation +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + Pause <= #Tp 1'b0; + else + if((TxDoneIn | TxAbortIn | ~TxUsedDataOutDetected) & ~TxStartFrmOut) + Pause <= #Tp RxFlow & ~PauseTimerEq0_sync2; +end + + +// Divider2 is used for incrementing the Slot timer every other clock +always @ (posedge MRxClk or posedge RxReset) +begin + if(RxReset) + Divider2 <= #Tp 1'b0; + else + if(|PauseTimer[15:0] & RxFlow) + Divider2 <= #Tp ~Divider2; + else + Divider2 <= #Tp 1'b0; +end + + +assign ResetSlotTimer = RxReset; +assign IncrementSlotTimer = Pause & RxFlow & Divider2; + + +// SlotTimer +always @ (posedge MRxClk or posedge RxReset) +begin + if(RxReset) + SlotTimer[5:0] <= #Tp 6'h0; + else + if(ResetSlotTimer) + SlotTimer[5:0] <= #Tp 6'h0; + else + if(IncrementSlotTimer) + SlotTimer[5:0] <= #Tp SlotTimer[5:0] + 1'b1; +end + + +assign SlotFinished = &SlotTimer[5:0] & IncrementSlotTimer; // Slot is 512 bits (64 bytes) + + + +// Pause Frame received +always @ (posedge MRxClk or posedge RxReset) +begin + if(RxReset) + ReceivedPauseFrm <=#Tp 1'b0; + else + if(RxStatusWriteLatched_sync2 & r_PassAll | ReceivedPauseFrm & (~r_PassAll)) + ReceivedPauseFrm <=#Tp 1'b0; + else + if(ByteCntEq16 & TypeLengthOK & OpCodeOK) + ReceivedPauseFrm <=#Tp 1'b1; +end + + +endmodule diff --git a/ethernet/source/ethernet/eth_register.v b/ethernet/source/ethernet/eth_register.v new file mode 100644 index 0000000..de496e4 --- /dev/null +++ b/ethernet/source/ethernet/eth_register.v @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_register.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_register.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2002/08/16 22:10:12 mohor +// Synchronous reset added. +// +// Revision 1.5 2002/08/16 12:33:27 mohor +// Parameter ResetValue changed to capital letters. +// +// Revision 1.4 2002/02/26 16:18:08 mohor +// Reset values are passed to registers through parameters +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// +// +// +// +// +// + +`include "timescale.v" + + +module eth_register(DataIn, DataOut, Write, Clk, Reset, SyncReset); + +parameter WIDTH = 8; // default parameter of the register width +parameter RESET_VALUE = 0; + +input [WIDTH-1:0] DataIn; + +input Write; +input Clk; +input Reset; +input SyncReset; + +output [WIDTH-1:0] DataOut; +reg [WIDTH-1:0] DataOut; + + + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + DataOut<=#1 RESET_VALUE; + else + if(SyncReset) + DataOut<=#1 RESET_VALUE; + else + if(Write) // write + DataOut<=#1 DataIn; +end + + + +endmodule // Register diff --git a/ethernet/source/ethernet/eth_registers.v b/ethernet/source/ethernet/eth_registers.v new file mode 100644 index 0000000..0775bbd --- /dev/null +++ b/ethernet/source/ethernet/eth_registers.v @@ -0,0 +1,1187 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_registers.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_registers.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.29 2005/03/21 20:07:18 igorm +// Some small fixes + some troubles fixed. +// +// Revision 1.28 2004/04/26 15:26:23 igorm +// - Bug connected to the TX_BD_NUM_Wr signal fixed (bug came in with the +// previous update of the core. +// - TxBDAddress is set to 0 after the TX is enabled in the MODER register. +// - RxBDAddress is set to r_TxBDNum<<1 after the RX is enabled in the MODER +// register. (thanks to Mathias and Torbjorn) +// - Multicast reception was fixed. Thanks to Ulrich Gries +// +// Revision 1.27 2004/04/26 11:42:17 igorm +// TX_BD_NUM_Wr error fixed. Error was entered with the last check-in. +// +// Revision 1.26 2003/11/12 18:24:59 tadejm +// WISHBONE slave changed and tested from only 32-bit accesss to byte access. +// +// Revision 1.25 2003/04/18 16:26:25 mohor +// RxBDAddress was updated also when value to r_TxBDNum was written with +// greater value than allowed. +// +// Revision 1.24 2002/11/22 01:57:06 mohor +// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort +// synchronized. +// +// Revision 1.23 2002/11/19 18:13:49 mohor +// r_MiiMRst is not used for resetting the MIIM module. wb_rst used instead. +// +// Revision 1.22 2002/11/14 18:37:20 mohor +// r_Rst signal does not reset any module any more and is removed from the design. +// +// Revision 1.21 2002/09/10 10:35:23 mohor +// Ethernet debug registers removed. +// +// Revision 1.20 2002/09/04 18:40:25 mohor +// ETH_TXCTRL and ETH_RXCTRL registers added. Interrupts related to +// the control frames connected. +// +// Revision 1.19 2002/08/19 16:01:40 mohor +// Only values smaller or equal to 0x80 can be written to TX_BD_NUM register. +// r_TxEn and r_RxEn depend on the limit values of the TX_BD_NUMOut. +// +// Revision 1.18 2002/08/16 22:28:23 mohor +// Syntax error fixed. +// +// Revision 1.17 2002/08/16 22:23:03 mohor +// Syntax error fixed. +// +// Revision 1.16 2002/08/16 22:14:22 mohor +// Synchronous reset added to all registers. Defines used for width. r_MiiMRst +// changed from bit position 10 to 9. +// +// Revision 1.15 2002/08/14 18:26:37 mohor +// LinkFailRegister is reflecting the status of the PHY's link fail status bit. +// +// Revision 1.14 2002/04/22 14:03:44 mohor +// Interrupts are visible in the ETH_INT_SOURCE regardless if they are enabled +// or not. +// +// Revision 1.13 2002/02/26 16:18:09 mohor +// Reset values are passed to registers through parameters +// +// Revision 1.12 2002/02/17 13:23:42 mohor +// Define missmatch fixed. +// +// Revision 1.11 2002/02/16 14:03:44 mohor +// Registered trimmed. Unused registers removed. +// +// Revision 1.10 2002/02/15 11:08:25 mohor +// File format fixed a bit. +// +// Revision 1.9 2002/02/14 20:19:41 billditt +// Modified for Address Checking, +// addition of eth_addrcheck.v +// +// Revision 1.8 2002/02/12 17:01:19 mohor +// HASH0 and HASH1 registers added. + +// Revision 1.7 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.6 2001/12/05 15:00:16 mohor +// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors +// instead of the number of RX descriptors). +// +// Revision 1.5 2001/12/05 10:22:19 mohor +// ETH_RX_BD_ADR register deleted. ETH_RX_BD_NUM is used instead. +// +// Revision 1.4 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.3 2001/10/18 12:07:11 mohor +// Status signals changed, Adress decoding changed, interrupt controller +// added. +// +// Revision 1.2 2001/09/24 15:02:56 mohor +// Defines changed (All precede with ETH_). Small changes because some +// tools generate warnings when two operands are together. Synchronization +// between two clocks domains in eth_wishbonedma.v is changed (due to ASIC +// demands). +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.2 2001/08/02 09:25:31 mohor +// Unconnected signals are now connected. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// +// +// +// +// + +`include "eth_defines.v" +`include "timescale.v" + + +module eth_registers( DataIn, Address, Rw, Cs, Clk, Reset, DataOut, + r_RecSmall, r_Pad, r_HugEn, r_CrcEn, r_DlyCrcEn, + r_FullD, r_ExDfrEn, r_NoBckof, r_LoopBck, r_IFG, + r_Pro, r_Iam, r_Bro, r_NoPre, r_TxEn, r_RxEn, + TxB_IRQ, TxE_IRQ, RxB_IRQ, RxE_IRQ, Busy_IRQ, + r_IPGT, r_IPGR1, r_IPGR2, r_MinFL, r_MaxFL, r_MaxRet, + r_CollValid, r_TxFlow, r_RxFlow, r_PassAll, + r_MiiNoPre, r_ClkDiv, r_WCtrlData, r_RStat, r_ScanStat, + r_RGAD, r_FIAD, r_CtrlData, NValid_stat, Busy_stat, + LinkFail, r_MAC, WCtrlDataStart, RStatStart, + UpdateMIIRX_DATAReg, Prsd, r_TxBDNum, int_o, + r_HASH0, r_HASH1, r_TxPauseTV, r_TxPauseRq, RstTxPauseRq, TxCtrlEndFrm, + StartTxDone, TxClk, RxClk, SetPauseTimer + ); + +parameter Tp = 1; + +input [31:0] DataIn; +input [7:0] Address; + +input Rw; +input [3:0] Cs; +input Clk; +input Reset; + +input WCtrlDataStart; +input RStatStart; + +input UpdateMIIRX_DATAReg; +input [15:0] Prsd; + +output [31:0] DataOut; +reg [31:0] DataOut; + +output r_RecSmall; +output r_Pad; +output r_HugEn; +output r_CrcEn; +output r_DlyCrcEn; +output r_FullD; +output r_ExDfrEn; +output r_NoBckof; +output r_LoopBck; +output r_IFG; +output r_Pro; +output r_Iam; +output r_Bro; +output r_NoPre; +output r_TxEn; +output r_RxEn; +output [31:0] r_HASH0; +output [31:0] r_HASH1; + +input TxB_IRQ; +input TxE_IRQ; +input RxB_IRQ; +input RxE_IRQ; +input Busy_IRQ; + +output [6:0] r_IPGT; + +output [6:0] r_IPGR1; + +output [6:0] r_IPGR2; + +output [15:0] r_MinFL; +output [15:0] r_MaxFL; + +output [3:0] r_MaxRet; +output [5:0] r_CollValid; + +output r_TxFlow; +output r_RxFlow; +output r_PassAll; + +output r_MiiNoPre; +output [7:0] r_ClkDiv; + +output r_WCtrlData; +output r_RStat; +output r_ScanStat; + +output [4:0] r_RGAD; +output [4:0] r_FIAD; + +output [15:0]r_CtrlData; + + +input NValid_stat; +input Busy_stat; +input LinkFail; + +output [47:0]r_MAC; +output [7:0] r_TxBDNum; +output int_o; +output [15:0]r_TxPauseTV; +output r_TxPauseRq; +input RstTxPauseRq; +input TxCtrlEndFrm; +input StartTxDone; +input TxClk; +input RxClk; +input SetPauseTimer; + +reg irq_txb; +reg irq_txe; +reg irq_rxb; +reg irq_rxe; +reg irq_busy; +reg irq_txc; +reg irq_rxc; + +reg SetTxCIrq_txclk; +reg SetTxCIrq_sync1, SetTxCIrq_sync2, SetTxCIrq_sync3; +reg SetTxCIrq; +reg ResetTxCIrq_sync1, ResetTxCIrq_sync2; + +reg SetRxCIrq_rxclk; +reg SetRxCIrq_sync1, SetRxCIrq_sync2, SetRxCIrq_sync3; +reg SetRxCIrq; +reg ResetRxCIrq_sync1; +reg ResetRxCIrq_sync2; +reg ResetRxCIrq_sync3; + +wire [3:0] Write = Cs & {4{Rw}}; +wire Read = (|Cs) & ~Rw; + +wire MODER_Sel = (Address == `ETH_MODER_ADR ); +wire INT_SOURCE_Sel = (Address == `ETH_INT_SOURCE_ADR ); +wire INT_MASK_Sel = (Address == `ETH_INT_MASK_ADR ); +wire IPGT_Sel = (Address == `ETH_IPGT_ADR ); +wire IPGR1_Sel = (Address == `ETH_IPGR1_ADR ); +wire IPGR2_Sel = (Address == `ETH_IPGR2_ADR ); +wire PACKETLEN_Sel = (Address == `ETH_PACKETLEN_ADR ); +wire COLLCONF_Sel = (Address == `ETH_COLLCONF_ADR ); + +wire CTRLMODER_Sel = (Address == `ETH_CTRLMODER_ADR ); +wire MIIMODER_Sel = (Address == `ETH_MIIMODER_ADR ); +wire MIICOMMAND_Sel = (Address == `ETH_MIICOMMAND_ADR ); +wire MIIADDRESS_Sel = (Address == `ETH_MIIADDRESS_ADR ); +wire MIITX_DATA_Sel = (Address == `ETH_MIITX_DATA_ADR ); +wire MAC_ADDR0_Sel = (Address == `ETH_MAC_ADDR0_ADR ); +wire MAC_ADDR1_Sel = (Address == `ETH_MAC_ADDR1_ADR ); +wire HASH0_Sel = (Address == `ETH_HASH0_ADR ); +wire HASH1_Sel = (Address == `ETH_HASH1_ADR ); +wire TXCTRL_Sel = (Address == `ETH_TX_CTRL_ADR ); +wire RXCTRL_Sel = (Address == `ETH_RX_CTRL_ADR ); +wire TX_BD_NUM_Sel = (Address == `ETH_TX_BD_NUM_ADR ); + + +wire [2:0] MODER_Wr; +wire [0:0] INT_SOURCE_Wr; +wire [0:0] INT_MASK_Wr; +wire [0:0] IPGT_Wr; +wire [0:0] IPGR1_Wr; +wire [0:0] IPGR2_Wr; +wire [3:0] PACKETLEN_Wr; +wire [2:0] COLLCONF_Wr; +wire [0:0] CTRLMODER_Wr; +wire [1:0] MIIMODER_Wr; +wire [0:0] MIICOMMAND_Wr; +wire [1:0] MIIADDRESS_Wr; +wire [1:0] MIITX_DATA_Wr; +wire MIIRX_DATA_Wr; +wire [3:0] MAC_ADDR0_Wr; +wire [1:0] MAC_ADDR1_Wr; +wire [3:0] HASH0_Wr; +wire [3:0] HASH1_Wr; +wire [2:0] TXCTRL_Wr; +wire [0:0] TX_BD_NUM_Wr; + +assign MODER_Wr[0] = Write[0] & MODER_Sel; +assign MODER_Wr[1] = Write[1] & MODER_Sel; +assign MODER_Wr[2] = Write[2] & MODER_Sel; +assign INT_SOURCE_Wr[0] = Write[0] & INT_SOURCE_Sel; +assign INT_MASK_Wr[0] = Write[0] & INT_MASK_Sel; +assign IPGT_Wr[0] = Write[0] & IPGT_Sel; +assign IPGR1_Wr[0] = Write[0] & IPGR1_Sel; +assign IPGR2_Wr[0] = Write[0] & IPGR2_Sel; +assign PACKETLEN_Wr[0] = Write[0] & PACKETLEN_Sel; +assign PACKETLEN_Wr[1] = Write[1] & PACKETLEN_Sel; +assign PACKETLEN_Wr[2] = Write[2] & PACKETLEN_Sel; +assign PACKETLEN_Wr[3] = Write[3] & PACKETLEN_Sel; +assign COLLCONF_Wr[0] = Write[0] & COLLCONF_Sel; +assign COLLCONF_Wr[1] = 1'b0; // Not used +assign COLLCONF_Wr[2] = Write[2] & COLLCONF_Sel; + +assign CTRLMODER_Wr[0] = Write[0] & CTRLMODER_Sel; +assign MIIMODER_Wr[0] = Write[0] & MIIMODER_Sel; +assign MIIMODER_Wr[1] = Write[1] & MIIMODER_Sel; +assign MIICOMMAND_Wr[0] = Write[0] & MIICOMMAND_Sel; +assign MIIADDRESS_Wr[0] = Write[0] & MIIADDRESS_Sel; +assign MIIADDRESS_Wr[1] = Write[1] & MIIADDRESS_Sel; +assign MIITX_DATA_Wr[0] = Write[0] & MIITX_DATA_Sel; +assign MIITX_DATA_Wr[1] = Write[1] & MIITX_DATA_Sel; +assign MIIRX_DATA_Wr = UpdateMIIRX_DATAReg; +assign MAC_ADDR0_Wr[0] = Write[0] & MAC_ADDR0_Sel; +assign MAC_ADDR0_Wr[1] = Write[1] & MAC_ADDR0_Sel; +assign MAC_ADDR0_Wr[2] = Write[2] & MAC_ADDR0_Sel; +assign MAC_ADDR0_Wr[3] = Write[3] & MAC_ADDR0_Sel; +assign MAC_ADDR1_Wr[0] = Write[0] & MAC_ADDR1_Sel; +assign MAC_ADDR1_Wr[1] = Write[1] & MAC_ADDR1_Sel; +assign HASH0_Wr[0] = Write[0] & HASH0_Sel; +assign HASH0_Wr[1] = Write[1] & HASH0_Sel; +assign HASH0_Wr[2] = Write[2] & HASH0_Sel; +assign HASH0_Wr[3] = Write[3] & HASH0_Sel; +assign HASH1_Wr[0] = Write[0] & HASH1_Sel; +assign HASH1_Wr[1] = Write[1] & HASH1_Sel; +assign HASH1_Wr[2] = Write[2] & HASH1_Sel; +assign HASH1_Wr[3] = Write[3] & HASH1_Sel; +assign TXCTRL_Wr[0] = Write[0] & TXCTRL_Sel; +assign TXCTRL_Wr[1] = Write[1] & TXCTRL_Sel; +assign TXCTRL_Wr[2] = Write[2] & TXCTRL_Sel; +assign TX_BD_NUM_Wr[0] = Write[0] & TX_BD_NUM_Sel & (DataIn<='h80); + + + +wire [31:0] MODEROut; +wire [31:0] INT_SOURCEOut; +wire [31:0] INT_MASKOut; +wire [31:0] IPGTOut; +wire [31:0] IPGR1Out; +wire [31:0] IPGR2Out; +wire [31:0] PACKETLENOut; +wire [31:0] COLLCONFOut; +wire [31:0] CTRLMODEROut; +wire [31:0] MIIMODEROut; +wire [31:0] MIICOMMANDOut; +wire [31:0] MIIADDRESSOut; +wire [31:0] MIITX_DATAOut; +wire [31:0] MIIRX_DATAOut; +wire [31:0] MIISTATUSOut; +wire [31:0] MAC_ADDR0Out; +wire [31:0] MAC_ADDR1Out; +wire [31:0] TX_BD_NUMOut; +wire [31:0] HASH0Out; +wire [31:0] HASH1Out; +wire [31:0] TXCTRLOut; + +// MODER Register +eth_register #(`ETH_MODER_WIDTH_0, `ETH_MODER_DEF_0) MODER_0 + ( + .DataIn (DataIn[`ETH_MODER_WIDTH_0 - 1:0]), + .DataOut (MODEROut[`ETH_MODER_WIDTH_0 - 1:0]), + .Write (MODER_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MODER_WIDTH_1, `ETH_MODER_DEF_1) MODER_1 + ( + .DataIn (DataIn[`ETH_MODER_WIDTH_1 + 7:8]), + .DataOut (MODEROut[`ETH_MODER_WIDTH_1 + 7:8]), + .Write (MODER_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MODER_WIDTH_2, `ETH_MODER_DEF_2) MODER_2 + ( + .DataIn (DataIn[`ETH_MODER_WIDTH_2 + 15:16]), + .DataOut (MODEROut[`ETH_MODER_WIDTH_2 + 15:16]), + .Write (MODER_Wr[2]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign MODEROut[31:`ETH_MODER_WIDTH_2 + 16] = 0; + +// INT_MASK Register +eth_register #(`ETH_INT_MASK_WIDTH_0, `ETH_INT_MASK_DEF_0) INT_MASK_0 + ( + .DataIn (DataIn[`ETH_INT_MASK_WIDTH_0 - 1:0]), + .DataOut (INT_MASKOut[`ETH_INT_MASK_WIDTH_0 - 1:0]), + .Write (INT_MASK_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign INT_MASKOut[31:`ETH_INT_MASK_WIDTH_0] = 0; + +// IPGT Register +eth_register #(`ETH_IPGT_WIDTH_0, `ETH_IPGT_DEF_0) IPGT_0 + ( + .DataIn (DataIn[`ETH_IPGT_WIDTH_0 - 1:0]), + .DataOut (IPGTOut[`ETH_IPGT_WIDTH_0 - 1:0]), + .Write (IPGT_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign IPGTOut[31:`ETH_IPGT_WIDTH_0] = 0; + +// IPGR1 Register +eth_register #(`ETH_IPGR1_WIDTH_0, `ETH_IPGR1_DEF_0) IPGR1_0 + ( + .DataIn (DataIn[`ETH_IPGR1_WIDTH_0 - 1:0]), + .DataOut (IPGR1Out[`ETH_IPGR1_WIDTH_0 - 1:0]), + .Write (IPGR1_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign IPGR1Out[31:`ETH_IPGR1_WIDTH_0] = 0; + +// IPGR2 Register +eth_register #(`ETH_IPGR2_WIDTH_0, `ETH_IPGR2_DEF_0) IPGR2_0 + ( + .DataIn (DataIn[`ETH_IPGR2_WIDTH_0 - 1:0]), + .DataOut (IPGR2Out[`ETH_IPGR2_WIDTH_0 - 1:0]), + .Write (IPGR2_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign IPGR2Out[31:`ETH_IPGR2_WIDTH_0] = 0; + +// PACKETLEN Register +eth_register #(`ETH_PACKETLEN_WIDTH_0, `ETH_PACKETLEN_DEF_0) PACKETLEN_0 + ( + .DataIn (DataIn[`ETH_PACKETLEN_WIDTH_0 - 1:0]), + .DataOut (PACKETLENOut[`ETH_PACKETLEN_WIDTH_0 - 1:0]), + .Write (PACKETLEN_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_PACKETLEN_WIDTH_1, `ETH_PACKETLEN_DEF_1) PACKETLEN_1 + ( + .DataIn (DataIn[`ETH_PACKETLEN_WIDTH_1 + 7:8]), + .DataOut (PACKETLENOut[`ETH_PACKETLEN_WIDTH_1 + 7:8]), + .Write (PACKETLEN_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_PACKETLEN_WIDTH_2, `ETH_PACKETLEN_DEF_2) PACKETLEN_2 + ( + .DataIn (DataIn[`ETH_PACKETLEN_WIDTH_2 + 15:16]), + .DataOut (PACKETLENOut[`ETH_PACKETLEN_WIDTH_2 + 15:16]), + .Write (PACKETLEN_Wr[2]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_PACKETLEN_WIDTH_3, `ETH_PACKETLEN_DEF_3) PACKETLEN_3 + ( + .DataIn (DataIn[`ETH_PACKETLEN_WIDTH_3 + 23:24]), + .DataOut (PACKETLENOut[`ETH_PACKETLEN_WIDTH_3 + 23:24]), + .Write (PACKETLEN_Wr[3]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); + +// COLLCONF Register +eth_register #(`ETH_COLLCONF_WIDTH_0, `ETH_COLLCONF_DEF_0) COLLCONF_0 + ( + .DataIn (DataIn[`ETH_COLLCONF_WIDTH_0 - 1:0]), + .DataOut (COLLCONFOut[`ETH_COLLCONF_WIDTH_0 - 1:0]), + .Write (COLLCONF_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_COLLCONF_WIDTH_2, `ETH_COLLCONF_DEF_2) COLLCONF_2 + ( + .DataIn (DataIn[`ETH_COLLCONF_WIDTH_2 + 15:16]), + .DataOut (COLLCONFOut[`ETH_COLLCONF_WIDTH_2 + 15:16]), + .Write (COLLCONF_Wr[2]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign COLLCONFOut[15:`ETH_COLLCONF_WIDTH_0] = 0; +assign COLLCONFOut[31:`ETH_COLLCONF_WIDTH_2 + 16] = 0; + +// TX_BD_NUM Register +eth_register #(`ETH_TX_BD_NUM_WIDTH_0, `ETH_TX_BD_NUM_DEF_0) TX_BD_NUM_0 + ( + .DataIn (DataIn[`ETH_TX_BD_NUM_WIDTH_0 - 1:0]), + .DataOut (TX_BD_NUMOut[`ETH_TX_BD_NUM_WIDTH_0 - 1:0]), + .Write (TX_BD_NUM_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign TX_BD_NUMOut[31:`ETH_TX_BD_NUM_WIDTH_0] = 0; + +// CTRLMODER Register +eth_register #(`ETH_CTRLMODER_WIDTH_0, `ETH_CTRLMODER_DEF_0) CTRLMODER_0 + ( + .DataIn (DataIn[`ETH_CTRLMODER_WIDTH_0 - 1:0]), + .DataOut (CTRLMODEROut[`ETH_CTRLMODER_WIDTH_0 - 1:0]), + .Write (CTRLMODER_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign CTRLMODEROut[31:`ETH_CTRLMODER_WIDTH_0] = 0; + +// MIIMODER Register +eth_register #(`ETH_MIIMODER_WIDTH_0, `ETH_MIIMODER_DEF_0) MIIMODER_0 + ( + .DataIn (DataIn[`ETH_MIIMODER_WIDTH_0 - 1:0]), + .DataOut (MIIMODEROut[`ETH_MIIMODER_WIDTH_0 - 1:0]), + .Write (MIIMODER_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MIIMODER_WIDTH_1, `ETH_MIIMODER_DEF_1) MIIMODER_1 + ( + .DataIn (DataIn[`ETH_MIIMODER_WIDTH_1 + 7:8]), + .DataOut (MIIMODEROut[`ETH_MIIMODER_WIDTH_1 + 7:8]), + .Write (MIIMODER_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign MIIMODEROut[31:`ETH_MIIMODER_WIDTH_1 + 8] = 0; + +// MIICOMMAND Register +eth_register #(1, 0) MIICOMMAND0 + ( + .DataIn (DataIn[0]), + .DataOut (MIICOMMANDOut[0]), + .Write (MIICOMMAND_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(1, 0) MIICOMMAND1 + ( + .DataIn (DataIn[1]), + .DataOut (MIICOMMANDOut[1]), + .Write (MIICOMMAND_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (RStatStart) + ); +eth_register #(1, 0) MIICOMMAND2 + ( + .DataIn (DataIn[2]), + .DataOut (MIICOMMANDOut[2]), + .Write (MIICOMMAND_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (WCtrlDataStart) + ); +assign MIICOMMANDOut[31:`ETH_MIICOMMAND_WIDTH_0] = 29'h0; + +// MIIADDRESSRegister +eth_register #(`ETH_MIIADDRESS_WIDTH_0, `ETH_MIIADDRESS_DEF_0) MIIADDRESS_0 + ( + .DataIn (DataIn[`ETH_MIIADDRESS_WIDTH_0 - 1:0]), + .DataOut (MIIADDRESSOut[`ETH_MIIADDRESS_WIDTH_0 - 1:0]), + .Write (MIIADDRESS_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MIIADDRESS_WIDTH_1, `ETH_MIIADDRESS_DEF_1) MIIADDRESS_1 + ( + .DataIn (DataIn[`ETH_MIIADDRESS_WIDTH_1 + 7:8]), + .DataOut (MIIADDRESSOut[`ETH_MIIADDRESS_WIDTH_1 + 7:8]), + .Write (MIIADDRESS_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign MIIADDRESSOut[7:`ETH_MIIADDRESS_WIDTH_0] = 0; +assign MIIADDRESSOut[31:`ETH_MIIADDRESS_WIDTH_1 + 8] = 0; + +// MIITX_DATA Register +eth_register #(`ETH_MIITX_DATA_WIDTH_0, `ETH_MIITX_DATA_DEF_0) MIITX_DATA_0 + ( + .DataIn (DataIn[`ETH_MIITX_DATA_WIDTH_0 - 1:0]), + .DataOut (MIITX_DATAOut[`ETH_MIITX_DATA_WIDTH_0 - 1:0]), + .Write (MIITX_DATA_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MIITX_DATA_WIDTH_1, `ETH_MIITX_DATA_DEF_1) MIITX_DATA_1 + ( + .DataIn (DataIn[`ETH_MIITX_DATA_WIDTH_1 + 7:8]), + .DataOut (MIITX_DATAOut[`ETH_MIITX_DATA_WIDTH_1 + 7:8]), + .Write (MIITX_DATA_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign MIITX_DATAOut[31:`ETH_MIITX_DATA_WIDTH_1 + 8] = 0; + +// MIIRX_DATA Register +eth_register #(`ETH_MIIRX_DATA_WIDTH, `ETH_MIIRX_DATA_DEF) MIIRX_DATA + ( + .DataIn (Prsd[`ETH_MIIRX_DATA_WIDTH-1:0]), + .DataOut (MIIRX_DATAOut[`ETH_MIIRX_DATA_WIDTH-1:0]), + .Write (MIIRX_DATA_Wr), // not written from WB + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign MIIRX_DATAOut[31:`ETH_MIIRX_DATA_WIDTH] = 0; + +// MAC_ADDR0 Register +eth_register #(`ETH_MAC_ADDR0_WIDTH_0, `ETH_MAC_ADDR0_DEF_0) MAC_ADDR0_0 + ( + .DataIn (DataIn[`ETH_MAC_ADDR0_WIDTH_0 - 1:0]), + .DataOut (MAC_ADDR0Out[`ETH_MAC_ADDR0_WIDTH_0 - 1:0]), + .Write (MAC_ADDR0_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MAC_ADDR0_WIDTH_1, `ETH_MAC_ADDR0_DEF_1) MAC_ADDR0_1 + ( + .DataIn (DataIn[`ETH_MAC_ADDR0_WIDTH_1 + 7:8]), + .DataOut (MAC_ADDR0Out[`ETH_MAC_ADDR0_WIDTH_1 + 7:8]), + .Write (MAC_ADDR0_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MAC_ADDR0_WIDTH_2, `ETH_MAC_ADDR0_DEF_2) MAC_ADDR0_2 + ( + .DataIn (DataIn[`ETH_MAC_ADDR0_WIDTH_2 + 15:16]), + .DataOut (MAC_ADDR0Out[`ETH_MAC_ADDR0_WIDTH_2 + 15:16]), + .Write (MAC_ADDR0_Wr[2]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MAC_ADDR0_WIDTH_3, `ETH_MAC_ADDR0_DEF_3) MAC_ADDR0_3 + ( + .DataIn (DataIn[`ETH_MAC_ADDR0_WIDTH_3 + 23:24]), + .DataOut (MAC_ADDR0Out[`ETH_MAC_ADDR0_WIDTH_3 + 23:24]), + .Write (MAC_ADDR0_Wr[3]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); + +// MAC_ADDR1 Register +eth_register #(`ETH_MAC_ADDR1_WIDTH_0, `ETH_MAC_ADDR1_DEF_0) MAC_ADDR1_0 + ( + .DataIn (DataIn[`ETH_MAC_ADDR1_WIDTH_0 - 1:0]), + .DataOut (MAC_ADDR1Out[`ETH_MAC_ADDR1_WIDTH_0 - 1:0]), + .Write (MAC_ADDR1_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_MAC_ADDR1_WIDTH_1, `ETH_MAC_ADDR1_DEF_1) MAC_ADDR1_1 + ( + .DataIn (DataIn[`ETH_MAC_ADDR1_WIDTH_1 + 7:8]), + .DataOut (MAC_ADDR1Out[`ETH_MAC_ADDR1_WIDTH_1 + 7:8]), + .Write (MAC_ADDR1_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +assign MAC_ADDR1Out[31:`ETH_MAC_ADDR1_WIDTH_1 + 8] = 0; + +// RXHASH0 Register +eth_register #(`ETH_HASH0_WIDTH_0, `ETH_HASH0_DEF_0) RXHASH0_0 + ( + .DataIn (DataIn[`ETH_HASH0_WIDTH_0 - 1:0]), + .DataOut (HASH0Out[`ETH_HASH0_WIDTH_0 - 1:0]), + .Write (HASH0_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_HASH0_WIDTH_1, `ETH_HASH0_DEF_1) RXHASH0_1 + ( + .DataIn (DataIn[`ETH_HASH0_WIDTH_1 + 7:8]), + .DataOut (HASH0Out[`ETH_HASH0_WIDTH_1 + 7:8]), + .Write (HASH0_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_HASH0_WIDTH_2, `ETH_HASH0_DEF_2) RXHASH0_2 + ( + .DataIn (DataIn[`ETH_HASH0_WIDTH_2 + 15:16]), + .DataOut (HASH0Out[`ETH_HASH0_WIDTH_2 + 15:16]), + .Write (HASH0_Wr[2]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_HASH0_WIDTH_3, `ETH_HASH0_DEF_3) RXHASH0_3 + ( + .DataIn (DataIn[`ETH_HASH0_WIDTH_3 + 23:24]), + .DataOut (HASH0Out[`ETH_HASH0_WIDTH_3 + 23:24]), + .Write (HASH0_Wr[3]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); + +// RXHASH1 Register +eth_register #(`ETH_HASH1_WIDTH_0, `ETH_HASH1_DEF_0) RXHASH1_0 + ( + .DataIn (DataIn[`ETH_HASH1_WIDTH_0 - 1:0]), + .DataOut (HASH1Out[`ETH_HASH1_WIDTH_0 - 1:0]), + .Write (HASH1_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_HASH1_WIDTH_1, `ETH_HASH1_DEF_1) RXHASH1_1 + ( + .DataIn (DataIn[`ETH_HASH1_WIDTH_1 + 7:8]), + .DataOut (HASH1Out[`ETH_HASH1_WIDTH_1 + 7:8]), + .Write (HASH1_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_HASH1_WIDTH_2, `ETH_HASH1_DEF_2) RXHASH1_2 + ( + .DataIn (DataIn[`ETH_HASH1_WIDTH_2 + 15:16]), + .DataOut (HASH1Out[`ETH_HASH1_WIDTH_2 + 15:16]), + .Write (HASH1_Wr[2]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_HASH1_WIDTH_3, `ETH_HASH1_DEF_3) RXHASH1_3 + ( + .DataIn (DataIn[`ETH_HASH1_WIDTH_3 + 23:24]), + .DataOut (HASH1Out[`ETH_HASH1_WIDTH_3 + 23:24]), + .Write (HASH1_Wr[3]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); + +// TXCTRL Register +eth_register #(`ETH_TX_CTRL_WIDTH_0, `ETH_TX_CTRL_DEF_0) TXCTRL_0 + ( + .DataIn (DataIn[`ETH_TX_CTRL_WIDTH_0 - 1:0]), + .DataOut (TXCTRLOut[`ETH_TX_CTRL_WIDTH_0 - 1:0]), + .Write (TXCTRL_Wr[0]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_TX_CTRL_WIDTH_1, `ETH_TX_CTRL_DEF_1) TXCTRL_1 + ( + .DataIn (DataIn[`ETH_TX_CTRL_WIDTH_1 + 7:8]), + .DataOut (TXCTRLOut[`ETH_TX_CTRL_WIDTH_1 + 7:8]), + .Write (TXCTRL_Wr[1]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (1'b0) + ); +eth_register #(`ETH_TX_CTRL_WIDTH_2, `ETH_TX_CTRL_DEF_2) TXCTRL_2 // Request bit is synchronously reset + ( + .DataIn (DataIn[`ETH_TX_CTRL_WIDTH_2 + 15:16]), + .DataOut (TXCTRLOut[`ETH_TX_CTRL_WIDTH_2 + 15:16]), + .Write (TXCTRL_Wr[2]), + .Clk (Clk), + .Reset (Reset), + .SyncReset (RstTxPauseRq) + ); +assign TXCTRLOut[31:`ETH_TX_CTRL_WIDTH_2 + 16] = 0; + + + +// Reading data from registers +always @ (Address or Read or MODEROut or INT_SOURCEOut or + INT_MASKOut or IPGTOut or IPGR1Out or IPGR2Out or + PACKETLENOut or COLLCONFOut or CTRLMODEROut or MIIMODEROut or + MIICOMMANDOut or MIIADDRESSOut or MIITX_DATAOut or MIIRX_DATAOut or + MIISTATUSOut or MAC_ADDR0Out or MAC_ADDR1Out or TX_BD_NUMOut or + HASH0Out or HASH1Out or TXCTRLOut + ) +begin + if(Read) // read + begin + case(Address) + `ETH_MODER_ADR : DataOut<=MODEROut; + `ETH_INT_SOURCE_ADR : DataOut<=INT_SOURCEOut; + `ETH_INT_MASK_ADR : DataOut<=INT_MASKOut; + `ETH_IPGT_ADR : DataOut<=IPGTOut; + `ETH_IPGR1_ADR : DataOut<=IPGR1Out; + `ETH_IPGR2_ADR : DataOut<=IPGR2Out; + `ETH_PACKETLEN_ADR : DataOut<=PACKETLENOut; + `ETH_COLLCONF_ADR : DataOut<=COLLCONFOut; + `ETH_CTRLMODER_ADR : DataOut<=CTRLMODEROut; + `ETH_MIIMODER_ADR : DataOut<=MIIMODEROut; + `ETH_MIICOMMAND_ADR : DataOut<=MIICOMMANDOut; + `ETH_MIIADDRESS_ADR : DataOut<=MIIADDRESSOut; + `ETH_MIITX_DATA_ADR : DataOut<=MIITX_DATAOut; + `ETH_MIIRX_DATA_ADR : DataOut<=MIIRX_DATAOut; + `ETH_MIISTATUS_ADR : DataOut<=MIISTATUSOut; + `ETH_MAC_ADDR0_ADR : DataOut<=MAC_ADDR0Out; + `ETH_MAC_ADDR1_ADR : DataOut<=MAC_ADDR1Out; + `ETH_TX_BD_NUM_ADR : DataOut<=TX_BD_NUMOut; + `ETH_HASH0_ADR : DataOut<=HASH0Out; + `ETH_HASH1_ADR : DataOut<=HASH1Out; + `ETH_TX_CTRL_ADR : DataOut<=TXCTRLOut; + + default: DataOut<=32'h0; + endcase + end + else + DataOut<=32'h0; +end + + +assign r_RecSmall = MODEROut[16]; +assign r_Pad = MODEROut[15]; +assign r_HugEn = MODEROut[14]; +assign r_CrcEn = MODEROut[13]; +assign r_DlyCrcEn = MODEROut[12]; +// assign r_Rst = MODEROut[11]; This signal is not used any more +assign r_FullD = MODEROut[10]; +assign r_ExDfrEn = MODEROut[9]; +assign r_NoBckof = MODEROut[8]; +assign r_LoopBck = MODEROut[7]; +assign r_IFG = MODEROut[6]; +assign r_Pro = MODEROut[5]; +assign r_Iam = MODEROut[4]; +assign r_Bro = MODEROut[3]; +assign r_NoPre = MODEROut[2]; +assign r_TxEn = MODEROut[1] & (TX_BD_NUMOut>0); // Transmission is enabled when there is at least one TxBD. +assign r_RxEn = MODEROut[0] & (TX_BD_NUMOut<'h80); // Reception is enabled when there is at least one RxBD. + +assign r_IPGT[6:0] = IPGTOut[6:0]; + +assign r_IPGR1[6:0] = IPGR1Out[6:0]; + +assign r_IPGR2[6:0] = IPGR2Out[6:0]; + +assign r_MinFL[15:0] = PACKETLENOut[31:16]; +assign r_MaxFL[15:0] = PACKETLENOut[15:0]; + +assign r_MaxRet[3:0] = COLLCONFOut[19:16]; +assign r_CollValid[5:0] = COLLCONFOut[5:0]; + +assign r_TxFlow = CTRLMODEROut[2]; +assign r_RxFlow = CTRLMODEROut[1]; +assign r_PassAll = CTRLMODEROut[0]; + +assign r_MiiNoPre = MIIMODEROut[8]; +assign r_ClkDiv[7:0] = MIIMODEROut[7:0]; + +assign r_WCtrlData = MIICOMMANDOut[2]; +assign r_RStat = MIICOMMANDOut[1]; +assign r_ScanStat = MIICOMMANDOut[0]; + +assign r_RGAD[4:0] = MIIADDRESSOut[12:8]; +assign r_FIAD[4:0] = MIIADDRESSOut[4:0]; + +assign r_CtrlData[15:0] = MIITX_DATAOut[15:0]; + +assign MIISTATUSOut[31:`ETH_MIISTATUS_WIDTH] = 0; +assign MIISTATUSOut[2] = NValid_stat ; +assign MIISTATUSOut[1] = Busy_stat ; +assign MIISTATUSOut[0] = LinkFail ; + +assign r_MAC[31:0] = MAC_ADDR0Out[31:0]; +assign r_MAC[47:32] = MAC_ADDR1Out[15:0]; +assign r_HASH1[31:0] = HASH1Out; +assign r_HASH0[31:0] = HASH0Out; + +assign r_TxBDNum[7:0] = TX_BD_NUMOut[7:0]; + +assign r_TxPauseTV[15:0] = TXCTRLOut[15:0]; +assign r_TxPauseRq = TXCTRLOut[16]; + + +// Synchronizing TxC Interrupt +always @ (posedge TxClk or posedge Reset) +begin + if(Reset) + SetTxCIrq_txclk <=#Tp 1'b0; + else + if(TxCtrlEndFrm & StartTxDone & r_TxFlow) + SetTxCIrq_txclk <=#Tp 1'b1; + else + if(ResetTxCIrq_sync2) + SetTxCIrq_txclk <=#Tp 1'b0; +end + + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + SetTxCIrq_sync1 <=#Tp 1'b0; + else + SetTxCIrq_sync1 <=#Tp SetTxCIrq_txclk; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + SetTxCIrq_sync2 <=#Tp 1'b0; + else + SetTxCIrq_sync2 <=#Tp SetTxCIrq_sync1; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + SetTxCIrq_sync3 <=#Tp 1'b0; + else + SetTxCIrq_sync3 <=#Tp SetTxCIrq_sync2; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + SetTxCIrq <=#Tp 1'b0; + else + SetTxCIrq <=#Tp SetTxCIrq_sync2 & ~SetTxCIrq_sync3; +end + +always @ (posedge TxClk or posedge Reset) +begin + if(Reset) + ResetTxCIrq_sync1 <=#Tp 1'b0; + else + ResetTxCIrq_sync1 <=#Tp SetTxCIrq_sync2; +end + +always @ (posedge TxClk or posedge Reset) +begin + if(Reset) + ResetTxCIrq_sync2 <=#Tp 1'b0; + else + ResetTxCIrq_sync2 <=#Tp SetTxCIrq_sync1; +end + + +// Synchronizing RxC Interrupt +always @ (posedge RxClk or posedge Reset) +begin + if(Reset) + SetRxCIrq_rxclk <=#Tp 1'b0; + else + if(SetPauseTimer & r_RxFlow) + SetRxCIrq_rxclk <=#Tp 1'b1; + else + if(ResetRxCIrq_sync2 & (~ResetRxCIrq_sync3)) + SetRxCIrq_rxclk <=#Tp 1'b0; +end + + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + SetRxCIrq_sync1 <=#Tp 1'b0; + else + SetRxCIrq_sync1 <=#Tp SetRxCIrq_rxclk; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + SetRxCIrq_sync2 <=#Tp 1'b0; + else + SetRxCIrq_sync2 <=#Tp SetRxCIrq_sync1; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + SetRxCIrq_sync3 <=#Tp 1'b0; + else + SetRxCIrq_sync3 <=#Tp SetRxCIrq_sync2; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + SetRxCIrq <=#Tp 1'b0; + else + SetRxCIrq <=#Tp SetRxCIrq_sync2 & ~SetRxCIrq_sync3; +end + +always @ (posedge RxClk or posedge Reset) +begin + if(Reset) + ResetRxCIrq_sync1 <=#Tp 1'b0; + else + ResetRxCIrq_sync1 <=#Tp SetRxCIrq_sync2; +end + +always @ (posedge RxClk or posedge Reset) +begin + if(Reset) + ResetRxCIrq_sync2 <=#Tp 1'b0; + else + ResetRxCIrq_sync2 <=#Tp ResetRxCIrq_sync1; +end + +always @ (posedge RxClk or posedge Reset) +begin + if(Reset) + ResetRxCIrq_sync3 <=#Tp 1'b0; + else + ResetRxCIrq_sync3 <=#Tp ResetRxCIrq_sync2; +end + + + +// Interrupt generation +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + irq_txb <= 1'b0; + else + if(TxB_IRQ) + irq_txb <= #Tp 1'b1; + else + if(INT_SOURCE_Wr[0] & DataIn[0]) + irq_txb <= #Tp 1'b0; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + irq_txe <= 1'b0; + else + if(TxE_IRQ) + irq_txe <= #Tp 1'b1; + else + if(INT_SOURCE_Wr[0] & DataIn[1]) + irq_txe <= #Tp 1'b0; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + irq_rxb <= 1'b0; + else + if(RxB_IRQ) + irq_rxb <= #Tp 1'b1; + else + if(INT_SOURCE_Wr[0] & DataIn[2]) + irq_rxb <= #Tp 1'b0; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + irq_rxe <= 1'b0; + else + if(RxE_IRQ) + irq_rxe <= #Tp 1'b1; + else + if(INT_SOURCE_Wr[0] & DataIn[3]) + irq_rxe <= #Tp 1'b0; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + irq_busy <= 1'b0; + else + if(Busy_IRQ) + irq_busy <= #Tp 1'b1; + else + if(INT_SOURCE_Wr[0] & DataIn[4]) + irq_busy <= #Tp 1'b0; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + irq_txc <= 1'b0; + else + if(SetTxCIrq) + irq_txc <= #Tp 1'b1; + else + if(INT_SOURCE_Wr[0] & DataIn[5]) + irq_txc <= #Tp 1'b0; +end + +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + irq_rxc <= 1'b0; + else + if(SetRxCIrq) + irq_rxc <= #Tp 1'b1; + else + if(INT_SOURCE_Wr[0] & DataIn[6]) + irq_rxc <= #Tp 1'b0; +end + +// Generating interrupt signal +assign int_o = irq_txb & INT_MASKOut[0] | + irq_txe & INT_MASKOut[1] | + irq_rxb & INT_MASKOut[2] | + irq_rxe & INT_MASKOut[3] | + irq_busy & INT_MASKOut[4] | + irq_txc & INT_MASKOut[5] | + irq_rxc & INT_MASKOut[6] ; + +// For reading interrupt status +assign INT_SOURCEOut = {{(32-`ETH_INT_SOURCE_WIDTH_0){1'b0}}, irq_rxc, irq_txc, irq_busy, irq_rxe, irq_rxb, irq_txe, irq_txb}; + + + +endmodule diff --git a/ethernet/source/ethernet/eth_rxaddrcheck.v b/ethernet/source/ethernet/eth_rxaddrcheck.v new file mode 100644 index 0000000..3dc3e0f --- /dev/null +++ b/ethernet/source/ethernet/eth_rxaddrcheck.v @@ -0,0 +1,214 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_rxaddrcheck.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/cores/ethmac/ //// +//// //// +//// Author(s): //// +//// - Bill Dittenhofer (billditt@aol.com) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_rxaddrcheck.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.9 2002/11/22 01:57:06 mohor +// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort +// synchronized. +// +// Revision 1.8 2002/11/19 17:34:52 mohor +// AddressMiss status is connecting to the Rx BD. AddressMiss is identifying +// that a frame was received because of the promiscous mode. +// +// Revision 1.7 2002/09/04 18:41:06 mohor +// Bug when last byte of destination address was not checked fixed. +// +// Revision 1.6 2002/03/20 15:14:11 mohor +// When in promiscous mode some frames were not received correctly. Fixed. +// +// Revision 1.5 2002/03/02 21:06:32 mohor +// Log info was missing. +// +// +// Revision 1.1 2002/02/08 12:51:54 ditt +// Initial release of the ethernet addresscheck module. +// +// +// +// +// + + +`include "timescale.v" + + +module eth_rxaddrcheck(MRxClk, Reset, RxData, Broadcast ,r_Bro ,r_Pro, + ByteCntEq2, ByteCntEq3, ByteCntEq4, ByteCntEq5, + ByteCntEq6, ByteCntEq7, HASH0, HASH1, + CrcHash, CrcHashGood, StateData, RxEndFrm, + Multicast, MAC, RxAbort, AddressMiss, PassAll, + ControlFrmAddressOK + ); + +parameter Tp = 1; + + input MRxClk; + input Reset; + input [7:0] RxData; + input Broadcast; + input r_Bro; + input r_Pro; + input ByteCntEq2; + input ByteCntEq3; + input ByteCntEq4; + input ByteCntEq5; + input ByteCntEq6; + input ByteCntEq7; + input [31:0] HASH0; + input [31:0] HASH1; + input [5:0] CrcHash; + input CrcHashGood; + input Multicast; + input [47:0] MAC; + input [1:0] StateData; + input RxEndFrm; + input PassAll; + input ControlFrmAddressOK; + + output RxAbort; + output AddressMiss; + + wire BroadcastOK; + wire ByteCntEq2; + wire ByteCntEq3; + wire ByteCntEq4; + wire ByteCntEq5; + wire RxAddressInvalid; + wire RxCheckEn; + wire HashBit; + wire [31:0] IntHash; + reg [7:0] ByteHash; + reg MulticastOK; + reg UnicastOK; + reg RxAbort; + reg AddressMiss; + +assign RxAddressInvalid = ~(UnicastOK | BroadcastOK | MulticastOK | r_Pro); + +assign BroadcastOK = Broadcast & ~r_Bro; + +assign RxCheckEn = | StateData; + + // Address Error Reported at end of address cycle + // RxAbort clears after one cycle + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxAbort <= #Tp 1'b0; + else if(RxAddressInvalid & ByteCntEq7 & RxCheckEn) + RxAbort <= #Tp 1'b1; + else + RxAbort <= #Tp 1'b0; +end + + +// This ff holds the "Address Miss" information that is written to the RX BD status. +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + AddressMiss <= #Tp 1'b0; + else if(ByteCntEq7 & RxCheckEn) + AddressMiss <= #Tp (~(UnicastOK | BroadcastOK | MulticastOK | (PassAll & ControlFrmAddressOK))); +end + + +// Hash Address Check, Multicast +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + MulticastOK <= #Tp 1'b0; + else if(RxEndFrm | RxAbort) + MulticastOK <= #Tp 1'b0; + else if(CrcHashGood & Multicast) + MulticastOK <= #Tp HashBit; +end + + +// Address Detection (unicast) +// start with ByteCntEq2 due to delay of addres from RxData +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + UnicastOK <= #Tp 1'b0; + else + if(RxCheckEn & ByteCntEq2) + UnicastOK <= #Tp RxData[7:0] == MAC[47:40]; + else + if(RxCheckEn & ByteCntEq3) + UnicastOK <= #Tp ( RxData[7:0] == MAC[39:32]) & UnicastOK; + else + if(RxCheckEn & ByteCntEq4) + UnicastOK <= #Tp ( RxData[7:0] == MAC[31:24]) & UnicastOK; + else + if(RxCheckEn & ByteCntEq5) + UnicastOK <= #Tp ( RxData[7:0] == MAC[23:16]) & UnicastOK; + else + if(RxCheckEn & ByteCntEq6) + UnicastOK <= #Tp ( RxData[7:0] == MAC[15:8]) & UnicastOK; + else + if(RxCheckEn & ByteCntEq7) + UnicastOK <= #Tp ( RxData[7:0] == MAC[7:0]) & UnicastOK; + else + if(RxEndFrm | RxAbort) + UnicastOK <= #Tp 1'b0; +end + +assign IntHash = (CrcHash[5])? HASH1 : HASH0; + +always@(CrcHash or IntHash) +begin + case(CrcHash[4:3]) + 2'b00: ByteHash = IntHash[7:0]; + 2'b01: ByteHash = IntHash[15:8]; + 2'b10: ByteHash = IntHash[23:16]; + 2'b11: ByteHash = IntHash[31:24]; + endcase +end + +assign HashBit = ByteHash[CrcHash[2:0]]; + + +endmodule diff --git a/ethernet/source/ethernet/eth_rxcounters.v b/ethernet/source/ethernet/eth_rxcounters.v new file mode 100644 index 0000000..285c7d4 --- /dev/null +++ b/ethernet/source/ethernet/eth_rxcounters.v @@ -0,0 +1,224 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_rxcounters.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// - Novan Hartadi (novan@vlsi.itb.ac.id) //// +//// - Mahmud Galela (mgalela@vlsi.itb.ac.id) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_rxcounters.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2005/02/21 11:00:57 igorm +// Delayed CRC fixed. +// +// Revision 1.5 2002/02/15 11:13:29 mohor +// Format of the file changed a bit. +// +// Revision 1.4 2002/02/14 20:19:41 billditt +// Modified for Address Checking, +// addition of eth_addrcheck.v +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.1 2001/06/27 21:26:19 mohor +// Initial release of the RxEthMAC module. +// +// +// +// +// +// + + +`include "timescale.v" + + +module eth_rxcounters (MRxClk, Reset, MRxDV, StateIdle, StateSFD, StateData, StateDrop, StatePreamble, + MRxDEqD, DlyCrcEn, DlyCrcCnt, Transmitting, MaxFL, r_IFG, HugEn, IFGCounterEq24, + ByteCntEq0, ByteCntEq1, ByteCntEq2,ByteCntEq3,ByteCntEq4,ByteCntEq5, ByteCntEq6, + ByteCntEq7, ByteCntGreat2, ByteCntSmall7, ByteCntMaxFrame, ByteCntOut + ); + +parameter Tp = 1; + +input MRxClk; +input Reset; +input MRxDV; +input StateSFD; +input [1:0] StateData; +input MRxDEqD; +input StateIdle; +input StateDrop; +input DlyCrcEn; +input StatePreamble; +input Transmitting; +input HugEn; +input [15:0] MaxFL; +input r_IFG; + +output IFGCounterEq24; // IFG counter reaches 9600 ns (960 ns) +output [3:0] DlyCrcCnt; // Delayed CRC counter +output ByteCntEq0; // Byte counter = 0 +output ByteCntEq1; // Byte counter = 1 +output ByteCntEq2; // Byte counter = 2 +output ByteCntEq3; // Byte counter = 3 +output ByteCntEq4; // Byte counter = 4 +output ByteCntEq5; // Byte counter = 5 +output ByteCntEq6; // Byte counter = 6 +output ByteCntEq7; // Byte counter = 7 +output ByteCntGreat2; // Byte counter > 2 +output ByteCntSmall7; // Byte counter < 7 +output ByteCntMaxFrame; // Byte counter = MaxFL +output [15:0] ByteCntOut; // Byte counter + +wire ResetByteCounter; +wire IncrementByteCounter; +wire ResetIFGCounter; +wire IncrementIFGCounter; +wire ByteCntMax; + +reg [15:0] ByteCnt; +reg [3:0] DlyCrcCnt; +reg [4:0] IFGCounter; + +wire [15:0] ByteCntDelayed; + + + +assign ResetByteCounter = MRxDV & (StateSFD & MRxDEqD | StateData[0] & ByteCntMaxFrame); + +assign IncrementByteCounter = ~ResetByteCounter & MRxDV & + (StatePreamble | StateSFD | StateIdle & ~Transmitting | + StateData[1] & ~ByteCntMax & ~(DlyCrcEn & |DlyCrcCnt) + ); + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + ByteCnt[15:0] <= #Tp 16'h0; + else + begin + if(ResetByteCounter) + ByteCnt[15:0] <= #Tp 16'h0; + else + if(IncrementByteCounter) + ByteCnt[15:0] <= #Tp ByteCnt[15:0] + 1'b1; + end +end + +assign ByteCntDelayed = ByteCnt + 3'h4; +assign ByteCntOut = DlyCrcEn? ByteCntDelayed : ByteCnt; + +assign ByteCntEq0 = ByteCnt == 16'h0; +assign ByteCntEq1 = ByteCnt == 16'h1; +assign ByteCntEq2 = ByteCnt == 16'h2; +assign ByteCntEq3 = ByteCnt == 16'h3; +assign ByteCntEq4 = ByteCnt == 16'h4; +assign ByteCntEq5 = ByteCnt == 16'h5; +assign ByteCntEq6 = ByteCnt == 16'h6; +assign ByteCntEq7 = ByteCnt == 16'h7; +assign ByteCntGreat2 = ByteCnt > 16'h2; +assign ByteCntSmall7 = ByteCnt < 16'h7; +assign ByteCntMax = ByteCnt == 16'hffff; +assign ByteCntMaxFrame = ByteCnt == MaxFL[15:0] & ~HugEn; + + +assign ResetIFGCounter = StateSFD & MRxDV & MRxDEqD | StateDrop; + +assign IncrementIFGCounter = ~ResetIFGCounter & (StateDrop | StateIdle | StatePreamble | StateSFD) & ~IFGCounterEq24; + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + IFGCounter[4:0] <= #Tp 5'h0; + else + begin + if(ResetIFGCounter) + IFGCounter[4:0] <= #Tp 5'h0; + else + if(IncrementIFGCounter) + IFGCounter[4:0] <= #Tp IFGCounter[4:0] + 1'b1; + end +end + + + +assign IFGCounterEq24 = (IFGCounter[4:0] == 5'h18) | r_IFG; // 24*400 = 9600 ns or r_IFG is set to 1 + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + DlyCrcCnt[3:0] <= #Tp 4'h0; + else + begin + if(DlyCrcCnt[3:0] == 4'h9) + DlyCrcCnt[3:0] <= #Tp 4'h0; + else + if(DlyCrcEn & StateSFD) + DlyCrcCnt[3:0] <= #Tp 4'h1; + else + if(DlyCrcEn & (|DlyCrcCnt[3:0])) + DlyCrcCnt[3:0] <= #Tp DlyCrcCnt[3:0] + 1'b1; + end +end + + +endmodule diff --git a/ethernet/source/ethernet/eth_rxethmac.v b/ethernet/source/ethernet/eth_rxethmac.v new file mode 100644 index 0000000..ec7e520 --- /dev/null +++ b/ethernet/source/ethernet/eth_rxethmac.v @@ -0,0 +1,383 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_rxethmac.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// - Novan Hartadi (novan@vlsi.itb.ac.id) //// +//// - Mahmud Galela (mgalela@vlsi.itb.ac.id) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_rxethmac.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.13 2005/02/21 12:48:07 igorm +// Warning fixes. +// +// Revision 1.12 2004/04/26 15:26:23 igorm +// - Bug connected to the TX_BD_NUM_Wr signal fixed (bug came in with the +// previous update of the core. +// - TxBDAddress is set to 0 after the TX is enabled in the MODER register. +// - RxBDAddress is set to r_TxBDNum<<1 after the RX is enabled in the MODER +// register. (thanks to Mathias and Torbjorn) +// - Multicast reception was fixed. Thanks to Ulrich Gries +// +// Revision 1.11 2004/03/17 09:32:15 igorm +// Multicast detection fixed. Only the LSB of the first byte is checked. +// +// Revision 1.10 2002/11/22 01:57:06 mohor +// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort +// synchronized. +// +// Revision 1.9 2002/11/19 17:35:35 mohor +// AddressMiss status is connecting to the Rx BD. AddressMiss is identifying +// that a frame was received because of the promiscous mode. +// +// Revision 1.8 2002/02/16 07:15:27 mohor +// Testbench fixed, code simplified, unused signals removed. +// +// Revision 1.7 2002/02/15 13:44:28 mohor +// RxAbort is an output. No need to have is declared as wire. +// +// Revision 1.6 2002/02/15 11:17:48 mohor +// File format changed. +// +// Revision 1.5 2002/02/14 20:48:43 billditt +// Addition of new module eth_addrcheck.v +// +// Revision 1.4 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.3 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.2 2001/09/11 14:17:00 mohor +// Few little NCSIM warnings fixed. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.1 2001/06/27 21:26:19 mohor +// Initial release of the RxEthMAC module. +// +// +// +// +// + +`include "timescale.v" + + +module eth_rxethmac (MRxClk, MRxDV, MRxD, Reset, Transmitting, MaxFL, r_IFG, HugEn, DlyCrcEn, + RxData, RxValid, RxStartFrm, RxEndFrm, ByteCnt, ByteCntEq0, ByteCntGreat2, + ByteCntMaxFrame, CrcError, StateIdle, StatePreamble, StateSFD, StateData, + MAC, r_Pro, r_Bro,r_HASH0, r_HASH1, RxAbort, AddressMiss, PassAll, ControlFrmAddressOK + ); + +parameter Tp = 1; + + + +input MRxClk; +input MRxDV; +input [3:0] MRxD; +input Transmitting; +input HugEn; +input DlyCrcEn; +input [15:0] MaxFL; +input r_IFG; +input Reset; +input [47:0] MAC; // Station Address +input r_Bro; // broadcast disable +input r_Pro; // promiscuous enable +input [31:0] r_HASH0; // lower 4 bytes Hash Table +input [31:0] r_HASH1; // upper 4 bytes Hash Table +input PassAll; +input ControlFrmAddressOK; + +output [7:0] RxData; +output RxValid; +output RxStartFrm; +output RxEndFrm; +output [15:0] ByteCnt; +output ByteCntEq0; +output ByteCntGreat2; +output ByteCntMaxFrame; +output CrcError; +output StateIdle; +output StatePreamble; +output StateSFD; +output [1:0] StateData; +output RxAbort; +output AddressMiss; + +reg [7:0] RxData; +reg RxValid; +reg RxStartFrm; +reg RxEndFrm; +reg Broadcast; +reg Multicast; +reg [5:0] CrcHash; +reg CrcHashGood; +reg DelayData; +reg [7:0] LatchedByte; +reg [7:0] RxData_d; +reg RxValid_d; +reg RxStartFrm_d; +reg RxEndFrm_d; + +wire MRxDEqD; +wire MRxDEq5; +wire StateDrop; +wire ByteCntEq1; +wire ByteCntEq2; +wire ByteCntEq3; +wire ByteCntEq4; +wire ByteCntEq5; +wire ByteCntEq6; +wire ByteCntEq7; +wire ByteCntSmall7; +wire [31:0] Crc; +wire Enable_Crc; +wire Initialize_Crc; +wire [3:0] Data_Crc; +wire GenerateRxValid; +wire GenerateRxStartFrm; +wire GenerateRxEndFrm; +wire DribbleRxEndFrm; +wire [3:0] DlyCrcCnt; +wire IFGCounterEq24; + +assign MRxDEqD = MRxD == 4'hd; +assign MRxDEq5 = MRxD == 4'h5; + + +// Rx State Machine module +eth_rxstatem rxstatem1 (.MRxClk(MRxClk), .Reset(Reset), .MRxDV(MRxDV), .ByteCntEq0(ByteCntEq0), + .ByteCntGreat2(ByteCntGreat2), .Transmitting(Transmitting), .MRxDEq5(MRxDEq5), + .MRxDEqD(MRxDEqD), .IFGCounterEq24(IFGCounterEq24), .ByteCntMaxFrame(ByteCntMaxFrame), + .StateData(StateData), .StateIdle(StateIdle), .StatePreamble(StatePreamble), + .StateSFD(StateSFD), .StateDrop(StateDrop) + ); + + +// Rx Counters module +eth_rxcounters rxcounters1 (.MRxClk(MRxClk), .Reset(Reset), .MRxDV(MRxDV), .StateIdle(StateIdle), + .StateSFD(StateSFD), .StateData(StateData), .StateDrop(StateDrop), + .StatePreamble(StatePreamble), .MRxDEqD(MRxDEqD), .DlyCrcEn(DlyCrcEn), + .DlyCrcCnt(DlyCrcCnt), .Transmitting(Transmitting), .MaxFL(MaxFL), .r_IFG(r_IFG), + .HugEn(HugEn), .IFGCounterEq24(IFGCounterEq24), .ByteCntEq0(ByteCntEq0), + .ByteCntEq1(ByteCntEq1), .ByteCntEq2(ByteCntEq2), .ByteCntEq3(ByteCntEq3), + .ByteCntEq4(ByteCntEq4), .ByteCntEq5(ByteCntEq5), .ByteCntEq6(ByteCntEq6), + .ByteCntEq7(ByteCntEq7), .ByteCntGreat2(ByteCntGreat2), + .ByteCntSmall7(ByteCntSmall7), .ByteCntMaxFrame(ByteCntMaxFrame), + .ByteCntOut(ByteCnt) + ); + +// Rx Address Check + +eth_rxaddrcheck rxaddrcheck1 + (.MRxClk(MRxClk), .Reset( Reset), .RxData(RxData), + .Broadcast (Broadcast), .r_Bro (r_Bro), .r_Pro(r_Pro), + .ByteCntEq6(ByteCntEq6), .ByteCntEq7(ByteCntEq7), .ByteCntEq2(ByteCntEq2), + .ByteCntEq3(ByteCntEq3), .ByteCntEq4(ByteCntEq4), .ByteCntEq5(ByteCntEq5), + .HASH0(r_HASH0), .HASH1(r_HASH1), + .CrcHash(CrcHash), .CrcHashGood(CrcHashGood), .StateData(StateData), + .Multicast(Multicast), .MAC(MAC), .RxAbort(RxAbort), + .RxEndFrm(RxEndFrm), .AddressMiss(AddressMiss), .PassAll(PassAll), + .ControlFrmAddressOK(ControlFrmAddressOK) + ); + + +assign Enable_Crc = MRxDV & (|StateData & ~ByteCntMaxFrame); +assign Initialize_Crc = StateSFD | DlyCrcEn & (|DlyCrcCnt[3:0]) & DlyCrcCnt[3:0] < 4'h9; + +assign Data_Crc[0] = MRxD[3]; +assign Data_Crc[1] = MRxD[2]; +assign Data_Crc[2] = MRxD[1]; +assign Data_Crc[3] = MRxD[0]; + + +// Connecting module Crc +eth_crc crcrx (.Clk(MRxClk), .Reset(Reset), .Data(Data_Crc), .Enable(Enable_Crc), .Initialize(Initialize_Crc), + .Crc(Crc), .CrcError(CrcError) + ); + + + +// Latching CRC for use in the hash table + +always @ (posedge MRxClk) +begin + CrcHashGood <= #Tp StateData[0] & ByteCntEq6; +end + +always @ (posedge MRxClk) +begin + if(Reset | StateIdle) + CrcHash[5:0] <= #Tp 6'h0; + else + if(StateData[0] & ByteCntEq6) + CrcHash[5:0] <= #Tp Crc[31:26]; +end + + +// Output byte stream +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + begin + RxData_d[7:0] <= #Tp 8'h0; + DelayData <= #Tp 1'b0; + LatchedByte[7:0] <= #Tp 8'h0; + RxData[7:0] <= #Tp 8'h0; + end + else + begin + LatchedByte[7:0] <= #Tp {MRxD[3:0], LatchedByte[7:4]}; // Latched byte + DelayData <= #Tp StateData[0]; + + if(GenerateRxValid) + RxData_d[7:0] <= #Tp LatchedByte[7:0] & {8{|StateData}}; // Data goes through only in data state + else + if(~DelayData) + RxData_d[7:0] <= #Tp 8'h0; // Delaying data to be valid for two cycles. Zero when not active. + + RxData[7:0] <= #Tp RxData_d[7:0]; // Output data byte + end +end + + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + Broadcast <= #Tp 1'b0; + else + begin + if(StateData[0] & ~(&LatchedByte[7:0]) & ByteCntSmall7) + Broadcast <= #Tp 1'b0; + else + if(StateData[0] & (&LatchedByte[7:0]) & ByteCntEq1) + Broadcast <= #Tp 1'b1; + else + if(RxAbort | RxEndFrm) + Broadcast <= #Tp 1'b0; + end +end + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + Multicast <= #Tp 1'b0; + else + begin + if(StateData[0] & ByteCntEq1 & LatchedByte[0]) + Multicast <= #Tp 1'b1; + else if(RxAbort | RxEndFrm) + Multicast <= #Tp 1'b0; + end +end + + +assign GenerateRxValid = StateData[0] & (~ByteCntEq0 | DlyCrcCnt >= 4'h3); + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + begin + RxValid_d <= #Tp 1'b0; + RxValid <= #Tp 1'b0; + end + else + begin + RxValid_d <= #Tp GenerateRxValid; + RxValid <= #Tp RxValid_d; + end +end + + +assign GenerateRxStartFrm = StateData[0] & (ByteCntEq1 & ~DlyCrcEn | DlyCrcCnt == 4'h3 & DlyCrcEn); + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + begin + RxStartFrm_d <= #Tp 1'b0; + RxStartFrm <= #Tp 1'b0; + end + else + begin + RxStartFrm_d <= #Tp GenerateRxStartFrm; + RxStartFrm <= #Tp RxStartFrm_d; + end +end + + +assign GenerateRxEndFrm = StateData[0] & (~MRxDV & ByteCntGreat2 | ByteCntMaxFrame); +assign DribbleRxEndFrm = StateData[1] & ~MRxDV & ByteCntGreat2; + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + begin + RxEndFrm_d <= #Tp 1'b0; + RxEndFrm <= #Tp 1'b0; + end + else + begin + RxEndFrm_d <= #Tp GenerateRxEndFrm; + RxEndFrm <= #Tp RxEndFrm_d | DribbleRxEndFrm; + end +end + + +endmodule diff --git a/ethernet/source/ethernet/eth_rxstatem.v b/ethernet/source/ethernet/eth_rxstatem.v new file mode 100644 index 0000000..e529719 --- /dev/null +++ b/ethernet/source/ethernet/eth_rxstatem.v @@ -0,0 +1,203 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_rxstatem.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// - Novan Hartadi (novan@vlsi.itb.ac.id) //// +//// - Mahmud Galela (mgalela@vlsi.itb.ac.id) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_rxstatem.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2002/11/13 22:28:26 tadejm +// StartIdle state changed (not important the size of the packet). +// StartData1 activates only while ByteCnt is smaller than the MaxFrame. +// +// Revision 1.5 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.4 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.3 2001/10/18 12:07:11 mohor +// Status signals changed, Adress decoding changed, interrupt controller +// added. +// +// Revision 1.2 2001/09/11 14:17:00 mohor +// Few little NCSIM warnings fixed. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.2 2001/07/03 12:55:41 mohor +// Minor changes because of the synthesys warnings. +// +// +// Revision 1.1 2001/06/27 21:26:19 mohor +// Initial release of the RxEthMAC module. +// +// +// +// + + +`include "timescale.v" + + +module eth_rxstatem (MRxClk, Reset, MRxDV, ByteCntEq0, ByteCntGreat2, Transmitting, MRxDEq5, MRxDEqD, + IFGCounterEq24, ByteCntMaxFrame, StateData, StateIdle, StatePreamble, StateSFD, + StateDrop + ); + +parameter Tp = 1; + +input MRxClk; +input Reset; +input MRxDV; +input ByteCntEq0; +input ByteCntGreat2; +input MRxDEq5; +input Transmitting; +input MRxDEqD; +input IFGCounterEq24; +input ByteCntMaxFrame; + +output [1:0] StateData; +output StateIdle; +output StateDrop; +output StatePreamble; +output StateSFD; + +reg StateData0; +reg StateData1; +reg StateIdle; +reg StateDrop; +reg StatePreamble; +reg StateSFD; + +wire StartIdle; +wire StartDrop; +wire StartData0; +wire StartData1; +wire StartPreamble; +wire StartSFD; + + +// Defining the next state +assign StartIdle = ~MRxDV & (StateDrop | StatePreamble | StateSFD | (|StateData)); + +assign StartPreamble = MRxDV & ~MRxDEq5 & (StateIdle & ~Transmitting); + +assign StartSFD = MRxDV & MRxDEq5 & (StateIdle & ~Transmitting | StatePreamble); + +assign StartData0 = MRxDV & (StateSFD & MRxDEqD & IFGCounterEq24 | StateData1); + +assign StartData1 = MRxDV & StateData0 & (~ByteCntMaxFrame); + +assign StartDrop = MRxDV & (StateIdle & Transmitting | StateSFD & ~IFGCounterEq24 & MRxDEqD + | StateData0 & ByteCntMaxFrame + ); + +// Rx State Machine +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + begin + StateIdle <= #Tp 1'b0; + StateDrop <= #Tp 1'b1; + StatePreamble <= #Tp 1'b0; + StateSFD <= #Tp 1'b0; + StateData0 <= #Tp 1'b0; + StateData1 <= #Tp 1'b0; + end + else + begin + if(StartPreamble | StartSFD | StartDrop) + StateIdle <= #Tp 1'b0; + else + if(StartIdle) + StateIdle <= #Tp 1'b1; + + if(StartIdle) + StateDrop <= #Tp 1'b0; + else + if(StartDrop) + StateDrop <= #Tp 1'b1; + + if(StartSFD | StartIdle | StartDrop) + StatePreamble <= #Tp 1'b0; + else + if(StartPreamble) + StatePreamble <= #Tp 1'b1; + + if(StartPreamble | StartIdle | StartData0 | StartDrop) + StateSFD <= #Tp 1'b0; + else + if(StartSFD) + StateSFD <= #Tp 1'b1; + + if(StartIdle | StartData1 | StartDrop) + StateData0 <= #Tp 1'b0; + else + if(StartData0) + StateData0 <= #Tp 1'b1; + + if(StartIdle | StartData0 | StartDrop) + StateData1 <= #Tp 1'b0; + else + if(StartData1) + StateData1 <= #Tp 1'b1; + end +end + +assign StateData[1:0] = {StateData1, StateData0}; + +endmodule diff --git a/ethernet/source/ethernet/eth_shiftreg.v b/ethernet/source/ethernet/eth_shiftreg.v new file mode 100644 index 0000000..167513b --- /dev/null +++ b/ethernet/source/ethernet/eth_shiftreg.v @@ -0,0 +1,157 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_shiftreg.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_shiftreg.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2005/03/08 14:45:09 igorm +// Case statement improved for synthesys. +// +// Revision 1.5 2002/08/14 18:16:59 mohor +// LinkFail signal was not latching appropriate bit. +// +// Revision 1.4 2002/03/02 21:06:01 mohor +// LinkFail signal was not latching appropriate bit. +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.3 2001/06/01 22:28:56 mohor +// This files (MIIM) are fully working. They were thoroughly tested. The testbench is not updated. +// +// + +`include "timescale.v" + + +module eth_shiftreg(Clk, Reset, MdcEn_n, Mdi, Fiad, Rgad, CtrlData, WriteOp, ByteSelect, + LatchByte, ShiftedBit, Prsd, LinkFail); + + +parameter Tp=1; + +input Clk; // Input clock (Host clock) +input Reset; // Reset signal +input MdcEn_n; // Enable signal is asserted for one Clk period before Mdc falls. +input Mdi; // MII input data +input [4:0] Fiad; // PHY address +input [4:0] Rgad; // Register address (within the selected PHY) +input [15:0]CtrlData; // Control data (data to be written to the PHY) +input WriteOp; // The current operation is a PHY register write operation +input [3:0] ByteSelect; // Byte select +input [1:0] LatchByte; // Byte select for latching (read operation) + +output ShiftedBit; // Bit shifted out of the shift register +output[15:0]Prsd; // Read Status Data (data read from the PHY) +output LinkFail; // Link Integrity Signal + +reg [7:0] ShiftReg; // Shift register for shifting the data in and out +reg [15:0]Prsd; +reg LinkFail; + + + + +// ShiftReg[7:0] :: Shift Register Data +always @ (posedge Clk or posedge Reset) +begin + if(Reset) + begin + ShiftReg[7:0] <= #Tp 8'h0; + Prsd[15:0] <= #Tp 16'h0; + LinkFail <= #Tp 1'b0; + end + else + begin + if(MdcEn_n) + begin + if(|ByteSelect) + begin + case (ByteSelect[3:0]) // synopsys parallel_case full_case + 4'h1 : ShiftReg[7:0] <= #Tp {2'b01, ~WriteOp, WriteOp, Fiad[4:1]}; + 4'h2 : ShiftReg[7:0] <= #Tp {Fiad[0], Rgad[4:0], 2'b10}; + 4'h4 : ShiftReg[7:0] <= #Tp CtrlData[15:8]; + 4'h8 : ShiftReg[7:0] <= #Tp CtrlData[7:0]; + endcase + end + else + begin + ShiftReg[7:0] <= #Tp {ShiftReg[6:0], Mdi}; + if(LatchByte[0]) + begin + Prsd[7:0] <= #Tp {ShiftReg[6:0], Mdi}; + if(Rgad == 5'h01) + LinkFail <= #Tp ~ShiftReg[1]; // this is bit [2], because it is not shifted yet + end + else + begin + if(LatchByte[1]) + Prsd[15:8] <= #Tp {ShiftReg[6:0], Mdi}; + end + end + end + end +end + + +assign ShiftedBit = ShiftReg[7]; + + +endmodule diff --git a/ethernet/source/ethernet/eth_spram_256x32.v b/ethernet/source/ethernet/eth_spram_256x32.v new file mode 100644 index 0000000..96c4616 --- /dev/null +++ b/ethernet/source/ethernet/eth_spram_256x32.v @@ -0,0 +1,315 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_spram_256x32.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is available in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_spram_256x32.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.10 2005/02/21 12:48:07 igorm +// Warning fixes. +// +// Revision 1.9 2003/12/05 12:43:06 tadejm +// Corrected address mismatch for xilinx RAMB4_S8 model which has wider address than RAMB4_S16. +// +// Revision 1.8 2003/12/04 14:59:13 simons +// Lapsus fixed (!we -> ~we). +// +// Revision 1.7 2003/11/12 18:24:59 tadejm +// WISHBONE slave changed and tested from only 32-bit accesss to byte access. +// +// Revision 1.6 2003/10/17 07:46:15 markom +// mbist signals updated according to newest convention +// +// Revision 1.5 2003/08/14 16:42:58 simons +// Artisan ram instance added. +// +// Revision 1.4 2002/10/18 17:04:20 tadejm +// Changed BIST scan signals. +// +// Revision 1.3 2002/10/10 16:29:30 mohor +// BIST added. +// +// Revision 1.2 2002/09/23 18:24:31 mohor +// ETH_VIRTUAL_SILICON_RAM supported (for ASIC implementation). +// +// Revision 1.1 2002/07/23 16:36:09 mohor +// ethernet spram added. So far a generic ram and xilinx RAMB4 are used. +// +// +// + +`include "eth_defines.v" +`include "timescale.v" + +module eth_spram_256x32( + // Generic synchronous single-port RAM interface + clk, rst, ce, we, oe, addr, di, do + +`ifdef ETH_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif + + + +); + + // + // Generic synchronous single-port RAM interface + // + input clk; // Clock, rising edge + input rst; // Reset, active high + input ce; // Chip enable input, active high + input [3:0] we; // Write enable input, active high + input oe; // Output enable input, active high + input [7:0] addr; // address bus inputs + input [31:0] di; // input data bus + output [31:0] do; // output data bus + + +`ifdef ETH_BIST + input mbist_si_i; // bist scan serial in + output mbist_so_o; // bist scan serial out + input [`ETH_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + +`ifdef ETH_XILINX_RAMB4 + + /*RAMB4_S16 ram0 + ( + .DO (do[15:0]), + .ADDR (addr), + .DI (di[15:0]), + .EN (ce), + .CLK (clk), + .WE (we), + .RST (rst) + ); + + RAMB4_S16 ram1 + ( + .DO (do[31:16]), + .ADDR (addr), + .DI (di[31:16]), + .EN (ce), + .CLK (clk), + .WE (we), + .RST (rst) + );*/ + + RAMB4_S8 ram0 + ( + .DO (do[7:0]), + .ADDR ({1'b0, addr}), + .DI (di[7:0]), + .EN (ce), + .CLK (clk), + .WE (we[0]), + .RST (rst) + ); + + RAMB4_S8 ram1 + ( + .DO (do[15:8]), + .ADDR ({1'b0, addr}), + .DI (di[15:8]), + .EN (ce), + .CLK (clk), + .WE (we[1]), + .RST (rst) + ); + + RAMB4_S8 ram2 + ( + .DO (do[23:16]), + .ADDR ({1'b0, addr}), + .DI (di[23:16]), + .EN (ce), + .CLK (clk), + .WE (we[2]), + .RST (rst) + ); + + RAMB4_S8 ram3 + ( + .DO (do[31:24]), + .ADDR ({1'b0, addr}), + .DI (di[31:24]), + .EN (ce), + .CLK (clk), + .WE (we[3]), + .RST (rst) + ); + +`else // !ETH_XILINX_RAMB4 +`ifdef ETH_VIRTUAL_SILICON_RAM + `ifdef ETH_BIST + //vs_hdsp_256x32_bist ram0_bist + vs_hdsp_256x32_bw_bist ram0_bist + `else + //vs_hdsp_256x32 ram0 + vs_hdsp_256x32_bw ram0 + `endif + ( + .CK (clk), + .CEN (!ce), + .WEN (~we), + .OEN (!oe), + .ADR (addr), + .DI (di), + .DOUT (do) + + `ifdef ETH_BIST + , + // debug chain signals + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) + `endif + ); + +`else // !ETH_VIRTUAL_SILICON_RAM + +`ifdef ETH_ARTISAN_RAM + `ifdef ETH_BIST + //art_hssp_256x32_bist ram0_bist + art_hssp_256x32_bw_bist ram0_bist + `else + //art_hssp_256x32 ram0 + art_hssp_256x32_bw ram0 + `endif + ( + .CLK (clk), + .CEN (!ce), + .WEN (~we), + .OEN (!oe), + .A (addr), + .D (di), + .Q (do) + + `ifdef ETH_BIST + , + // debug chain signals + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) + `endif + ); + +`else // !ETH_ARTISAN_RAM +`ifdef ETH_ALTERA_ALTSYNCRAM + + altera_spram_256x32 altera_spram_256x32_inst + ( + .address (addr), + .wren (ce & we), + .clock (clk), + .data (di), + .q (do) + ); //exemplar attribute altera_spram_256x32_inst NOOPT TRUE + +`else // !ETH_ALTERA_ALTSYNCRAM + + + // + // Generic single-port synchronous RAM model + // + + // + // Generic RAM's registers and wires + // + reg [ 7: 0] mem0 [255:0]; // RAM content + reg [15: 8] mem1 [255:0]; // RAM content + reg [23:16] mem2 [255:0]; // RAM content + reg [31:24] mem3 [255:0]; // RAM content + wire [31:0] q; // RAM output + reg [7:0] raddr; // RAM read address + // + // Data output drivers + // + assign do = (oe & ce) ? q : {32{1'bz}}; + + // + // RAM read and write + // + + // read operation + always@(posedge clk) + if (ce) // && !we) + raddr <= #1 addr; // read address needs to be registered to read clock + + assign #1 q = rst ? {32{1'b0}} : {mem3[raddr], mem2[raddr], mem1[raddr], mem0[raddr]}; + + // write operation + always@(posedge clk) + begin + if (ce && we[3]) + mem3[addr] <= #1 di[31:24]; + if (ce && we[2]) + mem2[addr] <= #1 di[23:16]; + if (ce && we[1]) + mem1[addr] <= #1 di[15: 8]; + if (ce && we[0]) + mem0[addr] <= #1 di[ 7: 0]; + end + + // Task prints range of memory + // *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations. + task print_ram; + input [7:0] start; + input [7:0] finish; + integer rnum; + begin + for (rnum=start;rnum<=finish;rnum=rnum+1) + $display("Addr %h = %0h %0h %0h %0h",rnum,mem3[rnum],mem2[rnum],mem1[rnum],mem0[rnum]); + end + endtask + +`endif // !ETH_ALTERA_ALTSYNCRAM +`endif // !ETH_ARTISAN_RAM +`endif // !ETH_VIRTUAL_SILICON_RAM +`endif // !ETH_XILINX_RAMB4 + +endmodule diff --git a/ethernet/source/ethernet/eth_top.v b/ethernet/source/ethernet/eth_top.v new file mode 100644 index 0000000..4ecb4f1 --- /dev/null +++ b/ethernet/source/ethernet/eth_top.v @@ -0,0 +1,974 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_top.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is available in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_top.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.52 2005/03/21 20:07:18 igorm +// Some small fixes + some troubles fixed. +// +// Revision 1.51 2005/02/21 11:13:17 igorm +// Defer indication fixed. +// +// Revision 1.50 2004/04/26 15:26:23 igorm +// - Bug connected to the TX_BD_NUM_Wr signal fixed (bug came in with the +// previous update of the core. +// - TxBDAddress is set to 0 after the TX is enabled in the MODER register. +// - RxBDAddress is set to r_TxBDNum<<1 after the RX is enabled in the MODER +// register. (thanks to Mathias and Torbjorn) +// - Multicast reception was fixed. Thanks to Ulrich Gries +// +// Revision 1.49 2003/11/12 18:24:59 tadejm +// WISHBONE slave changed and tested from only 32-bit accesss to byte access. +// +// Revision 1.48 2003/10/17 07:46:16 markom +// mbist signals updated according to newest convention +// +// Revision 1.47 2003/10/06 15:43:45 knguyen +// Update RxEnSync only when mrxdv_pad_i is inactive (LOW). +// +// Revision 1.46 2003/01/30 13:30:22 tadejm +// Defer indication changed. +// +// Revision 1.45 2003/01/22 13:49:26 tadejm +// When control packets were received, they were ignored in some cases. +// +// Revision 1.44 2003/01/21 12:09:40 mohor +// When receiving normal data frame and RxFlow control was switched on, RXB +// interrupt was not set. +// +// Revision 1.43 2002/11/22 01:57:06 mohor +// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort +// synchronized. +// +// Revision 1.42 2002/11/21 00:09:19 mohor +// TPauseRq synchronized to tx_clk. +// +// Revision 1.41 2002/11/19 18:13:49 mohor +// r_MiiMRst is not used for resetting the MIIM module. wb_rst used instead. +// +// Revision 1.40 2002/11/19 17:34:25 mohor +// AddressMiss status is connecting to the Rx BD. AddressMiss is identifying +// that a frame was received because of the promiscous mode. +// +// Revision 1.39 2002/11/18 17:31:55 mohor +// wb_rst_i is used for MIIM reset. +// +// Revision 1.38 2002/11/14 18:37:20 mohor +// r_Rst signal does not reset any module any more and is removed from the design. +// +// Revision 1.37 2002/11/13 22:25:36 tadejm +// All modules are reset with wb_rst instead of the r_Rst. Exception is MII module. +// +// Revision 1.36 2002/10/18 17:04:20 tadejm +// Changed BIST scan signals. +// +// Revision 1.35 2002/10/11 13:36:58 mohor +// Typo error fixed. (When using Bist) +// +// Revision 1.34 2002/10/10 16:49:50 mohor +// Signals for WISHBONE B3 compliant interface added. +// +// Revision 1.33 2002/10/10 16:29:30 mohor +// BIST added. +// +// Revision 1.32 2002/09/20 17:12:58 mohor +// CsMiss added. When address between 0x800 and 0xfff is accessed within +// Ethernet Core, error acknowledge is generated. +// +// Revision 1.31 2002/09/12 14:50:17 mohor +// CarrierSenseLost bug fixed when operating in full duplex mode. +// +// Revision 1.30 2002/09/10 10:35:23 mohor +// Ethernet debug registers removed. +// +// Revision 1.29 2002/09/09 13:03:13 mohor +// Error acknowledge is generated when accessing BDs and RST bit in the +// MODER register (r_Rst) is set. +// +// Revision 1.28 2002/09/04 18:44:10 mohor +// Signals related to the control frames connected. Debug registers reg1, 2, 3, 4 +// connected. +// +// Revision 1.27 2002/07/25 18:15:37 mohor +// RxAbort changed. Packets received with MRxErr (from PHY) are also +// aborted. +// +// Revision 1.26 2002/07/17 18:51:50 mohor +// EXTERNAL_DMA removed. External DMA not supported. +// +// Revision 1.25 2002/05/03 10:15:50 mohor +// Outputs registered. Reset changed for eth_wishbone module. +// +// Revision 1.24 2002/04/22 14:15:42 mohor +// Wishbone signals are registered when ETH_REGISTERED_OUTPUTS is +// selected in eth_defines.v +// +// Revision 1.23 2002/03/25 13:33:53 mohor +// md_padoen_o changed to md_padoe_o. Signal was always active high, just +// name was incorrect. +// +// Revision 1.22 2002/02/26 16:59:54 mohor +// Small fixes for external/internal DMA missmatches. +// +// Revision 1.21 2002/02/26 16:21:00 mohor +// Interrupts changed in the top file +// +// Revision 1.20 2002/02/18 10:40:17 mohor +// Small fixes. +// +// Revision 1.19 2002/02/16 14:03:44 mohor +// Registered trimmed. Unused registers removed. +// +// Revision 1.18 2002/02/16 13:06:33 mohor +// EXTERNAL_DMA used instead of WISHBONE_DMA. +// +// Revision 1.17 2002/02/16 07:15:27 mohor +// Testbench fixed, code simplified, unused signals removed. +// +// Revision 1.16 2002/02/15 13:49:39 mohor +// RxAbort is connected differently. +// +// Revision 1.15 2002/02/15 11:38:26 mohor +// Changes that were lost when updating from 1.11 to 1.14 fixed. +// +// Revision 1.14 2002/02/14 20:19:11 billditt +// Modified for Address Checking, +// addition of eth_addrcheck.v +// +// Revision 1.13 2002/02/12 17:03:03 mohor +// HASH0 and HASH1 registers added. Registers address width was +// changed to 8 bits. +// +// Revision 1.12 2002/02/11 09:18:22 mohor +// Tx status is written back to the BD. +// +// Revision 1.11 2002/02/08 16:21:54 mohor +// Rx status is written back to the BD. +// +// Revision 1.10 2002/02/06 14:10:21 mohor +// non-DMA host interface added. Select the right configutation in eth_defines. +// +// Revision 1.9 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.8 2001/12/05 15:00:16 mohor +// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors +// instead of the number of RX descriptors). +// +// Revision 1.7 2001/12/05 10:45:59 mohor +// ETH_RX_BD_ADR register deleted. ETH_RX_BD_NUM is used instead. +// +// Revision 1.6 2001/10/19 11:24:29 mohor +// Number of addresses (wb_adr_i) minimized. +// +// Revision 1.5 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.4 2001/10/18 12:07:11 mohor +// Status signals changed, Adress decoding changed, interrupt controller +// added. +// +// Revision 1.3 2001/09/24 15:02:56 mohor +// Defines changed (All precede with ETH_). Small changes because some +// tools generate warnings when two operands are together. Synchronization +// between two clocks domains in eth_wishbonedma.v is changed (due to ASIC +// demands). +// +// Revision 1.2 2001/08/15 14:03:59 mohor +// Signal names changed on the top level for easier pad insertion (ASIC). +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.2 2001/08/02 09:25:31 mohor +// Unconnected signals are now connected. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// +// +// + + +`include "eth_defines.v" +`include "timescale.v" + + +module eth_top +( + // WISHBONE common + wb_clk_i, wb_rst_i, wb_dat_i, wb_dat_o, + + // WISHBONE slave + wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i, wb_stb_i, wb_ack_o, wb_err_o, + + // WISHBONE master + m_wb_adr_o, m_wb_sel_o, m_wb_we_o, + m_wb_dat_o, m_wb_dat_i, m_wb_cyc_o, + m_wb_stb_o, m_wb_ack_i, m_wb_err_i, + +`ifdef ETH_WISHBONE_B3 + m_wb_cti_o, m_wb_bte_o, +`endif + + //TX + mtx_clk_pad_i, mtxd_pad_o, mtxen_pad_o, mtxerr_pad_o, + + //RX + mrx_clk_pad_i, mrxd_pad_i, mrxdv_pad_i, mrxerr_pad_i, mcoll_pad_i, mcrs_pad_i, + + // MIIM + mdc_pad_o, md_pad_i, md_pad_o, md_padoe_o, + + int_o + + // Bist +`ifdef ETH_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif + +); + + +parameter Tp = 1; + + +// WISHBONE common +input wb_clk_i; // WISHBONE clock +input wb_rst_i; // WISHBONE reset +input [31:0] wb_dat_i; // WISHBONE data input +output [31:0] wb_dat_o; // WISHBONE data output +output wb_err_o; // WISHBONE error output + +// WISHBONE slave +input [11:2] wb_adr_i; // WISHBONE address input +input [3:0] wb_sel_i; // WISHBONE byte select input +input wb_we_i; // WISHBONE write enable input +input wb_cyc_i; // WISHBONE cycle input +input wb_stb_i; // WISHBONE strobe input +output wb_ack_o; // WISHBONE acknowledge output + +// WISHBONE master +output [31:0] m_wb_adr_o; +output [3:0] m_wb_sel_o; +output m_wb_we_o; +input [31:0] m_wb_dat_i; +output [31:0] m_wb_dat_o; +output m_wb_cyc_o; +output m_wb_stb_o; +input m_wb_ack_i; +input m_wb_err_i; + +wire [29:0] m_wb_adr_tmp; + +`ifdef ETH_WISHBONE_B3 +output [2:0] m_wb_cti_o; // Cycle Type Identifier +output [1:0] m_wb_bte_o; // Burst Type Extension +`endif + +// Tx +input mtx_clk_pad_i; // Transmit clock (from PHY) +output [3:0] mtxd_pad_o; // Transmit nibble (to PHY) +output mtxen_pad_o; // Transmit enable (to PHY) +output mtxerr_pad_o; // Transmit error (to PHY) + +// Rx +input mrx_clk_pad_i; // Receive clock (from PHY) +input [3:0] mrxd_pad_i; // Receive nibble (from PHY) +input mrxdv_pad_i; // Receive data valid (from PHY) +input mrxerr_pad_i; // Receive data error (from PHY) + +// Common Tx and Rx +input mcoll_pad_i; // Collision (from PHY) +input mcrs_pad_i; // Carrier sense (from PHY) + +// MII Management interface +input md_pad_i; // MII data input (from I/O cell) +output mdc_pad_o; // MII Management data clock (to PHY) +output md_pad_o; // MII data output (to I/O cell) +output md_padoe_o; // MII data output enable (to I/O cell) + +output int_o; // Interrupt output + +// Bist +`ifdef ETH_BIST +input mbist_si_i; // bist scan serial in +output mbist_so_o; // bist scan serial out +input [`ETH_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + +wire [7:0] r_ClkDiv; +wire r_MiiNoPre; +wire [15:0] r_CtrlData; +wire [4:0] r_FIAD; +wire [4:0] r_RGAD; +wire r_WCtrlData; +wire r_RStat; +wire r_ScanStat; +wire NValid_stat; +wire Busy_stat; +wire LinkFail; +wire [15:0] Prsd; // Read Status Data (data read from the PHY) +wire WCtrlDataStart; +wire RStatStart; +wire UpdateMIIRX_DATAReg; + +wire TxStartFrm; +wire TxEndFrm; +wire TxUsedData; +wire [7:0] TxData; +wire TxRetry; +wire TxAbort; +wire TxUnderRun; +wire TxDone; + + +reg WillSendControlFrame_sync1; +reg WillSendControlFrame_sync2; +reg WillSendControlFrame_sync3; +reg RstTxPauseRq; + +reg TxPauseRq_sync1; +reg TxPauseRq_sync2; +reg TxPauseRq_sync3; +reg TPauseRq; + + +// Connecting Miim module +eth_miim miim1 +( + .Clk(wb_clk_i), .Reset(wb_rst_i), .Divider(r_ClkDiv), + .NoPre(r_MiiNoPre), .CtrlData(r_CtrlData), .Rgad(r_RGAD), + .Fiad(r_FIAD), .WCtrlData(r_WCtrlData), .RStat(r_RStat), + .ScanStat(r_ScanStat), .Mdi(md_pad_i), .Mdo(md_pad_o), + .MdoEn(md_padoe_o), .Mdc(mdc_pad_o), .Busy(Busy_stat), + .Prsd(Prsd), .LinkFail(LinkFail), .Nvalid(NValid_stat), + .WCtrlDataStart(WCtrlDataStart), .RStatStart(RStatStart), .UpdateMIIRX_DATAReg(UpdateMIIRX_DATAReg) +); + + + + +wire [3:0] RegCs; // Connected to registers +wire [31:0] RegDataOut; // Multiplexed to wb_dat_o +wire r_RecSmall; // Receive small frames +wire r_LoopBck; // Loopback +wire r_TxEn; // Tx Enable +wire r_RxEn; // Rx Enable + +wire MRxDV_Lb; // Muxed MII receive data valid +wire MRxErr_Lb; // Muxed MII Receive Error +wire [3:0] MRxD_Lb; // Muxed MII Receive Data +wire Transmitting; // Indication that TxEthMAC is transmitting +wire r_HugEn; // Huge packet enable +wire r_DlyCrcEn; // Delayed CRC enabled +wire [15:0] r_MaxFL; // Maximum frame length + +wire [15:0] r_MinFL; // Minimum frame length +wire ShortFrame; +wire DribbleNibble; // Extra nibble received +wire ReceivedPacketTooBig; // Received packet is too big +wire [47:0] r_MAC; // MAC address +wire LoadRxStatus; // Rx status was loaded +wire [31:0] r_HASH0; // HASH table, lower 4 bytes +wire [31:0] r_HASH1; // HASH table, upper 4 bytes +wire [7:0] r_TxBDNum; // Receive buffer descriptor number +wire [6:0] r_IPGT; // +wire [6:0] r_IPGR1; // +wire [6:0] r_IPGR2; // +wire [5:0] r_CollValid; // +wire [15:0] r_TxPauseTV; // Transmit PAUSE value +wire r_TxPauseRq; // Transmit PAUSE request + +wire [3:0] r_MaxRet; // +wire r_NoBckof; // +wire r_ExDfrEn; // +wire r_TxFlow; // Tx flow control enable +wire r_IFG; // Minimum interframe gap for incoming packets + +wire TxB_IRQ; // Interrupt Tx Buffer +wire TxE_IRQ; // Interrupt Tx Error +wire RxB_IRQ; // Interrupt Rx Buffer +wire RxE_IRQ; // Interrupt Rx Error +wire Busy_IRQ; // Interrupt Busy (lack of buffers) + +//wire DWord; +wire ByteSelected; +wire BDAck; +wire [31:0] BD_WB_DAT_O; // wb_dat_o that comes from the Wishbone module (for buffer descriptors read/write) +wire [3:0] BDCs; // Buffer descriptor CS +wire CsMiss; // When access to the address between 0x800 and 0xfff occurs, acknowledge is set + // but data is not valid. +wire r_Pad; +wire r_CrcEn; +wire r_FullD; +wire r_Pro; +wire r_Bro; +wire r_NoPre; +wire r_RxFlow; +wire r_PassAll; +wire TxCtrlEndFrm; +wire StartTxDone; +wire SetPauseTimer; +wire TxUsedDataIn; +wire TxDoneIn; +wire TxAbortIn; +wire PerPacketPad; +wire PadOut; +wire PerPacketCrcEn; +wire CrcEnOut; +wire TxStartFrmOut; +wire TxEndFrmOut; +wire ReceivedPauseFrm; +wire ControlFrmAddressOK; +wire RxStatusWriteLatched_sync2; +wire LateCollision; +wire DeferIndication; +wire LateCollLatched; +wire DeferLatched; +wire RstDeferLatched; +wire CarrierSenseLost; + +wire temp_wb_ack_o; +wire [31:0] temp_wb_dat_o; +wire temp_wb_err_o; + +`ifdef ETH_REGISTERED_OUTPUTS + reg temp_wb_ack_o_reg; + reg [31:0] temp_wb_dat_o_reg; + reg temp_wb_err_o_reg; +`endif + +//assign DWord = &wb_sel_i; +assign ByteSelected = |wb_sel_i; +assign RegCs[3] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & ~wb_adr_i[10] & wb_sel_i[3]; // 0x0 - 0x3FF +assign RegCs[2] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & ~wb_adr_i[10] & wb_sel_i[2]; // 0x0 - 0x3FF +assign RegCs[1] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & ~wb_adr_i[10] & wb_sel_i[1]; // 0x0 - 0x3FF +assign RegCs[0] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & ~wb_adr_i[10] & wb_sel_i[0]; // 0x0 - 0x3FF +assign BDCs[3] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & wb_adr_i[10] & wb_sel_i[3]; // 0x400 - 0x7FF +assign BDCs[2] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & wb_adr_i[10] & wb_sel_i[2]; // 0x400 - 0x7FF +assign BDCs[1] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & wb_adr_i[10] & wb_sel_i[1]; // 0x400 - 0x7FF +assign BDCs[0] = wb_stb_i & wb_cyc_i & ByteSelected & ~wb_adr_i[11] & wb_adr_i[10] & wb_sel_i[0]; // 0x400 - 0x7FF +assign CsMiss = wb_stb_i & wb_cyc_i & ByteSelected & wb_adr_i[11]; // 0x800 - 0xfFF +assign temp_wb_dat_o = ((|RegCs) & ~wb_we_i)? RegDataOut : BD_WB_DAT_O; +assign temp_wb_err_o = wb_stb_i & wb_cyc_i & (~ByteSelected | CsMiss); + +`ifdef ETH_REGISTERED_OUTPUTS + assign wb_ack_o = temp_wb_ack_o_reg; + assign wb_dat_o[31:0] = temp_wb_dat_o_reg; + assign wb_err_o = temp_wb_err_o_reg; +`else + assign wb_ack_o = temp_wb_ack_o; + assign wb_dat_o[31:0] = temp_wb_dat_o; + assign wb_err_o = temp_wb_err_o; +`endif + +`ifdef ETH_AVALON_BUS + // As Avalon has no corresponding "error" signal, I (erroneously) will + // send an ack to Avalon, even when accessing undefined memory. This + // is a grey area in Avalon vs. Wishbone specs: My understanding + // is that Avalon expects all memory addressable by the addr bus feeding + // a slave to be, at the very minimum, readable. + assign temp_wb_ack_o = (|RegCs) | BDAck | CsMiss; +`else // WISHBONE + assign temp_wb_ack_o = (|RegCs) | BDAck; +`endif + +`ifdef ETH_REGISTERED_OUTPUTS + always @ (posedge wb_clk_i or posedge wb_rst_i) + begin + if(wb_rst_i) + begin + temp_wb_ack_o_reg <=#Tp 1'b0; + temp_wb_dat_o_reg <=#Tp 32'h0; + temp_wb_err_o_reg <=#Tp 1'b0; + end + else + begin + temp_wb_ack_o_reg <=#Tp temp_wb_ack_o & ~temp_wb_ack_o_reg; + temp_wb_dat_o_reg <=#Tp temp_wb_dat_o; + temp_wb_err_o_reg <=#Tp temp_wb_err_o & ~temp_wb_err_o_reg; + end + end +`endif + + +// Connecting Ethernet registers +eth_registers ethreg1 +( + .DataIn(wb_dat_i), .Address(wb_adr_i[9:2]), .Rw(wb_we_i), + .Cs(RegCs), .Clk(wb_clk_i), .Reset(wb_rst_i), + .DataOut(RegDataOut), .r_RecSmall(r_RecSmall), + .r_Pad(r_Pad), .r_HugEn(r_HugEn), .r_CrcEn(r_CrcEn), + .r_DlyCrcEn(r_DlyCrcEn), .r_FullD(r_FullD), + .r_ExDfrEn(r_ExDfrEn), .r_NoBckof(r_NoBckof), .r_LoopBck(r_LoopBck), + .r_IFG(r_IFG), .r_Pro(r_Pro), .r_Iam(), + .r_Bro(r_Bro), .r_NoPre(r_NoPre), .r_TxEn(r_TxEn), + .r_RxEn(r_RxEn), .Busy_IRQ(Busy_IRQ), .RxE_IRQ(RxE_IRQ), + .RxB_IRQ(RxB_IRQ), .TxE_IRQ(TxE_IRQ), .TxB_IRQ(TxB_IRQ), + .r_IPGT(r_IPGT), + .r_IPGR1(r_IPGR1), .r_IPGR2(r_IPGR2), .r_MinFL(r_MinFL), + .r_MaxFL(r_MaxFL), .r_MaxRet(r_MaxRet), .r_CollValid(r_CollValid), + .r_TxFlow(r_TxFlow), .r_RxFlow(r_RxFlow), .r_PassAll(r_PassAll), + .r_MiiNoPre(r_MiiNoPre), .r_ClkDiv(r_ClkDiv), + .r_WCtrlData(r_WCtrlData), .r_RStat(r_RStat), .r_ScanStat(r_ScanStat), + .r_RGAD(r_RGAD), .r_FIAD(r_FIAD), .r_CtrlData(r_CtrlData), + .NValid_stat(NValid_stat), .Busy_stat(Busy_stat), + .LinkFail(LinkFail), .r_MAC(r_MAC), .WCtrlDataStart(WCtrlDataStart), + .RStatStart(RStatStart), .UpdateMIIRX_DATAReg(UpdateMIIRX_DATAReg), .Prsd(Prsd), + .r_TxBDNum(r_TxBDNum), .int_o(int_o), + .r_HASH0(r_HASH0), .r_HASH1(r_HASH1), .r_TxPauseRq(r_TxPauseRq), + .r_TxPauseTV(r_TxPauseTV), .RstTxPauseRq(RstTxPauseRq), .TxCtrlEndFrm(TxCtrlEndFrm), + .StartTxDone(StartTxDone), .TxClk(mtx_clk_pad_i), .RxClk(mrx_clk_pad_i), + .SetPauseTimer(SetPauseTimer) + +); + + + +wire [7:0] RxData; +wire RxValid; +wire RxStartFrm; +wire RxEndFrm; +wire RxAbort; + +wire WillTransmit; // Will transmit (to RxEthMAC) +wire ResetCollision; // Reset Collision (for synchronizing collision) +wire [7:0] TxDataOut; // Transmit Packet Data (to TxEthMAC) +wire WillSendControlFrame; +wire ReceiveEnd; +wire ReceivedPacketGood; +wire ReceivedLengthOK; +wire InvalidSymbol; +wire LatchedCrcError; +wire RxLateCollision; +wire [3:0] RetryCntLatched; +wire [3:0] RetryCnt; +wire StartTxAbort; +wire MaxCollisionOccured; +wire RetryLimit; +wire StatePreamble; +wire [1:0] StateData; + +// Connecting MACControl +eth_maccontrol maccontrol1 +( + .MTxClk(mtx_clk_pad_i), .TPauseRq(TPauseRq), + .TxPauseTV(r_TxPauseTV), .TxDataIn(TxData), + .TxStartFrmIn(TxStartFrm), .TxEndFrmIn(TxEndFrm), + .TxUsedDataIn(TxUsedDataIn), .TxDoneIn(TxDoneIn), + .TxAbortIn(TxAbortIn), .MRxClk(mrx_clk_pad_i), + .RxData(RxData), .RxValid(RxValid), + .RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), + .ReceiveEnd(ReceiveEnd), .ReceivedPacketGood(ReceivedPacketGood), + .TxFlow(r_TxFlow), + .RxFlow(r_RxFlow), .DlyCrcEn(r_DlyCrcEn), + .MAC(r_MAC), .PadIn(r_Pad | PerPacketPad), + .PadOut(PadOut), .CrcEnIn(r_CrcEn | PerPacketCrcEn), + .CrcEnOut(CrcEnOut), .TxReset(wb_rst_i), + .RxReset(wb_rst_i), .ReceivedLengthOK(ReceivedLengthOK), + .TxDataOut(TxDataOut), .TxStartFrmOut(TxStartFrmOut), + .TxEndFrmOut(TxEndFrmOut), .TxUsedDataOut(TxUsedData), + .TxDoneOut(TxDone), .TxAbortOut(TxAbort), + .WillSendControlFrame(WillSendControlFrame), .TxCtrlEndFrm(TxCtrlEndFrm), + .ReceivedPauseFrm(ReceivedPauseFrm), .ControlFrmAddressOK(ControlFrmAddressOK), + .SetPauseTimer(SetPauseTimer), + .RxStatusWriteLatched_sync2(RxStatusWriteLatched_sync2), .r_PassAll(r_PassAll) +); + + + +wire TxCarrierSense; // Synchronized CarrierSense (to Tx clock) +wire Collision; // Synchronized Collision + +reg CarrierSense_Tx1; +reg CarrierSense_Tx2; +reg Collision_Tx1; +reg Collision_Tx2; + +reg RxEnSync; // Synchronized Receive Enable +reg WillTransmit_q; +reg WillTransmit_q2; + + + +// Muxed MII receive data valid +assign MRxDV_Lb = r_LoopBck? mtxen_pad_o : mrxdv_pad_i & RxEnSync; + +// Muxed MII Receive Error +assign MRxErr_Lb = r_LoopBck? mtxerr_pad_o : mrxerr_pad_i & RxEnSync; + +// Muxed MII Receive Data +assign MRxD_Lb[3:0] = r_LoopBck? mtxd_pad_o[3:0] : mrxd_pad_i[3:0]; + + + +// Connecting TxEthMAC +eth_txethmac txethmac1 +( + .MTxClk(mtx_clk_pad_i), .Reset(wb_rst_i), .CarrierSense(TxCarrierSense), + .Collision(Collision), .TxData(TxDataOut), .TxStartFrm(TxStartFrmOut), + .TxUnderRun(TxUnderRun), .TxEndFrm(TxEndFrmOut), .Pad(PadOut), + .MinFL(r_MinFL), .CrcEn(CrcEnOut), .FullD(r_FullD), + .HugEn(r_HugEn), .DlyCrcEn(r_DlyCrcEn), .IPGT(r_IPGT), + .IPGR1(r_IPGR1), .IPGR2(r_IPGR2), .CollValid(r_CollValid), + .MaxRet(r_MaxRet), .NoBckof(r_NoBckof), .ExDfrEn(r_ExDfrEn), + .MaxFL(r_MaxFL), .MTxEn(mtxen_pad_o), .MTxD(mtxd_pad_o), + .MTxErr(mtxerr_pad_o), .TxUsedData(TxUsedDataIn), .TxDone(TxDoneIn), + .TxRetry(TxRetry), .TxAbort(TxAbortIn), .WillTransmit(WillTransmit), + .ResetCollision(ResetCollision), .RetryCnt(RetryCnt), .StartTxDone(StartTxDone), + .StartTxAbort(StartTxAbort), .MaxCollisionOccured(MaxCollisionOccured), .LateCollision(LateCollision), + .DeferIndication(DeferIndication), .StatePreamble(StatePreamble), .StateData(StateData) +); + + + + +wire [15:0] RxByteCnt; +wire RxByteCntEq0; +wire RxByteCntGreat2; +wire RxByteCntMaxFrame; +wire RxCrcError; +wire RxStateIdle; +wire RxStatePreamble; +wire RxStateSFD; +wire [1:0] RxStateData; +wire AddressMiss; + + + +// Connecting RxEthMAC +eth_rxethmac rxethmac1 +( + .MRxClk(mrx_clk_pad_i), .MRxDV(MRxDV_Lb), .MRxD(MRxD_Lb), + .Transmitting(Transmitting), .HugEn(r_HugEn), .DlyCrcEn(r_DlyCrcEn), + .MaxFL(r_MaxFL), .r_IFG(r_IFG), .Reset(wb_rst_i), + .RxData(RxData), .RxValid(RxValid), .RxStartFrm(RxStartFrm), + .RxEndFrm(RxEndFrm), .ByteCnt(RxByteCnt), + .ByteCntEq0(RxByteCntEq0), .ByteCntGreat2(RxByteCntGreat2), .ByteCntMaxFrame(RxByteCntMaxFrame), + .CrcError(RxCrcError), .StateIdle(RxStateIdle), .StatePreamble(RxStatePreamble), + .StateSFD(RxStateSFD), .StateData(RxStateData), + .MAC(r_MAC), .r_Pro(r_Pro), .r_Bro(r_Bro), + .r_HASH0(r_HASH0), .r_HASH1(r_HASH1), .RxAbort(RxAbort), + .AddressMiss(AddressMiss), .PassAll(r_PassAll), .ControlFrmAddressOK(ControlFrmAddressOK) +); + + +// MII Carrier Sense Synchronization +always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) +begin + if(wb_rst_i) + begin + CarrierSense_Tx1 <= #Tp 1'b0; + CarrierSense_Tx2 <= #Tp 1'b0; + end + else + begin + CarrierSense_Tx1 <= #Tp mcrs_pad_i; + CarrierSense_Tx2 <= #Tp CarrierSense_Tx1; + end +end + +assign TxCarrierSense = ~r_FullD & CarrierSense_Tx2; + + +// MII Collision Synchronization +always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) +begin + if(wb_rst_i) + begin + Collision_Tx1 <= #Tp 1'b0; + Collision_Tx2 <= #Tp 1'b0; + end + else + begin + Collision_Tx1 <= #Tp mcoll_pad_i; + if(ResetCollision) + Collision_Tx2 <= #Tp 1'b0; + else + if(Collision_Tx1) + Collision_Tx2 <= #Tp 1'b1; + end +end + + +// Synchronized Collision +assign Collision = ~r_FullD & Collision_Tx2; + + + +// Delayed WillTransmit +always @ (posedge mrx_clk_pad_i) +begin + WillTransmit_q <= #Tp WillTransmit; + WillTransmit_q2 <= #Tp WillTransmit_q; +end + + +assign Transmitting = ~r_FullD & WillTransmit_q2; + + + +// Synchronized Receive Enable +always @ (posedge mrx_clk_pad_i or posedge wb_rst_i) +begin + if(wb_rst_i) + RxEnSync <= #Tp 1'b0; + else + if(~mrxdv_pad_i) + RxEnSync <= #Tp r_RxEn; +end + + + +// Synchronizing WillSendControlFrame to WB_CLK; +always @ (posedge wb_clk_i or posedge wb_rst_i) +begin + if(wb_rst_i) + WillSendControlFrame_sync1 <= 1'b0; + else + WillSendControlFrame_sync1 <=#Tp WillSendControlFrame; +end + +always @ (posedge wb_clk_i or posedge wb_rst_i) +begin + if(wb_rst_i) + WillSendControlFrame_sync2 <= 1'b0; + else + WillSendControlFrame_sync2 <=#Tp WillSendControlFrame_sync1; +end + +always @ (posedge wb_clk_i or posedge wb_rst_i) +begin + if(wb_rst_i) + WillSendControlFrame_sync3 <= 1'b0; + else + WillSendControlFrame_sync3 <=#Tp WillSendControlFrame_sync2; +end + +always @ (posedge wb_clk_i or posedge wb_rst_i) +begin + if(wb_rst_i) + RstTxPauseRq <= 1'b0; + else + RstTxPauseRq <=#Tp WillSendControlFrame_sync2 & ~WillSendControlFrame_sync3; +end + + + + +// TX Pause request Synchronization +always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) +begin + if(wb_rst_i) + begin + TxPauseRq_sync1 <= #Tp 1'b0; + TxPauseRq_sync2 <= #Tp 1'b0; + TxPauseRq_sync3 <= #Tp 1'b0; + end + else + begin + TxPauseRq_sync1 <= #Tp (r_TxPauseRq & r_TxFlow); + TxPauseRq_sync2 <= #Tp TxPauseRq_sync1; + TxPauseRq_sync3 <= #Tp TxPauseRq_sync2; + end +end + + +always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) +begin + if(wb_rst_i) + TPauseRq <= #Tp 1'b0; + else + TPauseRq <= #Tp TxPauseRq_sync2 & (~TxPauseRq_sync3); +end + + +wire LatchedMRxErr; +reg RxAbort_latch; +reg RxAbort_sync1; +reg RxAbort_wb; +reg RxAbortRst_sync1; +reg RxAbortRst; + +// Synchronizing RxAbort to the WISHBONE clock +always @ (posedge mrx_clk_pad_i or posedge wb_rst_i) +begin + if(wb_rst_i) + RxAbort_latch <= #Tp 1'b0; + else if(RxAbort | (ShortFrame & ~r_RecSmall) | LatchedMRxErr & ~InvalidSymbol | (ReceivedPauseFrm & (~r_PassAll))) + RxAbort_latch <= #Tp 1'b1; + else if(RxAbortRst) + RxAbort_latch <= #Tp 1'b0; +end + +always @ (posedge wb_clk_i or posedge wb_rst_i) +begin + if(wb_rst_i) + begin + RxAbort_sync1 <= #Tp 1'b0; + RxAbort_wb <= #Tp 1'b0; + RxAbort_wb <= #Tp 1'b0; + end + else + begin + RxAbort_sync1 <= #Tp RxAbort_latch; + RxAbort_wb <= #Tp RxAbort_sync1; + end +end + +always @ (posedge mrx_clk_pad_i or posedge wb_rst_i) +begin + if(wb_rst_i) + begin + RxAbortRst_sync1 <= #Tp 1'b0; + RxAbortRst <= #Tp 1'b0; + end + else + begin + RxAbortRst_sync1 <= #Tp RxAbort_wb; + RxAbortRst <= #Tp RxAbortRst_sync1; + end +end + + + +// Connecting Wishbone module +eth_wishbone wishbone +( + .WB_CLK_I(wb_clk_i), .WB_DAT_I(wb_dat_i), + .WB_DAT_O(BD_WB_DAT_O), + + // WISHBONE slave + .WB_ADR_I(wb_adr_i[9:2]), .WB_WE_I(wb_we_i), + .BDCs(BDCs), .WB_ACK_O(BDAck), + + .Reset(wb_rst_i), + + // WISHBONE master + .m_wb_adr_o(m_wb_adr_tmp), .m_wb_sel_o(m_wb_sel_o), .m_wb_we_o(m_wb_we_o), + .m_wb_dat_i(m_wb_dat_i), .m_wb_dat_o(m_wb_dat_o), .m_wb_cyc_o(m_wb_cyc_o), + .m_wb_stb_o(m_wb_stb_o), .m_wb_ack_i(m_wb_ack_i), .m_wb_err_i(m_wb_err_i), + +`ifdef ETH_WISHBONE_B3 + .m_wb_cti_o(m_wb_cti_o), .m_wb_bte_o(m_wb_bte_o), +`endif + + + //TX + .MTxClk(mtx_clk_pad_i), .TxStartFrm(TxStartFrm), .TxEndFrm(TxEndFrm), + .TxUsedData(TxUsedData), .TxData(TxData), + .TxRetry(TxRetry), .TxAbort(TxAbort), .TxUnderRun(TxUnderRun), + .TxDone(TxDone), + .PerPacketCrcEn(PerPacketCrcEn), .PerPacketPad(PerPacketPad), + + // Register + .r_TxEn(r_TxEn), .r_RxEn(r_RxEn), .r_TxBDNum(r_TxBDNum), + .r_RxFlow(r_RxFlow), .r_PassAll(r_PassAll), + + //RX + .MRxClk(mrx_clk_pad_i), .RxData(RxData), .RxValid(RxValid), + .RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), + .Busy_IRQ(Busy_IRQ), .RxE_IRQ(RxE_IRQ), .RxB_IRQ(RxB_IRQ), + .TxE_IRQ(TxE_IRQ), .TxB_IRQ(TxB_IRQ), + + .RxAbort(RxAbort_wb), .RxStatusWriteLatched_sync2(RxStatusWriteLatched_sync2), + + .InvalidSymbol(InvalidSymbol), .LatchedCrcError(LatchedCrcError), .RxLength(RxByteCnt), + .RxLateCollision(RxLateCollision), .ShortFrame(ShortFrame), .DribbleNibble(DribbleNibble), + .ReceivedPacketTooBig(ReceivedPacketTooBig), .LoadRxStatus(LoadRxStatus), .RetryCntLatched(RetryCntLatched), + .RetryLimit(RetryLimit), .LateCollLatched(LateCollLatched), .DeferLatched(DeferLatched), + .RstDeferLatched(RstDeferLatched), + .CarrierSenseLost(CarrierSenseLost),.ReceivedPacketGood(ReceivedPacketGood), .AddressMiss(AddressMiss), + .ReceivedPauseFrm(ReceivedPauseFrm) + +`ifdef ETH_BIST + , + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) +`endif +); + +assign m_wb_adr_o = {m_wb_adr_tmp, 2'h0}; + +// Connecting MacStatus module +eth_macstatus macstatus1 +( + .MRxClk(mrx_clk_pad_i), .Reset(wb_rst_i), + .ReceiveEnd(ReceiveEnd), .ReceivedPacketGood(ReceivedPacketGood), .ReceivedLengthOK(ReceivedLengthOK), + .RxCrcError(RxCrcError), .MRxErr(MRxErr_Lb), .MRxDV(MRxDV_Lb), + .RxStateSFD(RxStateSFD), .RxStateData(RxStateData), .RxStatePreamble(RxStatePreamble), + .RxStateIdle(RxStateIdle), .Transmitting(Transmitting), .RxByteCnt(RxByteCnt), + .RxByteCntEq0(RxByteCntEq0), .RxByteCntGreat2(RxByteCntGreat2), .RxByteCntMaxFrame(RxByteCntMaxFrame), + .InvalidSymbol(InvalidSymbol), + .MRxD(MRxD_Lb), .LatchedCrcError(LatchedCrcError), .Collision(mcoll_pad_i), + .CollValid(r_CollValid), .RxLateCollision(RxLateCollision), .r_RecSmall(r_RecSmall), + .r_MinFL(r_MinFL), .r_MaxFL(r_MaxFL), .ShortFrame(ShortFrame), + .DribbleNibble(DribbleNibble), .ReceivedPacketTooBig(ReceivedPacketTooBig), .r_HugEn(r_HugEn), + .LoadRxStatus(LoadRxStatus), .RetryCnt(RetryCnt), .StartTxDone(StartTxDone), + .StartTxAbort(StartTxAbort), .RetryCntLatched(RetryCntLatched), .MTxClk(mtx_clk_pad_i), + .MaxCollisionOccured(MaxCollisionOccured), .RetryLimit(RetryLimit), .LateCollision(LateCollision), + .LateCollLatched(LateCollLatched), .DeferIndication(DeferIndication), .DeferLatched(DeferLatched), + .RstDeferLatched(RstDeferLatched), + .TxStartFrm(TxStartFrmOut), .StatePreamble(StatePreamble), .StateData(StateData), + .CarrierSense(CarrierSense_Tx2), .CarrierSenseLost(CarrierSenseLost), .TxUsedData(TxUsedDataIn), + .LatchedMRxErr(LatchedMRxErr), .Loopback(r_LoopBck), .r_FullD(r_FullD) +); + + +endmodule diff --git a/ethernet/source/ethernet/eth_transmitcontrol.v b/ethernet/source/ethernet/eth_transmitcontrol.v new file mode 100644 index 0000000..cd5e3f2 --- /dev/null +++ b/ethernet/source/ethernet/eth_transmitcontrol.v @@ -0,0 +1,333 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_transmitcontrol.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_transmitcontrol.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2002/11/21 00:16:14 mohor +// When TxUsedData and CtrlMux occur at the same time, byte counter needs +// to be incremented by 2. Signal IncrementByteCntBy2 added for that reason. +// +// Revision 1.5 2002/11/19 17:37:32 mohor +// When control frame (PAUSE) was sent, status was written in the +// eth_wishbone module and both TXB and TXC interrupts were set. Fixed. +// Only TXC interrupt is set. +// +// Revision 1.4 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.3 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.2 2001/09/11 14:17:00 mohor +// Few little NCSIM warnings fixed. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.1 2001/07/03 12:51:54 mohor +// Initial release of the MAC Control module. +// +// +// +// +// +// + + +`include "timescale.v" + + +module eth_transmitcontrol (MTxClk, TxReset, TxUsedDataIn, TxUsedDataOut, TxDoneIn, TxAbortIn, + TxStartFrmIn, TPauseRq, TxUsedDataOutDetected, TxFlow, DlyCrcEn, + TxPauseTV, MAC, TxCtrlStartFrm, TxCtrlEndFrm, SendingCtrlFrm, CtrlMux, + ControlData, WillSendControlFrame, BlockTxDone + ); + +parameter Tp = 1; + + +input MTxClk; +input TxReset; +input TxUsedDataIn; +input TxUsedDataOut; +input TxDoneIn; +input TxAbortIn; +input TxStartFrmIn; +input TPauseRq; +input TxUsedDataOutDetected; +input TxFlow; +input DlyCrcEn; +input [15:0] TxPauseTV; +input [47:0] MAC; + +output TxCtrlStartFrm; +output TxCtrlEndFrm; +output SendingCtrlFrm; +output CtrlMux; +output [7:0] ControlData; +output WillSendControlFrame; +output BlockTxDone; + +reg SendingCtrlFrm; +reg CtrlMux; +reg WillSendControlFrame; +reg [3:0] DlyCrcCnt; +reg [5:0] ByteCnt; +reg ControlEnd_q; +reg [7:0] MuxedCtrlData; +reg TxCtrlStartFrm; +reg TxCtrlStartFrm_q; +reg TxCtrlEndFrm; +reg [7:0] ControlData; +reg TxUsedDataIn_q; +reg BlockTxDone; + +wire IncrementDlyCrcCnt; +wire ResetByteCnt; +wire IncrementByteCnt; +wire ControlEnd; +wire IncrementByteCntBy2; +wire EnableCnt; + + +// A command for Sending the control frame is active (latched) +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + WillSendControlFrame <= #Tp 1'b0; + else + if(TxCtrlEndFrm & CtrlMux) + WillSendControlFrame <= #Tp 1'b0; + else + if(TPauseRq & TxFlow) + WillSendControlFrame <= #Tp 1'b1; +end + + +// Generation of the transmit control packet start frame +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + TxCtrlStartFrm <= #Tp 1'b0; + else + if(TxUsedDataIn_q & CtrlMux) + TxCtrlStartFrm <= #Tp 1'b0; + else + if(WillSendControlFrame & ~TxUsedDataOut & (TxDoneIn | TxAbortIn | TxStartFrmIn | (~TxUsedDataOutDetected))) + TxCtrlStartFrm <= #Tp 1'b1; +end + + + +// Generation of the transmit control packet end frame +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + TxCtrlEndFrm <= #Tp 1'b0; + else + if(ControlEnd | ControlEnd_q) + TxCtrlEndFrm <= #Tp 1'b1; + else + TxCtrlEndFrm <= #Tp 1'b0; +end + + +// Generation of the multiplexer signal (controls muxes for switching between +// normal and control packets) +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + CtrlMux <= #Tp 1'b0; + else + if(WillSendControlFrame & ~TxUsedDataOut) + CtrlMux <= #Tp 1'b1; + else + if(TxDoneIn) + CtrlMux <= #Tp 1'b0; +end + + + +// Generation of the Sending Control Frame signal (enables padding and CRC) +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + SendingCtrlFrm <= #Tp 1'b0; + else + if(WillSendControlFrame & TxCtrlStartFrm) + SendingCtrlFrm <= #Tp 1'b1; + else + if(TxDoneIn) + SendingCtrlFrm <= #Tp 1'b0; +end + + +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + TxUsedDataIn_q <= #Tp 1'b0; + else + TxUsedDataIn_q <= #Tp TxUsedDataIn; +end + + + +// Generation of the signal that will block sending the Done signal to the eth_wishbone module +// While sending the control frame +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + BlockTxDone <= #Tp 1'b0; + else + if(TxCtrlStartFrm) + BlockTxDone <= #Tp 1'b1; + else + if(TxStartFrmIn) + BlockTxDone <= #Tp 1'b0; +end + + +always @ (posedge MTxClk) +begin + ControlEnd_q <= #Tp ControlEnd; + TxCtrlStartFrm_q <= #Tp TxCtrlStartFrm; +end + + +assign IncrementDlyCrcCnt = CtrlMux & TxUsedDataIn & ~DlyCrcCnt[2]; + + +// Delayed CRC counter +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + DlyCrcCnt <= #Tp 4'h0; + else + if(ResetByteCnt) + DlyCrcCnt <= #Tp 4'h0; + else + if(IncrementDlyCrcCnt) + DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1; +end + + +assign ResetByteCnt = TxReset | (~TxCtrlStartFrm & (TxDoneIn | TxAbortIn)); +assign IncrementByteCnt = CtrlMux & (TxCtrlStartFrm & ~TxCtrlStartFrm_q & ~TxUsedDataIn | TxUsedDataIn & ~ControlEnd); +assign IncrementByteCntBy2 = CtrlMux & TxCtrlStartFrm & (~TxCtrlStartFrm_q) & TxUsedDataIn; // When TxUsedDataIn and CtrlMux are set at the same time + +assign EnableCnt = (~DlyCrcEn | DlyCrcEn & (&DlyCrcCnt[1:0])); +// Byte counter +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + ByteCnt <= #Tp 6'h0; + else + if(ResetByteCnt) + ByteCnt <= #Tp 6'h0; + else + if(IncrementByteCntBy2 & EnableCnt) + ByteCnt <= #Tp (ByteCnt[5:0] ) + 2'h2; + else + if(IncrementByteCnt & EnableCnt) + ByteCnt <= #Tp (ByteCnt[5:0] ) + 1'b1; +end + + +assign ControlEnd = ByteCnt[5:0] == 6'h22; + + +// Control data generation (goes to the TxEthMAC module) +always @ (ByteCnt or DlyCrcEn or MAC or TxPauseTV or DlyCrcCnt) +begin + case(ByteCnt) + 6'h0: if(~DlyCrcEn | DlyCrcEn & (&DlyCrcCnt[1:0])) + MuxedCtrlData[7:0] = 8'h01; // Reserved Multicast Address + else + MuxedCtrlData[7:0] = 8'h0; + 6'h2: MuxedCtrlData[7:0] = 8'h80; + 6'h4: MuxedCtrlData[7:0] = 8'hC2; + 6'h6: MuxedCtrlData[7:0] = 8'h00; + 6'h8: MuxedCtrlData[7:0] = 8'h00; + 6'hA: MuxedCtrlData[7:0] = 8'h01; + 6'hC: MuxedCtrlData[7:0] = MAC[47:40]; + 6'hE: MuxedCtrlData[7:0] = MAC[39:32]; + 6'h10: MuxedCtrlData[7:0] = MAC[31:24]; + 6'h12: MuxedCtrlData[7:0] = MAC[23:16]; + 6'h14: MuxedCtrlData[7:0] = MAC[15:8]; + 6'h16: MuxedCtrlData[7:0] = MAC[7:0]; + 6'h18: MuxedCtrlData[7:0] = 8'h88; // Type/Length + 6'h1A: MuxedCtrlData[7:0] = 8'h08; + 6'h1C: MuxedCtrlData[7:0] = 8'h00; // Opcode + 6'h1E: MuxedCtrlData[7:0] = 8'h01; + 6'h20: MuxedCtrlData[7:0] = TxPauseTV[15:8]; // Pause timer value + 6'h22: MuxedCtrlData[7:0] = TxPauseTV[7:0]; + default: MuxedCtrlData[7:0] = 8'h0; + endcase +end + + +// Latched Control data +always @ (posedge MTxClk or posedge TxReset) +begin + if(TxReset) + ControlData[7:0] <= #Tp 8'h0; + else + if(~ByteCnt[0]) + ControlData[7:0] <= #Tp MuxedCtrlData[7:0]; +end + + + +endmodule diff --git a/ethernet/source/ethernet/eth_txcounters.v b/ethernet/source/ethernet/eth_txcounters.v new file mode 100644 index 0000000..84c8e5e --- /dev/null +++ b/ethernet/source/ethernet/eth_txcounters.v @@ -0,0 +1,227 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_txcounters.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// - Novan Hartadi (novan@vlsi.itb.ac.id) //// +//// - Mahmud Galela (mgalela@vlsi.itb.ac.id) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_txcounters.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2005/02/21 11:25:27 igorm +// Delayed CRC fixed. +// +// Revision 1.5 2002/04/22 14:54:14 mohor +// FCS should not be included in NibbleMinFl. +// +// Revision 1.4 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.3 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.2 2001/09/11 14:17:00 mohor +// Few little NCSIM warnings fixed. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.4 2001/06/27 21:27:45 mohor +// Few typos fixed. +// +// Revision 1.2 2001/06/19 10:38:07 mohor +// Minor changes in header. +// +// Revision 1.1 2001/06/19 10:27:57 mohor +// TxEthMAC initial release. +// +// +// + + +`include "timescale.v" + + +module eth_txcounters (StatePreamble, StateIPG, StateData, StatePAD, StateFCS, StateJam, + StateBackOff, StateDefer, StateIdle, StartDefer, StartIPG, StartFCS, + StartJam, StartBackoff, TxStartFrm, MTxClk, Reset, MinFL, MaxFL, HugEn, + ExDfrEn, PacketFinished_q, DlyCrcEn, StateSFD, ByteCnt, NibCnt, + ExcessiveDefer, NibCntEq7, NibCntEq15, MaxFrame, NibbleMinFl, DlyCrcCnt + ); + +parameter Tp = 1; + +input MTxClk; // Tx clock +input Reset; // Reset +input StatePreamble; // Preamble state +input StateIPG; // IPG state +input [1:0] StateData; // Data state +input StatePAD; // PAD state +input StateFCS; // FCS state +input StateJam; // Jam state +input StateBackOff; // Backoff state +input StateDefer; // Defer state +input StateIdle; // Idle state +input StateSFD; // SFD state +input StartDefer; // Defer state will be activated in next clock +input StartIPG; // IPG state will be activated in next clock +input StartFCS; // FCS state will be activated in next clock +input StartJam; // Jam state will be activated in next clock +input StartBackoff; // Backoff state will be activated in next clock +input TxStartFrm; // Tx start frame +input [15:0] MinFL; // Minimum frame length (in bytes) +input [15:0] MaxFL; // Miximum frame length (in bytes) +input HugEn; // Pakets bigger then MaxFL enabled +input ExDfrEn; // Excessive deferral enabled +input PacketFinished_q; +input DlyCrcEn; // Delayed CRC enabled + +output [15:0] ByteCnt; // Byte counter +output [15:0] NibCnt; // Nibble counter +output ExcessiveDefer; // Excessive Deferral occuring +output NibCntEq7; // Nibble counter is equal to 7 +output NibCntEq15; // Nibble counter is equal to 15 +output MaxFrame; // Maximum frame occured +output NibbleMinFl; // Nibble counter is greater than the minimum frame length +output [2:0] DlyCrcCnt; // Delayed CRC Count + +wire ExcessiveDeferCnt; +wire ResetNibCnt; +wire IncrementNibCnt; +wire ResetByteCnt; +wire IncrementByteCnt; +wire ByteCntMax; + +reg [15:0] NibCnt; +reg [15:0] ByteCnt; +reg [2:0] DlyCrcCnt; + + + +assign IncrementNibCnt = StateIPG | StatePreamble | (|StateData) | StatePAD + | StateFCS | StateJam | StateBackOff | StateDefer & ~ExcessiveDefer & TxStartFrm; + + +assign ResetNibCnt = StateDefer & ExcessiveDefer & ~TxStartFrm | StatePreamble & NibCntEq15 + | StateJam & NibCntEq7 | StateIdle | StartDefer | StartIPG | StartFCS | StartJam; + +// Nibble Counter +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + NibCnt <= #Tp 16'h0; + else + begin + if(ResetNibCnt) + NibCnt <= #Tp 16'h0; + else + if(IncrementNibCnt) + NibCnt <= #Tp NibCnt + 1'b1; + end +end + + +assign NibCntEq7 = &NibCnt[2:0]; +assign NibCntEq15 = &NibCnt[3:0]; + +assign NibbleMinFl = NibCnt >= (((MinFL-3'h4)<<1) -1); // FCS should not be included in NibbleMinFl + +assign ExcessiveDeferCnt = NibCnt[13:0] == 16'h17b7; + +assign ExcessiveDefer = NibCnt[13:0] == 16'h17b7 & ~ExDfrEn; // 6071 nibbles + +assign IncrementByteCnt = StateData[1] & ~ByteCntMax + | StateBackOff & (&NibCnt[6:0]) + | (StatePAD | StateFCS) & NibCnt[0] & ~ByteCntMax; + +assign ResetByteCnt = StartBackoff | StateIdle & TxStartFrm | PacketFinished_q; + + +// Transmit Byte Counter +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + ByteCnt[15:0] <= #Tp 16'h0; + else + begin + if(ResetByteCnt) + ByteCnt[15:0] <= #Tp 16'h0; + else + if(IncrementByteCnt) + ByteCnt[15:0] <= #Tp ByteCnt[15:0] + 1'b1; + end +end + + +assign MaxFrame = ByteCnt[15:0] == MaxFL[15:0] & ~HugEn; + +assign ByteCntMax = &ByteCnt[15:0]; + + +// Delayed CRC counter +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + DlyCrcCnt <= #Tp 3'h0; + else + begin + if(StateData[1] & DlyCrcCnt == 3'h4 | StartJam | PacketFinished_q) + DlyCrcCnt <= #Tp 3'h0; + else + if(DlyCrcEn & (StateSFD | StateData[1] & (|DlyCrcCnt[2:0]))) + DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1; + end +end + + + +endmodule diff --git a/ethernet/source/ethernet/eth_txethmac.v b/ethernet/source/ethernet/eth_txethmac.v new file mode 100644 index 0000000..c190179 --- /dev/null +++ b/ethernet/source/ethernet/eth_txethmac.v @@ -0,0 +1,498 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_txethmac.v //// +/// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// - Novan Hartadi (novan@vlsi.itb.ac.id) //// +//// - Mahmud Galela (mgalela@vlsi.itb.ac.id) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_txethmac.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.9 2005/02/21 11:25:28 igorm +// Delayed CRC fixed. +// +// Revision 1.8 2003/01/30 13:33:24 mohor +// When padding was enabled and crc disabled, frame was not ended correctly. +// +// Revision 1.7 2002/02/26 16:24:01 mohor +// RetryCntLatched was unused and removed from design +// +// Revision 1.6 2002/02/22 12:56:35 mohor +// Retry is not activated when a Tx Underrun occured +// +// Revision 1.5 2002/02/11 09:18:22 mohor +// Tx status is written back to the BD. +// +// Revision 1.4 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.3 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.2 2001/09/11 14:17:00 mohor +// Few little NCSIM warnings fixed. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.3 2001/06/19 18:16:40 mohor +// TxClk changed to MTxClk (as discribed in the documentation). +// Crc changed so only one file can be used instead of two. +// +// Revision 1.2 2001/06/19 10:38:08 mohor +// Minor changes in header. +// +// Revision 1.1 2001/06/19 10:27:58 mohor +// TxEthMAC initial release. +// +// +// + +`include "timescale.v" + + +module eth_txethmac (MTxClk, Reset, TxStartFrm, TxEndFrm, TxUnderRun, TxData, CarrierSense, + Collision, Pad, CrcEn, FullD, HugEn, DlyCrcEn, MinFL, MaxFL, IPGT, + IPGR1, IPGR2, CollValid, MaxRet, NoBckof, ExDfrEn, + MTxD, MTxEn, MTxErr, TxDone, TxRetry, TxAbort, TxUsedData, WillTransmit, + ResetCollision, RetryCnt, StartTxDone, StartTxAbort, MaxCollisionOccured, + LateCollision, DeferIndication, StatePreamble, StateData + + ); + +parameter Tp = 1; + + +input MTxClk; // Transmit clock (from PHY) +input Reset; // Reset +input TxStartFrm; // Transmit packet start frame +input TxEndFrm; // Transmit packet end frame +input TxUnderRun; // Transmit packet under-run +input [7:0] TxData; // Transmit packet data byte +input CarrierSense; // Carrier sense (synchronized) +input Collision; // Collision (synchronized) +input Pad; // Pad enable (from register) +input CrcEn; // Crc enable (from register) +input FullD; // Full duplex (from register) +input HugEn; // Huge packets enable (from register) +input DlyCrcEn; // Delayed Crc enabled (from register) +input [15:0] MinFL; // Minimum frame length (from register) +input [15:0] MaxFL; // Maximum frame length (from register) +input [6:0] IPGT; // Back to back transmit inter packet gap parameter (from register) +input [6:0] IPGR1; // Non back to back transmit inter packet gap parameter IPGR1 (from register) +input [6:0] IPGR2; // Non back to back transmit inter packet gap parameter IPGR2 (from register) +input [5:0] CollValid; // Valid collision window (from register) +input [3:0] MaxRet; // Maximum retry number (from register) +input NoBckof; // No backoff (from register) +input ExDfrEn; // Excessive defferal enable (from register) + +output [3:0] MTxD; // Transmit nibble (to PHY) +output MTxEn; // Transmit enable (to PHY) +output MTxErr; // Transmit error (to PHY) +output TxDone; // Transmit packet done (to RISC) +output TxRetry; // Transmit packet retry (to RISC) +output TxAbort; // Transmit packet abort (to RISC) +output TxUsedData; // Transmit packet used data (to RISC) +output WillTransmit; // Will transmit (to RxEthMAC) +output ResetCollision; // Reset Collision (for synchronizing collision) +output [3:0] RetryCnt; // Latched Retry Counter for tx status purposes +output StartTxDone; +output StartTxAbort; +output MaxCollisionOccured; +output LateCollision; +output DeferIndication; +output StatePreamble; +output [1:0] StateData; + +reg [3:0] MTxD; +reg MTxEn; +reg MTxErr; +reg TxDone; +reg TxRetry; +reg TxAbort; +reg TxUsedData; +reg WillTransmit; +reg ColWindow; +reg StopExcessiveDeferOccured; +reg [3:0] RetryCnt; +reg [3:0] MTxD_d; +reg StatusLatch; +reg PacketFinished_q; +reg PacketFinished; + + +wire ExcessiveDeferOccured; +wire StartIPG; +wire StartPreamble; +wire [1:0] StartData; +wire StartFCS; +wire StartJam; +wire StartDefer; +wire StartBackoff; +wire StateDefer; +wire StateIPG; +wire StateIdle; +wire StatePAD; +wire StateFCS; +wire StateJam; +wire StateJam_q; +wire StateBackOff; +wire StateSFD; +wire StartTxRetry; +wire UnderRun; +wire TooBig; +wire [31:0] Crc; +wire CrcError; +wire [2:0] DlyCrcCnt; +wire [15:0] NibCnt; +wire NibCntEq7; +wire NibCntEq15; +wire NibbleMinFl; +wire ExcessiveDefer; +wire [15:0] ByteCnt; +wire MaxFrame; +wire RetryMax; +wire RandomEq0; +wire RandomEqByteCnt; +wire PacketFinished_d; + + + +assign ResetCollision = ~(StatePreamble | (|StateData) | StatePAD | StateFCS); + +assign ExcessiveDeferOccured = TxStartFrm & StateDefer & ExcessiveDefer & ~StopExcessiveDeferOccured; + +assign StartTxDone = ~Collision & (StateFCS & NibCntEq7 | StateData[1] & TxEndFrm & (~Pad | Pad & NibbleMinFl) & ~CrcEn); + +assign UnderRun = StateData[0] & TxUnderRun & ~Collision; + +assign TooBig = ~Collision & MaxFrame & (StateData[0] & ~TxUnderRun | StateFCS); + +// assign StartTxRetry = StartJam & (ColWindow & ~RetryMax); +assign StartTxRetry = StartJam & (ColWindow & ~RetryMax) & ~UnderRun; + +assign LateCollision = StartJam & ~ColWindow & ~UnderRun; + +assign MaxCollisionOccured = StartJam & ColWindow & RetryMax; + +assign StateSFD = StatePreamble & NibCntEq15; + +assign StartTxAbort = TooBig | UnderRun | ExcessiveDeferOccured | LateCollision | MaxCollisionOccured; + + +// StopExcessiveDeferOccured +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + StopExcessiveDeferOccured <= #Tp 1'b0; + else + begin + if(~TxStartFrm) + StopExcessiveDeferOccured <= #Tp 1'b0; + else + if(ExcessiveDeferOccured) + StopExcessiveDeferOccured <= #Tp 1'b1; + end +end + + +// Collision Window +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + ColWindow <= #Tp 1'b1; + else + begin + if(~Collision & ByteCnt[5:0] == CollValid[5:0] & (StateData[1] | StatePAD & NibCnt[0] | StateFCS & NibCnt[0])) + ColWindow <= #Tp 1'b0; + else + if(StateIdle | StateIPG) + ColWindow <= #Tp 1'b1; + end +end + + +// Start Window +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + StatusLatch <= #Tp 1'b0; + else + begin + if(~TxStartFrm) + StatusLatch <= #Tp 1'b0; + else + if(ExcessiveDeferOccured | StateIdle) + StatusLatch <= #Tp 1'b1; + end +end + + +// Transmit packet used data +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxUsedData <= #Tp 1'b0; + else + TxUsedData <= #Tp |StartData; +end + + +// Transmit packet done +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxDone <= #Tp 1'b0; + else + begin + if(TxStartFrm & ~StatusLatch) + TxDone <= #Tp 1'b0; + else + if(StartTxDone) + TxDone <= #Tp 1'b1; + end +end + + +// Transmit packet retry +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxRetry <= #Tp 1'b0; + else + begin + if(TxStartFrm & ~StatusLatch) + TxRetry <= #Tp 1'b0; + else + if(StartTxRetry) + TxRetry <= #Tp 1'b1; + end +end + + +// Transmit packet abort +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxAbort <= #Tp 1'b0; + else + begin + if(TxStartFrm & ~StatusLatch & ~ExcessiveDeferOccured) + TxAbort <= #Tp 1'b0; + else + if(StartTxAbort) + TxAbort <= #Tp 1'b1; + end +end + + +// Retry counter +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + RetryCnt[3:0] <= #Tp 4'h0; + else + begin + if(ExcessiveDeferOccured | UnderRun | TooBig | StartTxDone | TxUnderRun + | StateJam & NibCntEq7 & (~ColWindow | RetryMax)) + RetryCnt[3:0] <= #Tp 4'h0; + else + if(StateJam & NibCntEq7 & ColWindow & (RandomEq0 | NoBckof) | StateBackOff & RandomEqByteCnt) + RetryCnt[3:0] <= #Tp RetryCnt[3:0] + 1'b1; + end +end + + +assign RetryMax = RetryCnt[3:0] == MaxRet[3:0]; + + +// Transmit nibble +always @ (StatePreamble or StateData or StateData or StateFCS or StateJam or StateSFD or TxData or + Crc or NibCntEq15) +begin + if(StateData[0]) + MTxD_d[3:0] = TxData[3:0]; // Lower nibble + else + if(StateData[1]) + MTxD_d[3:0] = TxData[7:4]; // Higher nibble + else + if(StateFCS) + MTxD_d[3:0] = {~Crc[28], ~Crc[29], ~Crc[30], ~Crc[31]}; // Crc + else + if(StateJam) + MTxD_d[3:0] = 4'h9; // Jam pattern + else + if(StatePreamble) + if(NibCntEq15) + MTxD_d[3:0] = 4'hd; // SFD + else + MTxD_d[3:0] = 4'h5; // Preamble + else + MTxD_d[3:0] = 4'h0; +end + + +// Transmit Enable +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + MTxEn <= #Tp 1'b0; + else + MTxEn <= #Tp StatePreamble | (|StateData) | StatePAD | StateFCS | StateJam; +end + + +// Transmit nibble +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + MTxD[3:0] <= #Tp 4'h0; + else + MTxD[3:0] <= #Tp MTxD_d[3:0]; +end + + +// Transmit error +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + MTxErr <= #Tp 1'b0; + else + MTxErr <= #Tp TooBig | UnderRun; +end + + +// WillTransmit +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + WillTransmit <= #Tp 1'b0; + else + WillTransmit <= #Tp StartPreamble | StatePreamble | (|StateData) | StatePAD | StateFCS | StateJam; +end + + +assign PacketFinished_d = StartTxDone | TooBig | UnderRun | LateCollision | MaxCollisionOccured | ExcessiveDeferOccured; + + +// Packet finished +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + begin + PacketFinished <= #Tp 1'b0; + PacketFinished_q <= #Tp 1'b0; + end + else + begin + PacketFinished <= #Tp PacketFinished_d; + PacketFinished_q <= #Tp PacketFinished; + end +end + + +// Connecting module Counters +eth_txcounters txcounters1 (.StatePreamble(StatePreamble), .StateIPG(StateIPG), .StateData(StateData), + .StatePAD(StatePAD), .StateFCS(StateFCS), .StateJam(StateJam), .StateBackOff(StateBackOff), + .StateDefer(StateDefer), .StateIdle(StateIdle), .StartDefer(StartDefer), .StartIPG(StartIPG), + .StartFCS(StartFCS), .StartJam(StartJam), .TxStartFrm(TxStartFrm), .MTxClk(MTxClk), + .Reset(Reset), .MinFL(MinFL), .MaxFL(MaxFL), .HugEn(HugEn), .ExDfrEn(ExDfrEn), + .PacketFinished_q(PacketFinished_q), .DlyCrcEn(DlyCrcEn), .StartBackoff(StartBackoff), + .StateSFD(StateSFD), .ByteCnt(ByteCnt), .NibCnt(NibCnt), .ExcessiveDefer(ExcessiveDefer), + .NibCntEq7(NibCntEq7), .NibCntEq15(NibCntEq15), .MaxFrame(MaxFrame), .NibbleMinFl(NibbleMinFl), + .DlyCrcCnt(DlyCrcCnt) + ); + + +// Connecting module StateM +eth_txstatem txstatem1 (.MTxClk(MTxClk), .Reset(Reset), .ExcessiveDefer(ExcessiveDefer), .CarrierSense(CarrierSense), + .NibCnt(NibCnt[6:0]), .IPGT(IPGT), .IPGR1(IPGR1), .IPGR2(IPGR2), .FullD(FullD), + .TxStartFrm(TxStartFrm), .TxEndFrm(TxEndFrm), .TxUnderRun(TxUnderRun), .Collision(Collision), + .UnderRun(UnderRun), .StartTxDone(StartTxDone), .TooBig(TooBig), .NibCntEq7(NibCntEq7), + .NibCntEq15(NibCntEq15), .MaxFrame(MaxFrame), .Pad(Pad), .CrcEn(CrcEn), + .NibbleMinFl(NibbleMinFl), .RandomEq0(RandomEq0), .ColWindow(ColWindow), .RetryMax(RetryMax), + .NoBckof(NoBckof), .RandomEqByteCnt(RandomEqByteCnt), .StateIdle(StateIdle), + .StateIPG(StateIPG), .StatePreamble(StatePreamble), .StateData(StateData), .StatePAD(StatePAD), + .StateFCS(StateFCS), .StateJam(StateJam), .StateJam_q(StateJam_q), .StateBackOff(StateBackOff), + .StateDefer(StateDefer), .StartFCS(StartFCS), .StartJam(StartJam), .StartBackoff(StartBackoff), + .StartDefer(StartDefer), .DeferIndication(DeferIndication), .StartPreamble(StartPreamble), .StartData(StartData), .StartIPG(StartIPG) + ); + + +wire Enable_Crc; +wire [3:0] Data_Crc; +wire Initialize_Crc; + +assign Enable_Crc = ~StateFCS; + +assign Data_Crc[0] = StateData[0]? TxData[3] : StateData[1]? TxData[7] : 1'b0; +assign Data_Crc[1] = StateData[0]? TxData[2] : StateData[1]? TxData[6] : 1'b0; +assign Data_Crc[2] = StateData[0]? TxData[1] : StateData[1]? TxData[5] : 1'b0; +assign Data_Crc[3] = StateData[0]? TxData[0] : StateData[1]? TxData[4] : 1'b0; + +assign Initialize_Crc = StateIdle | StatePreamble | (|DlyCrcCnt); + + +// Connecting module Crc +eth_crc txcrc (.Clk(MTxClk), .Reset(Reset), .Data(Data_Crc), .Enable(Enable_Crc), .Initialize(Initialize_Crc), + .Crc(Crc), .CrcError(CrcError) + ); + + +// Connecting module Random +eth_random random1 (.MTxClk(MTxClk), .Reset(Reset), .StateJam(StateJam), .StateJam_q(StateJam_q), .RetryCnt(RetryCnt), + .NibCnt(NibCnt), .ByteCnt(ByteCnt[9:0]), .RandomEq0(RandomEq0), .RandomEqByteCnt(RandomEqByteCnt)); + + + + +endmodule diff --git a/ethernet/source/ethernet/eth_txstatem.v b/ethernet/source/ethernet/eth_txstatem.v new file mode 100644 index 0000000..52dc1c6 --- /dev/null +++ b/ethernet/source/ethernet/eth_txstatem.v @@ -0,0 +1,290 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_txstatem.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// - Novan Hartadi (novan@vlsi.itb.ac.id) //// +//// - Mahmud Galela (mgalela@vlsi.itb.ac.id) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_txstatem.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2003/01/30 13:29:08 tadejm +// Defer indication changed. +// +// Revision 1.5 2002/10/30 12:54:50 mohor +// State machine goes from idle to the defer state when CarrierSense is 1. FCS (CRC appending) fixed to check the CrcEn bit also when padding is necessery. +// +// Revision 1.4 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.3 2001/10/19 08:43:51 mohor +// eth_timescale.v changed to timescale.v This is done because of the +// simulation of the few cores in a one joined project. +// +// Revision 1.2 2001/09/11 14:17:00 mohor +// Few little NCSIM warnings fixed. +// +// Revision 1.1 2001/08/06 14:44:29 mohor +// A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). +// Include files fixed to contain no path. +// File names and module names changed ta have a eth_ prologue in the name. +// File eth_timescale.v is used to define timescale +// All pin names on the top module are changed to contain _I, _O or _OE at the end. +// Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O +// and Mdo_OE. The bidirectional signal must be created on the top level. This +// is done due to the ASIC tools. +// +// Revision 1.1 2001/07/30 21:23:42 mohor +// Directory structure changed. Files checked and joind together. +// +// Revision 1.3 2001/06/19 18:16:40 mohor +// TxClk changed to MTxClk (as discribed in the documentation). +// Crc changed so only one file can be used instead of two. +// +// Revision 1.2 2001/06/19 10:38:07 mohor +// Minor changes in header. +// +// Revision 1.1 2001/06/19 10:27:57 mohor +// TxEthMAC initial release. +// +// +// +// + + +`include "timescale.v" + + +module eth_txstatem (MTxClk, Reset, ExcessiveDefer, CarrierSense, NibCnt, IPGT, IPGR1, + IPGR2, FullD, TxStartFrm, TxEndFrm, TxUnderRun, Collision, UnderRun, + StartTxDone, TooBig, NibCntEq7, NibCntEq15, MaxFrame, Pad, CrcEn, + NibbleMinFl, RandomEq0, ColWindow, RetryMax, NoBckof, RandomEqByteCnt, + StateIdle, StateIPG, StatePreamble, StateData, StatePAD, StateFCS, + StateJam, StateJam_q, StateBackOff, StateDefer, StartFCS, StartJam, + StartBackoff, StartDefer, DeferIndication, StartPreamble, StartData, StartIPG + ); + +parameter Tp = 1; + +input MTxClk; +input Reset; +input ExcessiveDefer; +input CarrierSense; +input [6:0] NibCnt; +input [6:0] IPGT; +input [6:0] IPGR1; +input [6:0] IPGR2; +input FullD; +input TxStartFrm; +input TxEndFrm; +input TxUnderRun; +input Collision; +input UnderRun; +input StartTxDone; +input TooBig; +input NibCntEq7; +input NibCntEq15; +input MaxFrame; +input Pad; +input CrcEn; +input NibbleMinFl; +input RandomEq0; +input ColWindow; +input RetryMax; +input NoBckof; +input RandomEqByteCnt; + + +output StateIdle; // Idle state +output StateIPG; // IPG state +output StatePreamble; // Preamble state +output [1:0] StateData; // Data state +output StatePAD; // PAD state +output StateFCS; // FCS state +output StateJam; // Jam state +output StateJam_q; // Delayed Jam state +output StateBackOff; // Backoff state +output StateDefer; // Defer state + +output StartFCS; // FCS state will be activated in next clock +output StartJam; // Jam state will be activated in next clock +output StartBackoff; // Backoff state will be activated in next clock +output StartDefer; // Defer state will be activated in next clock +output DeferIndication; +output StartPreamble; // Preamble state will be activated in next clock +output [1:0] StartData; // Data state will be activated in next clock +output StartIPG; // IPG state will be activated in next clock + +wire StartIdle; // Idle state will be activated in next clock +wire StartPAD; // PAD state will be activated in next clock + + +reg StateIdle; +reg StateIPG; +reg StatePreamble; +reg [1:0] StateData; +reg StatePAD; +reg StateFCS; +reg StateJam; +reg StateJam_q; +reg StateBackOff; +reg StateDefer; +reg Rule1; + + +// Defining the next state +assign StartIPG = StateDefer & ~ExcessiveDefer & ~CarrierSense; + +assign StartIdle = StateIPG & (Rule1 & NibCnt[6:0] >= IPGT | ~Rule1 & NibCnt[6:0] >= IPGR2); + +assign StartPreamble = StateIdle & TxStartFrm & ~CarrierSense; + +assign StartData[0] = ~Collision & (StatePreamble & NibCntEq15 | StateData[1] & ~TxEndFrm); + +assign StartData[1] = ~Collision & StateData[0] & ~TxUnderRun & ~MaxFrame; + +assign StartPAD = ~Collision & StateData[1] & TxEndFrm & Pad & ~NibbleMinFl; + +assign StartFCS = ~Collision & StateData[1] & TxEndFrm & (~Pad | Pad & NibbleMinFl) & CrcEn + | ~Collision & StatePAD & NibbleMinFl & CrcEn; + +assign StartJam = (Collision | UnderRun) & ((StatePreamble & NibCntEq15) | (|StateData[1:0]) | StatePAD | StateFCS); + +assign StartBackoff = StateJam & ~RandomEq0 & ColWindow & ~RetryMax & NibCntEq7 & ~NoBckof; + +assign StartDefer = StateIPG & ~Rule1 & CarrierSense & NibCnt[6:0] <= IPGR1 & NibCnt[6:0] != IPGR2 + | StateIdle & CarrierSense + | StateJam & NibCntEq7 & (NoBckof | RandomEq0 | ~ColWindow | RetryMax) + | StateBackOff & (TxUnderRun | RandomEqByteCnt) + | StartTxDone | TooBig; + +assign DeferIndication = StateIdle & CarrierSense; + +// Tx State Machine +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + begin + StateIPG <= #Tp 1'b0; + StateIdle <= #Tp 1'b0; + StatePreamble <= #Tp 1'b0; + StateData[1:0] <= #Tp 2'b0; + StatePAD <= #Tp 1'b0; + StateFCS <= #Tp 1'b0; + StateJam <= #Tp 1'b0; + StateJam_q <= #Tp 1'b0; + StateBackOff <= #Tp 1'b0; + StateDefer <= #Tp 1'b1; + end + else + begin + StateData[1:0] <= #Tp StartData[1:0]; + StateJam_q <= #Tp StateJam; + + if(StartDefer | StartIdle) + StateIPG <= #Tp 1'b0; + else + if(StartIPG) + StateIPG <= #Tp 1'b1; + + if(StartDefer | StartPreamble) + StateIdle <= #Tp 1'b0; + else + if(StartIdle) + StateIdle <= #Tp 1'b1; + + if(StartData[0] | StartJam) + StatePreamble <= #Tp 1'b0; + else + if(StartPreamble) + StatePreamble <= #Tp 1'b1; + + if(StartFCS | StartJam) + StatePAD <= #Tp 1'b0; + else + if(StartPAD) + StatePAD <= #Tp 1'b1; + + if(StartJam | StartDefer) + StateFCS <= #Tp 1'b0; + else + if(StartFCS) + StateFCS <= #Tp 1'b1; + + if(StartBackoff | StartDefer) + StateJam <= #Tp 1'b0; + else + if(StartJam) + StateJam <= #Tp 1'b1; + + if(StartDefer) + StateBackOff <= #Tp 1'b0; + else + if(StartBackoff) + StateBackOff <= #Tp 1'b1; + + if(StartIPG) + StateDefer <= #Tp 1'b0; + else + if(StartDefer) + StateDefer <= #Tp 1'b1; + end +end + + +// This sections defines which interpack gap rule to use +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + Rule1 <= #Tp 1'b0; + else + begin + if(StateIdle | StateBackOff) + Rule1 <= #Tp 1'b0; + else + if(StatePreamble | FullD) + Rule1 <= #Tp 1'b1; + end +end + + + +endmodule diff --git a/ethernet/source/ethernet/eth_wishbone.v b/ethernet/source/ethernet/eth_wishbone.v new file mode 100644 index 0000000..e8caec3 --- /dev/null +++ b/ethernet/source/ethernet/eth_wishbone.v @@ -0,0 +1,2562 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// eth_wishbone.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is available in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001, 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: eth_wishbone.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.58 2005/03/21 20:07:18 igorm +// Some small fixes + some troubles fixed. +// +// Revision 1.57 2005/02/21 11:35:33 igorm +// Defer indication fixed. +// +// Revision 1.56 2004/04/30 10:30:00 igorm +// Accidently deleted line put back. +// +// Revision 1.55 2004/04/26 15:26:23 igorm +// - Bug connected to the TX_BD_NUM_Wr signal fixed (bug came in with the +// previous update of the core. +// - TxBDAddress is set to 0 after the TX is enabled in the MODER register. +// - RxBDAddress is set to r_TxBDNum<<1 after the RX is enabled in the MODER +// register. (thanks to Mathias and Torbjorn) +// - Multicast reception was fixed. Thanks to Ulrich Gries +// +// Revision 1.54 2003/11/12 18:24:59 tadejm +// WISHBONE slave changed and tested from only 32-bit accesss to byte access. +// +// Revision 1.53 2003/10/17 07:46:17 markom +// mbist signals updated according to newest convention +// +// Revision 1.52 2003/01/30 14:51:31 mohor +// Reset has priority in some flipflops. +// +// Revision 1.51 2003/01/30 13:36:22 mohor +// A new bug (entered with previous update) fixed. When abort occured sometimes +// data transmission was blocked. +// +// Revision 1.50 2003/01/22 13:49:26 tadejm +// When control packets were received, they were ignored in some cases. +// +// Revision 1.49 2003/01/21 12:09:40 mohor +// When receiving normal data frame and RxFlow control was switched on, RXB +// interrupt was not set. +// +// Revision 1.48 2003/01/20 12:05:26 mohor +// When in full duplex, transmit was sometimes blocked. Fixed. +// +// Revision 1.47 2002/11/22 13:26:21 mohor +// Registers RxStatusWrite_rck and RxStatusWriteLatched were not used +// anywhere. Removed. +// +// Revision 1.46 2002/11/22 01:57:06 mohor +// Rx Flow control fixed. CF flag added to the RX buffer descriptor. RxAbort +// synchronized. +// +// Revision 1.45 2002/11/19 17:33:34 mohor +// AddressMiss status is connecting to the Rx BD. AddressMiss is identifying +// that a frame was received because of the promiscous mode. +// +// Revision 1.44 2002/11/13 22:21:40 tadejm +// RxError is not generated when small frame reception is enabled and small +// frames are received. +// +// Revision 1.43 2002/10/18 20:53:34 mohor +// case changed to casex. +// +// Revision 1.42 2002/10/18 17:04:20 tadejm +// Changed BIST scan signals. +// +// Revision 1.41 2002/10/18 15:42:09 tadejm +// Igor added WB burst support and repaired BUG when handling TX under-run and retry. +// +// Revision 1.40 2002/10/14 16:07:02 mohor +// TxStatus is written after last access to the TX fifo is finished (in case of abort +// or retry). TxDone is fixed. +// +// Revision 1.39 2002/10/11 15:35:20 mohor +// txfifo_cnt and rxfifo_cnt counters width is defined in the eth_define.v file, +// TxDone and TxRetry are generated after the current WISHBONE access is +// finished. +// +// Revision 1.38 2002/10/10 16:29:30 mohor +// BIST added. +// +// Revision 1.37 2002/09/11 14:18:46 mohor +// Sometimes both RxB_IRQ and RxE_IRQ were activated. Bug fixed. +// +// Revision 1.36 2002/09/10 13:48:46 mohor +// Reception is possible after RxPointer is read and not after BD is read. For +// that reason RxBDReady is changed to RxReady. +// Busy_IRQ interrupt connected. When there is no RxBD ready and frame +// comes, interrupt is generated. +// +// Revision 1.35 2002/09/10 10:35:23 mohor +// Ethernet debug registers removed. +// +// Revision 1.34 2002/09/08 16:31:49 mohor +// Async reset for WB_ACK_O removed (when core was in reset, it was +// impossible to access BDs). +// RxPointers and TxPointers names changed to be more descriptive. +// TxUnderRun synchronized. +// +// Revision 1.33 2002/09/04 18:47:57 mohor +// Debug registers reg1, 2, 3, 4 connected. Synchronization of many signals +// changed (bugs fixed). Access to un-alligned buffers fixed. RxAbort signal +// was not used OK. +// +// Revision 1.32 2002/08/14 19:31:48 mohor +// Register TX_BD_NUM is changed so it contains value of the Tx buffer descriptors. No +// need to multiply or devide any more. +// +// Revision 1.31 2002/07/25 18:29:01 mohor +// WriteRxDataToMemory signal changed so end of frame (when last word is +// written to fifo) is changed. +// +// Revision 1.30 2002/07/23 15:28:31 mohor +// Ram , used for BDs changed from generic_spram to eth_spram_256x32. +// +// Revision 1.29 2002/07/20 00:41:32 mohor +// ShiftEnded synchronization changed. +// +// Revision 1.28 2002/07/18 16:11:46 mohor +// RxBDAddress takes `ETH_TX_BD_NUM_DEF value after reset. +// +// Revision 1.27 2002/07/11 02:53:20 mohor +// RxPointer bug fixed. +// +// Revision 1.26 2002/07/10 13:12:38 mohor +// Previous bug wasn't succesfully removed. Now fixed. +// +// Revision 1.25 2002/07/09 23:53:24 mohor +// Master state machine had a bug when switching from master write to +// master read. +// +// Revision 1.24 2002/07/09 20:44:41 mohor +// m_wb_cyc_o signal released after every single transfer. +// +// Revision 1.23 2002/05/03 10:15:50 mohor +// Outputs registered. Reset changed for eth_wishbone module. +// +// Revision 1.22 2002/04/24 08:52:19 mohor +// Compiler directives added. Tx and Rx fifo size incremented. A "late collision" +// bug fixed. +// +// Revision 1.21 2002/03/29 16:18:11 lampret +// Small typo fixed. +// +// Revision 1.20 2002/03/25 16:19:12 mohor +// Any address can be used for Tx and Rx BD pointers. Address does not need +// to be aligned. +// +// Revision 1.19 2002/03/19 12:51:50 mohor +// Comments in Slovene language removed. +// +// Revision 1.18 2002/03/19 12:46:52 mohor +// casex changed with case, fifo reset changed. +// +// Revision 1.17 2002/03/09 16:08:45 mohor +// rx_fifo was not always cleared ok. Fixed. +// +// Revision 1.16 2002/03/09 13:51:20 mohor +// Status was not latched correctly sometimes. Fixed. +// +// Revision 1.15 2002/03/08 06:56:46 mohor +// Big Endian problem when sending frames fixed. +// +// Revision 1.14 2002/03/02 19:12:40 mohor +// Byte ordering changed (Big Endian used). casex changed with case because +// Xilinx Foundation had problems. Tested in HW. It WORKS. +// +// Revision 1.13 2002/02/26 16:59:55 mohor +// Small fixes for external/internal DMA missmatches. +// +// Revision 1.12 2002/02/26 16:22:07 mohor +// Interrupts changed +// +// Revision 1.11 2002/02/15 17:07:39 mohor +// Status was not written correctly when frames were discarted because of +// address mismatch. +// +// Revision 1.10 2002/02/15 12:17:39 mohor +// RxStartFrm cleared when abort or retry comes. +// +// Revision 1.9 2002/02/15 11:59:10 mohor +// Changes that were lost when updating from 1.5 to 1.8 fixed. +// +// Revision 1.8 2002/02/14 20:54:33 billditt +// Addition of new module eth_addrcheck.v +// +// Revision 1.7 2002/02/12 17:03:47 mohor +// RxOverRun added to statuses. +// +// Revision 1.6 2002/02/11 09:18:22 mohor +// Tx status is written back to the BD. +// +// Revision 1.5 2002/02/08 16:21:54 mohor +// Rx status is written back to the BD. +// +// Revision 1.4 2002/02/06 14:10:21 mohor +// non-DMA host interface added. Select the right configutation in eth_defines. +// +// Revision 1.3 2002/02/05 16:44:39 mohor +// Both rx and tx part are finished. Tested with wb_clk_i between 10 and 200 +// MHz. Statuses, overrun, control frame transmission and reception still need +// to be fixed. +// +// Revision 1.2 2002/02/01 12:46:51 mohor +// Tx part finished. TxStatus needs to be fixed. Pause request needs to be +// added. +// +// Revision 1.1 2002/01/23 10:47:59 mohor +// Initial version. Equals to eth_wishbonedma.v at this moment. +// +// +// + +`include "eth_defines.v" +`include "timescale.v" + + +module eth_wishbone + ( + + // WISHBONE common + WB_CLK_I, WB_DAT_I, WB_DAT_O, + + // WISHBONE slave + WB_ADR_I, WB_WE_I, WB_ACK_O, + BDCs, + + Reset, + + // WISHBONE master + m_wb_adr_o, m_wb_sel_o, m_wb_we_o, + m_wb_dat_o, m_wb_dat_i, m_wb_cyc_o, + m_wb_stb_o, m_wb_ack_i, m_wb_err_i, + +`ifdef ETH_WISHBONE_B3 + m_wb_cti_o, m_wb_bte_o, +`endif + + //TX + MTxClk, TxStartFrm, TxEndFrm, TxUsedData, TxData, + TxRetry, TxAbort, TxUnderRun, TxDone, PerPacketCrcEn, + PerPacketPad, + + //RX + MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm, RxAbort, RxStatusWriteLatched_sync2, + + // Register + r_TxEn, r_RxEn, r_TxBDNum, r_RxFlow, r_PassAll, + + // Interrupts + TxB_IRQ, TxE_IRQ, RxB_IRQ, RxE_IRQ, Busy_IRQ, + + // Rx Status + InvalidSymbol, LatchedCrcError, RxLateCollision, ShortFrame, DribbleNibble, + ReceivedPacketTooBig, RxLength, LoadRxStatus, ReceivedPacketGood, AddressMiss, + ReceivedPauseFrm, + + // Tx Status + RetryCntLatched, RetryLimit, LateCollLatched, DeferLatched, RstDeferLatched, CarrierSenseLost + + // Bist +`ifdef ETH_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif + + + + ); + + +parameter Tp = 1; + + +// WISHBONE common +input WB_CLK_I; // WISHBONE clock +input [31:0] WB_DAT_I; // WISHBONE data input +output [31:0] WB_DAT_O; // WISHBONE data output + +// WISHBONE slave +input [9:2] WB_ADR_I; // WISHBONE address input +input WB_WE_I; // WISHBONE write enable input +input [3:0] BDCs; // Buffer descriptors are selected +output WB_ACK_O; // WISHBONE acknowledge output + +// WISHBONE master +output [29:0] m_wb_adr_o; // +output [3:0] m_wb_sel_o; // +output m_wb_we_o; // +output [31:0] m_wb_dat_o; // +output m_wb_cyc_o; // +output m_wb_stb_o; // +input [31:0] m_wb_dat_i; // +input m_wb_ack_i; // +input m_wb_err_i; // + +`ifdef ETH_WISHBONE_B3 +output [2:0] m_wb_cti_o; // Cycle Type Identifier +output [1:0] m_wb_bte_o; // Burst Type Extension +reg [2:0] m_wb_cti_o; // Cycle Type Identifier +`endif + +input Reset; // Reset signal + +// Rx Status signals +input InvalidSymbol; // Invalid symbol was received during reception in 100 Mbps mode +input LatchedCrcError; // CRC error +input RxLateCollision; // Late collision occured while receiving frame +input ShortFrame; // Frame shorter then the minimum size (r_MinFL) was received while small packets are enabled (r_RecSmall) +input DribbleNibble; // Extra nibble received +input ReceivedPacketTooBig;// Received packet is bigger than r_MaxFL +input [15:0] RxLength; // Length of the incoming frame +input LoadRxStatus; // Rx status was loaded +input ReceivedPacketGood;// Received packet's length and CRC are good +input AddressMiss; // When a packet is received AddressMiss status is written to the Rx BD +input r_RxFlow; +input r_PassAll; +input ReceivedPauseFrm; + +// Tx Status signals +input [3:0] RetryCntLatched; // Latched Retry Counter +input RetryLimit; // Retry limit reached (Retry Max value + 1 attempts were made) +input LateCollLatched; // Late collision occured +input DeferLatched; // Defer indication (Frame was defered before sucessfully sent) +output RstDeferLatched; +input CarrierSenseLost; // Carrier Sense was lost during the frame transmission + +// Tx +input MTxClk; // Transmit clock (from PHY) +input TxUsedData; // Transmit packet used data +input TxRetry; // Transmit packet retry +input TxAbort; // Transmit packet abort +input TxDone; // Transmission ended +output TxStartFrm; // Transmit packet start frame +output TxEndFrm; // Transmit packet end frame +output [7:0] TxData; // Transmit packet data byte +output TxUnderRun; // Transmit packet under-run +output PerPacketCrcEn; // Per packet crc enable +output PerPacketPad; // Per packet pading + +// Rx +input MRxClk; // Receive clock (from PHY) +input [7:0] RxData; // Received data byte (from PHY) +input RxValid; // +input RxStartFrm; // +input RxEndFrm; // +input RxAbort; // This signal is set when address doesn't match. +output RxStatusWriteLatched_sync2; + +//Register +input r_TxEn; // Transmit enable +input r_RxEn; // Receive enable +input [7:0] r_TxBDNum; // Receive buffer descriptor number + +// Interrupts +output TxB_IRQ; +output TxE_IRQ; +output RxB_IRQ; +output RxE_IRQ; +output Busy_IRQ; + + +// Bist +`ifdef ETH_BIST +input mbist_si_i; // bist scan serial in +output mbist_so_o; // bist scan serial out +input [`ETH_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + +reg TxB_IRQ; +reg TxE_IRQ; +reg RxB_IRQ; +reg RxE_IRQ; + +reg TxStartFrm; +reg TxEndFrm; +reg [7:0] TxData; + +reg TxUnderRun; +reg TxUnderRun_wb; + +reg TxBDRead; +wire TxStatusWrite; + +reg [1:0] TxValidBytesLatched; + +reg [15:0] TxLength; +reg [15:0] LatchedTxLength; +reg [14:11] TxStatus; + +reg [14:13] RxStatus; + +reg TxStartFrm_wb; +reg TxRetry_wb; +reg TxAbort_wb; +reg TxDone_wb; + +reg TxDone_wb_q; +reg TxAbort_wb_q; +reg TxRetry_wb_q; +reg TxRetryPacket; +reg TxRetryPacket_NotCleared; +reg TxDonePacket; +reg TxDonePacket_NotCleared; +reg TxAbortPacket; +reg TxAbortPacket_NotCleared; +reg RxBDReady; +reg RxReady; +reg TxBDReady; + +reg RxBDRead; + +reg [31:0] TxDataLatched; +reg [1:0] TxByteCnt; +reg LastWord; +reg ReadTxDataFromFifo_tck; + +reg BlockingTxStatusWrite; +reg BlockingTxBDRead; + +reg Flop; + +reg [7:1] TxBDAddress; +reg [7:1] RxBDAddress; + +reg TxRetrySync1; +reg TxAbortSync1; +reg TxDoneSync1; + +reg TxAbort_q; +reg TxRetry_q; +reg TxUsedData_q; + +reg [31:0] RxDataLatched2; + +reg [31:8] RxDataLatched1; // Big Endian Byte Ordering + +reg [1:0] RxValidBytes; +reg [1:0] RxByteCnt; +reg LastByteIn; +reg ShiftWillEnd; + +reg WriteRxDataToFifo; +reg [15:0] LatchedRxLength; +reg RxAbortLatched; + +reg ShiftEnded; +reg RxOverrun; + +reg [3:0] BDWrite; // BD Write Enable for access from WISHBONE side +reg BDRead; // BD Read access from WISHBONE side +wire [31:0] RxBDDataIn; // Rx BD data in +wire [31:0] TxBDDataIn; // Tx BD data in + +reg TxEndFrm_wb; + +wire TxRetryPulse; +wire TxDonePulse; +wire TxAbortPulse; + +wire StartRxBDRead; + +wire StartTxBDRead; + +wire TxIRQEn; +wire WrapTxStatusBit; + +wire RxIRQEn; +wire WrapRxStatusBit; + +wire [1:0] TxValidBytes; + +wire [7:1] TempTxBDAddress; +wire [7:1] TempRxBDAddress; + +wire RxStatusWrite; +wire RxBufferFull; +wire RxBufferAlmostEmpty; +wire RxBufferEmpty; + +reg WB_ACK_O; + +wire [8:0] RxStatusIn; +reg [8:0] RxStatusInLatched; + +reg WbEn, WbEn_q; +reg RxEn, RxEn_q; +reg TxEn, TxEn_q; +reg r_TxEn_q; +reg r_RxEn_q; + +wire ram_ce; +wire [3:0] ram_we; +wire ram_oe; +reg [7:0] ram_addr; +reg [31:0] ram_di; +wire [31:0] ram_do; + +wire StartTxPointerRead; +reg TxPointerRead; +reg TxEn_needed; +reg RxEn_needed; + +wire StartRxPointerRead; +reg RxPointerRead; + +`ifdef ETH_WISHBONE_B3 +assign m_wb_bte_o = 2'b00; // Linear burst +`endif + +assign m_wb_stb_o = m_wb_cyc_o; + +always @ (posedge WB_CLK_I) +begin + WB_ACK_O <=#Tp (|BDWrite) & WbEn & WbEn_q | BDRead & WbEn & ~WbEn_q; +end + +assign WB_DAT_O = ram_do; + +// Generic synchronous single-port RAM interface +eth_spram_256x32 bd_ram ( + .clk(WB_CLK_I), .rst(Reset), .ce(ram_ce), .we(ram_we), .oe(ram_oe), .addr(ram_addr), .di(ram_di), .do(ram_do) +`ifdef ETH_BIST + , + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) +`endif +); + +assign ram_ce = 1'b1; +assign ram_we = (BDWrite & {4{(WbEn & WbEn_q)}}) | {4{(TxStatusWrite | RxStatusWrite)}}; +assign ram_oe = BDRead & WbEn & WbEn_q | TxEn & TxEn_q & (TxBDRead | TxPointerRead) | RxEn & RxEn_q & (RxBDRead | RxPointerRead); + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxEn_needed <=#Tp 1'b0; + else + if(~TxBDReady & r_TxEn & WbEn & ~WbEn_q) + TxEn_needed <=#Tp 1'b1; + else + if(TxPointerRead & TxEn & TxEn_q) + TxEn_needed <=#Tp 1'b0; +end + +// Enabling access to the RAM for three devices. +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + begin + WbEn <=#Tp 1'b1; + RxEn <=#Tp 1'b0; + TxEn <=#Tp 1'b0; + ram_addr <=#Tp 8'h0; + ram_di <=#Tp 32'h0; + BDRead <=#Tp 1'b0; + BDWrite <=#Tp 1'b0; + end + else + begin + // Switching between three stages depends on enable signals + case ({WbEn_q, RxEn_q, TxEn_q, RxEn_needed, TxEn_needed}) // synopsys parallel_case + 5'b100_10, 5'b100_11 : + begin + WbEn <=#Tp 1'b0; + RxEn <=#Tp 1'b1; // wb access stage and r_RxEn is enabled + TxEn <=#Tp 1'b0; + ram_addr <=#Tp {RxBDAddress, RxPointerRead}; + ram_di <=#Tp RxBDDataIn; + end + 5'b100_01 : + begin + WbEn <=#Tp 1'b0; + RxEn <=#Tp 1'b0; + TxEn <=#Tp 1'b1; // wb access stage, r_RxEn is disabled but r_TxEn is enabled + ram_addr <=#Tp {TxBDAddress, TxPointerRead}; + ram_di <=#Tp TxBDDataIn; + end + 5'b010_00, 5'b010_10 : + begin + WbEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is disabled + RxEn <=#Tp 1'b0; + TxEn <=#Tp 1'b0; + ram_addr <=#Tp WB_ADR_I[9:2]; + ram_di <=#Tp WB_DAT_I; + BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}}; + BDRead <=#Tp (|BDCs) & ~WB_WE_I; + end + 5'b010_01, 5'b010_11 : + begin + WbEn <=#Tp 1'b0; + RxEn <=#Tp 1'b0; + TxEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is enabled + ram_addr <=#Tp {TxBDAddress, TxPointerRead}; + ram_di <=#Tp TxBDDataIn; + end + 5'b001_00, 5'b001_01, 5'b001_10, 5'b001_11 : + begin + WbEn <=#Tp 1'b1; // TxEn access stage (we always go to wb access stage) + RxEn <=#Tp 1'b0; + TxEn <=#Tp 1'b0; + ram_addr <=#Tp WB_ADR_I[9:2]; + ram_di <=#Tp WB_DAT_I; + BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}}; + BDRead <=#Tp (|BDCs) & ~WB_WE_I; + end + 5'b100_00 : + begin + WbEn <=#Tp 1'b0; // WbEn access stage and there is no need for other stages. WbEn needs to be switched off for a bit + end + 5'b000_00 : + begin + WbEn <=#Tp 1'b1; // Idle state. We go to WbEn access stage. + RxEn <=#Tp 1'b0; + TxEn <=#Tp 1'b0; + ram_addr <=#Tp WB_ADR_I[9:2]; + ram_di <=#Tp WB_DAT_I; + BDWrite <=#Tp BDCs[3:0] & {4{WB_WE_I}}; + BDRead <=#Tp (|BDCs) & ~WB_WE_I; + end + endcase + end +end + + +// Delayed stage signals +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + begin + WbEn_q <=#Tp 1'b0; + RxEn_q <=#Tp 1'b0; + TxEn_q <=#Tp 1'b0; + r_TxEn_q <=#Tp 1'b0; + r_RxEn_q <=#Tp 1'b0; + end + else + begin + WbEn_q <=#Tp WbEn; + RxEn_q <=#Tp RxEn; + TxEn_q <=#Tp TxEn; + r_TxEn_q <=#Tp r_TxEn; + r_RxEn_q <=#Tp r_RxEn; + end +end + +// Changes for tx occur every second clock. Flop is used for this manner. +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + Flop <=#Tp 1'b0; + else + if(TxDone | TxAbort | TxRetry_q) + Flop <=#Tp 1'b0; + else + if(TxUsedData) + Flop <=#Tp ~Flop; +end + +wire ResetTxBDReady; +assign ResetTxBDReady = TxDonePulse | TxAbortPulse | TxRetryPulse; + +// Latching READY status of the Tx buffer descriptor +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxBDReady <=#Tp 1'b0; + else + if(TxEn & TxEn_q & TxBDRead) + TxBDReady <=#Tp ram_do[15] & (ram_do[31:16] > 4); // TxBDReady is sampled only once at the beginning. + else // Only packets larger then 4 bytes are transmitted. + if(ResetTxBDReady) + TxBDReady <=#Tp 1'b0; +end + + +// Reading the Tx buffer descriptor +assign StartTxBDRead = (TxRetryPacket_NotCleared | TxStatusWrite) & ~BlockingTxBDRead & ~TxBDReady; + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxBDRead <=#Tp 1'b1; + else + if(StartTxBDRead) + TxBDRead <=#Tp 1'b1; + else + if(TxBDReady) + TxBDRead <=#Tp 1'b0; +end + + +// Reading Tx BD pointer +assign StartTxPointerRead = TxBDRead & TxBDReady; + +// Reading Tx BD Pointer +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxPointerRead <=#Tp 1'b0; + else + if(StartTxPointerRead) + TxPointerRead <=#Tp 1'b1; + else + if(TxEn_q) + TxPointerRead <=#Tp 1'b0; +end + + +// Writing status back to the Tx buffer descriptor +assign TxStatusWrite = (TxDonePacket_NotCleared | TxAbortPacket_NotCleared) & TxEn & TxEn_q & ~BlockingTxStatusWrite; + + + +// Status writing must occur only once. Meanwhile it is blocked. +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + BlockingTxStatusWrite <=#Tp 1'b0; + else + if(~TxDone_wb & ~TxAbort_wb) + BlockingTxStatusWrite <=#Tp 1'b0; + else + if(TxStatusWrite) + BlockingTxStatusWrite <=#Tp 1'b1; +end + + +reg BlockingTxStatusWrite_sync1; +reg BlockingTxStatusWrite_sync2; +reg BlockingTxStatusWrite_sync3; + +// Synchronizing BlockingTxStatusWrite to MTxClk +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + BlockingTxStatusWrite_sync1 <=#Tp 1'b0; + else + BlockingTxStatusWrite_sync1 <=#Tp BlockingTxStatusWrite; +end + +// Synchronizing BlockingTxStatusWrite to MTxClk +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + BlockingTxStatusWrite_sync2 <=#Tp 1'b0; + else + BlockingTxStatusWrite_sync2 <=#Tp BlockingTxStatusWrite_sync1; +end + +// Synchronizing BlockingTxStatusWrite to MTxClk +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + BlockingTxStatusWrite_sync3 <=#Tp 1'b0; + else + BlockingTxStatusWrite_sync3 <=#Tp BlockingTxStatusWrite_sync2; +end + +assign RstDeferLatched = BlockingTxStatusWrite_sync2 & ~BlockingTxStatusWrite_sync3; + +// TxBDRead state is activated only once. +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + BlockingTxBDRead <=#Tp 1'b0; + else + if(StartTxBDRead) + BlockingTxBDRead <=#Tp 1'b1; + else + if(~StartTxBDRead & ~TxBDReady) + BlockingTxBDRead <=#Tp 1'b0; +end + + +// Latching status from the tx buffer descriptor +// Data is avaliable one cycle after the access is started (at that time signal TxEn is not active) +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxStatus <=#Tp 4'h0; + else + if(TxEn & TxEn_q & TxBDRead) + TxStatus <=#Tp ram_do[14:11]; +end + +reg ReadTxDataFromMemory; +wire WriteRxDataToMemory; + +reg MasterWbTX; +reg MasterWbRX; + +reg [29:0] m_wb_adr_o; +reg m_wb_cyc_o; +reg [3:0] m_wb_sel_o; +reg m_wb_we_o; + +wire TxLengthEq0; +wire TxLengthLt4; + +reg BlockingIncrementTxPointer; +reg [31:2] TxPointerMSB; +reg [1:0] TxPointerLSB; +reg [1:0] TxPointerLSB_rst; +reg [31:2] RxPointerMSB; +reg [1:0] RxPointerLSB_rst; + +wire RxBurstAcc; +wire RxWordAcc; +wire RxHalfAcc; +wire RxByteAcc; + +//Latching length from the buffer descriptor; +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxLength <=#Tp 16'h0; + else + if(TxEn & TxEn_q & TxBDRead) + TxLength <=#Tp ram_do[31:16]; + else + if(MasterWbTX & m_wb_ack_i) + begin + if(TxLengthLt4) + TxLength <=#Tp 16'h0; + else + if(TxPointerLSB_rst==2'h0) + TxLength <=#Tp TxLength - 3'h4; // Length is subtracted at the data request + else + if(TxPointerLSB_rst==2'h1) + TxLength <=#Tp TxLength - 3'h3; // Length is subtracted at the data request + else + if(TxPointerLSB_rst==2'h2) + TxLength <=#Tp TxLength - 3'h2; // Length is subtracted at the data request + else + if(TxPointerLSB_rst==2'h3) + TxLength <=#Tp TxLength - 3'h1; // Length is subtracted at the data request + end +end + + + +//Latching length from the buffer descriptor; +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + LatchedTxLength <=#Tp 16'h0; + else + if(TxEn & TxEn_q & TxBDRead) + LatchedTxLength <=#Tp ram_do[31:16]; +end + +assign TxLengthEq0 = TxLength == 0; +assign TxLengthLt4 = TxLength < 4; + +reg cyc_cleared; +reg IncrTxPointer; + + +// Latching Tx buffer pointer from buffer descriptor. Only 30 MSB bits are latched +// because TxPointerMSB is only used for word-aligned accesses. +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxPointerMSB <=#Tp 30'h0; + else + if(TxEn & TxEn_q & TxPointerRead) + TxPointerMSB <=#Tp ram_do[31:2]; + else + if(IncrTxPointer & ~BlockingIncrementTxPointer) + TxPointerMSB <=#Tp TxPointerMSB + 1'b1; // TxPointer is word-aligned +end + + +// Latching 2 MSB bits of the buffer descriptor. Since word accesses are performed, +// valid data does not necesserly start at byte 0 (could be byte 0, 1, 2 or 3). This +// signals are used for proper selection of the start byte (TxData and TxByteCnt) are +// set by this two bits. +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxPointerLSB[1:0] <=#Tp 0; + else + if(TxEn & TxEn_q & TxPointerRead) + TxPointerLSB[1:0] <=#Tp ram_do[1:0]; +end + + +// Latching 2 MSB bits of the buffer descriptor. +// After the read access, TxLength needs to be decremented for the number of the valid +// bytes (1 to 4 bytes are valid in the first word). After the first read all bytes are +// valid so this two bits are reset to zero. +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxPointerLSB_rst[1:0] <=#Tp 0; + else + if(TxEn & TxEn_q & TxPointerRead) + TxPointerLSB_rst[1:0] <=#Tp ram_do[1:0]; + else + if(MasterWbTX & m_wb_ack_i) // After first access pointer is word alligned + TxPointerLSB_rst[1:0] <=#Tp 0; +end + + +reg [3:0] RxByteSel; +wire MasterAccessFinished; + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + BlockingIncrementTxPointer <=#Tp 0; + else + if(MasterAccessFinished) + BlockingIncrementTxPointer <=#Tp 0; + else + if(IncrTxPointer) + BlockingIncrementTxPointer <=#Tp 1'b1; +end + + +wire TxBufferAlmostFull; +wire TxBufferFull; +wire TxBufferEmpty; +wire TxBufferAlmostEmpty; +wire SetReadTxDataFromMemory; + +reg BlockReadTxDataFromMemory; + +assign SetReadTxDataFromMemory = TxEn & TxEn_q & TxPointerRead; + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + ReadTxDataFromMemory <=#Tp 1'b0; + else + if(TxLengthEq0 | TxAbortPulse | TxRetryPulse) + ReadTxDataFromMemory <=#Tp 1'b0; + else + if(SetReadTxDataFromMemory) + ReadTxDataFromMemory <=#Tp 1'b1; +end + +reg tx_burst_en; +reg rx_burst_en; + +wire ReadTxDataFromMemory_2 = ReadTxDataFromMemory & ~BlockReadTxDataFromMemory; +wire tx_burst = ReadTxDataFromMemory_2 & tx_burst_en; + +wire [31:0] TxData_wb; +wire ReadTxDataFromFifo_wb; + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + BlockReadTxDataFromMemory <=#Tp 1'b0; + else + if((TxBufferAlmostFull | TxLength <= 4)& MasterWbTX & (~cyc_cleared) & (!(TxAbortPacket_NotCleared | TxRetryPacket_NotCleared))) + BlockReadTxDataFromMemory <=#Tp 1'b1; + else + if(ReadTxDataFromFifo_wb | TxDonePacket | TxAbortPacket | TxRetryPacket) + BlockReadTxDataFromMemory <=#Tp 1'b0; +end + + +assign MasterAccessFinished = m_wb_ack_i | m_wb_err_i; +wire [`ETH_TX_FIFO_CNT_WIDTH-1:0] txfifo_cnt; +wire [`ETH_RX_FIFO_CNT_WIDTH-1:0] rxfifo_cnt; +reg [`ETH_BURST_CNT_WIDTH-1:0] tx_burst_cnt; +reg [`ETH_BURST_CNT_WIDTH-1:0] rx_burst_cnt; + +wire rx_burst; +wire enough_data_in_rxfifo_for_burst; +wire enough_data_in_rxfifo_for_burst_plus1; + +// Enabling master wishbone access to the memory for two devices TX and RX. +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + begin + MasterWbTX <=#Tp 1'b0; + MasterWbRX <=#Tp 1'b0; + m_wb_adr_o <=#Tp 30'h0; + m_wb_cyc_o <=#Tp 1'b0; + m_wb_we_o <=#Tp 1'b0; + m_wb_sel_o <=#Tp 4'h0; + cyc_cleared<=#Tp 1'b0; + tx_burst_cnt<=#Tp 0; + rx_burst_cnt<=#Tp 0; + IncrTxPointer<=#Tp 1'b0; + tx_burst_en<=#Tp 1'b1; + rx_burst_en<=#Tp 1'b0; + `ifdef ETH_WISHBONE_B3 + m_wb_cti_o <=#Tp 3'b0; + `endif + end + else + begin + // Switching between two stages depends on enable signals + casex ({MasterWbTX, MasterWbRX, ReadTxDataFromMemory_2, WriteRxDataToMemory, MasterAccessFinished, cyc_cleared, tx_burst, rx_burst}) // synopsys parallel_case + 8'b00_10_00_10, // Idle and MRB needed + 8'b10_1x_10_1x, // MRB continues + 8'b10_10_01_10, // Clear (previously MR) and MRB needed + 8'b01_1x_01_1x : // Clear (previously MW) and MRB needed + begin + MasterWbTX <=#Tp 1'b1; // tx burst + MasterWbRX <=#Tp 1'b0; + m_wb_cyc_o <=#Tp 1'b1; + m_wb_we_o <=#Tp 1'b0; + m_wb_sel_o <=#Tp 4'hf; + cyc_cleared<=#Tp 1'b0; + IncrTxPointer<=#Tp 1'b1; + tx_burst_cnt <=#Tp tx_burst_cnt+3'h1; + if(tx_burst_cnt==0) + m_wb_adr_o <=#Tp TxPointerMSB; + else + m_wb_adr_o <=#Tp m_wb_adr_o+1'b1; + + if(tx_burst_cnt==(`ETH_BURST_LENGTH-1)) + begin + tx_burst_en<=#Tp 1'b0; + `ifdef ETH_WISHBONE_B3 + m_wb_cti_o <=#Tp 3'b111; + `endif + end + else + begin + `ifdef ETH_WISHBONE_B3 + m_wb_cti_o <=#Tp 3'b010; + `endif + end + end + 8'b00_x1_00_x1, // Idle and MWB needed + 8'b01_x1_10_x1, // MWB continues + 8'b01_01_01_01, // Clear (previously MW) and MWB needed + 8'b10_x1_01_x1 : // Clear (previously MR) and MWB needed + begin + MasterWbTX <=#Tp 1'b0; // rx burst + MasterWbRX <=#Tp 1'b1; + m_wb_cyc_o <=#Tp 1'b1; + m_wb_we_o <=#Tp 1'b1; + m_wb_sel_o <=#Tp RxByteSel; + IncrTxPointer<=#Tp 1'b0; + cyc_cleared<=#Tp 1'b0; + rx_burst_cnt <=#Tp rx_burst_cnt+3'h1; + + if(rx_burst_cnt==0) + m_wb_adr_o <=#Tp RxPointerMSB; + else + m_wb_adr_o <=#Tp m_wb_adr_o+1'b1; + + if(rx_burst_cnt==(`ETH_BURST_LENGTH-1)) + begin + rx_burst_en<=#Tp 1'b0; + `ifdef ETH_WISHBONE_B3 + m_wb_cti_o <=#Tp 3'b111; + `endif + end + else + begin + `ifdef ETH_WISHBONE_B3 + m_wb_cti_o <=#Tp 3'b010; + `endif + end + end + 8'b00_x1_00_x0 : // idle and MW is needed (data write to rx buffer) + begin + MasterWbTX <=#Tp 1'b0; + MasterWbRX <=#Tp 1'b1; + m_wb_adr_o <=#Tp RxPointerMSB; + m_wb_cyc_o <=#Tp 1'b1; + m_wb_we_o <=#Tp 1'b1; + m_wb_sel_o <=#Tp RxByteSel; + IncrTxPointer<=#Tp 1'b0; + end + 8'b00_10_00_00 : // idle and MR is needed (data read from tx buffer) + begin + MasterWbTX <=#Tp 1'b1; + MasterWbRX <=#Tp 1'b0; + m_wb_adr_o <=#Tp TxPointerMSB; + m_wb_cyc_o <=#Tp 1'b1; + m_wb_we_o <=#Tp 1'b0; + m_wb_sel_o <=#Tp 4'hf; + IncrTxPointer<=#Tp 1'b1; + end + 8'b10_10_01_00, // MR and MR is needed (data read from tx buffer) + 8'b01_1x_01_0x : // MW and MR is needed (data read from tx buffer) + begin + MasterWbTX <=#Tp 1'b1; + MasterWbRX <=#Tp 1'b0; + m_wb_adr_o <=#Tp TxPointerMSB; + m_wb_cyc_o <=#Tp 1'b1; + m_wb_we_o <=#Tp 1'b0; + m_wb_sel_o <=#Tp 4'hf; + cyc_cleared<=#Tp 1'b0; + IncrTxPointer<=#Tp 1'b1; + end + 8'b01_01_01_00, // MW and MW needed (data write to rx buffer) + 8'b10_x1_01_x0 : // MR and MW is needed (data write to rx buffer) + begin + MasterWbTX <=#Tp 1'b0; + MasterWbRX <=#Tp 1'b1; + m_wb_adr_o <=#Tp RxPointerMSB; + m_wb_cyc_o <=#Tp 1'b1; + m_wb_we_o <=#Tp 1'b1; + m_wb_sel_o <=#Tp RxByteSel; + cyc_cleared<=#Tp 1'b0; + IncrTxPointer<=#Tp 1'b0; + end + 8'b01_01_10_00, // MW and MW needed (cycle is cleared between previous and next access) + 8'b01_1x_10_x0, // MW and MW or MR or MRB needed (cycle is cleared between previous and next access) + 8'b10_10_10_00, // MR and MR needed (cycle is cleared between previous and next access) + 8'b10_x1_10_0x : // MR and MR or MW or MWB (cycle is cleared between previous and next access) + begin + m_wb_cyc_o <=#Tp 1'b0; // whatever and master read or write is needed. We need to clear m_wb_cyc_o before next access is started + cyc_cleared<=#Tp 1'b1; + IncrTxPointer<=#Tp 1'b0; + tx_burst_cnt<=#Tp 0; + tx_burst_en<=#Tp txfifo_cnt<(`ETH_TX_FIFO_DEPTH-`ETH_BURST_LENGTH) & (TxLength>(`ETH_BURST_LENGTH*4+4)); + rx_burst_cnt<=#Tp 0; + rx_burst_en<=#Tp MasterWbRX ? enough_data_in_rxfifo_for_burst_plus1 : enough_data_in_rxfifo_for_burst; // Counter is not decremented, yet, so plus1 is used. + `ifdef ETH_WISHBONE_B3 + m_wb_cti_o <=#Tp 3'b0; + `endif + end + 8'bxx_00_10_00, // whatever and no master read or write is needed (ack or err comes finishing previous access) + 8'bxx_00_01_00 : // Between cyc_cleared request was cleared + begin + MasterWbTX <=#Tp 1'b0; + MasterWbRX <=#Tp 1'b0; + m_wb_cyc_o <=#Tp 1'b0; + cyc_cleared<=#Tp 1'b0; + IncrTxPointer<=#Tp 1'b0; + rx_burst_cnt<=#Tp 0; + rx_burst_en<=#Tp MasterWbRX ? enough_data_in_rxfifo_for_burst_plus1 : enough_data_in_rxfifo_for_burst; // Counter is not decremented, yet, so plus1 is used. + `ifdef ETH_WISHBONE_B3 + m_wb_cti_o <=#Tp 3'b0; + `endif + end + 8'b00_00_00_00: // whatever and no master read or write is needed (ack or err comes finishing previous access) + begin + tx_burst_cnt<=#Tp 0; + tx_burst_en<=#Tp txfifo_cnt<(`ETH_TX_FIFO_DEPTH-`ETH_BURST_LENGTH) & (TxLength>(`ETH_BURST_LENGTH*4+4)); + end + default: // Don't touch + begin + MasterWbTX <=#Tp MasterWbTX; + MasterWbRX <=#Tp MasterWbRX; + m_wb_cyc_o <=#Tp m_wb_cyc_o; + m_wb_sel_o <=#Tp m_wb_sel_o; + IncrTxPointer<=#Tp IncrTxPointer; + end + endcase + end +end + + +wire TxFifoClear; + +assign TxFifoClear = (TxAbortPacket | TxRetryPacket); + +eth_fifo #(`ETH_TX_FIFO_DATA_WIDTH, `ETH_TX_FIFO_DEPTH, `ETH_TX_FIFO_CNT_WIDTH) +tx_fifo ( .data_in(m_wb_dat_i), .data_out(TxData_wb), + .clk(WB_CLK_I), .reset(Reset), + .write(MasterWbTX & m_wb_ack_i), .read(ReadTxDataFromFifo_wb & ~TxBufferEmpty), + .clear(TxFifoClear), .full(TxBufferFull), + .almost_full(TxBufferAlmostFull), .almost_empty(TxBufferAlmostEmpty), + .empty(TxBufferEmpty), .cnt(txfifo_cnt) + ); + + +reg StartOccured; +reg TxStartFrm_sync1; +reg TxStartFrm_sync2; +reg TxStartFrm_syncb1; +reg TxStartFrm_syncb2; + + + +// Start: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxStartFrm_wb <=#Tp 1'b0; + else + if(TxBDReady & ~StartOccured & (TxBufferFull | TxLengthEq0)) + TxStartFrm_wb <=#Tp 1'b1; + else + if(TxStartFrm_syncb2) + TxStartFrm_wb <=#Tp 1'b0; +end + +// StartOccured: TxStartFrm_wb occurs only ones at the beginning. Then it's blocked. +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + StartOccured <=#Tp 1'b0; + else + if(TxStartFrm_wb) + StartOccured <=#Tp 1'b1; + else + if(ResetTxBDReady) + StartOccured <=#Tp 1'b0; +end + +// Synchronizing TxStartFrm_wb to MTxClk +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxStartFrm_sync1 <=#Tp 1'b0; + else + TxStartFrm_sync1 <=#Tp TxStartFrm_wb; +end + +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxStartFrm_sync2 <=#Tp 1'b0; + else + TxStartFrm_sync2 <=#Tp TxStartFrm_sync1; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxStartFrm_syncb1 <=#Tp 1'b0; + else + TxStartFrm_syncb1 <=#Tp TxStartFrm_sync2; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxStartFrm_syncb2 <=#Tp 1'b0; + else + TxStartFrm_syncb2 <=#Tp TxStartFrm_syncb1; +end + +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxStartFrm <=#Tp 1'b0; + else + if(TxStartFrm_sync2) + TxStartFrm <=#Tp 1'b1; + else + if(TxUsedData_q | ~TxStartFrm_sync2 & (TxRetry & (~TxRetry_q) | TxAbort & (~TxAbort_q))) + TxStartFrm <=#Tp 1'b0; +end +// End: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk + + +// TxEndFrm_wb: indicator of the end of frame +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxEndFrm_wb <=#Tp 1'b0; + else + if(TxLengthEq0 & TxBufferAlmostEmpty & TxUsedData) + TxEndFrm_wb <=#Tp 1'b1; + else + if(TxRetryPulse | TxDonePulse | TxAbortPulse) + TxEndFrm_wb <=#Tp 1'b0; +end + + +// Marks which bytes are valid within the word. +assign TxValidBytes = TxLengthLt4 ? TxLength[1:0] : 2'b0; + +reg LatchValidBytes; +reg LatchValidBytes_q; + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + LatchValidBytes <=#Tp 1'b0; + else + if(TxLengthLt4 & TxBDReady) + LatchValidBytes <=#Tp 1'b1; + else + LatchValidBytes <=#Tp 1'b0; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + LatchValidBytes_q <=#Tp 1'b0; + else + LatchValidBytes_q <=#Tp LatchValidBytes; +end + + +// Latching valid bytes +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxValidBytesLatched <=#Tp 2'h0; + else + if(LatchValidBytes & ~LatchValidBytes_q) + TxValidBytesLatched <=#Tp TxValidBytes; + else + if(TxRetryPulse | TxDonePulse | TxAbortPulse) + TxValidBytesLatched <=#Tp 2'h0; +end + + +assign TxIRQEn = TxStatus[14]; +assign WrapTxStatusBit = TxStatus[13]; +assign PerPacketPad = TxStatus[12]; +assign PerPacketCrcEn = TxStatus[11]; + + +assign RxIRQEn = RxStatus[14]; +assign WrapRxStatusBit = RxStatus[13]; + + +// Temporary Tx and Rx buffer descriptor address +assign TempTxBDAddress[7:1] = {7{ TxStatusWrite & ~WrapTxStatusBit}} & (TxBDAddress + 1'b1) ; // Tx BD increment or wrap (last BD) +assign TempRxBDAddress[7:1] = {7{ WrapRxStatusBit}} & (r_TxBDNum[6:0]) | // Using first Rx BD + {7{~WrapRxStatusBit}} & (RxBDAddress + 1'b1) ; // Using next Rx BD (incremenrement address) + + +// Latching Tx buffer descriptor address +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxBDAddress <=#Tp 7'h0; + else if (r_TxEn & (~r_TxEn_q)) + TxBDAddress <=#Tp 7'h0; + else if (TxStatusWrite) + TxBDAddress <=#Tp TempTxBDAddress; +end + + +// Latching Rx buffer descriptor address +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxBDAddress <=#Tp 7'h0; + else if(r_RxEn & (~r_RxEn_q)) + RxBDAddress <=#Tp r_TxBDNum[6:0]; + else if(RxStatusWrite) + RxBDAddress <=#Tp TempRxBDAddress; +end + +wire [8:0] TxStatusInLatched = {TxUnderRun, RetryCntLatched[3:0], RetryLimit, LateCollLatched, DeferLatched, CarrierSenseLost}; + +assign RxBDDataIn = {LatchedRxLength, 1'b0, RxStatus, 4'h0, RxStatusInLatched}; +assign TxBDDataIn = {LatchedTxLength, 1'b0, TxStatus, 2'h0, TxStatusInLatched}; + + +// Signals used for various purposes +assign TxRetryPulse = TxRetry_wb & ~TxRetry_wb_q; +assign TxDonePulse = TxDone_wb & ~TxDone_wb_q; +assign TxAbortPulse = TxAbort_wb & ~TxAbort_wb_q; + + + +// Generating delayed signals +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + begin + TxAbort_q <=#Tp 1'b0; + TxRetry_q <=#Tp 1'b0; + TxUsedData_q <=#Tp 1'b0; + end + else + begin + TxAbort_q <=#Tp TxAbort; + TxRetry_q <=#Tp TxRetry; + TxUsedData_q <=#Tp TxUsedData; + end +end + +// Generating delayed signals +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + begin + TxDone_wb_q <=#Tp 1'b0; + TxAbort_wb_q <=#Tp 1'b0; + TxRetry_wb_q <=#Tp 1'b0; + end + else + begin + TxDone_wb_q <=#Tp TxDone_wb; + TxAbort_wb_q <=#Tp TxAbort_wb; + TxRetry_wb_q <=#Tp TxRetry_wb; + end +end + + +reg TxAbortPacketBlocked; +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxAbortPacket <=#Tp 1'b0; + else + if(TxAbort_wb & (~tx_burst_en) & MasterWbTX & MasterAccessFinished & (~TxAbortPacketBlocked) | + TxAbort_wb & (~MasterWbTX) & (~TxAbortPacketBlocked)) + TxAbortPacket <=#Tp 1'b1; + else + TxAbortPacket <=#Tp 1'b0; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxAbortPacket_NotCleared <=#Tp 1'b0; + else + if(TxEn & TxEn_q & TxAbortPacket_NotCleared) + TxAbortPacket_NotCleared <=#Tp 1'b0; + else + if(TxAbort_wb & (~tx_burst_en) & MasterWbTX & MasterAccessFinished & (~TxAbortPacketBlocked) | + TxAbort_wb & (~MasterWbTX) & (~TxAbortPacketBlocked)) + TxAbortPacket_NotCleared <=#Tp 1'b1; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxAbortPacketBlocked <=#Tp 1'b0; + else + if(!TxAbort_wb & TxAbort_wb_q) + TxAbortPacketBlocked <=#Tp 1'b0; + else + if(TxAbortPacket) + TxAbortPacketBlocked <=#Tp 1'b1; +end + + +reg TxRetryPacketBlocked; +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxRetryPacket <=#Tp 1'b0; + else + if(TxRetry_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxRetryPacketBlocked | + TxRetry_wb & !MasterWbTX & !TxRetryPacketBlocked) + TxRetryPacket <=#Tp 1'b1; + else + TxRetryPacket <=#Tp 1'b0; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxRetryPacket_NotCleared <=#Tp 1'b0; + else + if(StartTxBDRead) + TxRetryPacket_NotCleared <=#Tp 1'b0; + else + if(TxRetry_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxRetryPacketBlocked | + TxRetry_wb & !MasterWbTX & !TxRetryPacketBlocked) + TxRetryPacket_NotCleared <=#Tp 1'b1; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxRetryPacketBlocked <=#Tp 1'b0; + else + if(!TxRetry_wb & TxRetry_wb_q) + TxRetryPacketBlocked <=#Tp 1'b0; + else + if(TxRetryPacket) + TxRetryPacketBlocked <=#Tp 1'b1; +end + + +reg TxDonePacketBlocked; +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxDonePacket <=#Tp 1'b0; + else + if(TxDone_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & !TxDonePacketBlocked | + TxDone_wb & !MasterWbTX & !TxDonePacketBlocked) + TxDonePacket <=#Tp 1'b1; + else + TxDonePacket <=#Tp 1'b0; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxDonePacket_NotCleared <=#Tp 1'b0; + else + if(TxEn & TxEn_q & TxDonePacket_NotCleared) + TxDonePacket_NotCleared <=#Tp 1'b0; + else + if(TxDone_wb & !tx_burst_en & MasterWbTX & MasterAccessFinished & (~TxDonePacketBlocked) | + TxDone_wb & !MasterWbTX & (~TxDonePacketBlocked)) + TxDonePacket_NotCleared <=#Tp 1'b1; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxDonePacketBlocked <=#Tp 1'b0; + else + if(!TxDone_wb & TxDone_wb_q) + TxDonePacketBlocked <=#Tp 1'b0; + else + if(TxDonePacket) + TxDonePacketBlocked <=#Tp 1'b1; +end + + +// Indication of the last word +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + LastWord <=#Tp 1'b0; + else + if((TxEndFrm | TxAbort | TxRetry) & Flop) + LastWord <=#Tp 1'b0; + else + if(TxUsedData & Flop & TxByteCnt == 2'h3) + LastWord <=#Tp TxEndFrm_wb; +end + + +// Tx end frame generation +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxEndFrm <=#Tp 1'b0; + else + if(Flop & TxEndFrm | TxAbort | TxRetry_q) + TxEndFrm <=#Tp 1'b0; + else + if(Flop & LastWord) + begin + case (TxValidBytesLatched) // synopsys parallel_case + 1 : TxEndFrm <=#Tp TxByteCnt == 2'h0; + 2 : TxEndFrm <=#Tp TxByteCnt == 2'h1; + 3 : TxEndFrm <=#Tp TxByteCnt == 2'h2; + 0 : TxEndFrm <=#Tp TxByteCnt == 2'h3; + default : TxEndFrm <=#Tp 1'b0; + endcase + end +end + + +// Tx data selection (latching) +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxData <=#Tp 0; + else + if(TxStartFrm_sync2 & ~TxStartFrm) + case(TxPointerLSB) // synopsys parallel_case + 2'h0 : TxData <=#Tp TxData_wb[31:24]; // Big Endian Byte Ordering + 2'h1 : TxData <=#Tp TxData_wb[23:16]; // Big Endian Byte Ordering + 2'h2 : TxData <=#Tp TxData_wb[15:08]; // Big Endian Byte Ordering + 2'h3 : TxData <=#Tp TxData_wb[07:00]; // Big Endian Byte Ordering + endcase + else + if(TxStartFrm & TxUsedData & TxPointerLSB==2'h3) + TxData <=#Tp TxData_wb[31:24]; // Big Endian Byte Ordering + else + if(TxUsedData & Flop) + begin + case(TxByteCnt) // synopsys parallel_case + 0 : TxData <=#Tp TxDataLatched[31:24]; // Big Endian Byte Ordering + 1 : TxData <=#Tp TxDataLatched[23:16]; + 2 : TxData <=#Tp TxDataLatched[15:8]; + 3 : TxData <=#Tp TxDataLatched[7:0]; + endcase + end +end + + +// Latching tx data +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxDataLatched[31:0] <=#Tp 32'h0; + else + if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 | TxStartFrm & TxUsedData & Flop & TxByteCnt == 2'h0) + TxDataLatched[31:0] <=#Tp TxData_wb[31:0]; +end + + +// Tx under run +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxUnderRun_wb <=#Tp 1'b0; + else + if(TxAbortPulse) + TxUnderRun_wb <=#Tp 1'b0; + else + if(TxBufferEmpty & ReadTxDataFromFifo_wb) + TxUnderRun_wb <=#Tp 1'b1; +end + + +reg TxUnderRun_sync1; + +// Tx under run +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxUnderRun_sync1 <=#Tp 1'b0; + else + if(TxUnderRun_wb) + TxUnderRun_sync1 <=#Tp 1'b1; + else + if(BlockingTxStatusWrite_sync2) + TxUnderRun_sync1 <=#Tp 1'b0; +end + +// Tx under run +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxUnderRun <=#Tp 1'b0; + else + if(BlockingTxStatusWrite_sync2) + TxUnderRun <=#Tp 1'b0; + else + if(TxUnderRun_sync1) + TxUnderRun <=#Tp 1'b1; +end + + +// Tx Byte counter +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + TxByteCnt <=#Tp 2'h0; + else + if(TxAbort_q | TxRetry_q) + TxByteCnt <=#Tp 2'h0; + else + if(TxStartFrm & ~TxUsedData) + case(TxPointerLSB) // synopsys parallel_case + 2'h0 : TxByteCnt <=#Tp 2'h1; + 2'h1 : TxByteCnt <=#Tp 2'h2; + 2'h2 : TxByteCnt <=#Tp 2'h3; + 2'h3 : TxByteCnt <=#Tp 2'h0; + endcase + else + if(TxUsedData & Flop) + TxByteCnt <=#Tp TxByteCnt + 1'b1; +end + + +// Start: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I +reg ReadTxDataFromFifo_sync1; +reg ReadTxDataFromFifo_sync2; +reg ReadTxDataFromFifo_sync3; +reg ReadTxDataFromFifo_syncb1; +reg ReadTxDataFromFifo_syncb2; +reg ReadTxDataFromFifo_syncb3; + + +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + ReadTxDataFromFifo_tck <=#Tp 1'b0; + else + if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord | TxStartFrm & TxUsedData & Flop & TxByteCnt == 2'h0) + ReadTxDataFromFifo_tck <=#Tp 1'b1; + else + if(ReadTxDataFromFifo_syncb2 & ~ReadTxDataFromFifo_syncb3) + ReadTxDataFromFifo_tck <=#Tp 1'b0; +end + +// Synchronizing TxStartFrm_wb to MTxClk +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + ReadTxDataFromFifo_sync1 <=#Tp 1'b0; + else + ReadTxDataFromFifo_sync1 <=#Tp ReadTxDataFromFifo_tck; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + ReadTxDataFromFifo_sync2 <=#Tp 1'b0; + else + ReadTxDataFromFifo_sync2 <=#Tp ReadTxDataFromFifo_sync1; +end + +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + ReadTxDataFromFifo_syncb1 <=#Tp 1'b0; + else + ReadTxDataFromFifo_syncb1 <=#Tp ReadTxDataFromFifo_sync2; +end + +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + ReadTxDataFromFifo_syncb2 <=#Tp 1'b0; + else + ReadTxDataFromFifo_syncb2 <=#Tp ReadTxDataFromFifo_syncb1; +end + +always @ (posedge MTxClk or posedge Reset) +begin + if(Reset) + ReadTxDataFromFifo_syncb3 <=#Tp 1'b0; + else + ReadTxDataFromFifo_syncb3 <=#Tp ReadTxDataFromFifo_syncb2; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + ReadTxDataFromFifo_sync3 <=#Tp 1'b0; + else + ReadTxDataFromFifo_sync3 <=#Tp ReadTxDataFromFifo_sync2; +end + +assign ReadTxDataFromFifo_wb = ReadTxDataFromFifo_sync2 & ~ReadTxDataFromFifo_sync3; +// End: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I + + +// Synchronizing TxRetry signal (synchronized to WISHBONE clock) +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxRetrySync1 <=#Tp 1'b0; + else + TxRetrySync1 <=#Tp TxRetry; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxRetry_wb <=#Tp 1'b0; + else + TxRetry_wb <=#Tp TxRetrySync1; +end + + +// Synchronized TxDone_wb signal (synchronized to WISHBONE clock) +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxDoneSync1 <=#Tp 1'b0; + else + TxDoneSync1 <=#Tp TxDone; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxDone_wb <=#Tp 1'b0; + else + TxDone_wb <=#Tp TxDoneSync1; +end + +// Synchronizing TxAbort signal (synchronized to WISHBONE clock) +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxAbortSync1 <=#Tp 1'b0; + else + TxAbortSync1 <=#Tp TxAbort; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxAbort_wb <=#Tp 1'b0; + else + TxAbort_wb <=#Tp TxAbortSync1; +end + + +reg RxAbortSync1; +reg RxAbortSync2; +reg RxAbortSync3; +reg RxAbortSync4; +reg RxAbortSyncb1; +reg RxAbortSyncb2; + +assign StartRxBDRead = RxStatusWrite | RxAbortSync3 & ~RxAbortSync4 | r_RxEn & ~r_RxEn_q; + +// Reading the Rx buffer descriptor +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxBDRead <=#Tp 1'b0; + else + if(StartRxBDRead & ~RxReady) + RxBDRead <=#Tp 1'b1; + else + if(RxBDReady) + RxBDRead <=#Tp 1'b0; +end + + +// Reading of the next receive buffer descriptor starts after reception status is +// written to the previous one. + +// Latching READY status of the Rx buffer descriptor +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxBDReady <=#Tp 1'b0; + else + if(RxPointerRead) + RxBDReady <=#Tp 1'b0; + else + if(RxEn & RxEn_q & RxBDRead) + RxBDReady <=#Tp ram_do[15]; // RxBDReady is sampled only once at the beginning +end + +// Latching Rx buffer descriptor status +// Data is avaliable one cycle after the access is started (at that time signal RxEn is not active) +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxStatus <=#Tp 2'h0; + else + if(RxEn & RxEn_q & RxBDRead) + RxStatus <=#Tp ram_do[14:13]; +end + + +// RxReady generation +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxReady <=#Tp 1'b0; + else + if(ShiftEnded | RxAbortSync2 & ~RxAbortSync3 | ~r_RxEn & r_RxEn_q) + RxReady <=#Tp 1'b0; + else + if(RxEn & RxEn_q & RxPointerRead) + RxReady <=#Tp 1'b1; +end + + +// Reading Rx BD pointer + + +assign StartRxPointerRead = RxBDRead & RxBDReady; + +// Reading Tx BD Pointer +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxPointerRead <=#Tp 1'b0; + else + if(StartRxPointerRead) + RxPointerRead <=#Tp 1'b1; + else + if(RxEn & RxEn_q) + RxPointerRead <=#Tp 1'b0; +end + + +//Latching Rx buffer pointer from buffer descriptor; +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxPointerMSB <=#Tp 30'h0; + else + if(RxEn & RxEn_q & RxPointerRead) + RxPointerMSB <=#Tp ram_do[31:2]; + else + if(MasterWbRX & m_wb_ack_i) + RxPointerMSB <=#Tp RxPointerMSB + 1'b1; // Word access (always word access. m_wb_sel_o are used for selecting bytes) +end + + +//Latching last addresses from buffer descriptor (used as byte-half-word indicator); +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxPointerLSB_rst[1:0] <=#Tp 0; + else + if(MasterWbRX & m_wb_ack_i) // After first write all RxByteSel are active + RxPointerLSB_rst[1:0] <=#Tp 0; + else + if(RxEn & RxEn_q & RxPointerRead) + RxPointerLSB_rst[1:0] <=#Tp ram_do[1:0]; +end + + +always @ (RxPointerLSB_rst) +begin + case(RxPointerLSB_rst[1:0]) // synopsys parallel_case + 2'h0 : RxByteSel[3:0] = 4'hf; + 2'h1 : RxByteSel[3:0] = 4'h7; + 2'h2 : RxByteSel[3:0] = 4'h3; + 2'h3 : RxByteSel[3:0] = 4'h1; + endcase +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxEn_needed <=#Tp 1'b0; + else + if(~RxReady & r_RxEn & WbEn & ~WbEn_q) + RxEn_needed <=#Tp 1'b1; + else + if(RxPointerRead & RxEn & RxEn_q) + RxEn_needed <=#Tp 1'b0; +end + + +// Reception status is written back to the buffer descriptor after the end of frame is detected. +assign RxStatusWrite = ShiftEnded & RxEn & RxEn_q; + +reg RxEnableWindow; + +// Indicating that last byte is being reveived +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + LastByteIn <=#Tp 1'b0; + else + if(ShiftWillEnd & (&RxByteCnt) | RxAbort) + LastByteIn <=#Tp 1'b0; + else + if(RxValid & RxReady & RxEndFrm & ~(&RxByteCnt) & RxEnableWindow) + LastByteIn <=#Tp 1'b1; +end + +reg ShiftEnded_rck; +reg ShiftEndedSync1; +reg ShiftEndedSync2; +reg ShiftEndedSync3; +reg ShiftEndedSync_c1; +reg ShiftEndedSync_c2; + +wire StartShiftWillEnd; +assign StartShiftWillEnd = LastByteIn | RxValid & RxEndFrm & (&RxByteCnt) & RxEnableWindow; + +// Indicating that data reception will end +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + ShiftWillEnd <=#Tp 1'b0; + else + if(ShiftEnded_rck | RxAbort) + ShiftWillEnd <=#Tp 1'b0; + else + if(StartShiftWillEnd) + ShiftWillEnd <=#Tp 1'b1; +end + + + +// Receive byte counter +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxByteCnt <=#Tp 2'h0; + else + if(ShiftEnded_rck | RxAbort) + RxByteCnt <=#Tp 2'h0; + else + if(RxValid & RxStartFrm & RxReady) + case(RxPointerLSB_rst) // synopsys parallel_case + 2'h0 : RxByteCnt <=#Tp 2'h1; + 2'h1 : RxByteCnt <=#Tp 2'h2; + 2'h2 : RxByteCnt <=#Tp 2'h3; + 2'h3 : RxByteCnt <=#Tp 2'h0; + endcase + else + if(RxValid & RxEnableWindow & RxReady | LastByteIn) + RxByteCnt <=#Tp RxByteCnt + 1'b1; +end + + +// Indicates how many bytes are valid within the last word +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxValidBytes <=#Tp 2'h1; + else + if(RxValid & RxStartFrm) + case(RxPointerLSB_rst) // synopsys parallel_case + 2'h0 : RxValidBytes <=#Tp 2'h1; + 2'h1 : RxValidBytes <=#Tp 2'h2; + 2'h2 : RxValidBytes <=#Tp 2'h3; + 2'h3 : RxValidBytes <=#Tp 2'h0; + endcase + else + if(RxValid & ~LastByteIn & ~RxStartFrm & RxEnableWindow) + RxValidBytes <=#Tp RxValidBytes + 1'b1; +end + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxDataLatched1 <=#Tp 24'h0; + else + if(RxValid & RxReady & ~LastByteIn) + if(RxStartFrm) + begin + case(RxPointerLSB_rst) // synopsys parallel_case + 2'h0: RxDataLatched1[31:24] <=#Tp RxData; // Big Endian Byte Ordering + 2'h1: RxDataLatched1[23:16] <=#Tp RxData; + 2'h2: RxDataLatched1[15:8] <=#Tp RxData; + 2'h3: RxDataLatched1 <=#Tp RxDataLatched1; + endcase + end + else if (RxEnableWindow) + begin + case(RxByteCnt) // synopsys parallel_case + 2'h0: RxDataLatched1[31:24] <=#Tp RxData; // Big Endian Byte Ordering + 2'h1: RxDataLatched1[23:16] <=#Tp RxData; + 2'h2: RxDataLatched1[15:8] <=#Tp RxData; + 2'h3: RxDataLatched1 <=#Tp RxDataLatched1; + endcase + end +end + +wire SetWriteRxDataToFifo; + +// Assembling data that will be written to the rx_fifo +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxDataLatched2 <=#Tp 32'h0; + else + if(SetWriteRxDataToFifo & ~ShiftWillEnd) + RxDataLatched2 <=#Tp {RxDataLatched1[31:8], RxData}; // Big Endian Byte Ordering + else + if(SetWriteRxDataToFifo & ShiftWillEnd) + case(RxValidBytes) // synopsys parallel_case + 0 : RxDataLatched2 <=#Tp {RxDataLatched1[31:8], RxData}; // Big Endian Byte Ordering + 1 : RxDataLatched2 <=#Tp {RxDataLatched1[31:24], 24'h0}; + 2 : RxDataLatched2 <=#Tp {RxDataLatched1[31:16], 16'h0}; + 3 : RxDataLatched2 <=#Tp {RxDataLatched1[31:8], 8'h0}; + endcase +end + + +reg WriteRxDataToFifoSync1; +reg WriteRxDataToFifoSync2; +reg WriteRxDataToFifoSync3; + + +// Indicating start of the reception process +assign SetWriteRxDataToFifo = (RxValid & RxReady & ~RxStartFrm & RxEnableWindow & (&RxByteCnt)) | + (RxValid & RxReady & RxStartFrm & (&RxPointerLSB_rst)) | + (ShiftWillEnd & LastByteIn & (&RxByteCnt)); + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + WriteRxDataToFifo <=#Tp 1'b0; + else + if(SetWriteRxDataToFifo & ~RxAbort) + WriteRxDataToFifo <=#Tp 1'b1; + else + if(WriteRxDataToFifoSync2 | RxAbort) + WriteRxDataToFifo <=#Tp 1'b0; +end + + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + WriteRxDataToFifoSync1 <=#Tp 1'b0; + else + if(WriteRxDataToFifo) + WriteRxDataToFifoSync1 <=#Tp 1'b1; + else + WriteRxDataToFifoSync1 <=#Tp 1'b0; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + WriteRxDataToFifoSync2 <=#Tp 1'b0; + else + WriteRxDataToFifoSync2 <=#Tp WriteRxDataToFifoSync1; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + WriteRxDataToFifoSync3 <=#Tp 1'b0; + else + WriteRxDataToFifoSync3 <=#Tp WriteRxDataToFifoSync2; +end + +wire WriteRxDataToFifo_wb; +assign WriteRxDataToFifo_wb = WriteRxDataToFifoSync2 & ~WriteRxDataToFifoSync3; + + +reg LatchedRxStartFrm; +reg SyncRxStartFrm; +reg SyncRxStartFrm_q; +reg SyncRxStartFrm_q2; +wire RxFifoReset; + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + LatchedRxStartFrm <=#Tp 0; + else + if(RxStartFrm & ~SyncRxStartFrm_q) + LatchedRxStartFrm <=#Tp 1; + else + if(SyncRxStartFrm_q) + LatchedRxStartFrm <=#Tp 0; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + SyncRxStartFrm <=#Tp 0; + else + if(LatchedRxStartFrm) + SyncRxStartFrm <=#Tp 1; + else + SyncRxStartFrm <=#Tp 0; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + SyncRxStartFrm_q <=#Tp 0; + else + SyncRxStartFrm_q <=#Tp SyncRxStartFrm; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + SyncRxStartFrm_q2 <=#Tp 0; + else + SyncRxStartFrm_q2 <=#Tp SyncRxStartFrm_q; +end + + +assign RxFifoReset = SyncRxStartFrm_q & ~SyncRxStartFrm_q2; + + +eth_fifo #(`ETH_RX_FIFO_DATA_WIDTH, `ETH_RX_FIFO_DEPTH, `ETH_RX_FIFO_CNT_WIDTH) +rx_fifo (.data_in(RxDataLatched2), .data_out(m_wb_dat_o), + .clk(WB_CLK_I), .reset(Reset), + .write(WriteRxDataToFifo_wb & ~RxBufferFull), .read(MasterWbRX & m_wb_ack_i), + .clear(RxFifoReset), .full(RxBufferFull), + .almost_full(), .almost_empty(RxBufferAlmostEmpty), + .empty(RxBufferEmpty), .cnt(rxfifo_cnt) + ); + +assign enough_data_in_rxfifo_for_burst = rxfifo_cnt>=`ETH_BURST_LENGTH; +assign enough_data_in_rxfifo_for_burst_plus1 = rxfifo_cnt>`ETH_BURST_LENGTH; +assign WriteRxDataToMemory = ~RxBufferEmpty; +assign rx_burst = rx_burst_en & WriteRxDataToMemory; + + +// Generation of the end-of-frame signal +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + ShiftEnded_rck <=#Tp 1'b0; + else + if(~RxAbort & SetWriteRxDataToFifo & StartShiftWillEnd) + ShiftEnded_rck <=#Tp 1'b1; + else + if(RxAbort | ShiftEndedSync_c1 & ShiftEndedSync_c2) + ShiftEnded_rck <=#Tp 1'b0; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + ShiftEndedSync1 <=#Tp 1'b0; + else + ShiftEndedSync1 <=#Tp ShiftEnded_rck; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + ShiftEndedSync2 <=#Tp 1'b0; + else + ShiftEndedSync2 <=#Tp ShiftEndedSync1; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + ShiftEndedSync3 <=#Tp 1'b0; + else + if(ShiftEndedSync1 & ~ShiftEndedSync2) + ShiftEndedSync3 <=#Tp 1'b1; + else + if(ShiftEnded) + ShiftEndedSync3 <=#Tp 1'b0; +end + +// Generation of the end-of-frame signal +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + ShiftEnded <=#Tp 1'b0; + else + if(ShiftEndedSync3 & MasterWbRX & m_wb_ack_i & RxBufferAlmostEmpty & ~ShiftEnded) + ShiftEnded <=#Tp 1'b1; + else + if(RxStatusWrite) + ShiftEnded <=#Tp 1'b0; +end + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + ShiftEndedSync_c1 <=#Tp 1'b0; + else + ShiftEndedSync_c1 <=#Tp ShiftEndedSync2; +end + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + ShiftEndedSync_c2 <=#Tp 1'b0; + else + ShiftEndedSync_c2 <=#Tp ShiftEndedSync_c1; +end + +// Generation of the end-of-frame signal +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxEnableWindow <=#Tp 1'b0; + else + if(RxStartFrm) + RxEnableWindow <=#Tp 1'b1; + else + if(RxEndFrm | RxAbort) + RxEnableWindow <=#Tp 1'b0; +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxAbortSync1 <=#Tp 1'b0; + else + RxAbortSync1 <=#Tp RxAbortLatched; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxAbortSync2 <=#Tp 1'b0; + else + RxAbortSync2 <=#Tp RxAbortSync1; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxAbortSync3 <=#Tp 1'b0; + else + RxAbortSync3 <=#Tp RxAbortSync2; +end + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxAbortSync4 <=#Tp 1'b0; + else + RxAbortSync4 <=#Tp RxAbortSync3; +end + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxAbortSyncb1 <=#Tp 1'b0; + else + RxAbortSyncb1 <=#Tp RxAbortSync2; +end + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxAbortSyncb2 <=#Tp 1'b0; + else + RxAbortSyncb2 <=#Tp RxAbortSyncb1; +end + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxAbortLatched <=#Tp 1'b0; + else + if(RxAbortSyncb2) + RxAbortLatched <=#Tp 1'b0; + else + if(RxAbort) + RxAbortLatched <=#Tp 1'b1; +end + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + LatchedRxLength[15:0] <=#Tp 16'h0; + else + if(LoadRxStatus) + LatchedRxLength[15:0] <=#Tp RxLength[15:0]; +end + + +assign RxStatusIn = {ReceivedPauseFrm, AddressMiss, RxOverrun, InvalidSymbol, DribbleNibble, ReceivedPacketTooBig, ShortFrame, LatchedCrcError, RxLateCollision}; + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + RxStatusInLatched <=#Tp 'h0; + else + if(LoadRxStatus) + RxStatusInLatched <=#Tp RxStatusIn; +end + + +// Rx overrun +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxOverrun <=#Tp 1'b0; + else + if(RxStatusWrite) + RxOverrun <=#Tp 1'b0; + else + if(RxBufferFull & WriteRxDataToFifo_wb) + RxOverrun <=#Tp 1'b1; +end + + + +wire TxError; +assign TxError = TxUnderRun | RetryLimit | LateCollLatched | CarrierSenseLost; + +wire RxError; + +// ShortFrame (RxStatusInLatched[2]) can not set an error because short frames +// are aborted when signal r_RecSmall is set to 0 in MODER register. +// AddressMiss is identifying that a frame was received because of the promiscous +// mode and is not an error +assign RxError = (|RxStatusInLatched[6:3]) | (|RxStatusInLatched[1:0]); + + + +reg RxStatusWriteLatched; +reg RxStatusWriteLatched_sync1; +reg RxStatusWriteLatched_sync2; +reg RxStatusWriteLatched_syncb1; +reg RxStatusWriteLatched_syncb2; + + +// Latching and synchronizing RxStatusWrite signal. This signal is used for clearing the ReceivedPauseFrm signal +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxStatusWriteLatched <=#Tp 1'b0; + else + if(RxStatusWriteLatched_syncb2) + RxStatusWriteLatched <=#Tp 1'b0; + else + if(RxStatusWrite) + RxStatusWriteLatched <=#Tp 1'b1; +end + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + begin + RxStatusWriteLatched_sync1 <=#Tp 1'b0; + RxStatusWriteLatched_sync2 <=#Tp 1'b0; + end + else + begin + RxStatusWriteLatched_sync1 <=#Tp RxStatusWriteLatched; + RxStatusWriteLatched_sync2 <=#Tp RxStatusWriteLatched_sync1; + end +end + + +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + begin + RxStatusWriteLatched_syncb1 <=#Tp 1'b0; + RxStatusWriteLatched_syncb2 <=#Tp 1'b0; + end + else + begin + RxStatusWriteLatched_syncb1 <=#Tp RxStatusWriteLatched_sync2; + RxStatusWriteLatched_syncb2 <=#Tp RxStatusWriteLatched_syncb1; + end +end + + + +// Tx Done Interrupt +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxB_IRQ <=#Tp 1'b0; + else + if(TxStatusWrite & TxIRQEn) + TxB_IRQ <=#Tp ~TxError; + else + TxB_IRQ <=#Tp 1'b0; +end + + +// Tx Error Interrupt +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + TxE_IRQ <=#Tp 1'b0; + else + if(TxStatusWrite & TxIRQEn) + TxE_IRQ <=#Tp TxError; + else + TxE_IRQ <=#Tp 1'b0; +end + + +// Rx Done Interrupt +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxB_IRQ <=#Tp 1'b0; + else + if(RxStatusWrite & RxIRQEn & ReceivedPacketGood & (~ReceivedPauseFrm | ReceivedPauseFrm & r_PassAll & (~r_RxFlow))) + RxB_IRQ <=#Tp (~RxError); + else + RxB_IRQ <=#Tp 1'b0; +end + + +// Rx Error Interrupt +always @ (posedge WB_CLK_I or posedge Reset) +begin + if(Reset) + RxE_IRQ <=#Tp 1'b0; + else + if(RxStatusWrite & RxIRQEn & (~ReceivedPauseFrm | ReceivedPauseFrm & r_PassAll & (~r_RxFlow))) + RxE_IRQ <=#Tp RxError; + else + RxE_IRQ <=#Tp 1'b0; +end + + +// Busy Interrupt + +reg Busy_IRQ_rck; +reg Busy_IRQ_sync1; +reg Busy_IRQ_sync2; +reg Busy_IRQ_sync3; +reg Busy_IRQ_syncb1; +reg Busy_IRQ_syncb2; + + +always @ (posedge MRxClk or posedge Reset) +begin + if(Reset) + Busy_IRQ_rck <=#Tp 1'b0; + else + if(RxValid & RxStartFrm & ~RxReady) + Busy_IRQ_rck <=#Tp 1'b1; + else + if(Busy_IRQ_syncb2) + Busy_IRQ_rck <=#Tp 1'b0; +end + +always @ (posedge WB_CLK_I) +begin + Busy_IRQ_sync1 <=#Tp Busy_IRQ_rck; + Busy_IRQ_sync2 <=#Tp Busy_IRQ_sync1; + Busy_IRQ_sync3 <=#Tp Busy_IRQ_sync2; +end + +always @ (posedge MRxClk) +begin + Busy_IRQ_syncb1 <=#Tp Busy_IRQ_sync2; + Busy_IRQ_syncb2 <=#Tp Busy_IRQ_syncb1; +end + +assign Busy_IRQ = Busy_IRQ_sync2 & ~Busy_IRQ_sync3; + + + + + +endmodule diff --git a/ethernet/source/ethernet/timescale.v b/ethernet/source/ethernet/timescale.v new file mode 100644 index 0000000..c053c01 --- /dev/null +++ b/ethernet/source/ethernet/timescale.v @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// timescale.v //// +//// //// +//// This file is part of the Ethernet IP core project //// +//// http://www.opencores.org/projects/ethmac/ //// +//// //// +//// Author(s): //// +//// - Igor Mohor (igorM@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: timescale.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.3 2002/01/23 10:28:16 mohor +// Link in the header changed. +// +// Revision 1.2 2001/10/19 11:36:31 mohor +// Log file added. +// +// +// + +`timescale 1ns / 1ns diff --git a/ethernet/source/ethernet/xilinx_dist_ram_16x32.v b/ethernet/source/ethernet/xilinx_dist_ram_16x32.v new file mode 100644 index 0000000..374357c --- /dev/null +++ b/ethernet/source/ethernet/xilinx_dist_ram_16x32.v @@ -0,0 +1,50 @@ +module xilinx_dist_ram_16x32 +( + data_out, + we, + data_in, + read_address, + write_address, + wclk +); + output [31:0] data_out; + input we, wclk; + input [31:0] data_in; + input [3:0] write_address, read_address; + + wire [3:0] waddr = write_address ; + wire [3:0] raddr = read_address ; + + RAM16X1D ram00 (.DPO(data_out[0]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[0]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram01 (.DPO(data_out[1]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[1]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram02 (.DPO(data_out[2]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[2]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram03 (.DPO(data_out[3]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[3]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram04 (.DPO(data_out[4]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[4]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram05 (.DPO(data_out[5]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[5]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram06 (.DPO(data_out[6]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[6]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram07 (.DPO(data_out[7]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[7]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram08 (.DPO(data_out[8]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[8]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram09 (.DPO(data_out[9]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[9]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram10 (.DPO(data_out[10]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[10]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram11 (.DPO(data_out[11]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[11]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram12 (.DPO(data_out[12]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[12]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram13 (.DPO(data_out[13]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[13]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram14 (.DPO(data_out[14]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[14]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram15 (.DPO(data_out[15]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[15]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram16 (.DPO(data_out[16]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[16]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram17 (.DPO(data_out[17]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[17]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram18 (.DPO(data_out[18]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[18]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram19 (.DPO(data_out[19]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[19]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram20 (.DPO(data_out[20]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[20]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram21 (.DPO(data_out[21]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[21]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram22 (.DPO(data_out[22]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[22]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram23 (.DPO(data_out[23]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[23]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram24 (.DPO(data_out[24]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[24]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram25 (.DPO(data_out[25]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[25]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram26 (.DPO(data_out[26]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[26]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram27 (.DPO(data_out[27]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[27]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram28 (.DPO(data_out[28]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[28]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram29 (.DPO(data_out[29]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[29]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram30 (.DPO(data_out[30]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[30]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); + RAM16X1D ram31 (.DPO(data_out[31]), .SPO(), .A0(waddr[0]), .A1(waddr[1]), .A2(waddr[2]), .A3(waddr[3]), .D(data_in[31]), .DPRA0(raddr[0]), .DPRA1(raddr[1]), .DPRA2(raddr[2]), .DPRA3(raddr[3]), .WCLK(wclk), .WE(we)); +endmodule diff --git a/ethernet/source/pci/bus_commands.v b/ethernet/source/pci/bus_commands.v new file mode 100644 index 0000000..eda7060 --- /dev/null +++ b/ethernet/source/pci/bus_commands.v @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "bus_commands.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README.pdf //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: bus_commands.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2002/08/22 13:28:05 mihad +// Updated for synthesis purposes. Gate level simulation was failing in some configurations +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +// definitions of PCI bus commands | used by PCI Master | used by PCI Target +`define BC_IACK 4'h0 // yes no +`define BC_SPECIAL 4'h1 // no no +`define BC_IO_READ 4'h2 // yes yes +`define BC_IO_WRITE 4'h3 // yes yes +`define BC_RESERVED0 4'h4 // no no +`define BC_RESERVED1 4'h5 // no no +`define BC_MEM_READ 4'h6 // yes yes +`define BC_MEM_WRITE 4'h7 // yes yes +`define BC_RESERVED2 4'h8 // no no +`define BC_RESERVED3 4'h9 // no no +`define BC_CONF_READ 4'hA // yes yes +`define BC_CONF_WRITE 4'hB // yes yes +`define BC_MEM_READ_MUL 4'hC // yes yes +`define BC_DUAL_ADDR_CYC 4'hD // no no +`define BC_MEM_READ_LN 4'hE // yes yes +`define BC_MEM_WRITE_INVAL 4'hF // no yes + +// common bits for configuration cycle commands +`define BC_CONF_RW 3'b101 +// common bits for io cycle commands +`define BC_IO_RW 3'b001 diff --git a/ethernet/source/pci/pci_async_reset_flop.v b/ethernet/source/pci/pci_async_reset_flop.v new file mode 100644 index 0000000..527d8cd --- /dev/null +++ b/ethernet/source/pci/pci_async_reset_flop.v @@ -0,0 +1,105 @@ +//=========================================================================== +// $Id: pci_async_reset_flop.v,v 1.1 2007-03-20 17:50:56 sithglan Exp $ +// +////////////////////////////////////////////////////////////////////// +//// //// +//// async_reset_flop //// +//// //// +//// This file is part of the general opencores effort. //// +//// //// +//// //// +//// Module Description: //// +//// //// +//// Make a rising-edge triggered flop with async reset with a //// +//// distinguished name so that it's output can be easily //// +//// traced, because it is used for asynchronous reset of some //// +//// flip-flops. //// +//// //// +//// This flop should be used instead of a regular flop for ALL //// +//// asynchronous-reset generator flops. //// +//// //// +//// To Do: //// +//// Nothing //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_async_reset_flop.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/08/14 16:44:19 mihad +// Include statement was enclosed in synosys translate off/on directive - repaired +// +// Revision 1.2 2002/02/25 15:15:43 mihad +// Added include statement that was missing and causing errors +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +`include "pci_constants.v" + +module pci_async_reset_flop ( + data_in, clk_in, async_reset_data_out, reset_in +); + +input data_in; +input clk_in; +output async_reset_data_out; +input reset_in; + +reg async_reset_data_out; + +always @(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + async_reset_data_out <= #`FF_DELAY 1'b0; + end + else + begin + async_reset_data_out <= #`FF_DELAY data_in; + end +end + +endmodule + diff --git a/ethernet/source/pci/pci_bridge32.v b/ethernet/source/pci/pci_bridge32.v new file mode 100644 index 0000000..1fe3115 --- /dev/null +++ b/ethernet/source/pci/pci_bridge32.v @@ -0,0 +1,1656 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_bridge32.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// - Tadej Markovic (tadej@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_bridge32.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.19 2004/09/23 13:48:53 mihad +// The control inputs from PCI are now muxed with control outputs +// using output enable state for given signal. +// +// Revision 1.18 2004/08/19 15:27:34 mihad +// Changed minimum pci image size to 256 bytes because +// of some PC system problems with size of IO images. +// +// Revision 1.17 2004/01/24 11:54:18 mihad +// Update! SPOCI Implemented! +// +// Revision 1.16 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.15 2003/12/10 12:02:54 mihad +// The wbs B3 to B2 translation logic had wrong reset wire connected! +// +// Revision 1.14 2003/12/09 09:33:57 simons +// Some warning cleanup. +// +// Revision 1.13 2003/10/17 09:11:52 markom +// mbist signals updated according to newest convention +// +// Revision 1.12 2003/08/21 20:49:03 tadejm +// Added signals for WB Master B3. +// +// Revision 1.11 2003/08/08 16:36:33 tadejm +// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. +// +// Revision 1.10 2003/08/03 18:05:06 mihad +// Added limited WISHBONE B3 support for WISHBONE Slave Unit. +// Doesn't support full speed bursts yet. +// +// Revision 1.9 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.8 2002/10/21 13:04:33 mihad +// Changed BIST signal names etc.. +// +// Revision 1.7 2002/10/18 03:36:37 tadejm +// Changed wrong signal name mbist_sen into mbist_ctrl_i. +// +// Revision 1.6 2002/10/17 22:51:50 tadejm +// Changed BIST signals for RAMs. +// +// Revision 1.5 2002/10/11 10:09:01 mihad +// Added additional testcase and changed rst name in BIST to trst +// +// Revision 1.4 2002/10/08 17:17:05 mihad +// Added BIST signals for RAMs. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// this is top level module of pci bridge core +// it instantiates and connects other lower level modules +// check polarity of PCI output enables in file out_reg.v and change it according to IO interface specification + +module pci_bridge32 +( + // WISHBONE system signals + wb_clk_i, + wb_rst_i, + wb_rst_o, + wb_int_i, + wb_int_o, + + // WISHBONE slave interface + wbs_adr_i, + wbs_dat_i, + wbs_dat_o, + wbs_sel_i, + wbs_cyc_i, + wbs_stb_i, + wbs_we_i, + +`ifdef PCI_WB_REV_B3 + + wbs_cti_i, + wbs_bte_i, + +`else + + wbs_cab_i, + +`endif + + wbs_ack_o, + wbs_rty_o, + wbs_err_o, + + // WISHBONE master interface + wbm_adr_o, + wbm_dat_i, + wbm_dat_o, + wbm_sel_o, + wbm_cyc_o, + wbm_stb_o, + wbm_we_o, + wbm_cti_o, + wbm_bte_o, + wbm_ack_i, + wbm_rty_i, + wbm_err_i, + + // pci interface - system pins + pci_clk_i, + pci_rst_i, + pci_rst_o, + pci_inta_i, + pci_inta_o, + pci_rst_oe_o, + pci_inta_oe_o, + + // arbitration pins + pci_req_o, + pci_req_oe_o, + + pci_gnt_i, + + // protocol pins + pci_frame_i, + pci_frame_o, + + pci_frame_oe_o, + pci_irdy_oe_o, + pci_devsel_oe_o, + pci_trdy_oe_o, + pci_stop_oe_o, + pci_ad_oe_o, + pci_cbe_oe_o, + + pci_irdy_i, + pci_irdy_o, + + pci_idsel_i, + + pci_devsel_i, + pci_devsel_o, + + pci_trdy_i, + pci_trdy_o, + + pci_stop_i, + pci_stop_o , + + // data transfer pins + pci_ad_i, + pci_ad_o, + + pci_cbe_i, + pci_cbe_o, + + // parity generation and checking pins + pci_par_i, + pci_par_o, + pci_par_oe_o, + + pci_perr_i, + pci_perr_o, + pci_perr_oe_o, + + // system error pin + pci_serr_o, + pci_serr_oe_o + +`ifdef PCI_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif + +`ifdef PCI_CPCI_HS_IMPLEMENT + , + // Compact PCI Hot Swap signals + pci_cpci_hs_enum_o , // ENUM# output with output enable (open drain) + pci_cpci_hs_enum_oe_o , // ENUM# enum output enable + pci_cpci_hs_led_o , // LED output with output enable (open drain) + pci_cpci_hs_led_oe_o , // LED output enable + pci_cpci_hs_es_i // ejector switch state indicator input +`endif + +`ifdef PCI_SPOCI + , + // Serial power on configuration interface + spoci_scl_o , + spoci_scl_oe_o , + spoci_sda_i , + spoci_sda_o , + spoci_sda_oe_o +`endif + +); + +`ifdef HOST + `ifdef NO_CNF_IMAGE + parameter pci_ba0_width = `PCI_NUM_OF_DEC_ADDR_LINES ; + `else + parameter pci_ba0_width = 20 ; + `endif +`endif + +`ifdef GUEST + parameter pci_ba0_width = 20 ; +`endif + +parameter pci_ba1_5_width = `PCI_NUM_OF_DEC_ADDR_LINES ; + +// WISHBONE system signals +input wb_clk_i ; +input wb_rst_i ; +output wb_rst_o ; +input wb_int_i ; +output wb_int_o ; + +// WISHBONE slave interface +input [31:0] wbs_adr_i ; +input [31:0] wbs_dat_i ; +output [31:0] wbs_dat_o ; +input [3:0] wbs_sel_i ; +input wbs_cyc_i ; +input wbs_stb_i ; +input wbs_we_i ; + +`ifdef PCI_WB_REV_B3 + +input [2:0] wbs_cti_i ; +input [1:0] wbs_bte_i ; + +`else + +input wbs_cab_i ; + +`endif + +output wbs_ack_o ; +output wbs_rty_o ; +output wbs_err_o ; + +// WISHBONE master interface +output [31:0] wbm_adr_o ; +input [31:0] wbm_dat_i ; +output [31:0] wbm_dat_o ; +output [3:0] wbm_sel_o ; +output wbm_cyc_o ; +output wbm_stb_o ; +output wbm_we_o ; +output [2:0] wbm_cti_o ; +output [1:0] wbm_bte_o ; +input wbm_ack_i ; +input wbm_rty_i ; +input wbm_err_i ; + +// pci interface - system pins +input pci_clk_i ; +input pci_rst_i ; +output pci_rst_o ; +output pci_rst_oe_o ; + +input pci_inta_i ; +output pci_inta_o ; +output pci_inta_oe_o ; + +// arbitration pins +output pci_req_o ; +output pci_req_oe_o ; + +input pci_gnt_i ; + +// protocol pins +input pci_frame_i ; +output pci_frame_o ; +output pci_frame_oe_o ; +output pci_irdy_oe_o ; +output pci_devsel_oe_o ; +output pci_trdy_oe_o ; +output pci_stop_oe_o ; +output [31:0] pci_ad_oe_o ; +output [3:0] pci_cbe_oe_o ; + +input pci_irdy_i ; +output pci_irdy_o ; + +input pci_idsel_i ; + +input pci_devsel_i ; +output pci_devsel_o ; + +input pci_trdy_i ; +output pci_trdy_o ; + +input pci_stop_i ; +output pci_stop_o ; + +// data transfer pins +input [31:0] pci_ad_i ; +output [31:0] pci_ad_o ; + +input [3:0] pci_cbe_i ; +output [3:0] pci_cbe_o ; + +// parity generation and checking pins +input pci_par_i ; +output pci_par_o ; +output pci_par_oe_o ; + +input pci_perr_i ; +output pci_perr_o ; +output pci_perr_oe_o ; + +// system error pin +output pci_serr_o ; +output pci_serr_oe_o ; + +`ifdef PCI_BIST +/*----------------------------------------------------- +BIST debug chain port signals +-----------------------------------------------------*/ +input mbist_si_i; // bist scan serial in +output mbist_so_o; // bist scan serial out +input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + +`ifdef PCI_CPCI_HS_IMPLEMENT + // Compact PCI Hot Swap signals +output pci_cpci_hs_enum_o ; // ENUM# output with output enable (open drain) +output pci_cpci_hs_enum_oe_o ; // ENUM# enum output enable +output pci_cpci_hs_led_o ; // LED output with output enable (open drain) +output pci_cpci_hs_led_oe_o ; // LED output enable +input pci_cpci_hs_es_i ; // ejector switch state indicator input + +assign pci_cpci_hs_enum_o = 1'b0 ; +assign pci_cpci_hs_led_o = 1'b0 ; +`endif + +`ifdef PCI_SPOCI +output spoci_scl_o ; +output spoci_scl_oe_o ; +input spoci_sda_i ; +output spoci_sda_o ; +output spoci_sda_oe_o ; + +assign spoci_scl_o = 1'b0 ; +assign spoci_sda_o = 1'b0 ; +`endif + +// declare clock and reset wires +wire pci_clk = pci_clk_i ; +wire wb_clk = wb_clk_i ; +wire reset ; // assigned at pci bridge reset and interrupt logic + +/*========================================================================================================= +First comes definition of all modules' outputs, so they can be assigned to any other module's input later + in the file, when module is instantiated +=========================================================================================================*/ +// PCI BRIDGE RESET AND INTERRUPT LOGIC OUTPUTS +wire pci_reso_reset ; +wire pci_reso_pci_rstn_out ; +wire pci_reso_pci_rstn_en_out ; +wire pci_reso_rst_o ; +wire pci_into_pci_intan_out ; +wire pci_into_pci_intan_en_out ; +wire pci_into_int_o ; +wire pci_into_conf_isr_int_prop_out ; + +// assign pci bridge reset interrupt logic outputs to top outputs where possible +assign reset = pci_reso_reset ; +assign pci_rst_o = pci_reso_pci_rstn_out ; +assign pci_rst_oe_o = pci_reso_pci_rstn_en_out ; +assign wb_rst_o = pci_reso_rst_o ; +assign pci_inta_o = pci_into_pci_intan_out ; +assign pci_inta_oe_o = pci_into_pci_intan_en_out ; +assign wb_int_o = pci_into_int_o ; + +// WISHBONE SLAVE UNIT OUTPUTS +wire [31:0] wbu_sdata_out ; +wire wbu_ack_out ; +wire wbu_rty_out ; +wire wbu_err_out ; +wire wbu_pciif_req_out ; +wire wbu_pciif_frame_out ; +wire wbu_pciif_frame_en_out ; +wire wbu_pciif_irdy_out ; +wire wbu_pciif_irdy_en_out ; +wire [31:0] wbu_pciif_ad_out ; +wire wbu_pciif_ad_en_out ; +wire [3:0] wbu_pciif_cbe_out ; +wire wbu_pciif_cbe_en_out ; +wire [31:0] wbu_err_addr_out ; +wire [3:0] wbu_err_bc_out ; +wire wbu_err_signal_out ; +wire wbu_err_source_out ; +wire wbu_err_rty_exp_out ; +wire wbu_tabort_rec_out ; +wire wbu_mabort_rec_out ; +wire [11:0] wbu_conf_offset_out ; +wire wbu_conf_renable_out ; +wire wbu_conf_wenable_out ; +wire [3:0] wbu_conf_be_out ; +wire [31:0] wbu_conf_data_out ; +wire wbu_del_read_comp_pending_out ; +wire wbu_wbw_fifo_empty_out ; +wire wbu_ad_load_out ; +wire wbu_ad_load_on_transfer_out ; +wire wbu_pciif_frame_load_out ; + +// PCI TARGET UNIT OUTPUTS +wire [31:0] pciu_adr_out ; +wire [31:0] pciu_mdata_out ; +wire pciu_cyc_out ; +wire pciu_stb_out ; +wire pciu_we_out ; +wire [2:0] pciu_cti_out ; +wire [1:0] pciu_bte_out ; +wire [3:0] pciu_sel_out ; +wire pciu_pciif_trdy_out ; +wire pciu_pciif_stop_out ; +wire pciu_pciif_devsel_out ; +wire pciu_pciif_trdy_en_out ; +wire pciu_pciif_stop_en_out ; +wire pciu_pciif_devsel_en_out ; +wire pciu_ad_load_out ; +wire pciu_ad_load_on_transfer_out ; +wire [31:0] pciu_pciif_ad_out ; +wire pciu_pciif_ad_en_out ; +wire pciu_pciif_tabort_set_out ; +wire [31:0] pciu_err_addr_out ; +wire [3:0] pciu_err_bc_out ; +wire [31:0] pciu_err_data_out ; +wire [3:0] pciu_err_be_out ; +wire pciu_err_signal_out ; +wire pciu_err_source_out ; +wire pciu_err_rty_exp_out ; +wire [11:0] pciu_conf_offset_out ; +wire pciu_conf_renable_out ; +wire pciu_conf_wenable_out ; +wire [3:0] pciu_conf_be_out ; +wire [31:0] pciu_conf_data_out ; +wire pciu_pci_drcomp_pending_out ; +wire pciu_pciw_fifo_empty_out ; + +// assign pci target unit's outputs to top outputs where possible +assign wbm_adr_o = pciu_adr_out ; +assign wbm_dat_o = pciu_mdata_out ; +assign wbm_cyc_o = pciu_cyc_out ; +assign wbm_stb_o = pciu_stb_out ; +assign wbm_we_o = pciu_we_out ; +assign wbm_cti_o = pciu_cti_out ; +assign wbm_bte_o = pciu_bte_out ; +assign wbm_sel_o = pciu_sel_out ; + +// CONFIGURATION SPACE OUTPUTS +wire [31:0] conf_w_data_out ; +wire [31:0] conf_r_data_out ; +wire conf_serr_enable_out ; +wire conf_perr_response_out ; +wire conf_pci_master_enable_out ; +wire conf_mem_space_enable_out ; +wire conf_io_space_enable_out ; +wire [7:0] conf_cache_line_size_to_pci_out ; +wire [7:0] conf_cache_line_size_to_wb_out ; +wire conf_cache_lsize_not_zero_to_wb_out ; +wire [7:0] conf_latency_tim_out ; + +wire [pci_ba0_width - 1:0] conf_pci_ba0_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ba1_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ba2_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ba3_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ba4_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ba5_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ta0_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ta1_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ta2_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ta3_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ta4_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_ta5_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_am0_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_am1_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_am2_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_am3_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_am4_out ; +wire [pci_ba1_5_width - 1:0] conf_pci_am5_out ; + +wire conf_pci_mem_io0_out ; +wire conf_pci_mem_io1_out ; +wire conf_pci_mem_io2_out ; +wire conf_pci_mem_io3_out ; +wire conf_pci_mem_io4_out ; +wire conf_pci_mem_io5_out ; + +wire [1:0] conf_pci_img_ctrl0_out ; +wire [1:0] conf_pci_img_ctrl1_out ; +wire [1:0] conf_pci_img_ctrl2_out ; +wire [1:0] conf_pci_img_ctrl3_out ; +wire [1:0] conf_pci_img_ctrl4_out ; +wire [1:0] conf_pci_img_ctrl5_out ; + +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba0_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba1_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba2_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba3_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba4_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ba5_out ; + +wire conf_wb_mem_io0_out ; +wire conf_wb_mem_io1_out ; +wire conf_wb_mem_io2_out ; +wire conf_wb_mem_io3_out ; +wire conf_wb_mem_io4_out ; +wire conf_wb_mem_io5_out ; + +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am0_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am1_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am2_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am3_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am4_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_am5_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta0_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta1_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta2_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta3_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta4_out ; +wire [19:(20 - `WB_NUM_OF_DEC_ADDR_LINES)] conf_wb_ta5_out ; +wire [2:0] conf_wb_img_ctrl0_out ; +wire [2:0] conf_wb_img_ctrl1_out ; +wire [2:0] conf_wb_img_ctrl2_out ; +wire [2:0] conf_wb_img_ctrl3_out ; +wire [2:0] conf_wb_img_ctrl4_out ; +wire [2:0] conf_wb_img_ctrl5_out ; +wire [23:0] conf_ccyc_addr_out ; +wire conf_soft_res_out ; +wire conf_int_out ; +wire conf_wb_init_complete_out ; +wire conf_pci_init_complete_out ; + +// PCI IO MUX OUTPUTS +wire pci_mux_frame_out ; +wire pci_mux_irdy_out ; +wire pci_mux_devsel_out ; +wire pci_mux_trdy_out ; +wire pci_mux_stop_out ; +wire [3:0] pci_mux_cbe_out ; +wire [31:0] pci_mux_ad_out ; +wire pci_mux_ad_load_out ; + +wire [31:0] pci_mux_ad_en_out ; +wire pci_mux_ad_en_unregistered_out ; +wire pci_mux_frame_en_out ; +wire pci_mux_irdy_en_out ; +wire pci_mux_devsel_en_out ; +wire pci_mux_trdy_en_out ; +wire pci_mux_stop_en_out ; +wire [3:0] pci_mux_cbe_en_out ; + +wire pci_mux_par_out ; +wire pci_mux_par_en_out ; +wire pci_mux_perr_out ; +wire pci_mux_perr_en_out ; +wire pci_mux_serr_out ; +wire pci_mux_serr_en_out ; + +wire pci_mux_req_out ; +wire pci_mux_req_en_out ; + +// assign outputs to top level outputs + +assign pci_ad_oe_o = pci_mux_ad_en_out ; +assign pci_frame_oe_o = pci_mux_frame_en_out ; +assign pci_irdy_oe_o = pci_mux_irdy_en_out ; +assign pci_cbe_oe_o = pci_mux_cbe_en_out ; + +assign pci_par_o = pci_mux_par_out ; +assign pci_par_oe_o = pci_mux_par_en_out ; +assign pci_perr_o = pci_mux_perr_out ; +assign pci_perr_oe_o = pci_mux_perr_en_out ; +assign pci_serr_o = pci_mux_serr_out ; +assign pci_serr_oe_o = pci_mux_serr_en_out ; + +assign pci_req_o = pci_mux_req_out ; +assign pci_req_oe_o = pci_mux_req_en_out ; + +assign pci_trdy_oe_o = pci_mux_trdy_en_out ; +assign pci_devsel_oe_o = pci_mux_devsel_en_out ; +assign pci_stop_oe_o = pci_mux_stop_en_out ; +assign pci_trdy_o = pci_mux_trdy_out ; +assign pci_devsel_o = pci_mux_devsel_out ; +assign pci_stop_o = pci_mux_stop_out ; + +assign pci_ad_o = pci_mux_ad_out ; +assign pci_frame_o = pci_mux_frame_out ; +assign pci_irdy_o = pci_mux_irdy_out ; +assign pci_cbe_o = pci_mux_cbe_out ; + +// duplicate output register's outputs +wire out_bckp_frame_out ; +wire out_bckp_irdy_out ; +wire out_bckp_devsel_out ; +wire out_bckp_trdy_out ; +wire out_bckp_stop_out ; +wire [3:0] out_bckp_cbe_out ; +wire out_bckp_cbe_en_out ; +wire [31:0] out_bckp_ad_out ; +wire out_bckp_ad_en_out ; +wire out_bckp_irdy_en_out ; +wire out_bckp_frame_en_out ; +wire out_bckp_tar_ad_en_out ; +wire out_bckp_mas_ad_en_out ; +wire out_bckp_trdy_en_out ; + +wire out_bckp_par_out ; +wire out_bckp_par_en_out ; +wire out_bckp_perr_out ; +wire out_bckp_perr_en_out ; +wire out_bckp_serr_out ; +wire out_bckp_serr_en_out ; + +wire int_pci_frame = out_bckp_frame_en_out ? out_bckp_frame_out : pci_frame_i ; +wire int_pci_irdy = out_bckp_irdy_en_out ? out_bckp_irdy_out : pci_irdy_i ; +wire int_pci_devsel = out_bckp_trdy_en_out ? out_bckp_devsel_out : pci_devsel_i ; +wire int_pci_trdy = out_bckp_trdy_en_out ? out_bckp_trdy_out : pci_trdy_i ; +wire int_pci_stop = out_bckp_trdy_en_out ? out_bckp_stop_out : pci_stop_i ; +wire [ 3: 0] int_pci_cbe = out_bckp_cbe_en_out ? out_bckp_cbe_out : pci_cbe_i ; +wire int_pci_par = out_bckp_par_en_out ? out_bckp_par_out : pci_par_i ; +wire int_pci_perr = out_bckp_perr_en_out ? out_bckp_perr_out : pci_perr_i ; +// PARITY CHECKER OUTPUTS +wire parchk_pci_par_out ; +wire parchk_pci_par_en_out ; +wire parchk_pci_perr_out ; +wire parchk_pci_perr_en_out ; +wire parchk_pci_serr_out ; +wire parchk_pci_serr_en_out ; +wire parchk_par_err_detect_out ; +wire parchk_perr_mas_detect_out ; +wire parchk_sig_serr_out ; + +// input register outputs +wire in_reg_gnt_out ; +wire in_reg_frame_out ; +wire in_reg_irdy_out ; +wire in_reg_trdy_out ; +wire in_reg_stop_out ; +wire in_reg_devsel_out ; +wire in_reg_idsel_out ; +wire [31:0] in_reg_ad_out ; +wire [3:0] in_reg_cbe_out ; + +/*========================================================================================================= +Now comes definition of all modules' and their appropriate inputs +=========================================================================================================*/ +// PCI BRIDGE RESET AND INTERRUPT LOGIC INPUTS +wire pci_resi_rst_i = wb_rst_i ; +wire pci_resi_pci_rstn_in = pci_rst_i ; +wire pci_resi_conf_soft_res_in = conf_soft_res_out ; +wire pci_inti_pci_intan_in = pci_inta_i ; +wire pci_inti_conf_int_in = conf_int_out ; +wire pci_inti_int_i = wb_int_i ; +wire pci_into_init_complete_in = conf_pci_init_complete_out ; + +pci_rst_int pci_resets_and_interrupts +( + .clk_in (pci_clk), + .rst_i (pci_resi_rst_i), + .pci_rstn_in (pci_resi_pci_rstn_in), + .conf_soft_res_in (pci_resi_conf_soft_res_in), + .reset (pci_reso_reset), + .pci_rstn_out (pci_reso_pci_rstn_out), + .pci_rstn_en_out (pci_reso_pci_rstn_en_out), + .rst_o (pci_reso_rst_o), + .pci_intan_in (pci_inti_pci_intan_in), + .conf_int_in (pci_inti_conf_int_in), + .int_i (pci_inti_int_i), + .pci_intan_out (pci_into_pci_intan_out), + .pci_intan_en_out (pci_into_pci_intan_en_out), + .int_o (pci_into_int_o), + .conf_isr_int_prop_out (pci_into_conf_isr_int_prop_out), + .init_complete_in (pci_into_init_complete_in) +); + + +`ifdef PCI_WB_REV_B3 + +wire wbs_wbb3_2_wbb2_cyc_o ; +wire wbs_wbb3_2_wbb2_stb_o ; +wire [31:0] wbs_wbb3_2_wbb2_adr_o ; +wire [31:0] wbs_wbb3_2_wbb2_dat_i_o ; +wire [31:0] wbs_wbb3_2_wbb2_dat_o_o ; +wire wbs_wbb3_2_wbb2_we_o ; +wire [ 3:0] wbs_wbb3_2_wbb2_sel_o ; +wire wbs_wbb3_2_wbb2_ack_o ; +wire wbs_wbb3_2_wbb2_err_o ; +wire wbs_wbb3_2_wbb2_rty_o ; +wire wbs_wbb3_2_wbb2_cab_o ; + +// assign wishbone slave unit's outputs to top outputs where possible +assign wbs_dat_o = wbs_wbb3_2_wbb2_dat_o_o ; +assign wbs_ack_o = wbs_wbb3_2_wbb2_ack_o ; +assign wbs_rty_o = wbs_wbb3_2_wbb2_rty_o ; +assign wbs_err_o = wbs_wbb3_2_wbb2_err_o ; + +wire wbs_wbb3_2_wbb2_cyc_i = wbs_cyc_i ; +wire wbs_wbb3_2_wbb2_stb_i = wbs_stb_i ; +wire wbs_wbb3_2_wbb2_we_i = wbs_we_i ; +wire wbs_wbb3_2_wbb2_ack_i = wbu_ack_out ; +wire wbs_wbb3_2_wbb2_err_i = wbu_err_out ; +wire wbs_wbb3_2_wbb2_rty_i = wbu_rty_out ; +wire [31:0] wbs_wbb3_2_wbb2_adr_i = wbs_adr_i ; +wire [ 3:0] wbs_wbb3_2_wbb2_sel_i = wbs_sel_i ; +wire [31:0] wbs_wbb3_2_wbb2_dat_i_i = wbs_dat_i ; +wire [31:0] wbs_wbb3_2_wbb2_dat_o_i = wbu_sdata_out ; +wire [ 2:0] wbs_wbb3_2_wbb2_cti_i = wbs_cti_i ; +wire [ 1:0] wbs_wbb3_2_wbb2_bte_i = wbs_bte_i ; + +pci_wbs_wbb3_2_wbb2 i_pci_wbs_wbb3_2_wbb2 +( + .wb_clk_i ( wb_clk_i ) , + .wb_rst_i ( reset ) , + + .wbs_cyc_i ( wbs_wbb3_2_wbb2_cyc_i ) , + .wbs_cyc_o ( wbs_wbb3_2_wbb2_cyc_o ) , + .wbs_stb_i ( wbs_wbb3_2_wbb2_stb_i ) , + .wbs_stb_o ( wbs_wbb3_2_wbb2_stb_o ) , + .wbs_adr_i ( wbs_wbb3_2_wbb2_adr_i ) , + .wbs_adr_o ( wbs_wbb3_2_wbb2_adr_o ) , + .wbs_dat_i_i ( wbs_wbb3_2_wbb2_dat_i_i ) , + .wbs_dat_i_o ( wbs_wbb3_2_wbb2_dat_i_o ) , + .wbs_dat_o_i ( wbs_wbb3_2_wbb2_dat_o_i ) , + .wbs_dat_o_o ( wbs_wbb3_2_wbb2_dat_o_o ) , + .wbs_we_i ( wbs_wbb3_2_wbb2_we_i ) , + .wbs_we_o ( wbs_wbb3_2_wbb2_we_o ) , + .wbs_sel_i ( wbs_wbb3_2_wbb2_sel_i ) , + .wbs_sel_o ( wbs_wbb3_2_wbb2_sel_o ) , + .wbs_ack_i ( wbs_wbb3_2_wbb2_ack_i ) , + .wbs_ack_o ( wbs_wbb3_2_wbb2_ack_o ) , + .wbs_err_i ( wbs_wbb3_2_wbb2_err_i ) , + .wbs_err_o ( wbs_wbb3_2_wbb2_err_o ) , + .wbs_rty_i ( wbs_wbb3_2_wbb2_rty_i ) , + .wbs_rty_o ( wbs_wbb3_2_wbb2_rty_o ) , + .wbs_cti_i ( wbs_wbb3_2_wbb2_cti_i ) , + .wbs_bte_i ( wbs_wbb3_2_wbb2_bte_i ) , + .wbs_cab_o ( wbs_wbb3_2_wbb2_cab_o ) , + .wb_init_complete_i ( conf_wb_init_complete_out ) +) ; + +// WISHBONE SLAVE UNIT INPUTS +wire [31:0] wbu_addr_in = wbs_wbb3_2_wbb2_adr_o ; +wire [31:0] wbu_sdata_in = wbs_wbb3_2_wbb2_dat_i_o ; +wire wbu_cyc_in = wbs_wbb3_2_wbb2_cyc_o ; +wire wbu_stb_in = wbs_wbb3_2_wbb2_stb_o ; +wire wbu_we_in = wbs_wbb3_2_wbb2_we_o ; +wire [3:0] wbu_sel_in = wbs_wbb3_2_wbb2_sel_o ; +wire wbu_cab_in = wbs_wbb3_2_wbb2_cab_o ; + +`else + +// WISHBONE SLAVE UNIT INPUTS +wire [31:0] wbu_addr_in = wbs_adr_i ; +wire [31:0] wbu_sdata_in = wbs_dat_i ; +wire wbu_cyc_in = wbs_cyc_i ; +wire wbu_stb_in = wbs_stb_i ; +wire wbu_we_in = wbs_we_i ; +wire [3:0] wbu_sel_in = wbs_sel_i ; +wire wbu_cab_in = wbs_cab_i ; + +// assign wishbone slave unit's outputs to top outputs where possible +assign wbs_dat_o = wbu_sdata_out ; +assign wbs_ack_o = wbu_ack_out ; +assign wbs_rty_o = wbu_rty_out ; +assign wbs_err_o = wbu_err_out ; + +`endif + +wire [5:0] wbu_map_in = { + conf_wb_mem_io5_out, + conf_wb_mem_io4_out, + conf_wb_mem_io3_out, + conf_wb_mem_io2_out, + conf_wb_mem_io1_out, + conf_wb_mem_io0_out + } ; + +wire [5:0] wbu_pref_en_in = { + conf_wb_img_ctrl5_out[1], + conf_wb_img_ctrl4_out[1], + conf_wb_img_ctrl3_out[1], + conf_wb_img_ctrl2_out[1], + conf_wb_img_ctrl1_out[1], + conf_wb_img_ctrl0_out[1] + }; +wire [5:0] wbu_mrl_en_in = { + conf_wb_img_ctrl5_out[0], + conf_wb_img_ctrl4_out[0], + conf_wb_img_ctrl3_out[0], + conf_wb_img_ctrl2_out[0], + conf_wb_img_ctrl1_out[0], + conf_wb_img_ctrl0_out[0] + }; + +wire [5:0] wbu_at_en_in = { + conf_wb_img_ctrl5_out[2], + conf_wb_img_ctrl4_out[2], + conf_wb_img_ctrl3_out[2], + conf_wb_img_ctrl2_out[2], + conf_wb_img_ctrl1_out[2], + conf_wb_img_ctrl0_out[2] + } ; + +wire wbu_pci_drcomp_pending_in = pciu_pci_drcomp_pending_out ; +wire wbu_pciw_empty_in = pciu_pciw_fifo_empty_out ; + +`ifdef HOST + wire [31:0] wbu_conf_data_in = conf_w_data_out ; +`else +`ifdef GUEST + wire [31:0] wbu_conf_data_in = conf_r_data_out ; +`endif +`endif + +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar0_in = conf_wb_ba0_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar1_in = conf_wb_ba1_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar2_in = conf_wb_ba2_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar3_in = conf_wb_ba3_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar4_in = conf_wb_ba4_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar5_in = conf_wb_ba5_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am0_in = conf_wb_am0_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am1_in = conf_wb_am1_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am2_in = conf_wb_am2_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am3_in = conf_wb_am3_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am4_in = conf_wb_am4_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am5_in = conf_wb_am5_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta0_in = conf_wb_ta0_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta1_in = conf_wb_ta1_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta2_in = conf_wb_ta2_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta3_in = conf_wb_ta3_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta4_in = conf_wb_ta4_out ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta5_in = conf_wb_ta5_out ; + +wire [23:0] wbu_ccyc_addr_in = conf_ccyc_addr_out ; +wire wbu_master_enable_in = conf_pci_master_enable_out ; +wire wbu_cache_line_size_not_zero = conf_cache_lsize_not_zero_to_wb_out ; +wire [7:0] wbu_cache_line_size_in = conf_cache_line_size_to_pci_out ; + +wire wbu_pciif_gnt_in = pci_gnt_i ; +wire wbu_pciif_frame_in = in_reg_frame_out ; +wire wbu_pciif_irdy_in = in_reg_irdy_out ; +wire wbu_pciif_trdy_in = int_pci_trdy ; +wire wbu_pciif_stop_in = int_pci_stop ; +wire wbu_pciif_devsel_in = int_pci_devsel ; +wire [31:0] wbu_pciif_ad_reg_in = in_reg_ad_out ; +wire wbu_pciif_trdy_reg_in = in_reg_trdy_out ; +wire wbu_pciif_stop_reg_in = in_reg_stop_out ; +wire wbu_pciif_devsel_reg_in = in_reg_devsel_out ; + + +wire [7:0] wbu_latency_tim_val_in = conf_latency_tim_out ; + +wire wbu_pciif_frame_en_in = out_bckp_frame_en_out ; +wire wbu_pciif_frame_out_in = out_bckp_frame_out ; +wire wbu_wb_init_complete_in = conf_wb_init_complete_out ; + +pci_wb_slave_unit wishbone_slave_unit +( + .reset_in (reset), + .wb_clock_in (wb_clk), + .pci_clock_in (pci_clk), + .ADDR_I (wbu_addr_in), + .SDATA_I (wbu_sdata_in), + .SDATA_O (wbu_sdata_out), + .CYC_I (wbu_cyc_in), + .STB_I (wbu_stb_in), + .WE_I (wbu_we_in), + .SEL_I (wbu_sel_in), + .ACK_O (wbu_ack_out), + .RTY_O (wbu_rty_out), + .ERR_O (wbu_err_out), + .CAB_I (wbu_cab_in), + .wbu_map_in (wbu_map_in), + .wbu_pref_en_in (wbu_pref_en_in), + .wbu_mrl_en_in (wbu_mrl_en_in), + .wbu_pci_drcomp_pending_in (wbu_pci_drcomp_pending_in), + .wbu_conf_data_in (wbu_conf_data_in), + .wbu_pciw_empty_in (wbu_pciw_empty_in), + .wbu_bar0_in (wbu_bar0_in), + .wbu_bar1_in (wbu_bar1_in), + .wbu_bar2_in (wbu_bar2_in), + .wbu_bar3_in (wbu_bar3_in), + .wbu_bar4_in (wbu_bar4_in), + .wbu_bar5_in (wbu_bar5_in), + .wbu_am0_in (wbu_am0_in), + .wbu_am1_in (wbu_am1_in), + .wbu_am2_in (wbu_am2_in), + .wbu_am3_in (wbu_am3_in), + .wbu_am4_in (wbu_am4_in), + .wbu_am5_in (wbu_am5_in), + .wbu_ta0_in (wbu_ta0_in), + .wbu_ta1_in (wbu_ta1_in), + .wbu_ta2_in (wbu_ta2_in), + .wbu_ta3_in (wbu_ta3_in), + .wbu_ta4_in (wbu_ta4_in), + .wbu_ta5_in (wbu_ta5_in), + .wbu_at_en_in (wbu_at_en_in), + .wbu_ccyc_addr_in (wbu_ccyc_addr_in), + .wbu_master_enable_in (wbu_master_enable_in), + .wb_init_complete_in (wbu_wb_init_complete_in), + .wbu_cache_line_size_not_zero (wbu_cache_line_size_not_zero), + .wbu_cache_line_size_in (wbu_cache_line_size_in), + .wbu_pciif_gnt_in (wbu_pciif_gnt_in), + .wbu_pciif_frame_in (wbu_pciif_frame_in), + .wbu_pciif_frame_en_in (wbu_pciif_frame_en_in), + .wbu_pciif_frame_out_in (wbu_pciif_frame_out_in), + .wbu_pciif_irdy_in (wbu_pciif_irdy_in), + .wbu_pciif_trdy_in (wbu_pciif_trdy_in), + .wbu_pciif_stop_in (wbu_pciif_stop_in), + .wbu_pciif_devsel_in (wbu_pciif_devsel_in), + .wbu_pciif_ad_reg_in (wbu_pciif_ad_reg_in), + .wbu_pciif_req_out (wbu_pciif_req_out), + .wbu_pciif_frame_out (wbu_pciif_frame_out), + .wbu_pciif_frame_en_out (wbu_pciif_frame_en_out), + .wbu_pciif_frame_load_out (wbu_pciif_frame_load_out), + .wbu_pciif_irdy_out (wbu_pciif_irdy_out), + .wbu_pciif_irdy_en_out (wbu_pciif_irdy_en_out), + .wbu_pciif_ad_out (wbu_pciif_ad_out), + .wbu_pciif_ad_en_out (wbu_pciif_ad_en_out), + .wbu_pciif_cbe_out (wbu_pciif_cbe_out), + .wbu_pciif_cbe_en_out (wbu_pciif_cbe_en_out), + .wbu_err_addr_out (wbu_err_addr_out), + .wbu_err_bc_out (wbu_err_bc_out), + .wbu_err_signal_out (wbu_err_signal_out), + .wbu_err_source_out (wbu_err_source_out), + .wbu_err_rty_exp_out (wbu_err_rty_exp_out), + .wbu_tabort_rec_out (wbu_tabort_rec_out), + .wbu_mabort_rec_out (wbu_mabort_rec_out), + .wbu_conf_offset_out (wbu_conf_offset_out), + .wbu_conf_renable_out (wbu_conf_renable_out), + .wbu_conf_wenable_out (wbu_conf_wenable_out), + .wbu_conf_be_out (wbu_conf_be_out), + .wbu_conf_data_out (wbu_conf_data_out), + .wbu_del_read_comp_pending_out (wbu_del_read_comp_pending_out), + .wbu_wbw_fifo_empty_out (wbu_wbw_fifo_empty_out), + .wbu_latency_tim_val_in (wbu_latency_tim_val_in), + .wbu_ad_load_out (wbu_ad_load_out), + .wbu_ad_load_on_transfer_out (wbu_ad_load_on_transfer_out), + .wbu_pciif_trdy_reg_in (wbu_pciif_trdy_reg_in), + .wbu_pciif_stop_reg_in (wbu_pciif_stop_reg_in), + .wbu_pciif_devsel_reg_in (wbu_pciif_devsel_reg_in) + +`ifdef PCI_BIST + , + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o_internal), + .mbist_ctrl_i (mbist_ctrl_i) +`endif +); + +// PCI TARGET UNIT INPUTS +wire [31:0] pciu_mdata_in = wbm_dat_i ; +wire pciu_ack_in = wbm_ack_i ; +wire pciu_rty_in = wbm_rty_i ; +wire pciu_err_in = wbm_err_i ; + +wire [5:0] pciu_map_in = { + conf_pci_mem_io5_out, + conf_pci_mem_io4_out, + conf_pci_mem_io3_out, + conf_pci_mem_io2_out, + conf_pci_mem_io1_out, + conf_pci_mem_io0_out + } ; + +wire [5:0] pciu_pref_en_in = { + conf_pci_img_ctrl5_out[0], + conf_pci_img_ctrl4_out[0], + conf_pci_img_ctrl3_out[0], + conf_pci_img_ctrl2_out[0], + conf_pci_img_ctrl1_out[0], + conf_pci_img_ctrl0_out[0] + }; + +wire [5:0] pciu_at_en_in = { + conf_pci_img_ctrl5_out[1], + conf_pci_img_ctrl4_out[1], + conf_pci_img_ctrl3_out[1], + conf_pci_img_ctrl2_out[1], + conf_pci_img_ctrl1_out[1], + conf_pci_img_ctrl0_out[1] + } ; + +wire pciu_mem_enable_in = conf_mem_space_enable_out ; +wire pciu_io_enable_in = conf_io_space_enable_out ; + +wire pciu_wbw_fifo_empty_in = wbu_wbw_fifo_empty_out ; +wire pciu_wbu_del_read_comp_pending_in = wbu_del_read_comp_pending_out ; +wire pciu_wbu_frame_en_in = out_bckp_frame_en_out ; + +`ifdef HOST + wire [31:0] pciu_conf_data_in = conf_r_data_out ; +`else +`ifdef GUEST + wire [31:0] pciu_conf_data_in = conf_w_data_out ; +`endif +`endif + +wire [pci_ba0_width - 1:0] pciu_bar0_in = conf_pci_ba0_out ; +wire [pci_ba1_5_width - 1:0] pciu_bar1_in = conf_pci_ba1_out ; +wire [pci_ba1_5_width - 1:0] pciu_bar2_in = conf_pci_ba2_out ; +wire [pci_ba1_5_width - 1:0] pciu_bar3_in = conf_pci_ba3_out ; +wire [pci_ba1_5_width - 1:0] pciu_bar4_in = conf_pci_ba4_out ; +wire [pci_ba1_5_width - 1:0] pciu_bar5_in = conf_pci_ba5_out ; +wire [pci_ba1_5_width - 1:0] pciu_am0_in = conf_pci_am0_out ; +wire [pci_ba1_5_width - 1:0] pciu_am1_in = conf_pci_am1_out ; +wire [pci_ba1_5_width - 1:0] pciu_am2_in = conf_pci_am2_out ; +wire [pci_ba1_5_width - 1:0] pciu_am3_in = conf_pci_am3_out ; +wire [pci_ba1_5_width - 1:0] pciu_am4_in = conf_pci_am4_out ; +wire [pci_ba1_5_width - 1:0] pciu_am5_in = conf_pci_am5_out ; +wire [pci_ba1_5_width - 1:0] pciu_ta0_in = conf_pci_ta0_out ; +wire [pci_ba1_5_width - 1:0] pciu_ta1_in = conf_pci_ta1_out ; +wire [pci_ba1_5_width - 1:0] pciu_ta2_in = conf_pci_ta2_out ; +wire [pci_ba1_5_width - 1:0] pciu_ta3_in = conf_pci_ta3_out ; +wire [pci_ba1_5_width - 1:0] pciu_ta4_in = conf_pci_ta4_out ; +wire [pci_ba1_5_width - 1:0] pciu_ta5_in = conf_pci_ta5_out ; + +wire [7:0] pciu_cache_line_size_in = conf_cache_line_size_to_wb_out ; +wire pciu_cache_lsize_not_zero_in = conf_cache_lsize_not_zero_to_wb_out ; + +wire pciu_pciif_frame_in = int_pci_frame ; +wire pciu_pciif_irdy_in = int_pci_irdy ; +wire pciu_pciif_idsel_in = pci_idsel_i ; +wire pciu_pciif_frame_reg_in = in_reg_frame_out ; +wire pciu_pciif_irdy_reg_in = in_reg_irdy_out ; +wire pciu_pciif_idsel_reg_in = in_reg_idsel_out ; +wire [31:0] pciu_pciif_ad_reg_in = in_reg_ad_out ; +wire [3:0] pciu_pciif_cbe_reg_in = in_reg_cbe_out ; +wire [3:0] pciu_pciif_cbe_in = int_pci_cbe ; + +wire pciu_pciif_bckp_trdy_en_in = out_bckp_trdy_en_out ; +wire pciu_pciif_bckp_devsel_in = out_bckp_devsel_out ; +wire pciu_pciif_bckp_trdy_in = out_bckp_trdy_out ; +wire pciu_pciif_bckp_stop_in = out_bckp_stop_out ; +wire pciu_pciif_trdy_reg_in = in_reg_trdy_out ; +wire pciu_pciif_stop_reg_in = in_reg_stop_out ; + +pci_target_unit pci_target_unit +( + .reset_in (reset), + .wb_clock_in (wb_clk), + .pci_clock_in (pci_clk), + .pciu_wbm_adr_o (pciu_adr_out), + .pciu_wbm_dat_o (pciu_mdata_out), + .pciu_wbm_dat_i (pciu_mdata_in), + .pciu_wbm_cyc_o (pciu_cyc_out), + .pciu_wbm_stb_o (pciu_stb_out), + .pciu_wbm_we_o (pciu_we_out), + .pciu_wbm_cti_o (pciu_cti_out), + .pciu_wbm_bte_o (pciu_bte_out), + .pciu_wbm_sel_o (pciu_sel_out), + .pciu_wbm_ack_i (pciu_ack_in), + .pciu_wbm_rty_i (pciu_rty_in), + .pciu_wbm_err_i (pciu_err_in), + .pciu_mem_enable_in (pciu_mem_enable_in), + .pciu_io_enable_in (pciu_io_enable_in), + .pciu_map_in (pciu_map_in), + .pciu_pref_en_in (pciu_pref_en_in), + .pciu_conf_data_in (pciu_conf_data_in), + .pciu_wbw_fifo_empty_in (pciu_wbw_fifo_empty_in), + .pciu_wbu_del_read_comp_pending_in (pciu_wbu_del_read_comp_pending_in), + .pciu_wbu_frame_en_in (pciu_wbu_frame_en_in), + .pciu_bar0_in (pciu_bar0_in), + .pciu_bar1_in (pciu_bar1_in), + .pciu_bar2_in (pciu_bar2_in), + .pciu_bar3_in (pciu_bar3_in), + .pciu_bar4_in (pciu_bar4_in), + .pciu_bar5_in (pciu_bar5_in), + .pciu_am0_in (pciu_am0_in), + .pciu_am1_in (pciu_am1_in), + .pciu_am2_in (pciu_am2_in), + .pciu_am3_in (pciu_am3_in), + .pciu_am4_in (pciu_am4_in), + .pciu_am5_in (pciu_am5_in), + .pciu_ta0_in (pciu_ta0_in), + .pciu_ta1_in (pciu_ta1_in), + .pciu_ta2_in (pciu_ta2_in), + .pciu_ta3_in (pciu_ta3_in), + .pciu_ta4_in (pciu_ta4_in), + .pciu_ta5_in (pciu_ta5_in), + .pciu_at_en_in (pciu_at_en_in), + .pciu_cache_line_size_in (pciu_cache_line_size_in), + .pciu_cache_lsize_not_zero_in (pciu_cache_lsize_not_zero_in), + .pciu_pciif_frame_in (pciu_pciif_frame_in), + .pciu_pciif_irdy_in (pciu_pciif_irdy_in), + .pciu_pciif_idsel_in (pciu_pciif_idsel_in), + .pciu_pciif_frame_reg_in (pciu_pciif_frame_reg_in), + .pciu_pciif_irdy_reg_in (pciu_pciif_irdy_reg_in), + .pciu_pciif_idsel_reg_in (pciu_pciif_idsel_reg_in), + .pciu_pciif_ad_reg_in (pciu_pciif_ad_reg_in), + .pciu_pciif_cbe_reg_in (pciu_pciif_cbe_reg_in), + .pciu_pciif_cbe_in (pciu_pciif_cbe_in), + .pciu_pciif_bckp_trdy_en_in (pciu_pciif_bckp_trdy_en_in), + .pciu_pciif_bckp_devsel_in (pciu_pciif_bckp_devsel_in), + .pciu_pciif_bckp_trdy_in (pciu_pciif_bckp_trdy_in), + .pciu_pciif_bckp_stop_in (pciu_pciif_bckp_stop_in), + .pciu_pciif_trdy_reg_in (pciu_pciif_trdy_reg_in), + .pciu_pciif_stop_reg_in (pciu_pciif_stop_reg_in), + .pciu_pciif_trdy_out (pciu_pciif_trdy_out), + .pciu_pciif_stop_out (pciu_pciif_stop_out), + .pciu_pciif_devsel_out (pciu_pciif_devsel_out), + .pciu_pciif_trdy_en_out (pciu_pciif_trdy_en_out), + .pciu_pciif_stop_en_out (pciu_pciif_stop_en_out), + .pciu_pciif_devsel_en_out (pciu_pciif_devsel_en_out), + .pciu_ad_load_out (pciu_ad_load_out), + .pciu_ad_load_on_transfer_out (pciu_ad_load_on_transfer_out), + .pciu_pciif_ad_out (pciu_pciif_ad_out), + .pciu_pciif_ad_en_out (pciu_pciif_ad_en_out), + .pciu_pciif_tabort_set_out (pciu_pciif_tabort_set_out), + .pciu_err_addr_out (pciu_err_addr_out), + .pciu_err_bc_out (pciu_err_bc_out), + .pciu_err_data_out (pciu_err_data_out), + .pciu_err_be_out (pciu_err_be_out), + .pciu_err_signal_out (pciu_err_signal_out), + .pciu_err_source_out (pciu_err_source_out), + .pciu_err_rty_exp_out (pciu_err_rty_exp_out), + .pciu_conf_offset_out (pciu_conf_offset_out), + .pciu_conf_renable_out (pciu_conf_renable_out), + .pciu_conf_wenable_out (pciu_conf_wenable_out), + .pciu_conf_be_out (pciu_conf_be_out), + .pciu_conf_data_out (pciu_conf_data_out), + .pciu_pci_drcomp_pending_out (pciu_pci_drcomp_pending_out), + .pciu_pciw_fifo_empty_out (pciu_pciw_fifo_empty_out) + +`ifdef PCI_BIST + , + .mbist_si_i (mbist_so_o_internal), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) +`endif +); + + +// CONFIGURATION SPACE INPUTS +`ifdef HOST + + wire [11:0] conf_w_addr_in = wbu_conf_offset_out ; + wire [31:0] conf_w_data_in = wbu_conf_data_out ; + wire conf_w_we_in = wbu_conf_wenable_out ; + wire conf_w_re_in = wbu_conf_renable_out ; + wire [3:0] conf_w_be_in = wbu_conf_be_out ; + wire conf_w_clock = wb_clk ; + wire [11:0] conf_r_addr_in = pciu_conf_offset_out ; + wire conf_r_re_in = pciu_conf_renable_out ; + +`else +`ifdef GUEST + + wire [11:0] conf_r_addr_in = wbu_conf_offset_out ; + wire conf_r_re_in = wbu_conf_renable_out ; + wire conf_w_clock = pci_clk ; + wire [11:0] conf_w_addr_in = pciu_conf_offset_out ; + wire [31:0] conf_w_data_in = pciu_conf_data_out ; + wire conf_w_we_in = pciu_conf_wenable_out ; + wire conf_w_re_in = pciu_conf_renable_out ; + wire [3:0] conf_w_be_in = pciu_conf_be_out ; + +`endif +`endif + + +wire conf_perr_in = parchk_par_err_detect_out ; +wire conf_serr_in = parchk_sig_serr_out ; +wire conf_master_abort_recv_in = wbu_mabort_rec_out ; +wire conf_target_abort_recv_in = wbu_tabort_rec_out ; +wire conf_target_abort_set_in = pciu_pciif_tabort_set_out ; + +wire conf_master_data_par_err_in = parchk_perr_mas_detect_out ; + +wire [3:0] conf_pci_err_be_in = pciu_err_be_out ; +wire [3:0] conf_pci_err_bc_in = pciu_err_bc_out; +wire conf_pci_err_es_in = pciu_err_source_out ; +wire conf_pci_err_rty_exp_in = pciu_err_rty_exp_out ; +wire conf_pci_err_sig_in = pciu_err_signal_out ; +wire [31:0] conf_pci_err_addr_in = pciu_err_addr_out ; +wire [31:0] conf_pci_err_data_in = pciu_err_data_out ; + +wire [3:0] conf_wb_err_be_in = out_bckp_cbe_out ; +wire [3:0] conf_wb_err_bc_in = wbu_err_bc_out ; +wire conf_wb_err_rty_exp_in = wbu_err_rty_exp_out ; +wire conf_wb_err_es_in = wbu_err_source_out ; +wire conf_wb_err_sig_in = wbu_err_signal_out ; +wire [31:0] conf_wb_err_addr_in = wbu_err_addr_out ; +wire [31:0] conf_wb_err_data_in = out_bckp_ad_out ; + +wire conf_isr_int_prop_in = pci_into_conf_isr_int_prop_out ; +wire conf_par_err_int_in = parchk_perr_mas_detect_out ; +wire conf_sys_err_int_in = parchk_sig_serr_out ; + +pci_conf_space configuration( + .reset (reset), + .pci_clk (pci_clk), + .wb_clk (wb_clk), + .w_conf_address_in (conf_w_addr_in), + .w_conf_data_in (conf_w_data_in), + .w_conf_data_out (conf_w_data_out), + .r_conf_address_in (conf_r_addr_in), + .r_conf_data_out (conf_r_data_out), + .w_we_i (conf_w_we_in), + .w_re (conf_w_re_in), + .r_re (conf_r_re_in), + .w_byte_en_in (conf_w_be_in), + .w_clock (conf_w_clock), + .serr_enable (conf_serr_enable_out), + .perr_response (conf_perr_response_out), + .pci_master_enable (conf_pci_master_enable_out), + .memory_space_enable (conf_mem_space_enable_out), + .io_space_enable (conf_io_space_enable_out), + .perr_in (conf_perr_in), + .serr_in (conf_serr_in), + .master_abort_recv (conf_master_abort_recv_in), + .target_abort_recv (conf_target_abort_recv_in), + .target_abort_set (conf_target_abort_set_in), + .master_data_par_err (conf_master_data_par_err_in), + .cache_line_size_to_pci (conf_cache_line_size_to_pci_out), + .cache_line_size_to_wb (conf_cache_line_size_to_wb_out), + .cache_lsize_not_zero_to_wb (conf_cache_lsize_not_zero_to_wb_out), + .latency_tim (conf_latency_tim_out), + .pci_base_addr0 (conf_pci_ba0_out), + .pci_base_addr1 (conf_pci_ba1_out), + .pci_base_addr2 (conf_pci_ba2_out), + .pci_base_addr3 (conf_pci_ba3_out), + .pci_base_addr4 (conf_pci_ba4_out), + .pci_base_addr5 (conf_pci_ba5_out), + .pci_memory_io0 (conf_pci_mem_io0_out), + .pci_memory_io1 (conf_pci_mem_io1_out), + .pci_memory_io2 (conf_pci_mem_io2_out), + .pci_memory_io3 (conf_pci_mem_io3_out), + .pci_memory_io4 (conf_pci_mem_io4_out), + .pci_memory_io5 (conf_pci_mem_io5_out), + .pci_addr_mask0 (conf_pci_am0_out), + .pci_addr_mask1 (conf_pci_am1_out), + .pci_addr_mask2 (conf_pci_am2_out), + .pci_addr_mask3 (conf_pci_am3_out), + .pci_addr_mask4 (conf_pci_am4_out), + .pci_addr_mask5 (conf_pci_am5_out), + .pci_tran_addr0 (conf_pci_ta0_out), + .pci_tran_addr1 (conf_pci_ta1_out), + .pci_tran_addr2 (conf_pci_ta2_out), + .pci_tran_addr3 (conf_pci_ta3_out), + .pci_tran_addr4 (conf_pci_ta4_out), + .pci_tran_addr5 (conf_pci_ta5_out), + .pci_img_ctrl0 (conf_pci_img_ctrl0_out), + .pci_img_ctrl1 (conf_pci_img_ctrl1_out), + .pci_img_ctrl2 (conf_pci_img_ctrl2_out), + .pci_img_ctrl3 (conf_pci_img_ctrl3_out), + .pci_img_ctrl4 (conf_pci_img_ctrl4_out), + .pci_img_ctrl5 (conf_pci_img_ctrl5_out), + .pci_error_be (conf_pci_err_be_in), + .pci_error_bc (conf_pci_err_bc_in), + .pci_error_rty_exp (conf_pci_err_rty_exp_in), + .pci_error_es (conf_pci_err_es_in), + .pci_error_sig (conf_pci_err_sig_in), + .pci_error_addr (conf_pci_err_addr_in), + .pci_error_data (conf_pci_err_data_in), + .wb_base_addr0 (conf_wb_ba0_out), + .wb_base_addr1 (conf_wb_ba1_out), + .wb_base_addr2 (conf_wb_ba2_out), + .wb_base_addr3 (conf_wb_ba3_out), + .wb_base_addr4 (conf_wb_ba4_out), + .wb_base_addr5 (conf_wb_ba5_out), + .wb_memory_io0 (conf_wb_mem_io0_out), + .wb_memory_io1 (conf_wb_mem_io1_out), + .wb_memory_io2 (conf_wb_mem_io2_out), + .wb_memory_io3 (conf_wb_mem_io3_out), + .wb_memory_io4 (conf_wb_mem_io4_out), + .wb_memory_io5 (conf_wb_mem_io5_out), + .wb_addr_mask0 (conf_wb_am0_out), + .wb_addr_mask1 (conf_wb_am1_out), + .wb_addr_mask2 (conf_wb_am2_out), + .wb_addr_mask3 (conf_wb_am3_out), + .wb_addr_mask4 (conf_wb_am4_out), + .wb_addr_mask5 (conf_wb_am5_out), + .wb_tran_addr0 (conf_wb_ta0_out), + .wb_tran_addr1 (conf_wb_ta1_out), + .wb_tran_addr2 (conf_wb_ta2_out), + .wb_tran_addr3 (conf_wb_ta3_out), + .wb_tran_addr4 (conf_wb_ta4_out), + .wb_tran_addr5 (conf_wb_ta5_out), + .wb_img_ctrl0 (conf_wb_img_ctrl0_out), + .wb_img_ctrl1 (conf_wb_img_ctrl1_out), + .wb_img_ctrl2 (conf_wb_img_ctrl2_out), + .wb_img_ctrl3 (conf_wb_img_ctrl3_out), + .wb_img_ctrl4 (conf_wb_img_ctrl4_out), + .wb_img_ctrl5 (conf_wb_img_ctrl5_out), + .wb_error_be (conf_wb_err_be_in), + .wb_error_bc (conf_wb_err_bc_in), + .wb_error_rty_exp (conf_wb_err_rty_exp_in), + .wb_error_es (conf_wb_err_es_in), + .wb_error_sig (conf_wb_err_sig_in), + .wb_error_addr (conf_wb_err_addr_in), + .wb_error_data (conf_wb_err_data_in), + .config_addr (conf_ccyc_addr_out), + .icr_soft_res (conf_soft_res_out), + .int_out (conf_int_out), + .isr_int_prop (conf_isr_int_prop_in), + .isr_par_err_int (conf_par_err_int_in), + .isr_sys_err_int (conf_sys_err_int_in), + + .pci_init_complete_out (conf_pci_init_complete_out), + .wb_init_complete_out (conf_wb_init_complete_out) + + `ifdef PCI_CPCI_HS_IMPLEMENT + , + .pci_cpci_hs_enum_oe_o (pci_cpci_hs_enum_oe_o) , + .pci_cpci_hs_led_oe_o (pci_cpci_hs_led_oe_o ) , + .pci_cpci_hs_es_i (pci_cpci_hs_es_i) + `endif + + `ifdef PCI_SPOCI + , + // Serial power on configuration interface + .spoci_scl_oe_o (spoci_scl_oe_o ) , + .spoci_sda_i (spoci_sda_i ) , + .spoci_sda_oe_o (spoci_sda_oe_o ) + `endif + ) ; + +// pci data io multiplexer inputs +wire pci_mux_tar_ad_en_in = pciu_pciif_ad_en_out ; +wire pci_mux_tar_ad_en_reg_in = out_bckp_tar_ad_en_out ; +wire [31:0] pci_mux_tar_ad_in = pciu_pciif_ad_out ; +wire pci_mux_devsel_in = pciu_pciif_devsel_out ; +wire pci_mux_devsel_en_in = pciu_pciif_devsel_en_out ; +wire pci_mux_trdy_in = pciu_pciif_trdy_out ; +wire pci_mux_trdy_en_in = pciu_pciif_trdy_en_out ; +wire pci_mux_stop_in = pciu_pciif_stop_out ; +wire pci_mux_stop_en_in = pciu_pciif_stop_en_out ; +wire pci_mux_tar_load_in = pciu_ad_load_out ; +wire pci_mux_tar_load_on_transfer_in = pciu_ad_load_on_transfer_out ; + +wire pci_mux_mas_ad_en_in = wbu_pciif_ad_en_out ; +wire [31:0] pci_mux_mas_ad_in = wbu_pciif_ad_out ; + +wire pci_mux_frame_in = wbu_pciif_frame_out ; +wire pci_mux_frame_en_in = wbu_pciif_frame_en_out ; +wire pci_mux_irdy_in = wbu_pciif_irdy_out; +wire pci_mux_irdy_en_in = wbu_pciif_irdy_en_out; +wire pci_mux_mas_load_in = wbu_ad_load_out ; +wire pci_mux_mas_load_on_transfer_in = wbu_ad_load_on_transfer_out ; +wire [3:0] pci_mux_cbe_in = wbu_pciif_cbe_out ; +wire pci_mux_cbe_en_in = wbu_pciif_cbe_en_out ; + +wire pci_mux_par_in = parchk_pci_par_out ; +wire pci_mux_par_en_in = parchk_pci_par_en_out ; +wire pci_mux_perr_in = parchk_pci_perr_out ; +wire pci_mux_perr_en_in = parchk_pci_perr_en_out ; +wire pci_mux_serr_in = parchk_pci_serr_out ; +wire pci_mux_serr_en_in = parchk_pci_serr_en_out; + +wire pci_mux_req_in = wbu_pciif_req_out ; +wire pci_mux_frame_load_in = wbu_pciif_frame_load_out ; + +wire pci_mux_pci_irdy_in = int_pci_irdy ; +wire pci_mux_pci_trdy_in = int_pci_trdy ; +wire pci_mux_pci_frame_in = int_pci_frame ; +wire pci_mux_pci_stop_in = int_pci_stop ; + +wire pci_mux_init_complete_in = conf_pci_init_complete_out ; + +pci_io_mux pci_io_mux +( + .reset_in (reset), + .clk_in (pci_clk), + .frame_in (pci_mux_frame_in), + .frame_en_in (pci_mux_frame_en_in), + .frame_load_in (pci_mux_frame_load_in), + .irdy_in (pci_mux_irdy_in), + .irdy_en_in (pci_mux_irdy_en_in), + .devsel_in (pci_mux_devsel_in), + .devsel_en_in (pci_mux_devsel_en_in), + .trdy_in (pci_mux_trdy_in), + .trdy_en_in (pci_mux_trdy_en_in), + .stop_in (pci_mux_stop_in), + .stop_en_in (pci_mux_stop_en_in), + .master_load_in (pci_mux_mas_load_in), + .master_load_on_transfer_in (pci_mux_mas_load_on_transfer_in), + .target_load_in (pci_mux_tar_load_in), + .target_load_on_transfer_in (pci_mux_tar_load_on_transfer_in), + .cbe_in (pci_mux_cbe_in), + .cbe_en_in (pci_mux_cbe_en_in), + .mas_ad_in (pci_mux_mas_ad_in), + .tar_ad_in (pci_mux_tar_ad_in), + + .mas_ad_en_in (pci_mux_mas_ad_en_in), + .tar_ad_en_in (pci_mux_tar_ad_en_in), + .tar_ad_en_reg_in (pci_mux_tar_ad_en_reg_in), + + .par_in (pci_mux_par_in), + .par_en_in (pci_mux_par_en_in), + .perr_in (pci_mux_perr_in), + .perr_en_in (pci_mux_perr_en_in), + .serr_in (pci_mux_serr_in), + .serr_en_in (pci_mux_serr_en_in), + + .frame_en_out (pci_mux_frame_en_out), + .irdy_en_out (pci_mux_irdy_en_out), + .devsel_en_out (pci_mux_devsel_en_out), + .trdy_en_out (pci_mux_trdy_en_out), + .stop_en_out (pci_mux_stop_en_out), + .cbe_en_out (pci_mux_cbe_en_out), + .ad_en_out (pci_mux_ad_en_out), + + .frame_out (pci_mux_frame_out), + .irdy_out (pci_mux_irdy_out), + .devsel_out (pci_mux_devsel_out), + .trdy_out (pci_mux_trdy_out), + .stop_out (pci_mux_stop_out), + .cbe_out (pci_mux_cbe_out), + .ad_out (pci_mux_ad_out), + .ad_load_out (pci_mux_ad_load_out), + + .par_out (pci_mux_par_out), + .par_en_out (pci_mux_par_en_out), + .perr_out (pci_mux_perr_out), + .perr_en_out (pci_mux_perr_en_out), + .serr_out (pci_mux_serr_out), + .serr_en_out (pci_mux_serr_en_out), + .req_in (pci_mux_req_in), + .req_out (pci_mux_req_out), + .req_en_out (pci_mux_req_en_out), + .pci_irdy_in (pci_mux_pci_irdy_in), + .pci_trdy_in (pci_mux_pci_trdy_in), + .pci_frame_in (pci_mux_pci_frame_in), + .pci_stop_in (pci_mux_pci_stop_in), + .ad_en_unregistered_out (pci_mux_ad_en_unregistered_out), + + .init_complete_in (pci_mux_init_complete_in) +); + +pci_cur_out_reg output_backup +( + .reset_in (reset), + .clk_in (pci_clk), + .frame_in (pci_mux_frame_in), + .frame_en_in (pci_mux_frame_en_in), + .frame_load_in (pci_mux_frame_load_in), + .irdy_in (pci_mux_irdy_in), + .irdy_en_in (pci_mux_irdy_en_in), + .devsel_in (pci_mux_devsel_in), + .trdy_in (pci_mux_trdy_in), + .trdy_en_in (pci_mux_trdy_en_in), + .stop_in (pci_mux_stop_in), + .ad_load_in (pci_mux_ad_load_out), + .cbe_in (pci_mux_cbe_in), + .cbe_en_in (pci_mux_cbe_en_in), + .mas_ad_in (pci_mux_mas_ad_in), + .tar_ad_in (pci_mux_tar_ad_in), + + .mas_ad_en_in (pci_mux_mas_ad_en_in), + .tar_ad_en_in (pci_mux_tar_ad_en_in), + .ad_en_unregistered_in (pci_mux_ad_en_unregistered_out), + + .par_in (pci_mux_par_in), + .par_en_in (pci_mux_par_en_in), + .perr_in (pci_mux_perr_in), + .perr_en_in (pci_mux_perr_en_in), + .serr_in (pci_mux_serr_in), + .serr_en_in (pci_mux_serr_en_in), + + .frame_out (out_bckp_frame_out), + .frame_en_out (out_bckp_frame_en_out), + .irdy_out (out_bckp_irdy_out), + .irdy_en_out (out_bckp_irdy_en_out), + .devsel_out (out_bckp_devsel_out), + .trdy_out (out_bckp_trdy_out), + .trdy_en_out (out_bckp_trdy_en_out), + .stop_out (out_bckp_stop_out), + .cbe_out (out_bckp_cbe_out), + .ad_out (out_bckp_ad_out), + .ad_en_out (out_bckp_ad_en_out), + .cbe_en_out (out_bckp_cbe_en_out), + .tar_ad_en_out (out_bckp_tar_ad_en_out), + .mas_ad_en_out (out_bckp_mas_ad_en_out), + + .par_out (out_bckp_par_out), + .par_en_out (out_bckp_par_en_out), + .perr_out (out_bckp_perr_out), + .perr_en_out (out_bckp_perr_en_out), + .serr_out (out_bckp_serr_out), + .serr_en_out (out_bckp_serr_en_out) +) ; + +// PARITY CHECKER INPUTS +wire parchk_pci_par_in = int_pci_par ; +wire parchk_pci_perr_in = int_pci_perr ; +wire parchk_pci_frame_reg_in = in_reg_frame_out ; +wire parchk_pci_frame_en_in = out_bckp_frame_en_out ; +wire parchk_pci_irdy_en_in = out_bckp_irdy_en_out ; +wire parchk_pci_irdy_reg_in = in_reg_irdy_out ; +wire parchk_pci_trdy_reg_in = in_reg_trdy_out ; + + +wire parchk_pci_trdy_en_in = out_bckp_trdy_en_out ; + + +wire [31:0] parchk_pci_ad_out_in = out_bckp_ad_out ; +wire [31:0] parchk_pci_ad_reg_in = in_reg_ad_out ; +wire [3:0] parchk_pci_cbe_in_in = int_pci_cbe ; +wire [3:0] parchk_pci_cbe_reg_in = in_reg_cbe_out ; +wire [3:0] parchk_pci_cbe_out_in = out_bckp_cbe_out ; +wire parchk_pci_ad_en_in = out_bckp_ad_en_out ; +wire parchk_par_err_response_in = conf_perr_response_out ; +wire parchk_serr_enable_in = conf_serr_enable_out ; + +wire parchk_pci_perr_out_in = out_bckp_perr_out ; +wire parchk_pci_serr_en_in = out_bckp_serr_en_out ; +wire parchk_pci_serr_out_in = out_bckp_serr_out ; +wire parchk_pci_cbe_en_in = out_bckp_cbe_en_out ; + +wire parchk_pci_par_en_in = out_bckp_par_en_out ; + +pci_parity_check parity_checker +( + .reset_in (reset), + .clk_in (pci_clk), + .pci_par_in (parchk_pci_par_in), + .pci_par_out (parchk_pci_par_out), + .pci_par_en_out (parchk_pci_par_en_out), + .pci_par_en_in (parchk_pci_par_en_in), + .pci_perr_in (parchk_pci_perr_in), + .pci_perr_out (parchk_pci_perr_out), + .pci_perr_en_out (parchk_pci_perr_en_out), + .pci_perr_out_in (parchk_pci_perr_out_in), + .pci_serr_out (parchk_pci_serr_out), + .pci_serr_out_in (parchk_pci_serr_out_in), + .pci_serr_en_out (parchk_pci_serr_en_out), + .pci_serr_en_in (parchk_pci_serr_en_in), + .pci_frame_reg_in (parchk_pci_frame_reg_in), + .pci_frame_en_in (parchk_pci_frame_en_in), + .pci_irdy_en_in (parchk_pci_irdy_en_in), + .pci_irdy_reg_in (parchk_pci_irdy_reg_in), + .pci_trdy_reg_in (parchk_pci_trdy_reg_in), + .pci_trdy_en_in (parchk_pci_trdy_en_in), + .pci_ad_out_in (parchk_pci_ad_out_in), + .pci_ad_reg_in (parchk_pci_ad_reg_in), + .pci_cbe_in_in (parchk_pci_cbe_in_in), + .pci_cbe_reg_in (parchk_pci_cbe_reg_in), + .pci_cbe_en_in (parchk_pci_cbe_en_in), + .pci_cbe_out_in (parchk_pci_cbe_out_in), + .pci_ad_en_in (parchk_pci_ad_en_in), + .par_err_response_in (parchk_par_err_response_in), + .par_err_detect_out (parchk_par_err_detect_out), + .perr_mas_detect_out (parchk_perr_mas_detect_out), + .serr_enable_in (parchk_serr_enable_in), + .sig_serr_out (parchk_sig_serr_out) +); + +wire in_reg_gnt_in = pci_gnt_i ; +wire in_reg_frame_in = int_pci_frame ; +wire in_reg_irdy_in = int_pci_irdy ; +wire in_reg_trdy_in = int_pci_trdy ; +wire in_reg_stop_in = int_pci_stop ; +wire in_reg_devsel_in = int_pci_devsel ; +wire in_reg_idsel_in = pci_idsel_i ; +wire [31:0] in_reg_ad_in = pci_ad_i ; +wire [3:0] in_reg_cbe_in = int_pci_cbe ; + +pci_in_reg input_register +( + .reset_in (reset), + .clk_in (pci_clk), + .init_complete_in (conf_pci_init_complete_out), + + .pci_gnt_in (in_reg_gnt_in), + .pci_frame_in (in_reg_frame_in), + .pci_irdy_in (in_reg_irdy_in), + .pci_trdy_in (in_reg_trdy_in), + .pci_stop_in (in_reg_stop_in), + .pci_devsel_in (in_reg_devsel_in), + .pci_idsel_in (in_reg_idsel_in), + .pci_ad_in (in_reg_ad_in), + .pci_cbe_in (in_reg_cbe_in), + + .pci_gnt_reg_out (in_reg_gnt_out), + .pci_frame_reg_out (in_reg_frame_out), + .pci_irdy_reg_out (in_reg_irdy_out), + .pci_trdy_reg_out (in_reg_trdy_out), + .pci_stop_reg_out (in_reg_stop_out), + .pci_devsel_reg_out (in_reg_devsel_out), + .pci_idsel_reg_out (in_reg_idsel_out), + .pci_ad_reg_out (in_reg_ad_out), + .pci_cbe_reg_out (in_reg_cbe_out) +); + +endmodule diff --git a/ethernet/source/pci/pci_cbe_en_crit.v b/ethernet/source/pci/pci_cbe_en_crit.v new file mode 100644 index 0000000..8130715 --- /dev/null +++ b/ethernet/source/pci/pci_cbe_en_crit.v @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "cbe_en_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_cbe_en_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// this one is included in master state machine for CBE output enable driving + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_cbe_en_crit +( + pci_cbe_en_out, + cbe_en_slow_in, + cbe_en_keep_in, + pci_stop_in, + pci_trdy_in +) ; + +output pci_cbe_en_out ; +input cbe_en_slow_in, + cbe_en_keep_in, + pci_stop_in, + pci_trdy_in ; + +assign pci_cbe_en_out = cbe_en_slow_in || cbe_en_keep_in && pci_stop_in && pci_trdy_in ; + +endmodule diff --git a/ethernet/source/pci/pci_conf_cyc_addr_dec.v b/ethernet/source/pci/pci_conf_cyc_addr_dec.v new file mode 100644 index 0000000..df09046 --- /dev/null +++ b/ethernet/source/pci/pci_conf_cyc_addr_dec.v @@ -0,0 +1,122 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "conf_cyc_addr_dec.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_conf_cyc_addr_dec.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + + +// module is a simple decoder which decodes device num field of configuration address +// for type0 configuration cycles. If type 1 configuration cycle is +// initiated then address goes through unchanged + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_conf_cyc_addr_dec +( + ccyc_addr_in, + ccyc_addr_out +) ; + +input [31:0] ccyc_addr_in ; +output [31:0] ccyc_addr_out ; +reg [31:11] ccyc_addr_31_11 ; + +// lower 11 address lines are alweys going through unchanged +assign ccyc_addr_out = {ccyc_addr_31_11, ccyc_addr_in[10:0]} ; + +// configuration cycle type indicator +wire ccyc_type = ccyc_addr_in[0] ; + +always@(ccyc_addr_in or ccyc_type) +begin + if (ccyc_type) + // type 1 cycle - address goes through unchanged + ccyc_addr_31_11 = ccyc_addr_in[31:11] ; + else + begin + // type 0 conf. cycle - decode device number field to appropriate value + case (ccyc_addr_in[15:11]) + 5'h00:ccyc_addr_31_11 = 21'h00_0001 ; + 5'h01:ccyc_addr_31_11 = 21'h00_0002 ; + 5'h02:ccyc_addr_31_11 = 21'h00_0004 ; + 5'h03:ccyc_addr_31_11 = 21'h00_0008 ; + 5'h04:ccyc_addr_31_11 = 21'h00_0010 ; + 5'h05:ccyc_addr_31_11 = 21'h00_0020 ; + 5'h06:ccyc_addr_31_11 = 21'h00_0040 ; + 5'h07:ccyc_addr_31_11 = 21'h00_0080 ; + 5'h08:ccyc_addr_31_11 = 21'h00_0100 ; + 5'h09:ccyc_addr_31_11 = 21'h00_0200 ; + 5'h0A:ccyc_addr_31_11 = 21'h00_0400 ; + 5'h0B:ccyc_addr_31_11 = 21'h00_0800 ; + 5'h0C:ccyc_addr_31_11 = 21'h00_1000 ; + 5'h0D:ccyc_addr_31_11 = 21'h00_2000 ; + 5'h0E:ccyc_addr_31_11 = 21'h00_4000 ; + 5'h0F:ccyc_addr_31_11 = 21'h00_8000 ; + 5'h10:ccyc_addr_31_11 = 21'h01_0000 ; + 5'h11:ccyc_addr_31_11 = 21'h02_0000 ; + 5'h12:ccyc_addr_31_11 = 21'h04_0000 ; + 5'h13:ccyc_addr_31_11 = 21'h08_0000 ; + 5'h14:ccyc_addr_31_11 = 21'h10_0000 ; + default: ccyc_addr_31_11 = 21'h00_0000 ; + endcase + end +end + +endmodule diff --git a/ethernet/source/pci/pci_conf_space.v b/ethernet/source/pci/pci_conf_space.v new file mode 100644 index 0000000..3e6c102 --- /dev/null +++ b/ethernet/source/pci/pci_conf_space.v @@ -0,0 +1,3935 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_conf_space.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - tadej@opencores.org //// +//// - Tadej Markovic //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_conf_space.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.10 2004/08/19 16:04:53 mihad +// Removed some unused signals. +// +// Revision 1.9 2004/08/19 15:27:34 mihad +// Changed minimum pci image size to 256 bytes because +// of some PC system problems with size of IO images. +// +// Revision 1.8 2004/07/07 12:45:01 mihad +// Added SubsystemVendorID, SubsystemID, MAXLatency, MinGnt defines. +// Enabled value loading from serial EEPROM for all of the above + VendorID and DeviceID registers. +// +// Revision 1.7 2004/01/24 11:54:18 mihad +// Update! SPOCI Implemented! +// +// Revision 1.6 2003/12/28 09:54:48 fr2201 +// def_wb_imagex_addr_map defined correctly +// +// Revision 1.5 2003/12/28 09:20:00 fr2201 +// Reset values for PCI, WB defined (PCI_TAx,WB_BAx,WB_TAx,WB_AMx,WB_BAx_MEM_IO) +// +// Revision 1.4 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.3 2003/08/14 13:06:02 simons +// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. +// +// Revision 1.2 2003/03/26 13:16:18 mihad +// Added the reset value parameter to the synchronizer flop module. +// Added resets to all synchronizer flop instances. +// Repaired initial sync value in fifos. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.4 2002/08/13 11:03:53 mihad +// Added a few testcases. Repaired wrong reset value for PCI_AM5 register. Repaired Parity Error Detected bit setting. Changed PCI_AM0 to always enabled(regardles of PCI_AM0 define), if image 0 is used as configuration image +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +/*----------------------------------------------------------------------------------------------------------- + w_ prefix is a sign for Write (and read) side of Dual-Port registers + r_ prefix is a sign for Read only side of Dual-Port registers +In the first line there are DATA and ADDRESS ports, in the second line there are write enable and read +enable signals with chip-select (conf_hit) for config. space. +In the third line there are output signlas from Command register of the PCI configuration header !!! +In the fourth line there are input signals to Status register of the PCI configuration header !!! +In the fifth line there is output from Latency Timer & r_Interrupt pin registers of the PCI conf. header !!! +Following are IMAGE specific registers, from which PCI_BASE_ADDR registers are the same as base address +registers from the PCI conf. header !!! +-----------------------------------------------------------------------------------------------------------*/ + // normal R/W address, data and control +module pci_conf_space + ( w_conf_address_in, w_conf_data_in, w_conf_data_out, r_conf_address_in, r_conf_data_out, + w_we_i, w_re, r_re, w_byte_en_in, w_clock, reset, pci_clk, wb_clk, + // outputs from command register of the PCI header + serr_enable, perr_response, pci_master_enable, memory_space_enable, io_space_enable, + // inputs to status register of the PCI header + perr_in, serr_in, master_abort_recv, target_abort_recv, target_abort_set, master_data_par_err, + // output from cache_line_size, latency timer and r_interrupt_pin register of the PCI header + cache_line_size_to_pci, cache_line_size_to_wb, cache_lsize_not_zero_to_wb, + latency_tim, + // output from all pci IMAGE registers + pci_base_addr0, pci_base_addr1, pci_base_addr2, pci_base_addr3, pci_base_addr4, pci_base_addr5, + pci_memory_io0, pci_memory_io1, pci_memory_io2, pci_memory_io3, pci_memory_io4, pci_memory_io5, + pci_addr_mask0, pci_addr_mask1, pci_addr_mask2, pci_addr_mask3, pci_addr_mask4, pci_addr_mask5, + pci_tran_addr0, pci_tran_addr1, pci_tran_addr2, pci_tran_addr3, pci_tran_addr4, pci_tran_addr5, + pci_img_ctrl0, pci_img_ctrl1, pci_img_ctrl2, pci_img_ctrl3, pci_img_ctrl4, pci_img_ctrl5, + // input to pci error control and status register, error address and error data registers + pci_error_be, pci_error_bc, pci_error_rty_exp, pci_error_es, pci_error_sig, pci_error_addr, + pci_error_data, + // output from all wishbone IMAGE registers + wb_base_addr0, wb_base_addr1, wb_base_addr2, wb_base_addr3, wb_base_addr4, wb_base_addr5, + wb_memory_io0, wb_memory_io1, wb_memory_io2, wb_memory_io3, wb_memory_io4, wb_memory_io5, + wb_addr_mask0, wb_addr_mask1, wb_addr_mask2, wb_addr_mask3, wb_addr_mask4, wb_addr_mask5, + wb_tran_addr0, wb_tran_addr1, wb_tran_addr2, wb_tran_addr3, wb_tran_addr4, wb_tran_addr5, + wb_img_ctrl0, wb_img_ctrl1, wb_img_ctrl2, wb_img_ctrl3, wb_img_ctrl4, wb_img_ctrl5, + // input to wb error control and status register, error address and error data registers + wb_error_be, wb_error_bc, wb_error_rty_exp, wb_error_es, wb_error_sig, wb_error_addr, wb_error_data, + // output from conf. cycle generation register (sddress), int. control register & interrupt output + config_addr, icr_soft_res, int_out, + // input to interrupt status register + isr_sys_err_int, isr_par_err_int, isr_int_prop, + + pci_init_complete_out, wb_init_complete_out + + `ifdef PCI_CPCI_HS_IMPLEMENT + , + pci_cpci_hs_enum_oe_o, pci_cpci_hs_led_oe_o, pci_cpci_hs_es_i + `endif + + `ifdef PCI_SPOCI + , + spoci_scl_oe_o, spoci_sda_i, spoci_sda_oe_o + `endif + ) ; + + +/*########################################################################################################### +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + Input and output ports + ====================== +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +###########################################################################################################*/ + +// output data +output [31 : 0] w_conf_data_out ; +output [31 : 0] r_conf_data_out ; +reg [31 : 0] w_conf_data_out ; + +`ifdef NO_CNF_IMAGE +`else +reg [31 : 0] r_conf_data_out ; +`endif + +// input data +input [31 : 0] w_conf_data_in ; +wire [31 : 0] w_conf_pdata_reduced ; // reduced data written into PCI image registers +wire [31 : 0] w_conf_wdata_reduced ; // reduced data written into WB image registers +// input address +input [11 : 0] w_conf_address_in ; +input [11 : 0] r_conf_address_in ; +// input control signals +input w_we_i ; +input w_re ; +input r_re ; +input [3 : 0] w_byte_en_in ; +input w_clock ; +input reset ; +input pci_clk ; +input wb_clk ; +// PCI header outputs from command register +output serr_enable ; +output perr_response ; +output pci_master_enable ; +output memory_space_enable ; +output io_space_enable ; +// PCI header inputs to status register +input perr_in ; +input serr_in ; +input master_abort_recv ; +input target_abort_recv ; +input target_abort_set ; +input master_data_par_err ; +// PCI header output from cache_line_size, latency timer and interrupt pin +output [7 : 0] cache_line_size_to_pci ; // sinchronized to PCI clock +output [7 : 0] cache_line_size_to_wb ; // sinchronized to WB clock +output cache_lsize_not_zero_to_wb ; // used in WBU and PCIU +output [7 : 0] latency_tim ; +//output [2 : 0] int_pin ; // only 3 LSbits are important! +// PCI output from image registers +`ifdef GUEST + output [31:12] pci_base_addr0 ; +`endif + +`ifdef HOST + `ifdef NO_CNF_IMAGE + output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr0 ; + `else + output [31:12] pci_base_addr0 ; + `endif +`endif + +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr1 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr2 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr3 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr4 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_base_addr5 ; +output pci_memory_io0 ; +output pci_memory_io1 ; +output pci_memory_io2 ; +output pci_memory_io3 ; +output pci_memory_io4 ; +output pci_memory_io5 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask0 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask1 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask2 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask3 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask4 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_addr_mask5 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr0 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr1 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr2 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr3 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr4 ; +output [31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] pci_tran_addr5 ; +output [2 : 1] pci_img_ctrl0 ; +output [2 : 1] pci_img_ctrl1 ; +output [2 : 1] pci_img_ctrl2 ; +output [2 : 1] pci_img_ctrl3 ; +output [2 : 1] pci_img_ctrl4 ; +output [2 : 1] pci_img_ctrl5 ; +// PCI input to pci error control and status register, error address and error data registers +input [3 : 0] pci_error_be ; +input [3 : 0] pci_error_bc ; +input pci_error_rty_exp ; +input pci_error_es ; +input pci_error_sig ; +input [31 : 0] pci_error_addr ; +input [31 : 0] pci_error_data ; +// WISHBONE output from image registers +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr0 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr1 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr2 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr3 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr4 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_base_addr5 ; +output wb_memory_io0 ; +output wb_memory_io1 ; +output wb_memory_io2 ; +output wb_memory_io3 ; +output wb_memory_io4 ; +output wb_memory_io5 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask0 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask1 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask2 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask3 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask4 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_addr_mask5 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr0 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr1 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr2 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr3 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr4 ; +output [31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] wb_tran_addr5 ; +output [2 : 0] wb_img_ctrl0 ; +output [2 : 0] wb_img_ctrl1 ; +output [2 : 0] wb_img_ctrl2 ; +output [2 : 0] wb_img_ctrl3 ; +output [2 : 0] wb_img_ctrl4 ; +output [2 : 0] wb_img_ctrl5 ; +// WISHBONE input to wb error control and status register, error address and error data registers +input [3 : 0] wb_error_be ; +input [3 : 0] wb_error_bc ; +input wb_error_rty_exp ; +input wb_error_es ; +input wb_error_sig ; +input [31 : 0] wb_error_addr ; +input [31 : 0] wb_error_data ; +// GENERAL output from conf. cycle generation register & int. control register +output [23 : 0] config_addr ; +output icr_soft_res ; +output int_out ; +// GENERAL input to interrupt status register +input isr_sys_err_int ; +input isr_par_err_int ; +input isr_int_prop ; + +output pci_init_complete_out ; +output wb_init_complete_out ; + +`ifdef PCI_CPCI_HS_IMPLEMENT +output pci_cpci_hs_enum_oe_o ; +output pci_cpci_hs_led_oe_o ; +input pci_cpci_hs_es_i ; + +reg pci_cpci_hs_enum_oe_o ; +reg pci_cpci_hs_led_oe_o ; + +// set the hot swap ejector switch debounce counter width +// it is only 4 for simulation purposes +`ifdef PCI_CPCI_SIM + + parameter hs_es_cnt_width = 4 ; + +`else + + `ifdef PCI33 + + parameter hs_es_cnt_width = 16 ; + + `endif + + `ifdef PCI66 + + parameter hs_es_cnt_width = 17 ; + + `endif +`endif + +`endif + +`ifdef PCI_SPOCI +output spoci_scl_oe_o ; +input spoci_sda_i ; +output spoci_sda_oe_o ; + +reg spoci_cs_nack, + spoci_cs_write, + spoci_cs_read; + +reg [10: 0] spoci_cs_adr ; +reg [ 7: 0] spoci_cs_dat ; +`endif + +/*########################################################################################################### +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + REGISTERS definition + ==================== +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +###########################################################################################################*/ + +// Decoded Register Select signals for writting (only one address decoder) +reg [56 : 0] w_reg_select_dec ; + +/*########################################################################################################### +------------------------------------------------------------------------------------------------------------- +PCI CONFIGURATION SPACE HEADER (type 00h) registers + + BIST and some other registers are not implemented and therefor written in correct + place with comment line. There are also some registers with NOT all bits implemented and therefor uses + _bitX or _bitX2_X1 to sign which bit or range of bits are implemented. + Some special cases and examples are described below! +------------------------------------------------------------------------------------------------------------- +###########################################################################################################*/ + +/*----------------------------------------------------------------------------------------------------------- +[000h-00Ch] First 4 DWORDs (32-bit) of PCI configuration header - the same regardless of the HEADER type ! + r_ prefix is a sign for read only registers + Vendor_ID is an ID for a specific vendor defined by PCI_SIG - 2321h does not belong to anyone (e.g. + Xilinx's Vendor_ID is 10EEh and Altera's Vendor_ID is 1172h). Device_ID and Revision_ID should be used + together by application. Class_Code has 3 bytes to define BASE class (06h for PCI Bridge), SUB class + (00h for HOST type, 80h for Other Bridge type) and Interface type (00h for normal). +-----------------------------------------------------------------------------------------------------------*/ + reg [15: 0] r_vendor_id ; + reg [15: 0] r_device_id ; + reg [15: 0] r_subsys_vendor_id ; + reg [15: 0] r_subsys_id ; + + reg command_bit8 ; + reg command_bit6 ; + reg [2 : 0] command_bit2_0 ; + reg [15 : 11] status_bit15_11 ; + parameter r_status_bit10_9 = 2'b01 ; // 2'b01 means MEDIUM devsel timing !!! + reg status_bit8 ; + parameter r_status_bit7 = 1'b1 ; // fast back-to-back capable response !!! + parameter r_status_bit5 = `HEADER_66MHz ; // 1'b0 indicates 33 MHz capable !!! + +`ifdef PCI_CPCI_HS_IMPLEMENT + wire r_status_bit4 = 1 ; + reg hs_ins ; + reg hs_ext ; + wire [ 1: 0] hs_pi = 2'b00 ; + reg hs_loo ; + reg hs_eim ; + wire [ 7: 0] hs_cap_id = 8'h06 ; + reg hs_ins_armed ; + reg hs_ext_armed ; +`else + wire r_status_bit4 = 0 ; +`endif + + reg [ 7: 0] r_revision_id ; + +`ifdef HOST + parameter r_class_code = 24'h06_00_00 ; +`else + parameter r_class_code = 24'h06_80_00 ; +`endif + reg [7 : 0] cache_line_size_reg ; + reg [7 : 0] latency_timer ; + parameter r_header_type = 8'h00 ; + // REG bist NOT implemented !!! + +/*----------------------------------------------------------------------------------------------------------- +[010h-03Ch] all other DWORDs (32-bit) of PCI configuration header - only for HEADER type 00h ! + r_ prefix is a sign for read only registers + BASE_ADDRESS_REGISTERS are the same as ones in the PCI Target configuration registers section. They + are duplicated and therefor defined just ones and used with the same name as written below. If + IMAGEx is NOT defined there is only parameter image_X assigned to '0' and this parameter is used + elsewhere in the code. This parameter is defined in the INTERNAL SIGNALS part !!! + Interrupt_Pin value 8'h01 is used for INT_A pin used. + MIN_GNT and MAX_LAT are used for device's desired values for Latency Timer value. The value in boath + registers specifies a period of time in units of 1/4 microsecond. ZERO indicates that there are no + major requirements for the settings of Latency Timer. + MIN_GNT specifieshow how long a burst period the device needs at 33MHz. MAX_LAT specifies how often + the device needs to gain access to the PCI bus. Values are choosen assuming that the target does not + insert any wait states. Follow the expamle of settings for simple display card. + If we use 64 (32-bit) FIFO locations for one burst then we need 8 x 1/4 microsecond periods at 33MHz + clock rate => MIN_GNT = 08h ! Resolution is 1024 x 768 (= 786432 pixels for one frame) with 16-bit + color mode. We can transfere 2 16-bit pixels in one FIFO location. From that we calculate, that for + one frame we need 6144 burst transferes in 1/25 second. So we need one burst every 6,51 microsecond + and that is 26 x 1/4 microsecond or 1Ah x 1/4 microsecond => MAX_LAT = 1Ah ! +-----------------------------------------------------------------------------------------------------------*/ + // REG x 6 base_address_register_X IMPLEMENTED as pci_ba_X !!! + // REG r_cardbus_cis_pointer NOT implemented !!! + // REG r_subsystem_vendor_id NOT implemented !!! + // REG r_subsystem_id NOT implemented !!! + // REG r_expansion_rom_base_address NOT implemented !!! + // REG r_cap_list_pointer NOT implemented !!! + reg [7 : 0] interrupt_line ; + parameter r_interrupt_pin = 8'h01 ; + reg [7 : 0] r_min_gnt ; + reg [7 : 0] r_max_lat ; + +/*########################################################################################################### +------------------------------------------------------------------------------------------------------------- +PCI Target configuration registers + There are also some registers with NOT all bits implemented and therefor uses _bitX or _bitX2_X1 to + sign which bit or range of bits are implemented. Some special cases and examples are described below! +------------------------------------------------------------------------------------------------------------- +###########################################################################################################*/ + +/*----------------------------------------------------------------------------------------------------------- +[100h-168h] + Depending on defines (PCI_IMAGE1 or .. or PCI_IMAGE5 or (PCI_IMAGE0 and HOST)) in constants.v file, + there are registers corresponding to each IMAGE defined to REG and parameter pci_image_X assigned to '1'. + The maximum number of images is "6". By default there are first two images used and the first (PCI_IMAGE0) + is assigned to Configuration space! With a 'define' PCI_IMAGEx you choose the number of used PCI IMAGES + in a bridge without PCI_IMAGE0 (e.g. PCI_IMAGE3 tells, that PCI_IMAGE1, PCI_IMAGE2 and PCI_IMAGE3 are + used for mapping the space from WB to PCI. Offcourse, PCI_IMAGE0 is assigned to Configuration space). + That leave us PCI_IMAGE5 as the maximum number of images. + There is one exeption, when the core is implemented as HOST. If so, then the PCI specification allowes + the Configuration space NOT to be visible on the PCI bus. With `define PCI_IMAGE0 (and `define HOST), we + assign PCI_IMAGE0 to normal WB to PCI image and not to configuration space! + + When error occurs, PCI ERR_ADDR and ERR_DATA registers stores address and data on the bus that + caused error. While ERR_CS register stores Byte Enables and Bus Command in the MSByte. In bits 10 + and 8 it reports Retry Counter Expired (for posted writes), Error Source (Master Abort) and Error + Report Signal (signals that error has occured) respectively. With bit 0 we enable Error Reporting + mechanism. +-----------------------------------------------------------------------------------------------------------*/ +`ifdef HOST + `ifdef NO_CNF_IMAGE + `ifdef PCI_IMAGE0 // if PCI bridge is HOST and IMAGE0 is assigned as general image space + reg [31 : 8] pci_ba0_bit31_8 ; + reg [2 : 1] pci_img_ctrl0_bit2_1 ; + reg pci_ba0_bit0 ; + reg [31 : 8] pci_am0 ; + reg [31 : 8] pci_ta0 ; + `else // if PCI bridge is HOST and IMAGE0 is not used + wire [31 : 8] pci_ba0_bit31_8 = 24'h0000_00 ; // NO base address needed + wire [2 : 1] pci_img_ctrl0_bit2_1 = 2'b00 ; // NO addr.transl. and pre-fetch + wire pci_ba0_bit0 = 0 ; // config. space is MEMORY space + wire [31 : 8] pci_am0 = 24'h0000_00 ; // NO address mask needed + wire [31 : 8] pci_ta0 = 24'h0000_00 ; // NO address translation needed + `endif + `else // if PCI bridge is HOST and IMAGE0 is assigned to PCI configuration space + reg [31 : 8] pci_ba0_bit31_8 ; + wire [2 : 1] pci_img_ctrl0_bit2_1 = 2'b00 ; // NO pre-fetch and read line support + wire pci_ba0_bit0 = 0 ; // config. space is MEMORY space + wire [31 : 8] pci_am0 = 24'hFFFF_F0 ; // address mask for configuration image always 20'hffff_f + wire [31 : 8] pci_ta0 = 24'h0000_00 ; // NO address translation needed + `endif +`endif + +`ifdef GUEST // if PCI bridge is GUEST, then IMAGE0 is assigned to PCI configuration space + reg [31 : 8] pci_ba0_bit31_8 ; + wire [2 : 1] pci_img_ctrl0_bit2_1 = 2'b00 ; // NO addr.transl. and pre-fetch + wire pci_ba0_bit0 = 0 ; // config. space is MEMORY space + wire [31 : 8] pci_am0 = 24'hffff_f0 ; // address mask for configuration image always 24'hffff_f0 - 4KB mem image + wire [31 : 8] pci_ta0 = 24'h0000_00 ; // NO address translation needed +`endif + +// IMAGE1 is included by default, meanwhile other IMAGEs are optional !!! + reg [2 : 1] pci_img_ctrl1_bit2_1 ; + reg [31 : 8] pci_ba1_bit31_8 ; + `ifdef HOST + reg pci_ba1_bit0 ; + `else + wire pci_ba1_bit0 = `PCI_BA1_MEM_IO ; + `endif + reg [31 : 8] pci_am1 ; + reg [31 : 8] pci_ta1 ; +`ifdef PCI_IMAGE2 + reg [2 : 1] pci_img_ctrl2_bit2_1 ; + reg [31 : 8] pci_ba2_bit31_8 ; + `ifdef HOST + reg pci_ba2_bit0 ; + `else + wire pci_ba2_bit0 = `PCI_BA2_MEM_IO ; + `endif + reg [31 : 8] pci_am2 ; + reg [31 : 8] pci_ta2 ; +`else + wire [2 : 1] pci_img_ctrl2_bit2_1 = 2'b00 ; + wire [31 : 8] pci_ba2_bit31_8 = 24'h0000_00 ; + wire pci_ba2_bit0 = 1'b0 ; + wire [31 : 8] pci_am2 = 24'h0000_00 ; + wire [31 : 8] pci_ta2 = 24'h0000_00 ; +`endif +`ifdef PCI_IMAGE3 + reg [2 : 1] pci_img_ctrl3_bit2_1 ; + reg [31 : 8] pci_ba3_bit31_8 ; + `ifdef HOST + reg pci_ba3_bit0 ; + `else + wire pci_ba3_bit0 = `PCI_BA3_MEM_IO ; + `endif + reg [31 : 8] pci_am3 ; + reg [31 : 8] pci_ta3 ; +`else + wire [2 : 1] pci_img_ctrl3_bit2_1 = 2'b00 ; + wire [31 : 8] pci_ba3_bit31_8 = 24'h0000_00 ; + wire pci_ba3_bit0 = 1'b0 ; + wire [31 : 8] pci_am3 = 24'h0000_00 ; + wire [31 : 8] pci_ta3 = 24'h0000_00 ; +`endif +`ifdef PCI_IMAGE4 + reg [2 : 1] pci_img_ctrl4_bit2_1 ; + reg [31 : 8] pci_ba4_bit31_8 ; + `ifdef HOST + reg pci_ba4_bit0 ; + `else + wire pci_ba4_bit0 = `PCI_BA4_MEM_IO ; + `endif + reg [31 : 8] pci_am4 ; + reg [31 : 8] pci_ta4 ; +`else + wire [2 : 1] pci_img_ctrl4_bit2_1 = 2'b00 ; + wire [31 : 8] pci_ba4_bit31_8 = 24'h0000_00 ; + wire pci_ba4_bit0 = 1'b0 ; + wire [31 : 8] pci_am4 = 24'h0000_00 ; + wire [31 : 8] pci_ta4 = 24'h0000_00 ; +`endif +`ifdef PCI_IMAGE5 + reg [2 : 1] pci_img_ctrl5_bit2_1 ; + reg [31 : 8] pci_ba5_bit31_8 ; + `ifdef HOST + reg pci_ba5_bit0 ; + `else + wire pci_ba5_bit0 = `PCI_BA5_MEM_IO ; + `endif + reg [31 : 8] pci_am5 ; + reg [31 : 8] pci_ta5 ; +`else + wire [2 : 1] pci_img_ctrl5_bit2_1 = 2'b00 ; + wire [31 : 8] pci_ba5_bit31_8 = 24'h0000_00 ; + wire pci_ba5_bit0 = 1'b0 ; + wire [31 : 8] pci_am5 = 24'h0000_00 ; + wire [31 : 8] pci_ta5 = 24'h0000_00 ; +`endif + reg [31 : 24] pci_err_cs_bit31_24 ; + reg pci_err_cs_bit10 ; + reg pci_err_cs_bit9 ; + reg pci_err_cs_bit8 ; + reg pci_err_cs_bit0 ; + reg [31 : 0] pci_err_addr ; + reg [31 : 0] pci_err_data ; + + +/*########################################################################################################### +------------------------------------------------------------------------------------------------------------- +WISHBONE Slave configuration registers + There are also some registers with NOT all bits implemented and therefor uses _bitX or _bitX2_X1 to + sign which bit or range of bits are implemented. Some special cases and examples are described below! +------------------------------------------------------------------------------------------------------------- +###########################################################################################################*/ + +/*----------------------------------------------------------------------------------------------------------- +[800h-85Ch] + Depending on defines (WB_IMAGE1 or .. or WB_IMAGE4 or WB_IMAGE5) in constants.v file, there are + registers corresponding to each IMAGE defined to REG and parameter wb_image_X assigned to '1'. + The maximum number of images is "6". By default there are first two images used and the first (WB_IMAGE0) + is assigned to Configuration space! With a 'define' WB_IMAGEx you choose the number of used WB IMAGES in + a bridge without WB_IMAGE0 (e.g. WB_IMAGE3 tells, that WB_IMAGE1, WB_IMAGE2 and WB_IMAGE3 are used for + mapping the space from PCI to WB. Offcourse, WB_IMAGE0 is assigned to Configuration space). That leave + us WB_IMAGE5 as the maximum number of images. + + When error occurs, WISHBONE ERR_ADDR and ERR_DATA registers stores address and data on the bus that + caused error. While ERR_CS register stores Byte Enables and Bus Command in the MSByte. In bits 10, 9 + and 8 it reports Retry Counter Expired (for posted writes), Error Source (Master Abort) and Error + Report Signal (signals that error has occured) respectively. With bit 0 we enable Error Reporting + mechanism. +-----------------------------------------------------------------------------------------------------------*/ +// WB_IMAGE0 is always assigned to config. space or is not used + wire [2 : 0] wb_img_ctrl0_bit2_0 = 3'b000 ; // NO addr.transl., pre-fetch and read-line + wire [31 : 12] wb_ba0_bit31_12 = `WB_CONFIGURATION_BASE ; + wire wb_ba0_bit0 = 0 ; // config. space is MEMORY space + wire [31 : 12] wb_am0 = `WB_AM0 ; // 4KBytes of configuration space is minimum + wire [31 : 12] wb_ta0 = 20'h0000_0 ; // NO address translation needed +// WB_IMAGE1 is included by default meanwhile others are optional ! + reg [2 : 0] wb_img_ctrl1_bit2_0 ; + reg [31 : 12] wb_ba1_bit31_12 ; + reg wb_ba1_bit0 ; + reg [31 : 12] wb_am1 ; + reg [31 : 12] wb_ta1 ; +`ifdef WB_IMAGE2 + reg [2 : 0] wb_img_ctrl2_bit2_0 ; + reg [31 : 12] wb_ba2_bit31_12 ; + reg wb_ba2_bit0 ; + reg [31 : 12] wb_am2 ; + reg [31 : 12] wb_ta2 ; +`else + wire [2 : 0] wb_img_ctrl2_bit2_0 = 3'b000 ; + wire [31 : 12] wb_ba2_bit31_12 = 20'h0000_0 ; + wire wb_ba2_bit0 = 1'b0 ; + wire [31 : 12] wb_am2 = 20'h0000_0 ; + wire [31 : 12] wb_ta2 = 20'h0000_0 ; +`endif +`ifdef WB_IMAGE3 + reg [2 : 0] wb_img_ctrl3_bit2_0 ; + reg [31 : 12] wb_ba3_bit31_12 ; + reg wb_ba3_bit0 ; + reg [31 : 12] wb_am3 ; + reg [31 : 12] wb_ta3 ; +`else + wire [2 : 0] wb_img_ctrl3_bit2_0 = 3'b000 ; + wire [31 : 12] wb_ba3_bit31_12 = 20'h0000_0 ; + wire wb_ba3_bit0 = 1'b0 ; + wire [31 : 12] wb_am3 = 20'h0000_0 ; + wire [31 : 12] wb_ta3 = 20'h0000_0 ; +`endif +`ifdef WB_IMAGE4 + reg [2 : 0] wb_img_ctrl4_bit2_0 ; + reg [31 : 12] wb_ba4_bit31_12 ; + reg wb_ba4_bit0 ; + reg [31 : 12] wb_am4 ; + reg [31 : 12] wb_ta4 ; +`else + wire [2 : 0] wb_img_ctrl4_bit2_0 = 3'b000 ; + wire [31 : 12] wb_ba4_bit31_12 = 20'h0000_0 ; + wire wb_ba4_bit0 = 1'b0 ; + wire [31 : 12] wb_am4 = 20'h0000_0 ; + wire [31 : 12] wb_ta4 = 20'h0000_0 ; +`endif +`ifdef WB_IMAGE5 + reg [2 : 0] wb_img_ctrl5_bit2_0 ; + reg [31 : 12] wb_ba5_bit31_12 ; + reg wb_ba5_bit0 ; + reg [31 : 12] wb_am5 ; + reg [31 : 12] wb_ta5 ; +`else + wire [2 : 0] wb_img_ctrl5_bit2_0 = 3'b000 ; + wire [31 : 12] wb_ba5_bit31_12 = 20'h0000_0 ; + wire wb_ba5_bit0 = 1'b0 ; + wire [31 : 12] wb_am5 = 20'h0000_0 ; + wire [31 : 12] wb_ta5 = 20'h0000_0 ; +`endif + reg [31 : 24] wb_err_cs_bit31_24 ; +/* reg wb_err_cs_bit10 ;*/ + reg wb_err_cs_bit9 ; + reg wb_err_cs_bit8 ; + reg wb_err_cs_bit0 ; + reg [31 : 0] wb_err_addr ; + reg [31 : 0] wb_err_data ; + + +/*########################################################################################################### +------------------------------------------------------------------------------------------------------------- +Configuration Cycle address register + There are also some registers with NOT all bits implemented and therefor uses _bitX or _bitX2_X1 to + sign which bit or range of bits are implemented. +------------------------------------------------------------------------------------------------------------- +###########################################################################################################*/ + +/*----------------------------------------------------------------------------------------------------------- +[860h-868h] + PCI bridge must ignore Type 1 configuration cycles (Master Abort) since they are used for PCI to PCI + bridges. This is single function device, that means responding on configuration cycles to all functions + (or responding only to function 0). Configuration address register for generating configuration cycles + is prepared for all options (it includes Bus Number, Device, Function, Offset and Type). + Interrupt acknowledge register stores interrupt vector data returned during Interrupt Acknowledge cycle. +-----------------------------------------------------------------------------------------------------------*/ +`ifdef HOST + reg [23 : 2] cnf_addr_bit23_2 ; + reg cnf_addr_bit0 ; +`else // GUEST + wire [23 : 2] cnf_addr_bit23_2 = 22'h0 ; + wire cnf_addr_bit0 = 1'b0 ; +`endif + // reg [31 : 0] cnf_data ; IMPLEMENTED elsewhere !!!!! + // reg [31 : 0] int_ack ; IMPLEMENTED elsewhere !!!!! + + +/*########################################################################################################### +------------------------------------------------------------------------------------------------------------- +General Interrupt registers + There are also some registers with NOT all bits implemented and therefor uses _bitX or _bitX2_X1 to + sign which bit or range of bits are implemented. +------------------------------------------------------------------------------------------------------------- +###########################################################################################################*/ + +/*----------------------------------------------------------------------------------------------------------- +[FF8h-FFCh] + Bit 31 in the Interrupt Control register is set by software and used to generate SOFT RESET. Other 4 + bits are used to enable interrupt generations. + 5 LSbits in the Interrupt Status register are indicating System Error Int, Parity Error Int, PCI & WB + Error Int and Inerrupt respecively. System and Parity errors are implented only in HOST bridge + implementations! +-----------------------------------------------------------------------------------------------------------*/ + reg icr_bit31 ; +`ifdef HOST + reg [4 : 3] icr_bit4_3 ; + reg [4 : 3] isr_bit4_3 ; + reg [2 : 0] icr_bit2_0 ; + reg [2 : 0] isr_bit2_0 ; +`else // GUEST + wire [4 : 3] icr_bit4_3 = 2'h0 ; + wire [4 : 3] isr_bit4_3 = 2'h0 ; + reg [2 : 0] icr_bit2_0 ; + reg [2 : 0] isr_bit2_0 ; +`endif + +/*########################################################################################################### +------------------------------------------------------------------------------------------------------------- +Initialization complete identifier + When using I2C or similar initialisation mechanism, + the bridge must not respond to transaction requests on PCI bus, + not even to configuration cycles. + Therefore, only when init_complete is set, the bridge starts + participating on the PCI bus as an active device. + Two additional flip flops are also provided for GUEST implementation, + to synchronize to the pci clock after PCI reset is asynchronously de-asserted. +------------------------------------------------------------------------------------------------------------- +###########################################################################################################*/ + +`ifdef GUEST + +reg rst_inactive_sync ; +reg rst_inactive ; + +`else + +wire rst_inactive = 1'b1 ; + +`endif + +reg init_complete ; + +wire sync_init_complete ; + +`ifdef HOST +assign wb_init_complete_out = init_complete ; + +pci_synchronizer_flop #(1, 0) i_pci_init_complete_sync +( + .data_in ( init_complete ), + .clk_out ( pci_clk ), + .sync_data_out ( sync_init_complete ), + .async_reset ( reset ) +); + +reg pci_init_complete_out ; + +always@(posedge pci_clk or posedge reset) +begin + if (reset) + pci_init_complete_out <= 1'b0 ; + else + pci_init_complete_out <= sync_init_complete ; +end + +`endif + +`ifdef GUEST + +assign pci_init_complete_out = init_complete ; + +pci_synchronizer_flop #(1, 0) i_wb_init_complete_sync +( + .data_in ( init_complete ), + .clk_out ( wb_clk ), + .sync_data_out ( sync_init_complete ), + .async_reset ( reset ) +); + +reg wb_init_complete_out ; + +always@(posedge wb_clk or posedge reset) +begin + if (reset) + wb_init_complete_out <= 1'b0 ; + else + wb_init_complete_out <= sync_init_complete ; +end + +`endif + +/*########################################################################################################### +------------------------------------------------------------------------------------------------------------- + + +-----------------------------------------------------------------------------------------------------------*/ + +`ifdef NO_CNF_IMAGE // if IMAGE0 is assigned as general image space + + assign r_conf_data_out = 32'h0000_0000 ; + +`else + + always@(r_conf_address_in or + status_bit15_11 or status_bit8 or r_status_bit4 or command_bit8 or command_bit6 or command_bit2_0 or + latency_timer or cache_line_size_reg or r_vendor_id or r_device_id or r_revision_id or + r_subsys_vendor_id or r_subsys_id or r_max_lat or r_min_gnt or + pci_ba0_bit31_8 or + pci_img_ctrl0_bit2_1 or pci_am0 or pci_ta0 or pci_ba0_bit0 or + pci_img_ctrl1_bit2_1 or pci_am1 or pci_ta1 or pci_ba1_bit31_8 or pci_ba1_bit0 or + pci_img_ctrl2_bit2_1 or pci_am2 or pci_ta2 or pci_ba2_bit31_8 or pci_ba2_bit0 or + pci_img_ctrl3_bit2_1 or pci_am3 or pci_ta3 or pci_ba3_bit31_8 or pci_ba3_bit0 or + pci_img_ctrl4_bit2_1 or pci_am4 or pci_ta4 or pci_ba4_bit31_8 or pci_ba4_bit0 or + pci_img_ctrl5_bit2_1 or pci_am5 or pci_ta5 or pci_ba5_bit31_8 or pci_ba5_bit0 or + interrupt_line or + pci_err_cs_bit31_24 or pci_err_cs_bit10 or pci_err_cs_bit9 or pci_err_cs_bit8 or pci_err_cs_bit0 or + pci_err_addr or pci_err_data or + wb_ba0_bit31_12 or wb_ba0_bit0 or + wb_img_ctrl1_bit2_0 or wb_ba1_bit31_12 or wb_ba1_bit0 or wb_am1 or wb_ta1 or + wb_img_ctrl2_bit2_0 or wb_ba2_bit31_12 or wb_ba2_bit0 or wb_am2 or wb_ta2 or + wb_img_ctrl3_bit2_0 or wb_ba3_bit31_12 or wb_ba3_bit0 or wb_am3 or wb_ta3 or + wb_img_ctrl4_bit2_0 or wb_ba4_bit31_12 or wb_ba4_bit0 or wb_am4 or wb_ta4 or + wb_img_ctrl5_bit2_0 or wb_ba5_bit31_12 or wb_ba5_bit0 or wb_am5 or wb_ta5 or + wb_err_cs_bit31_24 or /*wb_err_cs_bit10 or*/ wb_err_cs_bit9 or wb_err_cs_bit8 or wb_err_cs_bit0 or + wb_err_addr or wb_err_data or + cnf_addr_bit23_2 or cnf_addr_bit0 or icr_bit31 or icr_bit4_3 or icr_bit2_0 or isr_bit4_3 or isr_bit2_0 + + `ifdef PCI_CPCI_HS_IMPLEMENT + or hs_ins or hs_ext or hs_pi or hs_loo or hs_eim or hs_cap_id + `endif + + `ifdef PCI_SPOCI + or spoci_cs_nack or spoci_cs_write or spoci_cs_read or spoci_cs_adr or spoci_cs_dat + `endif + ) + begin + case (r_conf_address_in[9:2]) + // PCI header - configuration space + 8'h0: r_conf_data_out = { r_device_id, r_vendor_id } ; + 8'h1: r_conf_data_out = { status_bit15_11, r_status_bit10_9, status_bit8, r_status_bit7, 1'h0, r_status_bit5, r_status_bit4, + 4'h0, 7'h00, command_bit8, 1'h0, command_bit6, 3'h0, command_bit2_0 } ; + 8'h2: r_conf_data_out = { r_class_code, r_revision_id } ; + 8'h3: r_conf_data_out = { 8'h00, r_header_type, latency_timer, cache_line_size_reg } ; + 8'h4: + begin + `ifdef HOST + `ifdef NO_CNF_IMAGE + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba0_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba0_bit0 & pci_am0[31]; + `else + r_conf_data_out[31:12] = pci_ba0_bit31_8[31:12] ; + r_conf_data_out[11: 0] = 12'h000 ; + `endif + `endif + + `ifdef GUEST + r_conf_data_out[31:12] = pci_ba0_bit31_8[31:12] ; + r_conf_data_out[11: 0] = 12'h000 ; + `endif + end + 8'h5: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba1_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba1_bit0 & pci_am1[31]; + end + 8'h6: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba2_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba2_bit0 & pci_am2[31]; + end + 8'h7: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba3_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba3_bit0 & pci_am3[31]; + end + 8'h8: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba4_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba4_bit0 & pci_am4[31]; + end + 8'h9: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba5_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba5_bit0 & pci_am5[31]; + end + 8'hB: + begin + r_conf_data_out = {r_subsys_id, r_subsys_vendor_id} ; + end + `ifdef PCI_CPCI_HS_IMPLEMENT + 8'hD: + begin + r_conf_data_out = {24'h0000_00, `PCI_CAP_PTR_VAL} ; + end + `endif + 8'hf: r_conf_data_out = { r_max_lat, r_min_gnt, r_interrupt_pin, interrupt_line } ; + `ifdef PCI_CPCI_HS_IMPLEMENT + (`PCI_CAP_PTR_VAL >> 2): + begin + r_conf_data_out = {8'h00, hs_ins, hs_ext, hs_pi, hs_loo, 1'b0, hs_eim, 1'b0, 8'h00, hs_cap_id} ; + end + `endif + // PCI target - configuration space + {2'b01, `P_IMG_CTRL0_ADDR}: r_conf_data_out = { 29'h00000000, pci_img_ctrl0_bit2_1, 1'h0 } ; + {2'b01, `P_BA0_ADDR} : + begin + `ifdef HOST + `ifdef NO_CNF_IMAGE + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba0_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba0_bit0 & pci_am0[31]; + `else + r_conf_data_out[31:12] = pci_ba0_bit31_8[31:12] ; + r_conf_data_out[11: 0] = 12'h000 ; + `endif + `endif + + `ifdef GUEST + r_conf_data_out[31:12] = pci_ba0_bit31_8[31:12] ; + r_conf_data_out[11: 0] = 12'h000 ; + `endif + end + {2'b01, `P_AM0_ADDR}: + begin + `ifdef HOST + `ifdef NO_CNF_IMAGE + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + `else + r_conf_data_out[31:12] = pci_am0[31:12] ; + r_conf_data_out[11: 0] = 12'h000 ; + `endif + `endif + + `ifdef GUEST + r_conf_data_out[31:12] = pci_am0[31:12] ; + r_conf_data_out[11: 0] = 12'h000 ; + `endif + end + {2'b01, `P_TA0_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_IMG_CTRL1_ADDR}: r_conf_data_out = { 29'h00000000, pci_img_ctrl1_bit2_1, 1'h0 } ; + {2'b01, `P_BA1_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba1_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba1_bit0 & pci_am1[31]; + end + {2'b01, `P_AM1_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_TA1_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_IMG_CTRL2_ADDR}: r_conf_data_out = { 29'h00000000, pci_img_ctrl2_bit2_1, 1'h0 } ; + {2'b01, `P_BA2_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba2_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba2_bit0 & pci_am2[31]; + end + {2'b01, `P_AM2_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_TA2_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_IMG_CTRL3_ADDR}: r_conf_data_out = { 29'h00000000, pci_img_ctrl3_bit2_1, 1'h0 } ; + {2'b01, `P_BA3_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba3_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba3_bit0 & pci_am3[31]; + end + {2'b01, `P_AM3_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_TA3_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_IMG_CTRL4_ADDR}: r_conf_data_out = { 29'h00000000, pci_img_ctrl4_bit2_1, 1'h0 } ; + {2'b01, `P_BA4_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba4_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba4_bit0 & pci_am4[31]; + end + {2'b01, `P_AM4_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_TA4_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_IMG_CTRL5_ADDR}: r_conf_data_out = { 29'h00000000, pci_img_ctrl5_bit2_1, 1'h0 } ; + {2'b01, `P_BA5_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba5_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = pci_ba5_bit0 & pci_am5[31]; + end + {2'b01, `P_AM5_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_TA5_ADDR}: + begin + r_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `P_ERR_CS_ADDR}: r_conf_data_out = { pci_err_cs_bit31_24, 13'h0000, pci_err_cs_bit10, pci_err_cs_bit9, + pci_err_cs_bit8, 7'h00, pci_err_cs_bit0 } ; + {2'b01, `P_ERR_ADDR_ADDR}: r_conf_data_out = pci_err_addr ; + {2'b01, `P_ERR_DATA_ADDR}: r_conf_data_out = pci_err_data ; + // WB slave - configuration space + {2'b01, `WB_CONF_SPC_BAR_ADDR}: r_conf_data_out = { wb_ba0_bit31_12, 11'h000, wb_ba0_bit0 } ; + {2'b01, `W_IMG_CTRL1_ADDR}: r_conf_data_out = { 29'h00000000, wb_img_ctrl1_bit2_0 } ; + {2'b01, `W_BA1_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba1_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = wb_ba1_bit0 ; + end + {2'b01, `W_AM1_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_TA1_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_IMG_CTRL2_ADDR}: r_conf_data_out = { 29'h00000000, wb_img_ctrl2_bit2_0 } ; + `W_BA2_ADDR : + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba2_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = wb_ba2_bit0 ; + end + {2'b01, `W_AM2_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_TA2_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_IMG_CTRL3_ADDR}: r_conf_data_out = { 29'h00000000, wb_img_ctrl3_bit2_0 } ; + {2'b01, `W_BA3_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba3_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = wb_ba3_bit0 ; + end + {2'b01, `W_AM3_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_TA3_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_IMG_CTRL4_ADDR}: r_conf_data_out = { 29'h00000000, wb_img_ctrl4_bit2_0 } ; + {2'b01, `W_BA4_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba4_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = wb_ba4_bit0 ; + end + {2'b01, `W_AM4_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_TA4_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_IMG_CTRL5_ADDR}: r_conf_data_out = { 29'h00000000, wb_img_ctrl5_bit2_0 } ; + {2'b01, `W_BA5_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba5_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + r_conf_data_out[0] = wb_ba5_bit0 ; + end + {2'b01, `W_AM5_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_TA5_ADDR}: + begin + r_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + r_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + end + {2'b01, `W_ERR_CS_ADDR}: r_conf_data_out = { wb_err_cs_bit31_24, /*13*/14'h0000, /*wb_err_cs_bit10,*/ + wb_err_cs_bit9, wb_err_cs_bit8, 7'h00, wb_err_cs_bit0 } ; + {2'b01, `W_ERR_ADDR_ADDR}: r_conf_data_out = wb_err_addr ; + {2'b01, `W_ERR_DATA_ADDR}: r_conf_data_out = wb_err_data ; + + {2'b01, `CNF_ADDR_ADDR}: r_conf_data_out = { 8'h00, cnf_addr_bit23_2, 1'h0, cnf_addr_bit0 } ; + // `CNF_DATA_ADDR: implemented elsewhere !!! + // `INT_ACK_ADDR : implemented elsewhere !!! + {2'b01, `ICR_ADDR}: r_conf_data_out = { icr_bit31, 26'h0000_000, icr_bit4_3, icr_bit2_0 } ; + {2'b01, `ISR_ADDR}: r_conf_data_out = { 27'h0000_000, isr_bit4_3, isr_bit2_0 } ; + + `ifdef PCI_SPOCI + 8'hff: r_conf_data_out = {spoci_cs_nack, 5'h0, spoci_cs_write, spoci_cs_read, + 5'h0, spoci_cs_adr[10:8], + spoci_cs_adr[7:0], + spoci_cs_dat[7:0]} ; + `endif + default : r_conf_data_out = 32'h0000_0000 ; + endcase + end + +`endif + +`ifdef PCI_SPOCI +reg [ 7: 0] spoci_reg_num ; +wire [11: 0] w_conf_address = init_complete ? w_conf_address_in : {2'b00, spoci_reg_num, 2'b00} ; +`else +wire [11: 0] w_conf_address = w_conf_address_in ; +wire [ 7: 0] spoci_reg_num = 'hff ; +`endif + +always@(w_conf_address or + status_bit15_11 or status_bit8 or r_status_bit4 or command_bit8 or command_bit6 or command_bit2_0 or + latency_timer or cache_line_size_reg or r_vendor_id or r_device_id or r_revision_id or + r_subsys_id or r_subsys_vendor_id or r_max_lat or r_min_gnt or + pci_ba0_bit31_8 or + pci_img_ctrl0_bit2_1 or pci_am0 or pci_ta0 or pci_ba0_bit0 or + pci_img_ctrl1_bit2_1 or pci_am1 or pci_ta1 or pci_ba1_bit31_8 or pci_ba1_bit0 or + pci_img_ctrl2_bit2_1 or pci_am2 or pci_ta2 or pci_ba2_bit31_8 or pci_ba2_bit0 or + pci_img_ctrl3_bit2_1 or pci_am3 or pci_ta3 or pci_ba3_bit31_8 or pci_ba3_bit0 or + pci_img_ctrl4_bit2_1 or pci_am4 or pci_ta4 or pci_ba4_bit31_8 or pci_ba4_bit0 or + pci_img_ctrl5_bit2_1 or pci_am5 or pci_ta5 or pci_ba5_bit31_8 or pci_ba5_bit0 or + interrupt_line or + pci_err_cs_bit31_24 or pci_err_cs_bit10 or pci_err_cs_bit9 or pci_err_cs_bit8 or pci_err_cs_bit0 or + pci_err_addr or pci_err_data or + wb_ba0_bit31_12 or wb_ba0_bit0 or + wb_img_ctrl1_bit2_0 or wb_ba1_bit31_12 or wb_ba1_bit0 or wb_am1 or wb_ta1 or + wb_img_ctrl2_bit2_0 or wb_ba2_bit31_12 or wb_ba2_bit0 or wb_am2 or wb_ta2 or + wb_img_ctrl3_bit2_0 or wb_ba3_bit31_12 or wb_ba3_bit0 or wb_am3 or wb_ta3 or + wb_img_ctrl4_bit2_0 or wb_ba4_bit31_12 or wb_ba4_bit0 or wb_am4 or wb_ta4 or + wb_img_ctrl5_bit2_0 or wb_ba5_bit31_12 or wb_ba5_bit0 or wb_am5 or wb_ta5 or + wb_err_cs_bit31_24 or /*wb_err_cs_bit10 or*/ wb_err_cs_bit9 or wb_err_cs_bit8 or wb_err_cs_bit0 or + wb_err_addr or wb_err_data or + cnf_addr_bit23_2 or cnf_addr_bit0 or icr_bit31 or icr_bit4_3 or icr_bit2_0 or isr_bit4_3 or isr_bit2_0 + + `ifdef PCI_CPCI_HS_IMPLEMENT + or hs_ins or hs_ext or hs_pi or hs_loo or hs_eim or hs_cap_id + `endif + + `ifdef PCI_SPOCI + or spoci_cs_nack or spoci_cs_write or spoci_cs_read or spoci_cs_adr or spoci_cs_dat + `endif + ) +begin + case (w_conf_address[9:2]) + 8'h0: + begin + w_conf_data_out = { r_device_id, r_vendor_id } ; + w_reg_select_dec = 57'h000_0000_0000_0000 ; // Read-Only register + end + 8'h1: // w_reg_select_dec bit 0 + begin + w_conf_data_out = { status_bit15_11, r_status_bit10_9, status_bit8, r_status_bit7, 1'h0, r_status_bit5, r_status_bit4, + 4'h0, 7'h00, command_bit8, 1'h0, command_bit6, 3'h0, command_bit2_0 } ; + w_reg_select_dec = 57'h000_0000_0000_0001 ; + end + 8'h2: + begin + w_conf_data_out = { r_class_code, r_revision_id } ; + w_reg_select_dec = 57'h000_0000_0000_0000 ; // Read-Only register + end + 8'h3: // w_reg_select_dec bit 1 + begin + w_conf_data_out = { 8'h00, r_header_type, latency_timer, cache_line_size_reg } ; + w_reg_select_dec = 57'h000_0000_0000_0002 ; + end + 8'h4: // w_reg_select_dec bit 4 + begin + `ifdef HOST + `ifdef NO_CNF_IMAGE + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba0_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba0_bit0 & pci_am0[31]; + `else + w_conf_data_out[31:12] = pci_ba0_bit31_8[31:12] ; + w_conf_data_out[11: 0] = 12'h000 ; + `endif + `endif + + `ifdef GUEST + w_conf_data_out[31:12] = pci_ba0_bit31_8[31:12] ; + w_conf_data_out[11: 0] = 12'h000 ; + `endif + w_reg_select_dec = 57'h000_0000_0000_0010 ; // The same for another address + end + 8'h5: // w_reg_select_dec bit 8 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba1_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba1_bit0 & pci_am1[31]; + w_reg_select_dec = 57'h000_0000_0000_0100 ; // The same for another address + end + 8'h6: // w_reg_select_dec bit 12 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba2_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba2_bit0 & pci_am2[31]; + w_reg_select_dec = 57'h000_0000_0000_1000 ; // The same for another address + end + 8'h7: // w_reg_select_dec bit 16 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba3_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba3_bit0 & pci_am3[31]; + w_reg_select_dec = 57'h000_0000_0001_0000 ; // The same for another address + end + 8'h8: // w_reg_select_dec bit 20 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba4_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba4_bit0 & pci_am4[31]; + w_reg_select_dec = 57'h000_0000_0010_0000 ; // The same for another address + end + 8'h9: // w_reg_select_dec bit 24 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba5_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba5_bit0 & pci_am5[31]; + w_reg_select_dec = 57'h000_0000_0100_0000 ; // The same for another address + end + 8'hB: + begin + w_conf_data_out = {r_subsys_id, r_subsys_vendor_id} ; + w_reg_select_dec = 57'h000_0000_0000_0000 ; + end + +`ifdef PCI_CPCI_HS_IMPLEMENT + 8'hD: + begin + w_conf_data_out = {24'h0000_00, `PCI_CAP_PTR_VAL} ; + w_reg_select_dec = 57'h000_0000_0000_0000 ; // Read-Only register + end +`endif + 8'hf: // w_reg_select_dec bit 2 + begin + w_conf_data_out = { r_max_lat, r_min_gnt, r_interrupt_pin, interrupt_line } ; + w_reg_select_dec = 57'h000_0000_0000_0004 ; + end +`ifdef PCI_CPCI_HS_IMPLEMENT + (`PCI_CAP_PTR_VAL >> 2): + begin + w_reg_select_dec = 57'h100_0000_0000_0000 ; + w_conf_data_out = {8'h00, hs_ins, hs_ext, hs_pi, hs_loo, 1'b0, hs_eim, 1'b0, 8'h00, hs_cap_id} ; + end +`endif + {2'b01, `P_IMG_CTRL0_ADDR}: // w_reg_select_dec bit 3 + begin + w_conf_data_out = { 29'h00000000, pci_img_ctrl0_bit2_1, 1'h0 } ; + w_reg_select_dec = 57'h000_0000_0000_0008 ; + end + {2'b01, `P_BA0_ADDR}: // w_reg_select_dec bit 4 + begin + `ifdef HOST + `ifdef NO_CNF_IMAGE + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba0_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba0_bit0 & pci_am0[31]; + `else + w_conf_data_out[31:12] = pci_ba0_bit31_8[31:12] ; + w_conf_data_out[11: 0] = 12'h000 ; + `endif + `endif + + `ifdef GUEST + w_conf_data_out[31:12] = pci_ba0_bit31_8[31:12] ; + w_conf_data_out[11: 0] = 12'h000 ; + `endif + w_reg_select_dec = 57'h000_0000_0000_0010 ; // The same for another address + end + {2'b01, `P_AM0_ADDR}: // w_reg_select_dec bit 5 + begin + `ifdef HOST + `ifdef NO_CNF_IMAGE + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + `else + w_conf_data_out[31:12] = pci_am0[31:12] ; + w_conf_data_out[11: 0] = 12'h000 ; + `endif + `endif + + `ifdef GUEST + w_conf_data_out[31:12] = pci_am0[31:12] ; + w_conf_data_out[11: 0] = 12'h000 ; + `endif + w_reg_select_dec = 57'h000_0000_0000_0020 ; + end + {2'b01, `P_TA0_ADDR}: // w_reg_select_dec bit 6 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0000_0040 ; + end + {2'b01, `P_IMG_CTRL1_ADDR}: // w_reg_select_dec bit 7 + begin + w_conf_data_out = { 29'h00000000, pci_img_ctrl1_bit2_1, 1'h0 } ; + w_reg_select_dec = 57'h000_0000_0000_0080 ; + end + {2'b01, `P_BA1_ADDR}: // w_reg_select_dec bit 8 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba1_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba1_bit0 & pci_am1[31]; + w_reg_select_dec = 57'h000_0000_0000_0100 ; // The same for another address + end + {2'b01, `P_AM1_ADDR}: // w_reg_select_dec bit 9 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0000_0200 ; + end + {2'b01, `P_TA1_ADDR}: // w_reg_select_dec bit 10 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0000_0400 ; + end + {2'b01, `P_IMG_CTRL2_ADDR}: // w_reg_select_dec bit 11 + begin + w_conf_data_out = { 29'h00000000, pci_img_ctrl2_bit2_1, 1'h0 } ; + w_reg_select_dec = 57'h000_0000_0000_0800 ; + end + {2'b01, `P_BA2_ADDR}: // w_reg_select_dec bit 12 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba2_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba2_bit0 & pci_am2[31]; + w_reg_select_dec = 57'h000_0000_0000_1000 ; // The same for another address + end + {2'b01, `P_AM2_ADDR}: // w_reg_select_dec bit 13 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0000_2000 ; + end + {2'b01, `P_TA2_ADDR}: // w_reg_select_dec bit 14 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0000_4000 ; + end + {2'b01, `P_IMG_CTRL3_ADDR}: // w_reg_select_dec bit 15 + begin + w_conf_data_out = { 29'h00000000, pci_img_ctrl3_bit2_1, 1'h0 } ; + w_reg_select_dec = 57'h000_0000_0000_8000 ; + end + {2'b01, `P_BA3_ADDR}: // w_reg_select_dec bit 16 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba3_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba3_bit0 & pci_am3[31]; + w_reg_select_dec = 57'h000_0000_0001_0000 ; // The same for another address + end + {2'b01, `P_AM3_ADDR}: // w_reg_select_dec bit 17 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0002_0000 ; + end + {2'b01, `P_TA3_ADDR}: // w_reg_select_dec bit 18 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0004_0000 ; + end + {2'b01, `P_IMG_CTRL4_ADDR}: // w_reg_select_dec bit 19 + begin + w_conf_data_out = { 29'h00000000, pci_img_ctrl4_bit2_1, 1'h0 } ; + w_reg_select_dec = 57'h000_0000_0008_0000 ; + end + {2'b01, `P_BA4_ADDR}: // w_reg_select_dec bit 20 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba4_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba4_bit0 & pci_am4[31]; + w_reg_select_dec = 57'h000_0000_0010_0000 ; // The same for another address + end + {2'b01, `P_AM4_ADDR}: // w_reg_select_dec bit 21 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0020_0000 ; + end + {2'b01, `P_TA4_ADDR}: // w_reg_select_dec bit 22 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0040_0000 ; + end + {2'b01, `P_IMG_CTRL5_ADDR}: // w_reg_select_dec bit 23 + begin + w_conf_data_out = { 29'h00000000, pci_img_ctrl5_bit2_1, 1'h0 } ; + w_reg_select_dec = 57'h000_0000_0080_0000 ; + end + {2'b01, `P_BA5_ADDR}: // w_reg_select_dec bit 24 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ba5_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] & + pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = pci_ba5_bit0 & pci_am5[31]; + w_reg_select_dec = 57'h000_0000_0100_0000 ; // The same for another address + end + {2'b01, `P_AM5_ADDR}: // w_reg_select_dec bit 25 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0200_0000 ; + end + {2'b01, `P_TA5_ADDR}: // w_reg_select_dec bit 26 + begin + w_conf_data_out[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = pci_ta5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`PCI_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0000_0400_0000 ; + end + {2'b01, `P_ERR_CS_ADDR}: // w_reg_select_dec bit 27 + begin + w_conf_data_out = { pci_err_cs_bit31_24, 13'h0000, pci_err_cs_bit10, pci_err_cs_bit9, + pci_err_cs_bit8, 7'h00, pci_err_cs_bit0 } ; + w_reg_select_dec = 57'h000_0000_0800_0000 ; + end + {2'b01, `P_ERR_ADDR_ADDR}: // w_reg_select_dec bit 28 + begin + w_conf_data_out = pci_err_addr ; + w_reg_select_dec = 57'h000_0000_0000_0000 ; // = 56'h00_0000_1000_0000 ; + end + {2'b01, `P_ERR_DATA_ADDR}: // w_reg_select_dec bit 29 + begin + w_conf_data_out = pci_err_data ; + w_reg_select_dec = 57'h000_0000_0000_0000 ; // = 56'h00_0000_2000_0000 ; + end + // WB slave - configuration space + {2'b01, `WB_CONF_SPC_BAR_ADDR}: + begin + w_conf_data_out = { wb_ba0_bit31_12, 11'h000, wb_ba0_bit0 } ; + w_reg_select_dec = 57'h000_0000_0000_0000 ; // Read-Only register + end + {2'b01, `W_IMG_CTRL1_ADDR}: // w_reg_select_dec bit 30 + begin + w_conf_data_out = { 29'h00000000, wb_img_ctrl1_bit2_0 } ; + w_reg_select_dec = 57'h000_0000_4000_0000 ; + end + {2'b01, `W_BA1_ADDR}: // w_reg_select_dec bit 31 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba1_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = wb_ba1_bit0 ; + w_reg_select_dec = 57'h000_0000_8000_0000 ; + end + {2'b01, `W_AM1_ADDR}: // w_reg_select_dec bit 32 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0001_0000_0000 ; + end + {2'b01, `W_TA1_ADDR}: // w_reg_select_dec bit 33 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0002_0000_0000 ; + end + {2'b01, `W_IMG_CTRL2_ADDR}: // w_reg_select_dec bit 34 + begin + w_conf_data_out = { 29'h00000000, wb_img_ctrl2_bit2_0 } ; + w_reg_select_dec = 57'h000_0004_0000_0000 ; + end + {2'b01, `W_BA2_ADDR}: // w_reg_select_dec bit 35 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba2_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = wb_ba2_bit0 ; + w_reg_select_dec = 57'h000_0008_0000_0000 ; + end + {2'b01, `W_AM2_ADDR}: // w_reg_select_dec bit 36 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0010_0000_0000 ; + end + {2'b01, `W_TA2_ADDR}: // w_reg_select_dec bit 37 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0020_0000_0000 ; + end + {2'b01, `W_IMG_CTRL3_ADDR}: // w_reg_select_dec bit 38 + begin + w_conf_data_out = { 29'h00000000, wb_img_ctrl3_bit2_0 } ; + w_reg_select_dec = 57'h000_0040_0000_0000 ; + end + {2'b01, `W_BA3_ADDR}: // w_reg_select_dec bit 39 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba3_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = wb_ba3_bit0 ; + w_reg_select_dec = 57'h000_0080_0000_0000 ; + end + {2'b01, `W_AM3_ADDR}: // w_reg_select_dec bit 40 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0100_0000_0000 ; + end + {2'b01, `W_TA3_ADDR}: // w_reg_select_dec bit 41 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_0200_0000_0000 ; + end + {2'b01, `W_IMG_CTRL4_ADDR}: // w_reg_select_dec bit 42 + begin + w_conf_data_out = { 29'h00000000, wb_img_ctrl4_bit2_0 } ; + w_reg_select_dec = 57'h000_0400_0000_0000 ; + end + {2'b01, `W_BA4_ADDR}: // w_reg_select_dec bit 43 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba4_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = wb_ba4_bit0 ; + w_reg_select_dec = 57'h000_0800_0000_0000 ; + end + {2'b01, `W_AM4_ADDR}: // w_reg_select_dec bit 44 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_1000_0000_0000 ; + end + {2'b01, `W_TA4_ADDR}: // w_reg_select_dec bit 45 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h000_2000_0000_0000 ; + end + {2'b01, `W_IMG_CTRL5_ADDR}: // w_reg_select_dec bit 46 + begin + w_conf_data_out = { 29'h00000000, wb_img_ctrl5_bit2_0 } ; + w_reg_select_dec = 57'h000_4000_0000_0000 ; + end + {2'b01, `W_BA5_ADDR}: // w_reg_select_dec bit 47 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ba5_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] & + wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):1] = 0 ; + w_conf_data_out[0] = wb_ba5_bit0 ; + w_reg_select_dec = 57'h000_8000_0000_0000 ; + end + {2'b01, `W_AM5_ADDR}: // w_reg_select_dec bit 48 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h001_0000_0000_0000 ; + end + {2'b01, `W_TA5_ADDR}: // w_reg_select_dec bit 49 + begin + w_conf_data_out[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = wb_ta5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; + w_conf_data_out[(31-`WB_NUM_OF_DEC_ADDR_LINES):0] = 0 ; + w_reg_select_dec = 57'h002_0000_0000_0000 ; + end + {2'b01, `W_ERR_CS_ADDR}: // w_reg_select_dec bit 50 + begin + w_conf_data_out = { wb_err_cs_bit31_24, /*13*/14'h0000, /*wb_err_cs_bit10,*/ + wb_err_cs_bit9, wb_err_cs_bit8, 7'h00, wb_err_cs_bit0 } ; + w_reg_select_dec = 57'h004_0000_0000_0000 ; + end + {2'b01, `W_ERR_ADDR_ADDR}: // w_reg_select_dec bit 51 + begin + w_conf_data_out = wb_err_addr ; + w_reg_select_dec = 57'h008_0000_0000_0000 ; + end + {2'b01, `W_ERR_DATA_ADDR}: // w_reg_select_dec bit 52 + begin + w_conf_data_out = wb_err_data ; + w_reg_select_dec = 57'h010_0000_0000_0000 ; + end + {2'b01, `CNF_ADDR_ADDR}: // w_reg_select_dec bit 53 + begin + w_conf_data_out = { 8'h00, cnf_addr_bit23_2, 1'h0, cnf_addr_bit0 } ; + w_reg_select_dec = 57'h020_0000_0000_0000 ; + end + // `CNF_DATA_ADDR: implemented elsewhere !!! + // `INT_ACK_ADDR: implemented elsewhere !!! + {2'b01, `ICR_ADDR}: // w_reg_select_dec bit 54 + begin + w_conf_data_out = { icr_bit31, 26'h0000_000, icr_bit4_3, icr_bit2_0 } ; + w_reg_select_dec = 57'h040_0000_0000_0000 ; + end + {2'b01, `ISR_ADDR}: // w_reg_select_dec bit 55 + begin + w_conf_data_out = { 27'h0000_000, isr_bit4_3, isr_bit2_0 } ; + w_reg_select_dec = 57'h080_0000_0000_0000 ; + end + +`ifdef PCI_SPOCI + 8'hff: + begin + w_conf_data_out = {spoci_cs_nack, 5'h0, spoci_cs_write, spoci_cs_read, + 5'h0, spoci_cs_adr[10:8], + spoci_cs_adr[7:0], + spoci_cs_dat[7:0]} ; + + // this register is implemented separate from other registers, because + // it has special features implemented + w_reg_select_dec = 57'h000_0000_0000_0000 ; + end +`endif + + default: + begin + w_conf_data_out = 32'h0000_0000 ; + w_reg_select_dec = 57'h000_0000_0000_0000 ; + end + endcase +end + +`ifdef PCI_SPOCI +reg init_we ; +reg init_cfg_done ; +reg [31: 0] spoci_dat ; +wire [31: 0] w_conf_data = init_cfg_done ? w_conf_data_in : spoci_dat ; +wire [ 3: 0] w_byte_en = init_cfg_done ? w_byte_en_in : 4'b0000 ; +`else +wire init_we = 1'b0 ; +wire init_cfg_done = 1'b1 ; +wire [31: 0] w_conf_data = w_conf_data_in ; +wire [ 3: 0] w_byte_en = w_byte_en_in ; +wire [31: 0] spoci_dat = 'h0000_0000 ; +`endif + +// Reduced write data for BASE, MASK and TRANSLATION registers of PCI and WB images +assign w_conf_pdata_reduced[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] = w_conf_data[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign w_conf_pdata_reduced[(31-`PCI_NUM_OF_DEC_ADDR_LINES): 0] = 0 ; +assign w_conf_wdata_reduced[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] = w_conf_data[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign w_conf_wdata_reduced[(31-`WB_NUM_OF_DEC_ADDR_LINES): 0] = 0 ; + +wire w_we = w_we_i | init_we ; + +always@(posedge w_clock or posedge reset) +begin + // Here are implemented all registers that are reset with RESET signal otherwise they can be normaly written!!! + // Registers that are commented are implemented after this alwasy statement, because they are e.g. reset with + // RESET signal, set with some status signal and they are erased with writting '1' into them !!! + if (reset) + begin + /*status_bit15_11 ; status_bit8 ;*/ command_bit8 <= 1'h0 ; command_bit6 <= 1'h0 ; command_bit2_0 <= 3'h0 ; + latency_timer <= 8'h00 ; cache_line_size_reg <= 8'h00 ; + // ALL pci_base address registers are the same as pci_baX registers ! + interrupt_line <= 8'h00 ; + + `ifdef HOST + `ifdef NO_CNF_IMAGE // if PCI bridge is HOST and IMAGE0 is assigned as general image space + `ifdef PCI_IMAGE0 + pci_img_ctrl0_bit2_1 <= {`PCI_AT_EN0, 1'b0} ; + pci_ba0_bit31_8 <= 24'h0000_00 ; + pci_ba0_bit0 <= `PCI_BA0_MEM_IO ; + pci_am0 <= `PCI_AM0 ; + pci_ta0 <= `PCI_TA0 ;//fr2201 translation address + `endif + `else + pci_ba0_bit31_8 <= 24'h0000_00 ; + `endif + `endif + + `ifdef GUEST + pci_ba0_bit31_8 <= 24'h0000_00 ; + `endif + + pci_img_ctrl1_bit2_1 <= {`PCI_AT_EN1, 1'b0} ; + + pci_ba1_bit31_8 <= 24'h0000_00 ; + `ifdef HOST + pci_ba1_bit0 <= `PCI_BA1_MEM_IO ; + `endif + pci_am1 <= `PCI_AM1; + pci_ta1 <= `PCI_TA1 ;//FR2201 translation address ; + `ifdef PCI_IMAGE2 + + pci_img_ctrl2_bit2_1 <= {`PCI_AT_EN2, 1'b0} ; + + pci_ba2_bit31_8 <= 24'h0000_00 ; + `ifdef HOST + pci_ba2_bit0 <= `PCI_BA2_MEM_IO ; + `endif + pci_am2 <= `PCI_AM2; + pci_ta2 <= `PCI_TA2 ;//FR2201 translation address ; + `endif + `ifdef PCI_IMAGE3 + + pci_img_ctrl3_bit2_1 <= {`PCI_AT_EN3, 1'b0} ; //FR2201 when defined enabled + + pci_ba3_bit31_8 <= 24'h0000_00 ; + `ifdef HOST + pci_ba3_bit0 <= `PCI_BA3_MEM_IO ; + `endif + pci_am3 <= `PCI_AM3; + pci_ta3 <= `PCI_TA3 ;//FR2201 translation address ; + `endif + `ifdef PCI_IMAGE4 + + pci_img_ctrl4_bit2_1 <= {`PCI_AT_EN4, 1'b0} ; //FR2201 when defined enabled + + pci_ba4_bit31_8 <= 24'h0000_00 ; + `ifdef HOST + pci_ba4_bit0 <= `PCI_BA4_MEM_IO ; + `endif + pci_am4 <= `PCI_AM4; + pci_ta4 <= `PCI_TA4 ;//FR2201 translation address ; + `endif + `ifdef PCI_IMAGE5 + + pci_img_ctrl5_bit2_1 <= {`PCI_AT_EN5, 1'b0} ; //FR2201 when defined enabled + + pci_ba5_bit31_8 <= 24'h0000_00 ; + `ifdef HOST + pci_ba5_bit0 <= `PCI_BA5_MEM_IO ; + `endif + pci_am5 <= `PCI_AM5; //FR2201 pci_am0 + pci_ta5 <= `PCI_TA5 ;//FR2201 translation address ; + `endif + /*pci_err_cs_bit31_24 ; pci_err_cs_bit10; pci_err_cs_bit9 ; pci_err_cs_bit8 ;*/ pci_err_cs_bit0 <= 1'h0 ; + /*pci_err_addr ;*/ + /*pci_err_data ;*/ + // + wb_img_ctrl1_bit2_0 <= {`WB_AT_EN1, 2'b00} ; + + wb_ba1_bit31_12 <=`WB_BA1; //FR2201 Address bar + wb_ba1_bit0 <=`WB_BA1_MEM_IO;// + wb_am1 <= `WB_AM1 ;//FR2201 Address mask + wb_ta1 <= `WB_TA1 ;//FR2201 20'h0000_0 ; + `ifdef WB_IMAGE2 + wb_img_ctrl2_bit2_0 <= {`WB_AT_EN2, 2'b00} ; + + wb_ba2_bit31_12 <=`WB_BA2; //FR2201 Address bar + wb_ba2_bit0 <=`WB_BA2_MEM_IO;// + wb_am2 <=`WB_AM2 ;//FR2201 Address mask + wb_ta2 <=`WB_TA2 ;//FR2201 translation address ; + `endif + `ifdef WB_IMAGE3 + wb_img_ctrl3_bit2_0 <= {`WB_AT_EN3, 2'b00} ; + + wb_ba3_bit31_12 <=`WB_BA3; //FR2201 Address bar + wb_ba3_bit0 <=`WB_BA3_MEM_IO;// + wb_am3 <=`WB_AM3 ;//FR2201 Address mask + wb_ta3 <=`WB_TA3 ;//FR2201 translation address ; + `endif + `ifdef WB_IMAGE4 + wb_img_ctrl4_bit2_0 <= {`WB_AT_EN4, 2'b00} ; + + wb_ba4_bit31_12 <=`WB_BA4; //FR2201 Address bar + wb_ba4_bit0 <=`WB_BA4_MEM_IO;// + wb_am4 <=`WB_AM4 ;//FR2201 Address mask + wb_ta4 <=`WB_TA4 ;//FR2201 translation address ; + `endif + `ifdef WB_IMAGE5 + wb_img_ctrl5_bit2_0 <= {`WB_AT_EN5, 2'b00} ; + + wb_ba5_bit31_12 <=`WB_BA5; //FR2201 Address bar ; + wb_ba5_bit0 <=`WB_BA5_MEM_IO;//FR2201 1'h0 ; + wb_am5 <=`WB_AM5 ;//FR2201 Address mask + wb_ta5 <=`WB_TA5 ;//FR2201 translation address ; + `endif + /*wb_err_cs_bit31_24 ; wb_err_cs_bit10 ; wb_err_cs_bit9 ; wb_err_cs_bit8 ;*/ wb_err_cs_bit0 <= 1'h0 ; + /*wb_err_addr ;*/ + /*wb_err_data ;*/ + + `ifdef HOST + cnf_addr_bit23_2 <= 22'h0000_00 ; cnf_addr_bit0 <= 1'h0 ; + `endif + + icr_bit31 <= 1'h0 ; + `ifdef HOST + icr_bit2_0 <= 3'h0 ; + icr_bit4_3 <= 2'h0 ; + `else + icr_bit2_0[2:0] <= 3'h0 ; + `endif + /*isr_bit4_3 ; isr_bit2_0 ;*/ + + // Not register bit; used only internally after reset! + init_complete <= 1'b0 ; + + `ifdef GUEST + rst_inactive_sync <= 1'b0 ; + rst_inactive <= 1'b0 ; + `endif + + `ifdef PCI_CPCI_HS_IMPLEMENT + /*hs_ins hs_ext*/ hs_loo <= 1'b0; hs_eim <= 1'b0; + // Not register bits; used only internally after reset! + /*hs_ins_armed hs_ext_armed*/ + `endif + end +/* ----------------------------------------------------------------------------------------------------------- +Following register bits should have asynchronous RESET & SET! That is why they are IMPLEMENTED separately +after this ALWAYS block!!! (for every register bit, there are two D-FF implemented) + status_bit15_11[15] <= 1'b1 ; + status_bit15_11[14] <= 1'b1 ; + status_bit15_11[13] <= 1'b1 ; + status_bit15_11[12] <= 1'b1 ; + status_bit15_11[11] <= 1'b1 ; + status_bit8 <= 1'b1 ; + pci_err_cs_bit10 <= 1'b1 ; + pci_err_cs_bit9 <= 1'b1 ; + pci_err_cs_bit8 <= 1'b1 ; + pci_err_cs_bit31_24 <= { pci_error_be, pci_error_bc } ; + pci_err_addr <= pci_error_addr ; + pci_err_data <= pci_error_data ; + wb_err_cs_bit10 <= 1'b1 ; + wb_err_cs_bit9 <= 1'b1 ; + wb_err_cs_bit8 <= 1'b1 ; + wb_err_cs_bit31_24 <= { wb_error_be, wb_error_bc } ; + wb_err_addr <= wb_error_addr ; + wb_err_data <= wb_error_data ; + isr_bit4_0[4] <= 1'b1 & icr_bit4_0[4] ; + isr_bit4_0[3] <= 1'b1 & icr_bit4_0[3] ; + isr_bit4_0[2] <= 1'b1 & icr_bit4_0[2] ; + isr_bit4_0[1] <= 1'b1 & icr_bit4_0[1] ; + isr_bit4_0[0] <= 1'b1 & icr_bit4_0[0] ; + + hs_ins; hs_ext; +-----------------------------------------------------------------------------------------------------------*/ + // Here follows normal writting to registers (only to their valid bits) ! + else + begin + if (w_we) + begin + // PCI header - configuration space + if (w_reg_select_dec[0]) // w_conf_address[5:2] = 4'h1: + begin + if (~w_byte_en[1]) + command_bit8 <= w_conf_data[8] ; + if (~w_byte_en[0]) + begin + command_bit6 <= w_conf_data[6] ; + command_bit2_0 <= w_conf_data[2:0] ; + end + end + if (w_reg_select_dec[1]) // w_conf_address[5:2] = 4'h3: + begin + if (~w_byte_en[1]) + latency_timer <= w_conf_data[15:8] ; + if (~w_byte_en[0]) + cache_line_size_reg <= w_conf_data[7:0] ; + end +// if (w_reg_select_dec[4]) // w_conf_address[5:2] = 4'h4: +// Also used with IMAGE0 + +// if (w_reg_select_dec[8]) // w_conf_address[5:2] = 4'h5: +// Also used with IMAGE1 + +// if (w_reg_select_dec[12]) // w_conf_address[5:2] = 4'h6: +// Also used with IMAGE2 + +// if (w_reg_select_dec[16]) // w_conf_address[5:2] = 4'h7: +// Also used with IMAGE3 + +// if (w_reg_select_dec[20]) // w_conf_address[5:2] = 4'h8: +// Also used with IMAGE4 + +// if (w_reg_select_dec[24]) // w_conf_address[5:2] = 4'h9: +// Also used with IMAGE5 and IMAGE6 + if (w_reg_select_dec[2]) // w_conf_address[5:2] = 4'hf: + begin + if (~w_byte_en[0]) + interrupt_line <= w_conf_data[7:0] ; + end + // PCI target - configuration space +`ifdef HOST + `ifdef NO_CNF_IMAGE + `ifdef PCI_IMAGE0 // if PCI bridge is HOST and IMAGE0 is assigned as general image space + if (w_reg_select_dec[3]) // case (w_conf_address[7:2]) = `P_IMG_CTRL0_ADDR: + begin + if (~w_byte_en[0]) + pci_img_ctrl0_bit2_1 <= w_conf_data[2:1] ; + end + if (w_reg_select_dec[4]) // case (w_conf_address[7:2]) = `P_BA0_ADDR: + begin + if (~w_byte_en[3]) + pci_ba0_bit31_8[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ba0_bit31_8[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ba0_bit31_8[15: 8] <= w_conf_pdata_reduced[15: 8] ; + if (~w_byte_en[0]) + pci_ba0_bit0 <= w_conf_data[0] ; + end + if (w_reg_select_dec[5]) // case (w_conf_address[7:2]) = `P_AM0_ADDR: + begin + if (~w_byte_en[3]) + pci_am0[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_am0[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_am0[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end + if (w_reg_select_dec[6]) // case (w_conf_address[7:2]) = `P_TA0_ADDR: + begin + if (~w_byte_en[3]) + pci_ta0[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ta0[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ta0[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end + `endif + `else + if (w_reg_select_dec[4]) // case (w_conf_address[7:2]) = `P_BA0_ADDR: + begin + if (~w_byte_en[3]) + pci_ba0_bit31_8[31:24] <= w_conf_data[31:24] ; + if (~w_byte_en[2]) + pci_ba0_bit31_8[23:16] <= w_conf_data[23:16] ; + if (~w_byte_en[1]) + pci_ba0_bit31_8[15:12] <= w_conf_data[15:12] ; + end + `endif +`endif + +`ifdef GUEST + if (w_reg_select_dec[4]) // case (w_conf_address[7:2]) = `P_BA0_ADDR: + begin + if (~w_byte_en[3]) + pci_ba0_bit31_8[31:24] <= w_conf_data[31:24] ; + if (~w_byte_en[2]) + pci_ba0_bit31_8[23:16] <= w_conf_data[23:16] ; + if (~w_byte_en[1]) + pci_ba0_bit31_8[15:12] <= w_conf_data[15:12] ; + end +`endif + if (w_reg_select_dec[7]) // case (w_conf_address[7:2]) = `P_IMG_CTRL1_ADDR: + begin + if (~w_byte_en[0]) + pci_img_ctrl1_bit2_1 <= w_conf_data[2:1] ; + end + if (w_reg_select_dec[8]) // case (w_conf_address[7:2]) = `P_BA1_ADDR: + begin + if (~w_byte_en[3]) + pci_ba1_bit31_8[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ba1_bit31_8[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ba1_bit31_8[15: 8] <= w_conf_pdata_reduced[15: 8] ; + `ifdef HOST + if (~w_byte_en[0]) + pci_ba1_bit0 <= w_conf_data[0] ; + `endif + end + if (w_reg_select_dec[9]) // case (w_conf_address[7:2]) = `P_AM1_ADDR: + begin + if (~w_byte_en[3]) + pci_am1[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_am1[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_am1[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end + if (w_reg_select_dec[10]) // case (w_conf_address[7:2]) = `P_TA1_ADDR: + begin + if (~w_byte_en[3]) + pci_ta1[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ta1[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ta1[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end +`ifdef PCI_IMAGE2 + if (w_reg_select_dec[11]) // case (w_conf_address[7:2]) = `P_IMG_CTRL2_ADDR: + begin + if (~w_byte_en[0]) + pci_img_ctrl2_bit2_1 <= w_conf_data[2:1] ; + end + if (w_reg_select_dec[12]) // case (w_conf_address[7:2]) = `P_BA2_ADDR: + begin + if (~w_byte_en[3]) + pci_ba2_bit31_8[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ba2_bit31_8[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ba2_bit31_8[15: 8] <= w_conf_pdata_reduced[15: 8] ; + `ifdef HOST + if (~w_byte_en[0]) + pci_ba2_bit0 <= w_conf_data[0] ; + `endif + end + if (w_reg_select_dec[13]) // case (w_conf_address[7:2]) = `P_AM2_ADDR: + begin + if (~w_byte_en[3]) + pci_am2[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_am2[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_am2[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end + if (w_reg_select_dec[14]) // case (w_conf_address[7:2]) = `P_TA2_ADDR: + begin + if (~w_byte_en[3]) + pci_ta2[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ta2[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ta2[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end +`endif +`ifdef PCI_IMAGE3 + if (w_reg_select_dec[15]) // case (w_conf_address[7:2]) = `P_IMG_CTRL3_ADDR: + begin + if (~w_byte_en[0]) + pci_img_ctrl3_bit2_1 <= w_conf_data[2:1] ; + end + if (w_reg_select_dec[16]) // case (w_conf_address[7:2]) = `P_BA3_ADDR: + begin + if (~w_byte_en[3]) + pci_ba3_bit31_8[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ba3_bit31_8[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ba3_bit31_8[15: 8] <= w_conf_pdata_reduced[15: 8] ; + `ifdef HOST + if (~w_byte_en[0]) + pci_ba3_bit0 <= w_conf_data[0] ; + `endif + end + if (w_reg_select_dec[17]) // case (w_conf_address[7:2]) = `P_AM3_ADDR: + begin + if (~w_byte_en[3]) + pci_am3[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_am3[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_am3[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end + if (w_reg_select_dec[18]) // case (w_conf_address[7:2]) = `P_TA3_ADDR: + begin + if (~w_byte_en[3]) + pci_ta3[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ta3[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ta3[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end +`endif +`ifdef PCI_IMAGE4 + if (w_reg_select_dec[19]) // case (w_conf_address[7:2]) = `P_IMG_CTRL4_ADDR: + begin + if (~w_byte_en[0]) + pci_img_ctrl4_bit2_1 <= w_conf_data[2:1] ; + end + if (w_reg_select_dec[20]) // case (w_conf_address[7:2]) = `P_BA4_ADDR: + begin + if (~w_byte_en[3]) + pci_ba4_bit31_8[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ba4_bit31_8[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ba4_bit31_8[15: 8] <= w_conf_pdata_reduced[15: 8] ; + `ifdef HOST + if (~w_byte_en[0]) + pci_ba4_bit0 <= w_conf_data[0] ; + `endif + end + if (w_reg_select_dec[21]) // case (w_conf_address[7:2]) = `P_AM4_ADDR: + begin + if (~w_byte_en[3]) + pci_am4[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_am4[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_am4[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end + if (w_reg_select_dec[22]) // case (w_conf_address[7:2]) = `P_TA4_ADDR: + begin + if (~w_byte_en[3]) + pci_ta4[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ta4[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ta4[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end +`endif +`ifdef PCI_IMAGE5 + if (w_reg_select_dec[23]) // case (w_conf_address[7:2]) = `P_IMG_CTRL5_ADDR: + begin + if (~w_byte_en[0]) + pci_img_ctrl5_bit2_1 <= w_conf_data[2:1] ; + end + if (w_reg_select_dec[24]) // case (w_conf_address[7:2]) = `P_BA5_ADDR: + begin + if (~w_byte_en[3]) + pci_ba5_bit31_8[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ba5_bit31_8[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ba5_bit31_8[15: 8] <= w_conf_pdata_reduced[15: 8] ; + `ifdef HOST + if (~w_byte_en[0]) + pci_ba5_bit0 <= w_conf_data[0] ; + `endif + end + if (w_reg_select_dec[25]) // case (w_conf_address[7:2]) = `P_AM5_ADDR: + begin + if (~w_byte_en[3]) + pci_am5[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_am5[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_am5[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end + if (w_reg_select_dec[26]) // case (w_conf_address[7:2]) = `P_TA5_ADDR: + begin + if (~w_byte_en[3]) + pci_ta5[31:24] <= w_conf_pdata_reduced[31:24] ; + if (~w_byte_en[2]) + pci_ta5[23:16] <= w_conf_pdata_reduced[23:16] ; + if (~w_byte_en[1]) + pci_ta5[15: 8] <= w_conf_pdata_reduced[15: 8] ; + end +`endif + if (w_reg_select_dec[27]) // case (w_conf_address[7:2]) = `P_ERR_CS_ADDR: + begin + if (~w_byte_en[0]) + pci_err_cs_bit0 <= w_conf_data[0] ; + end + // WB slave - configuration space + if (w_reg_select_dec[30]) // case (w_conf_address[7:2]) = `W_IMG_CTRL1_ADDR: + begin + if (~w_byte_en[0]) + wb_img_ctrl1_bit2_0 <= w_conf_data[2:0] ; + end + if (w_reg_select_dec[31]) // case (w_conf_address[7:2]) = `W_BA1_ADDR: + begin + if (~w_byte_en[3]) + wb_ba1_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ba1_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ba1_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; + if (~w_byte_en[0]) + wb_ba1_bit0 <= w_conf_data[0] ; + end + if (w_reg_select_dec[32]) // case (w_conf_address[7:2]) = `W_AM1_ADDR: + begin + if (~w_byte_en[3]) + wb_am1[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_am1[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_am1[15:12] <= w_conf_wdata_reduced[15:12] ; + end + if (w_reg_select_dec[33]) // case (w_conf_address[7:2]) = `W_TA1_ADDR: + begin + if (~w_byte_en[3]) + wb_ta1[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ta1[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ta1[15:12] <= w_conf_wdata_reduced[15:12] ; + end +`ifdef WB_IMAGE2 + if (w_reg_select_dec[34]) // case (w_conf_address[7:2]) = `W_IMG_CTRL2_ADDR: + begin + if (~w_byte_en[0]) + wb_img_ctrl2_bit2_0 <= w_conf_data[2:0] ; + end + if (w_reg_select_dec[35]) // case (w_conf_address[7:2]) = `W_BA2_ADDR: + begin + if (~w_byte_en[3]) + wb_ba2_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ba2_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ba2_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; + if (~w_byte_en[0]) + wb_ba2_bit0 <= w_conf_data[0] ; + end + if (w_reg_select_dec[36]) // case (w_conf_address[7:2]) = `W_AM2_ADDR: + begin + if (~w_byte_en[3]) + wb_am2[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_am2[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_am2[15:12] <= w_conf_wdata_reduced[15:12] ; + end + if (w_reg_select_dec[37]) // case (w_conf_address[7:2]) = `W_TA2_ADDR: + begin + if (~w_byte_en[3]) + wb_ta2[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ta2[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ta2[15:12] <= w_conf_wdata_reduced[15:12] ; + end +`endif +`ifdef WB_IMAGE3 + if (w_reg_select_dec[38]) // case (w_conf_address[7:2]) = `W_IMG_CTRL3_ADDR: + begin + if (~w_byte_en[0]) + wb_img_ctrl3_bit2_0 <= w_conf_data[2:0] ; + end + if (w_reg_select_dec[39]) // case (w_conf_address[7:2]) = `W_BA3_ADDR: + begin + if (~w_byte_en[3]) + wb_ba3_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ba3_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ba3_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; + if (~w_byte_en[0]) + wb_ba3_bit0 <= w_conf_data[0] ; + end + if (w_reg_select_dec[40]) // case (w_conf_address[7:2]) = `W_AM3_ADDR: + begin + if (~w_byte_en[3]) + wb_am3[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_am3[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_am3[15:12] <= w_conf_wdata_reduced[15:12] ; + end + if (w_reg_select_dec[41]) // case (w_conf_address[7:2]) = `W_TA3_ADDR: + begin + if (~w_byte_en[3]) + wb_ta3[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ta3[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ta3[15:12] <= w_conf_wdata_reduced[15:12] ; + end +`endif +`ifdef WB_IMAGE4 + if (w_reg_select_dec[42]) // case (w_conf_address[7:2]) = `W_IMG_CTRL4_ADDR: + begin + if (~w_byte_en[0]) + wb_img_ctrl4_bit2_0 <= w_conf_data[2:0] ; + end + if (w_reg_select_dec[43]) // case (w_conf_address[7:2]) = `W_BA4_ADDR: + begin + if (~w_byte_en[3]) + wb_ba4_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ba4_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ba4_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; + if (~w_byte_en[0]) + wb_ba4_bit0 <= w_conf_data[0] ; + end + if (w_reg_select_dec[44]) // case (w_conf_address[7:2]) = `W_AM4_ADDR: + begin + if (~w_byte_en[3]) + wb_am4[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_am4[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_am4[15:12] <= w_conf_wdata_reduced[15:12] ; + end + if (w_reg_select_dec[45]) // case (w_conf_address[7:2]) = `W_TA4_ADDR: + begin + if (~w_byte_en[3]) + wb_ta4[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ta4[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ta4[15:12] <= w_conf_wdata_reduced[15:12] ; + end +`endif +`ifdef WB_IMAGE5 + if (w_reg_select_dec[46]) // case (w_conf_address[7:2]) = `W_IMG_CTRL5_ADDR: + begin + if (~w_byte_en[0]) + wb_img_ctrl5_bit2_0 <= w_conf_data[2:0] ; + end + if (w_reg_select_dec[47]) // case (w_conf_address[7:2]) = `W_BA5_ADDR: + begin + if (~w_byte_en[3]) + wb_ba5_bit31_12[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ba5_bit31_12[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ba5_bit31_12[15:12] <= w_conf_wdata_reduced[15:12] ; + if (~w_byte_en[0]) + wb_ba5_bit0 <= w_conf_data[0] ; + end + if (w_reg_select_dec[48]) // case (w_conf_address[7:2]) = `W_AM5_ADDR: + begin + if (~w_byte_en[3]) + wb_am5[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_am5[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_am5[15:12] <= w_conf_wdata_reduced[15:12] ; + end + if (w_reg_select_dec[49]) // case (w_conf_address[7:2]) = `W_TA5_ADDR: + begin + if (~w_byte_en[3]) + wb_ta5[31:24] <= w_conf_wdata_reduced[31:24] ; + if (~w_byte_en[2]) + wb_ta5[23:16] <= w_conf_wdata_reduced[23:16] ; + if (~w_byte_en[1]) + wb_ta5[15:12] <= w_conf_wdata_reduced[15:12] ; + end +`endif + if (w_reg_select_dec[50]) // case (w_conf_address[7:2]) = `W_ERR_CS_ADDR: + begin + if (~w_byte_en[0]) + wb_err_cs_bit0 <= w_conf_data[0] ; + end + +`ifdef HOST + if (w_reg_select_dec[53]) // case (w_conf_address[7:2]) = `CNF_ADDR_ADDR: + begin + if (~w_byte_en[2]) + cnf_addr_bit23_2[23:16] <= w_conf_data[23:16] ; + if (~w_byte_en[1]) + cnf_addr_bit23_2[15:8] <= w_conf_data[15:8] ; + if (~w_byte_en[0]) + begin + cnf_addr_bit23_2[7:2] <= w_conf_data[7:2] ; + cnf_addr_bit0 <= w_conf_data[0] ; + end + end +`endif + // `CNF_DATA_ADDR: implemented elsewhere !!! + // `INT_ACK_ADDR : implemented elsewhere !!! + if (w_reg_select_dec[54]) // case (w_conf_address[7:2]) = `ICR_ADDR: + begin + if (~w_byte_en[3]) + icr_bit31 <= w_conf_data[31] ; + + if (~w_byte_en[0]) + begin +`ifdef HOST + icr_bit4_3 <= w_conf_data[4:3] ; + icr_bit2_0 <= w_conf_data[2:0] ; +`else + icr_bit2_0[2:0] <= w_conf_data[2:0] ; +`endif + end + end + +`ifdef PCI_CPCI_HS_IMPLEMENT + if (w_reg_select_dec[56]) + begin + if (~w_byte_en[2]) + begin + hs_loo <= w_conf_data[19]; + hs_eim <= w_conf_data[17]; + end + end +`endif + end // end of we + + // Not register bits; used only internally after reset! + `ifdef GUEST + rst_inactive_sync <= 1'b1 ; + rst_inactive <= rst_inactive_sync ; + `endif + + if (rst_inactive & ~init_complete & init_cfg_done) + init_complete <= 1'b1 ; + end +end + +// implementation of read only device identification registers +always@(posedge w_clock or posedge reset) +begin + if (reset) + begin + r_vendor_id <= `HEADER_VENDOR_ID ; + r_device_id <= `HEADER_DEVICE_ID ; + r_revision_id <= `HEADER_REVISION_ID ; + r_subsys_vendor_id <= `HEADER_SUBSYS_VENDOR_ID ; + r_subsys_id <= `HEADER_SUBSYS_ID ; + r_max_lat <= `HEADER_MAX_LAT ; + r_min_gnt <= `HEADER_MIN_GNT ; + end else + begin + if (init_we) + begin + if (spoci_reg_num == 'h0) + begin + r_vendor_id <= spoci_dat[15: 0] ; + r_device_id <= spoci_dat[31:16] ; + end + + if (spoci_reg_num == 'hB) + begin + r_subsys_vendor_id <= spoci_dat[15: 0] ; + r_subsys_id <= spoci_dat[31:16] ; + end + + if (spoci_reg_num == 'h2) + begin + r_revision_id <= spoci_dat[ 7: 0] ; + end + + if (spoci_reg_num == 'hF) + begin + r_max_lat <= spoci_dat[31:24] ; + r_min_gnt <= spoci_dat[23:16] ; + end + end + end +end + +// This signals are synchronous resets for registers, whic occures when asynchronous RESET is '1' or +// data '1' is synchronously written into them! +reg delete_status_bit15 ; +reg delete_status_bit14 ; +reg delete_status_bit13 ; +reg delete_status_bit12 ; +reg delete_status_bit11 ; +reg delete_status_bit8 ; +reg delete_pci_err_cs_bit8 ; +reg delete_wb_err_cs_bit8 ; +reg delete_isr_bit4 ; +reg delete_isr_bit3 ; +reg delete_isr_bit2 ; +reg delete_isr_bit1 ; + +// This are aditional register bits, which are resets when their value is '1' !!! +always@(w_we or w_reg_select_dec or w_conf_data or w_byte_en) +begin +// I' is written into, then it also sets signals to '1' + delete_status_bit15 = w_conf_data[31] & !w_byte_en[3] & w_we & w_reg_select_dec[0] ; + delete_status_bit14 = w_conf_data[30] & !w_byte_en[3] & w_we & w_reg_select_dec[0] ; + delete_status_bit13 = w_conf_data[29] & !w_byte_en[3] & w_we & w_reg_select_dec[0] ; + delete_status_bit12 = w_conf_data[28] & !w_byte_en[3] & w_we & w_reg_select_dec[0] ; + delete_status_bit11 = w_conf_data[27] & !w_byte_en[3] & w_we & w_reg_select_dec[0] ; + delete_status_bit8 = w_conf_data[24] & !w_byte_en[3] & w_we & w_reg_select_dec[0] ; + delete_pci_err_cs_bit8 = w_conf_data[8] & !w_byte_en[1] & w_we & w_reg_select_dec[27] ; + delete_wb_err_cs_bit8 = w_conf_data[8] & !w_byte_en[1] & w_we & w_reg_select_dec[50] ; + delete_isr_bit4 = w_conf_data[4] & !w_byte_en[0] & w_we & w_reg_select_dec[55] ; + delete_isr_bit3 = w_conf_data[3] & !w_byte_en[0] & w_we & w_reg_select_dec[55] ; + delete_isr_bit2 = w_conf_data[2] & !w_byte_en[0] & w_we & w_reg_select_dec[55] ; + delete_isr_bit1 = w_conf_data[1] & !w_byte_en[0] & w_we & w_reg_select_dec[55] ; +end + +// STATUS BITS of PCI Header status register +`ifdef SYNCHRONEOUS_CLOCK_DOMAINS + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[15] <= 1'b0 ; + else + begin + if (perr_in) // Synchronous set + status_bit15_11[15] <= 1'b1 ; + else if (delete_status_bit15) // Synchronous reset + status_bit15_11[15] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[14] <= 1'b0 ; + else + begin + if (serr_in) // Synchronous set + status_bit15_11[14] <= 1'b1 ; + else if (delete_status_bit14) // Synchronous reset + status_bit15_11[14] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[13] <= 1'b0 ; + else + begin + if (master_abort_recv) // Synchronous set + status_bit15_11[13] <= 1'b1 ; + else if (delete_status_bit13) // Synchronous reset + status_bit15_11[13] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[12] <= 1'b0 ; + else + begin + if (target_abort_recv) // Synchronous set + status_bit15_11[12] <= 1'b1 ; + else if (delete_status_bit12) // Synchronous reset + status_bit15_11[12] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[11] <= 1'b0 ; + else + begin + if (target_abort_set) // Synchronous set + status_bit15_11[11] <= 1'b1 ; + else if (delete_status_bit11) // Synchronous reset + status_bit15_11[11] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit8 <= 1'b0 ; + else + begin + if (master_data_par_err) // Synchronous set + status_bit8 <= 1'b1 ; + else if (delete_status_bit8) // Synchronous reset + status_bit8 <= 1'b0 ; + end + end +`else // not SYNCHRONEOUS_CLOCK_DOMAINS + `ifdef HOST + reg [15:11] set_status_bit15_11; + reg set_status_bit8; + wire delete_set_status_bit15; + wire delete_set_status_bit14; + wire delete_set_status_bit13; + wire delete_set_status_bit12; + wire delete_set_status_bit11; + wire delete_set_status_bit8; + wire block_set_status_bit15; + wire block_set_status_bit14; + wire block_set_status_bit13; + wire block_set_status_bit12; + wire block_set_status_bit11; + wire block_set_status_bit8; + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_status_15 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_status_bit15), + .block_set_out (block_set_status_bit15), + .delete_in (delete_status_bit15) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_status_bit15_11[15] <= 1'b0 ; + else + begin + if (perr_in) // Synchronous set + set_status_bit15_11[15] <= 1'b1 ; + else if (delete_set_status_bit15) // Synchronous reset + set_status_bit15_11[15] <= 1'b0 ; + end + end + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_status_14 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_status_bit14), + .block_set_out (block_set_status_bit14), + .delete_in (delete_status_bit14) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_status_bit15_11[14] <= 1'b0 ; + else + begin + if (serr_in) // Synchronous set + set_status_bit15_11[14] <= 1'b1 ; + else if (delete_set_status_bit14) // Synchronous reset + set_status_bit15_11[14] <= 1'b0 ; + end + end + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_status_13 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_status_bit13), + .block_set_out (block_set_status_bit13), + .delete_in (delete_status_bit13) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_status_bit15_11[13] <= 1'b0 ; + else + begin + if (master_abort_recv) // Synchronous set + set_status_bit15_11[13] <= 1'b1 ; + else if (delete_set_status_bit13) // Synchronous reset + set_status_bit15_11[13] <= 1'b0 ; + end + end + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_status_12 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_status_bit12), + .block_set_out (block_set_status_bit12), + .delete_in (delete_status_bit12) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_status_bit15_11[12] <= 1'b0 ; + else + begin + if (target_abort_recv) // Synchronous set + set_status_bit15_11[12] <= 1'b1 ; + else if (delete_set_status_bit12) // Synchronous reset + set_status_bit15_11[12] <= 1'b0 ; + end + end + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_status_11 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_status_bit11), + .block_set_out (block_set_status_bit11), + .delete_in (delete_status_bit11) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_status_bit15_11[11] <= 1'b0 ; + else + begin + if (target_abort_set) // Synchronous set + set_status_bit15_11[11] <= 1'b1 ; + else if (delete_set_status_bit11) // Synchronous reset + set_status_bit15_11[11] <= 1'b0 ; + end + end + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_status_8 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_status_bit8), + .block_set_out (block_set_status_bit8), + .delete_in (delete_status_bit8) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_status_bit8 <= 1'b0 ; + else + begin + if (master_data_par_err) // Synchronous set + set_status_bit8 <= 1'b1 ; + else if (delete_set_status_bit8) // Synchronous reset + set_status_bit8 <= 1'b0 ; + end + end + wire [5:0] status_bits = {set_status_bit15_11[15] && !block_set_status_bit15, + set_status_bit15_11[14] && !block_set_status_bit14, + set_status_bit15_11[13] && !block_set_status_bit13, + set_status_bit15_11[12] && !block_set_status_bit12, + set_status_bit15_11[11] && !block_set_status_bit11, + set_status_bit8 && !block_set_status_bit8 } ; + wire [5:0] meta_status_bits ; + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(6, 0) status_bits_sync + ( + .data_in (status_bits), + .clk_out (wb_clk), + .sync_data_out (meta_status_bits), + .async_reset (reset) + ) ; + always@(posedge wb_clk or posedge reset) + begin + if (reset) + begin + status_bit15_11[15:11] <= 5'b0 ; + status_bit8 <= 1'b0 ; + end + else + begin + status_bit15_11[15:11] <= meta_status_bits[5:1] ; + status_bit8 <= meta_status_bits[0] ; + end + end + `else // GUEST + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[15] <= 1'b0 ; + else + begin + if (perr_in) // Synchronous set + status_bit15_11[15] <= 1'b1 ; + else if (delete_status_bit15) // Synchronous reset + status_bit15_11[15] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[14] <= 1'b0 ; + else + begin + if (serr_in) // Synchronous set + status_bit15_11[14] <= 1'b1 ; + else if (delete_status_bit14) // Synchronous reset + status_bit15_11[14] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[13] <= 1'b0 ; + else + begin + if (master_abort_recv) // Synchronous set + status_bit15_11[13] <= 1'b1 ; + else if (delete_status_bit13) // Synchronous reset + status_bit15_11[13] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[12] <= 1'b0 ; + else + begin + if (target_abort_recv) // Synchronous set + status_bit15_11[12] <= 1'b1 ; + else if (delete_status_bit12) // Synchronous reset + status_bit15_11[12] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit15_11[11] <= 1'b0 ; + else + begin + if (target_abort_set) // Synchronous set + status_bit15_11[11] <= 1'b1 ; + else if (delete_status_bit11) // Synchronous reset + status_bit15_11[11] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + status_bit8 <= 1'b0 ; + else + begin + if (master_data_par_err) // Synchronous set + status_bit8 <= 1'b1 ; + else if (delete_status_bit8) // Synchronous reset + status_bit8 <= 1'b0 ; + end + end + `endif +`endif + +// STATUS BITS of P_ERR_CS - PCI error control and status register +`ifdef SYNCHRONEOUS_CLOCK_DOMAINS + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + pci_err_cs_bit8 <= 1'b0 ; + else + begin + if (pci_error_sig && pci_err_cs_bit0) // Synchronous set + pci_err_cs_bit8 <= 1'b1 ; + else if (delete_pci_err_cs_bit8) // Synchronous reset + pci_err_cs_bit8 <= 1'b0 ; + end + end +`else // not SYNCHRONEOUS_CLOCK_DOMAINS + `ifdef HOST + // Set and clear FF + always@(posedge wb_clk or posedge reset) + begin + if (reset) // Asynchronous reset + pci_err_cs_bit8 <= 1'b0 ; + else + begin + if (pci_error_sig && pci_err_cs_bit0) // Synchronous set + pci_err_cs_bit8 <= 1'b1 ; + else if (delete_pci_err_cs_bit8) // Synchronous reset + pci_err_cs_bit8 <= 1'b0 ; + end + end + `else // GUEST + reg set_pci_err_cs_bit8; + wire delete_set_pci_err_cs_bit8; + wire block_set_pci_err_cs_bit8; + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_pci_err_cs_8 + ( + .set_clk_in (wb_clk), + .delete_clk_in (pci_clk), + .reset_in (reset), + .delete_set_out (delete_set_pci_err_cs_bit8), + .block_set_out (block_set_pci_err_cs_bit8), + .delete_in (delete_pci_err_cs_bit8) + ); + // Setting FF + always@(posedge wb_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_pci_err_cs_bit8 <= 1'b0 ; + else + begin + if (pci_error_sig && pci_err_cs_bit0) // Synchronous set + set_pci_err_cs_bit8 <= 1'b1 ; + else if (delete_set_pci_err_cs_bit8) // Synchronous reset + set_pci_err_cs_bit8 <= 1'b0 ; + end + end + wire pci_err_cs_bits = set_pci_err_cs_bit8 && !block_set_pci_err_cs_bit8 ; + wire meta_pci_err_cs_bits ; + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(1,0) pci_err_cs_bits_sync + ( + .data_in (pci_err_cs_bits), + .clk_out (pci_clk), + .sync_data_out (meta_pci_err_cs_bits), + .async_reset (reset) + ) ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + pci_err_cs_bit8 <= 1'b0 ; + else + pci_err_cs_bit8 <= meta_pci_err_cs_bits ; + end + `endif +`endif + // Set and clear FF + always@(posedge wb_clk or posedge reset) + begin + if (reset) // Asynchronous reset + pci_err_cs_bit10 <= 1'b0 ; + else + begin + if (pci_error_sig) // Synchronous report + pci_err_cs_bit10 <= pci_error_rty_exp ; + end + end + // Set and clear FF + always@(posedge wb_clk or posedge reset) + begin + if (reset) // Asynchronous reset + pci_err_cs_bit9 <= 1'b0 ; + else + begin + if (pci_error_sig) // Synchronous report + pci_err_cs_bit9 <= pci_error_es ; + end + end + // Set and clear FF + always@(posedge wb_clk or posedge reset) + begin + if (reset) // Asynchronous reset + begin + pci_err_cs_bit31_24 <= 8'h00 ; + pci_err_addr <= 32'h0000_0000 ; + pci_err_data <= 32'h0000_0000 ; + end + else + if (pci_error_sig) // Synchronous report + begin + pci_err_cs_bit31_24 <= { pci_error_be, pci_error_bc } ; + pci_err_addr <= pci_error_addr ; + pci_err_data <= pci_error_data ; + end + end + +// STATUS BITS of W_ERR_CS - WB error control and status register +`ifdef SYNCHRONEOUS_CLOCK_DOMAINS + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + wb_err_cs_bit8 <= 1'b0 ; + else + begin + if (wb_error_sig && wb_err_cs_bit0) // Synchronous set + wb_err_cs_bit8 <= 1'b1 ; + else if (delete_wb_err_cs_bit8) // Synchronous reset + wb_err_cs_bit8 <= 1'b0 ; + end + end +`else // not SYNCHRONEOUS_CLOCK_DOMAINS + `ifdef HOST + reg set_wb_err_cs_bit8; + wire delete_set_wb_err_cs_bit8; + wire block_set_wb_err_cs_bit8; + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_wb_err_cs_8 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_wb_err_cs_bit8), + .block_set_out (block_set_wb_err_cs_bit8), + .delete_in (delete_wb_err_cs_bit8) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_wb_err_cs_bit8 <= 1'b0 ; + else + begin + if (wb_error_sig && wb_err_cs_bit0) // Synchronous set + set_wb_err_cs_bit8 <= 1'b1 ; + else if (delete_set_wb_err_cs_bit8) // Synchronous reset + set_wb_err_cs_bit8 <= 1'b0 ; + end + end + wire wb_err_cs_bits = set_wb_err_cs_bit8 && !block_set_wb_err_cs_bit8 ; + wire meta_wb_err_cs_bits ; + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(1,0) wb_err_cs_bits_sync + ( + .data_in (wb_err_cs_bits), + .clk_out (wb_clk), + .sync_data_out (meta_wb_err_cs_bits), + .async_reset (reset) + ) ; + always@(posedge wb_clk or posedge reset) + begin + if (reset) + wb_err_cs_bit8 <= 1'b0 ; + else + wb_err_cs_bit8 <= meta_wb_err_cs_bits ; + end + `else // GUEST + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + wb_err_cs_bit8 <= 1'b0 ; + else + begin + if (wb_error_sig && wb_err_cs_bit0) // Synchronous set + wb_err_cs_bit8 <= 1'b1 ; + else if (delete_wb_err_cs_bit8) // Synchronous reset + wb_err_cs_bit8 <= 1'b0 ; + end + end + `endif +`endif +/* // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + wb_err_cs_bit10 <= 1'b0 ; + else + begin + if (wb_error_sig) // Synchronous report + wb_err_cs_bit10 <= wb_error_rty_exp ; + end + end */ + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + wb_err_cs_bit9 <= 1'b0 ; + else + begin + if (wb_error_sig) // Synchronous report + wb_err_cs_bit9 <= wb_error_es ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + begin + wb_err_cs_bit31_24 <= 8'h00 ; + wb_err_addr <= 32'h0000_0000 ; + wb_err_data <= 32'h0000_0000 ; + end + else + if (wb_error_sig) + begin + wb_err_cs_bit31_24 <= { wb_error_be, wb_error_bc } ; + wb_err_addr <= wb_error_addr ; + wb_err_data <= wb_error_data ; + end + end + +// SERR_INT and PERR_INT STATUS BITS of ISR - interrupt status register +`ifdef SYNCHRONEOUS_CLOCK_DOMAINS + `ifdef HOST + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + isr_bit4_3[4] <= 1'b0 ; + else + begin + if (isr_sys_err_int && icr_bit4_3[4]) // Synchronous set + isr_bit4_3[4] <= 1'b1 ; + else if (delete_isr_bit4) // Synchronous reset + isr_bit4_3[4] <= 1'b0 ; + end + end + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + isr_bit4_3[3] <= 1'b0 ; + else + begin + if (isr_par_err_int && icr_bit4_3[3]) // Synchronous set + isr_bit4_3[3] <= 1'b1 ; + else if (delete_isr_bit3) // Synchronous reset + isr_bit4_3[3] <= 1'b0 ; + end + end + `endif +`else // not SYNCHRONEOUS_CLOCK_DOMAINS + `ifdef HOST + reg [4:3] set_isr_bit4_3; + wire delete_set_isr_bit4; + wire delete_set_isr_bit3; + wire block_set_isr_bit4; + wire block_set_isr_bit3; + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_isr_4 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_isr_bit4), + .block_set_out (block_set_isr_bit4), + .delete_in (delete_isr_bit4) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_isr_bit4_3[4] <= 1'b0 ; + else + begin + if (isr_sys_err_int && icr_bit4_3[4]) // Synchronous set + set_isr_bit4_3[4] <= 1'b1 ; + else if (delete_set_isr_bit4) // Synchronous reset + set_isr_bit4_3[4] <= 1'b0 ; + end + end + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_isr_3 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_isr_bit3), + .block_set_out (block_set_isr_bit3), + .delete_in (delete_isr_bit3) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_isr_bit4_3[3] <= 1'b0 ; + else + begin + if (isr_par_err_int && icr_bit4_3[3]) // Synchronous set + set_isr_bit4_3[3] <= 1'b1 ; + else if (delete_set_isr_bit3) // Synchronous reset + set_isr_bit4_3[3] <= 1'b0 ; + end + end + wire [4:3] isr_bits4_3 = {set_isr_bit4_3[4] && !block_set_isr_bit4, + set_isr_bit4_3[3] && !block_set_isr_bit3 } ; + wire [4:3] meta_isr_bits4_3 ; + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(2, 0) isr_bits_sync + ( + .data_in (isr_bits4_3), + .clk_out (wb_clk), + .sync_data_out (meta_isr_bits4_3), + .async_reset (reset) + ) ; + always@(posedge wb_clk or posedge reset) + begin + if (reset) + isr_bit4_3[4:3] <= 2'b0 ; + else + isr_bit4_3[4:3] <= meta_isr_bits4_3[4:3] ; + end + `endif +`endif + +// PCI_EINT and WB_EINT STATUS BITS of ISR - interrupt status register +`ifdef SYNCHRONEOUS_CLOCK_DOMAINS + // WB_EINT STATUS BIT + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + isr_bit2_0[1] <= 1'b0 ; + else + begin + if (wb_error_sig && icr_bit2_0[1] && wb_err_cs_bit0) // Synchronous set + isr_bit2_0[1] <= 1'b1 ; + else if (delete_isr_bit1) // Synchronous reset + isr_bit2_0[1] <= 1'b0 ; + end + end + // PCI_EINT STATUS BIT + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + isr_bit2_0[2] <= 1'b0 ; + else + begin + if (pci_error_sig && icr_bit2_0[2] && pci_err_cs_bit0) // Synchronous set + isr_bit2_0[2] <= 1'b1 ; + else if (delete_isr_bit2) // Synchronous reset + isr_bit2_0[2] <= 1'b0 ; + end + end +`else // not SYNCHRONEOUS_CLOCK_DOMAINS + `ifdef HOST + // WB_EINT STATUS BIT + reg set_isr_bit1; + wire delete_set_isr_bit1; + wire block_set_isr_bit1; + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_isr_1 + ( + .set_clk_in (pci_clk), + .delete_clk_in (wb_clk), + .reset_in (reset), + .delete_set_out (delete_set_isr_bit1), + .block_set_out (block_set_isr_bit1), + .delete_in (delete_isr_bit1) + ); + // Setting FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_isr_bit1 <= 1'b0 ; + else + begin + if (wb_error_sig && icr_bit2_0[1] && wb_err_cs_bit0) // Synchronous set + set_isr_bit1 <= 1'b1 ; + else if (delete_set_isr_bit1) // Synchronous reset + set_isr_bit1 <= 1'b0 ; + end + end + wire isr_bit1 = set_isr_bit1 && !block_set_isr_bit1 ; + wire meta_isr_bit1 ; + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(1, 0) isr_bit1_sync + ( + .data_in (isr_bit1), + .clk_out (wb_clk), + .sync_data_out (meta_isr_bit1), + .async_reset (reset) + ) ; + always@(posedge wb_clk or posedge reset) + begin + if (reset) + isr_bit2_0[1] <= 1'b0 ; + else + isr_bit2_0[1] <= meta_isr_bit1 ; + end + // PCI_EINT STATUS BIT + // Set and clear FF + always@(posedge wb_clk or posedge reset) + begin + if (reset) // Asynchronous reset + isr_bit2_0[2] <= 1'b0 ; + else + begin + if (pci_error_sig && icr_bit2_0[2] && pci_err_cs_bit0) // Synchronous set + isr_bit2_0[2] <= 1'b1 ; + else if (delete_isr_bit2) // Synchronous reset + isr_bit2_0[2] <= 1'b0 ; + end + end + `else // GUEST + // WB_EINT STATUS BIT + // Set and clear FF + always@(posedge pci_clk or posedge reset) + begin + if (reset) // Asynchronous reset + isr_bit2_0[1] <= 1'b0 ; + else + begin + if (wb_error_sig && icr_bit2_0[1] && wb_err_cs_bit0) // Synchronous set + isr_bit2_0[1] <= 1'b1 ; + else if (delete_isr_bit1) // Synchronous reset + isr_bit2_0[1] <= 1'b0 ; + end + end + // PCI_EINT STATUS BIT + reg set_isr_bit2; + wire delete_set_isr_bit2; + wire block_set_isr_bit2; + // Synchronization module for clearing FF between two clock domains + pci_sync_module sync_isr_2 + ( + .set_clk_in (wb_clk), + .delete_clk_in (pci_clk), + .reset_in (reset), + .delete_set_out (delete_set_isr_bit2), + .block_set_out (block_set_isr_bit2), + .delete_in (delete_isr_bit2) + ); + // Setting FF + always@(posedge wb_clk or posedge reset) + begin + if (reset) // Asynchronous reset + set_isr_bit2 <= 1'b0 ; + else + begin + if (pci_error_sig && icr_bit2_0[2] && pci_err_cs_bit0) // Synchronous set + set_isr_bit2 <= 1'b1 ; + else if (delete_set_isr_bit2) // Synchronous reset + set_isr_bit2 <= 1'b0 ; + end + end + wire isr_bit2 = set_isr_bit2 && !block_set_isr_bit2 ; + wire meta_isr_bit2 ; + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(1, 0) isr_bit2_sync + ( + .data_in (isr_bit2), + .clk_out (pci_clk), + .sync_data_out (meta_isr_bit2), + .async_reset (reset) + ) ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + isr_bit2_0[2] <= 1'b0 ; + else + isr_bit2_0[2] <= meta_isr_bit2 ; + end + `endif +`endif + +// INT BIT of ISR - interrupt status register +`ifdef HOST + wire isr_int_prop_bit = isr_int_prop && icr_bit2_0[0] ; + wire meta_isr_int_prop_bit ; + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(1, 0) isr_bit0_sync + ( + .data_in (isr_int_prop_bit), + .clk_out (wb_clk), + .sync_data_out (meta_isr_int_prop_bit), + .async_reset (reset) + ) ; + always@(posedge wb_clk or posedge reset) + begin + if (reset) + isr_bit2_0[0] <= 1'b0 ; + else + isr_bit2_0[0] <= meta_isr_int_prop_bit ; + end +`else // GUEST + `ifdef SYNCHRONEOUS_CLOCK_DOMAINS + wire isr_int_prop_bit = isr_int_prop && icr_bit2_0[0] ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + isr_bit2_0[0] <= 1'b0 ; + else + isr_bit2_0[0] <= isr_int_prop_bit ; + end + `else // not SYNCHRONEOUS_CLOCK_DOMAINS + wire isr_int_prop_bit = isr_int_prop && icr_bit2_0[0] ; + wire meta_isr_int_prop_bit ; + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(1, 0) isr_bit0_sync + ( + .data_in (isr_int_prop_bit), + .clk_out (pci_clk), + .sync_data_out (meta_isr_int_prop_bit), + .async_reset (reset) + ) ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + isr_bit2_0[0] <= 1'b0 ; + else + isr_bit2_0[0] <= meta_isr_int_prop_bit ; + end + `endif +`endif + +// INT PIN +wire int_in; +wire int_meta; +reg interrupt_out; +`ifdef HOST + `ifdef SYNCHRONEOUS_CLOCK_DOMAINS + assign int_in = isr_int_prop_bit || isr_bit2_0[1] || isr_bit2_0[2] || isr_bit4_3[3] || isr_bit4_3[4]; + `else // not SYNCHRONEOUS_CLOCK_DOMAINS + assign int_in = isr_int_prop_bit || isr_bit1 || isr_bit2_0[2] || isr_bits4_3[3] || isr_bits4_3[4]; + `endif + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(1, 0) int_pin_sync + ( + .data_in (int_in), + .clk_out (wb_clk), + .sync_data_out (int_meta), + .async_reset (reset) + ) ; + always@(posedge wb_clk or posedge reset) + begin + if (reset) + interrupt_out <= 1'b0 ; + else + interrupt_out <= int_meta ; + end +`else // GUEST + `ifdef SYNCHRONEOUS_CLOCK_DOMAINS + assign int_in = isr_int_prop_bit || isr_bit2_0[1] || isr_bit2_0[2]; + `else // not SYNCHRONEOUS_CLOCK_DOMAINS + assign int_in = isr_int_prop_bit || isr_bit2_0[1] || isr_bit2; + `endif + // interemediate stage to clk synchronization flip - flops - this ones are prone to metastability + pci_synchronizer_flop #(1, 0) int_pin_sync + ( + .data_in (int_in), + .clk_out (pci_clk), + .sync_data_out (int_meta), + .async_reset (reset) + ) ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + interrupt_out <= 1'b0 ; + else + interrupt_out <= int_meta ; + end +`endif + + +`ifdef PCI_CPCI_HS_IMPLEMENT + reg [hs_es_cnt_width - 1:0] hs_es_cnt ; // debounce counter + reg hs_es_in_state, // current state of ejector switch input - synchronized + hs_es_sync, // synchronization flop for ejector switch input + hs_es_cur_state ; // current valid state of ejector switch + +`ifdef ACTIVE_HIGH_OE + wire oe_active_val = 1'b1 ; +`endif + +`ifdef ACTIVE_LOW_OE + wire oe_active_val = 1'b0 ; +`endif + + always@(posedge pci_clk or posedge reset) + begin + if (reset) + begin + hs_ins <= 1'b0 ; + hs_ins_armed <= 1'b1 ; + hs_ext <= 1'b0 ; + hs_ext_armed <= 1'b0 ; + hs_es_in_state <= 1'b0 ; + hs_es_sync <= 1'b0 ; + hs_es_cur_state <= 1'b0 ; + hs_es_cnt <= 'h0 ; + + `ifdef ACTIVE_LOW_OE + pci_cpci_hs_enum_oe_o <= 1'b1 ; + pci_cpci_hs_led_oe_o <= 1'b0 ; + `endif + + `ifdef ACTIVE_HIGH_OE + pci_cpci_hs_enum_oe_o <= 1'b0 ; + pci_cpci_hs_led_oe_o <= 1'b1 ; + `endif + + end + else + begin + // INS + if (hs_ins) + begin + if (w_conf_data[23] & ~w_byte_en[2] & w_we & w_reg_select_dec[56]) // clear + hs_ins <= 1'b0 ; + end + else if (hs_ins_armed) // set + hs_ins <= init_complete & (hs_es_cur_state == 1'b1) ; + + // INS armed + if (~hs_ins & hs_ins_armed & init_complete & (hs_es_cur_state == 1'b1)) // clear + hs_ins_armed <= 1'b0 ; + else if (hs_ext) // set + hs_ins_armed <= w_conf_data[22] & ~w_byte_en[2] & w_we & w_reg_select_dec[56] ; + + // EXT + if (hs_ext) // clear + begin + if (w_conf_data[22] & ~w_byte_en[2] & w_we & w_reg_select_dec[56]) + hs_ext <= 1'b0 ; + end + else if (hs_ext_armed) // set + hs_ext <= (hs_es_cur_state == 1'b0) ; + + // EXT armed + if (~hs_ext & hs_ext_armed & (hs_es_cur_state == 1'b0)) // clear + hs_ext_armed <= 1'b0 ; + else if (hs_ins) // set + hs_ext_armed <= w_conf_data[23] & !w_byte_en[2] & w_we & w_reg_select_dec[56] ; + + // ejector switch debounce counter logic + hs_es_sync <= pci_cpci_hs_es_i ; + hs_es_in_state <= hs_es_sync ; + + if (hs_es_in_state == hs_es_cur_state) + hs_es_cnt <= 'h0 ; + else + hs_es_cnt <= hs_es_cnt + 1'b1 ; + + if (hs_es_cnt == {hs_es_cnt_width{1'b1}}) + hs_es_cur_state <= hs_es_in_state ; + + if ((hs_ins | hs_ext) & ~hs_eim) + pci_cpci_hs_enum_oe_o <= oe_active_val ; + else + pci_cpci_hs_enum_oe_o <= ~oe_active_val ; + + if (~init_complete | hs_loo) + pci_cpci_hs_led_oe_o <= oe_active_val ; + else + pci_cpci_hs_led_oe_o <= ~oe_active_val ; + end + end +`endif + +`ifdef PCI_SPOCI + + wire spoci_write_done, + spoci_dat_rdy , + spoci_no_ack ; + + wire [ 7: 0] spoci_wdat ; + wire [ 7: 0] spoci_rdat ; + + // power on configuration control and status register + always@(posedge pci_clk or posedge reset) + begin + if (reset) + begin + spoci_cs_nack <= 1'b0 ; + spoci_cs_write <= 1'b0 ; + spoci_cs_read <= 1'b0 ; + spoci_cs_adr <= 'h0 ; + spoci_cs_dat <= 'h0 ; + end + else + begin + if (spoci_cs_write) + begin + if (spoci_write_done | spoci_no_ack) + spoci_cs_write <= 1'b0 ; + end + else if ( w_we & (w_conf_address[9:2] == 8'hFF) & ~w_byte_en[3]) + spoci_cs_write <= w_conf_data[25] ; + + if (spoci_cs_read) + begin + if (spoci_dat_rdy | spoci_no_ack) + spoci_cs_read <= 1'b0 ; + end + else if ( w_we & (w_conf_address[9:2] == 8'hFF) & ~w_byte_en[3] ) + spoci_cs_read <= w_conf_data[24] ; + + if (spoci_cs_nack) + begin + if ( w_we & (w_conf_address[9:2] == 8'hFF) & ~w_byte_en[3] & w_conf_data[31] ) + spoci_cs_nack <= 1'b0 ; + end + else if (spoci_cs_write | spoci_cs_read | ~init_cfg_done) + begin + spoci_cs_nack <= spoci_no_ack ; + end + + if ( w_we & (w_conf_address[9:2] == 8'hFF) ) + begin + if (~w_byte_en[2]) + spoci_cs_adr[10: 8] <= w_conf_data[18:16] ; + + if (~w_byte_en[1]) + spoci_cs_adr[ 7: 0] <= w_conf_data[15: 8] ; + end + + if ( w_we & (w_conf_address[9:2] == 8'hFF) & ~w_byte_en[0] ) + spoci_cs_dat <= w_conf_data[ 7: 0] ; + else if (spoci_cs_read & spoci_dat_rdy) + spoci_cs_dat <= spoci_rdat ; + + end + end + + reg [ 2 : 0] bytes_received ; + + always@(posedge pci_clk or posedge reset) + begin + if (reset) + begin + init_we <= 1'b0 ; + init_cfg_done <= 1'b0 ; + bytes_received <= 1'b0 ; + spoci_dat <= 'h0 ; + spoci_reg_num <= 'h0 ; + end + else if (~init_cfg_done) + begin + if (spoci_dat_rdy) + begin + case (bytes_received) + 'h0:spoci_reg_num <= spoci_rdat ; + 'h1:spoci_dat[ 7: 0] <= spoci_rdat ; + 'h2:spoci_dat[15: 8] <= spoci_rdat ; + 'h3:spoci_dat[23:16] <= spoci_rdat ; + 'h4:spoci_dat[31:24] <= spoci_rdat ; + default: + begin + spoci_dat <= 32'hxxxx_xxxx ; + spoci_reg_num <= 'hxx ; + end + endcase + end + + if (init_we) + bytes_received <= 'h0 ; + else if (spoci_dat_rdy) + bytes_received <= bytes_received + 1'b1 ; + + if (init_we) + init_we <= 1'b0 ; + else if (bytes_received == 'h5) + init_we <= 1'b1 ; + + if (spoci_no_ack | ((bytes_received == 'h1) & (spoci_reg_num == 'hff)) ) + init_cfg_done <= 1'b1 ; + end + end + + assign spoci_wdat = spoci_cs_dat ; + + pci_spoci_ctrl i_pci_spoci_ctrl + ( + .reset_i (reset ), + .clk_i (pci_clk ), + + .do_rnd_read_i (spoci_cs_read ), + .do_seq_read_i (rst_inactive & ~init_cfg_done ), + .do_write_i (spoci_cs_write ), + + .write_done_o (spoci_write_done ), + .dat_rdy_o (spoci_dat_rdy ), + .no_ack_o (spoci_no_ack ), + + .adr_i (spoci_cs_adr ), + .dat_i (spoci_wdat ), + .dat_o (spoci_rdat ), + + .pci_spoci_sda_i (spoci_sda_i ), + .pci_spoci_sda_oe_o (spoci_sda_oe_o ), + .pci_spoci_scl_oe_o (spoci_scl_oe_o ) + ); +`endif + +/*----------------------------------------------------------------------------------------------------------- + OUTPUTs from registers !!! +-----------------------------------------------------------------------------------------------------------*/ + +// if bridge is HOST then write clock is equal to WB clock, and synchronization of outputs has to be done +`ifdef HOST + wire [3:0] command_bits = {command_bit8, command_bit6, command_bit2_0[1:0]} ; + wire [3:0] meta_command_bits ; + reg [3:0] sync_command_bits ; + pci_synchronizer_flop #(4, 0) command_bits_sync + ( + .data_in (command_bits), + .clk_out (pci_clk), + .sync_data_out (meta_command_bits), + .async_reset (reset) + ) ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + sync_command_bits <= 4'b0 ; + else + sync_command_bits <= meta_command_bits ; + end + wire sync_command_bit8 = sync_command_bits[3] ; + wire sync_command_bit6 = sync_command_bits[2] ; + wire sync_command_bit1 = sync_command_bits[1] ; + wire sync_command_bit0 = sync_command_bits[0] ; + wire sync_command_bit2 = command_bit2_0[2] ; +`else // GUEST + wire command_bit = command_bit2_0[2] ; + wire meta_command_bit ; + reg sync_command_bit ; + pci_synchronizer_flop #(1, 0) command_bit_sync + ( + .data_in (command_bit), + .clk_out (pci_clk), + .sync_data_out (meta_command_bit), + .async_reset (reset) + ) ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + sync_command_bit <= 1'b0 ; + else + sync_command_bit <= meta_command_bit ; + end + wire sync_command_bit8 = command_bit8 ; + wire sync_command_bit6 = command_bit6 ; + wire sync_command_bit1 = command_bit2_0[1] ; + wire sync_command_bit0 = command_bit2_0[0] ; + wire sync_command_bit2 = sync_command_bit ; +`endif +// PCI header outputs from command register +assign serr_enable = sync_command_bit8 & pci_init_complete_out ; // to PCI clock +assign perr_response = sync_command_bit6 & pci_init_complete_out ; // to PCI clock +assign pci_master_enable = sync_command_bit2 & wb_init_complete_out ; // to WB clock +assign memory_space_enable = sync_command_bit1 & pci_init_complete_out ; // to PCI clock +assign io_space_enable = sync_command_bit0 & pci_init_complete_out ; // to PCI clock + +// if bridge is HOST then write clock is equal to WB clock, and synchronization of outputs has to be done + // We don't support cache line sizes smaller that 4 and it must have last two bits zero!!! +wire cache_lsize_not_zero = ((cache_line_size_reg[7] || cache_line_size_reg[6] || cache_line_size_reg[5] || + cache_line_size_reg[4] || cache_line_size_reg[3] || cache_line_size_reg[2]) && + (!cache_line_size_reg[1] && !cache_line_size_reg[0]) ); +`ifdef HOST + wire [7:2] cache_lsize_to_pci_bits = { cache_line_size_reg[7:2] } ; + wire [7:2] meta_cache_lsize_to_pci_bits ; + reg [7:2] sync_cache_lsize_to_pci_bits ; + pci_synchronizer_flop #(6, 0) cache_lsize_to_pci_bits_sync + ( + .data_in (cache_lsize_to_pci_bits), + .clk_out (pci_clk), + .sync_data_out (meta_cache_lsize_to_pci_bits), + .async_reset (reset) + ) ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + sync_cache_lsize_to_pci_bits <= 6'b0 ; + else + sync_cache_lsize_to_pci_bits <= meta_cache_lsize_to_pci_bits ; + end + wire [7:2] sync_cache_line_size_to_pci_reg = sync_cache_lsize_to_pci_bits[7:2] ; + wire [7:2] sync_cache_line_size_to_wb_reg = cache_line_size_reg[7:2] ; + wire sync_cache_lsize_not_zero_to_wb = cache_lsize_not_zero ; +// Latency timer is sinchronized only to PCI clock when bridge implementation is HOST + wire [7:0] latency_timer_bits = latency_timer ; + wire [7:0] meta_latency_timer_bits ; + reg [7:0] sync_latency_timer_bits ; + pci_synchronizer_flop #(8, 0) latency_timer_bits_sync + ( + .data_in (latency_timer_bits), + .clk_out (pci_clk), + .sync_data_out (meta_latency_timer_bits), + .async_reset (reset) + ) ; + always@(posedge pci_clk or posedge reset) + begin + if (reset) + sync_latency_timer_bits <= 8'b0 ; + else + sync_latency_timer_bits <= meta_latency_timer_bits ; + end + wire [7:0] sync_latency_timer = sync_latency_timer_bits ; +`else // GUEST + wire [8:2] cache_lsize_to_wb_bits = { cache_lsize_not_zero, cache_line_size_reg[7:2] } ; + wire [8:2] meta_cache_lsize_to_wb_bits ; + reg [8:2] sync_cache_lsize_to_wb_bits ; + pci_synchronizer_flop #(7, 0) cache_lsize_to_wb_bits_sync + ( + .data_in (cache_lsize_to_wb_bits), + .clk_out (wb_clk), + .sync_data_out (meta_cache_lsize_to_wb_bits), + .async_reset (reset) + ) ; + always@(posedge wb_clk or posedge reset) + begin + if (reset) + sync_cache_lsize_to_wb_bits <= 7'b0 ; + else + sync_cache_lsize_to_wb_bits <= meta_cache_lsize_to_wb_bits ; + end + wire [7:2] sync_cache_line_size_to_pci_reg = cache_line_size_reg[7:2] ; + wire [7:2] sync_cache_line_size_to_wb_reg = sync_cache_lsize_to_wb_bits[7:2] ; + wire sync_cache_lsize_not_zero_to_wb = sync_cache_lsize_to_wb_bits[8] ; +// Latency timer + wire [7:0] sync_latency_timer = latency_timer ; +`endif +// PCI header output from cache_line_size, latency timer and interrupt pin +assign cache_line_size_to_pci = {sync_cache_line_size_to_pci_reg, 2'h0} ; // [7 : 0] to PCI clock +assign cache_line_size_to_wb = {sync_cache_line_size_to_wb_reg, 2'h0} ; // [7 : 0] to WB clock +assign cache_lsize_not_zero_to_wb = sync_cache_lsize_not_zero_to_wb ; + +assign latency_tim[7 : 0] = sync_latency_timer ; // to PCI clock +//assign int_pin[2 : 0] = r_interrupt_pin ; +assign int_out = interrupt_out ; +// PCI output from image registers +// base address, address mask, translation address and control registers are sinchronized in PCI_DECODER.V module +`ifdef HOST + `ifdef NO_CNF_IMAGE + assign pci_base_addr0 = pci_ba0_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; + `else + assign pci_base_addr0 = pci_ba0_bit31_8[31:12] ; + `endif +`endif + +`ifdef GUEST + assign pci_base_addr0 = pci_ba0_bit31_8[31:12] ; +`endif + +assign pci_base_addr1 = pci_ba1_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_base_addr2 = pci_ba2_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_base_addr3 = pci_ba3_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_base_addr4 = pci_ba4_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_base_addr5 = pci_ba5_bit31_8[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_memory_io0 = pci_ba0_bit0 ; +assign pci_memory_io1 = pci_ba1_bit0 ; +assign pci_memory_io2 = pci_ba2_bit0 ; +assign pci_memory_io3 = pci_ba3_bit0 ; +assign pci_memory_io4 = pci_ba4_bit0 ; +assign pci_memory_io5 = pci_ba5_bit0 ; + +assign pci_addr_mask0 = pci_am0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_addr_mask1 = pci_am1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_addr_mask2 = pci_am2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_addr_mask3 = pci_am3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_addr_mask4 = pci_am4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_addr_mask5 = pci_am5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_tran_addr0 = pci_ta0[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_tran_addr1 = pci_ta1[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_tran_addr2 = pci_ta2[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_tran_addr3 = pci_ta3[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_tran_addr4 = pci_ta4[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_tran_addr5 = pci_ta5[31:(32-`PCI_NUM_OF_DEC_ADDR_LINES)] ; +assign pci_img_ctrl0[2 : 1] = pci_img_ctrl0_bit2_1 ; +assign pci_img_ctrl1[2 : 1] = pci_img_ctrl1_bit2_1 ; +assign pci_img_ctrl2[2 : 1] = pci_img_ctrl2_bit2_1 ; +assign pci_img_ctrl3[2 : 1] = pci_img_ctrl3_bit2_1 ; +assign pci_img_ctrl4[2 : 1] = pci_img_ctrl4_bit2_1 ; +assign pci_img_ctrl5[2 : 1] = pci_img_ctrl5_bit2_1 ; +// WISHBONE output from image registers +// base address, address mask, translation address and control registers are sinchronized in DECODER.V module +assign wb_base_addr0 = wb_ba0_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_base_addr1 = wb_ba1_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_base_addr2 = wb_ba2_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_base_addr3 = wb_ba3_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_base_addr4 = wb_ba4_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_base_addr5 = wb_ba5_bit31_12[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_memory_io0 = wb_ba0_bit0 ; +assign wb_memory_io1 = wb_ba1_bit0 ; +assign wb_memory_io2 = wb_ba2_bit0 ; +assign wb_memory_io3 = wb_ba3_bit0 ; +assign wb_memory_io4 = wb_ba4_bit0 ; +assign wb_memory_io5 = wb_ba5_bit0 ; +assign wb_addr_mask0 = wb_am0[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_addr_mask1 = wb_am1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_addr_mask2 = wb_am2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_addr_mask3 = wb_am3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_addr_mask4 = wb_am4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_addr_mask5 = wb_am5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_tran_addr0 = wb_ta0[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_tran_addr1 = wb_ta1[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_tran_addr2 = wb_ta2[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_tran_addr3 = wb_ta3[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_tran_addr4 = wb_ta4[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_tran_addr5 = wb_ta5[31:(32-`WB_NUM_OF_DEC_ADDR_LINES)] ; +assign wb_img_ctrl0[2 : 0] = wb_img_ctrl0_bit2_0 ; +assign wb_img_ctrl1[2 : 0] = wb_img_ctrl1_bit2_0 ; +assign wb_img_ctrl2[2 : 0] = wb_img_ctrl2_bit2_0 ; +assign wb_img_ctrl3[2 : 0] = wb_img_ctrl3_bit2_0 ; +assign wb_img_ctrl4[2 : 0] = wb_img_ctrl4_bit2_0 ; +assign wb_img_ctrl5[2 : 0] = wb_img_ctrl5_bit2_0 ; +// GENERAL output from conf. cycle generation register & int. control register +assign config_addr[23 : 0] = { cnf_addr_bit23_2, 1'b0, cnf_addr_bit0 } ; +assign icr_soft_res = icr_bit31 ; + +endmodule + diff --git a/ethernet/source/pci/pci_constants.v b/ethernet/source/pci/pci_constants.v new file mode 100644 index 0000000..73919ac --- /dev/null +++ b/ethernet/source/pci/pci_constants.v @@ -0,0 +1,173 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_constants.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// - Tadej Markovic (tadej@opencores.org) //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_constants.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.2 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// + +// first include user definable parameters +`ifdef REGRESSION // Used only for regression testing purposes!!! + `include "pci_regression_constants.v" +`else + `include "pci_user_constants.v" +`endif + +//////////////////////////////////////////////////////////////////////// +//// //// +//// FIFO parameters define behaviour of FIFO control logic and //// +//// FIFO depths. //// +//// //// +//////////////////////////////////////////////////////////////////////// +`define WBW_DEPTH (1 << `WBW_ADDR_LENGTH) +`define WBR_DEPTH (1 << `WBR_ADDR_LENGTH) +`define PCIW_DEPTH (1 << `PCIW_ADDR_LENGTH) +`define PCIR_DEPTH (1 << `PCIR_ADDR_LENGTH) + +// defines on which bit in control bus means what +`define ADDR_CTRL_BIT 3 +`define LAST_CTRL_BIT 0 +`define DATA_ERROR_CTRL_BIT 1 +`define UNUSED_CTRL_BIT 2 +`define BURST_BIT 2 + +// MAX Retry counter value for PCI Master state-machine +// This value is 8-bit because of 8-bit retry counter !!! +//`define PCI_RTY_CNT_MAX 8'h08 + +// Value of address mask for WB configuration image. This has to be defined always, since it is a value, that is not changable in runtime. +// !!!!!!!!!!!!!!!!!!!!!!!If this is not defined, WB configuration access will not be possible!!!!!!!!!!!!!!!!!!!!!1 +`define WB_AM0 20'hffff_f + +// PCI target & WB slave ADDRESS names for configuration space !!! +// This does not include address offsets of PCI Header registers - they starts at offset 0 (see PCI spec.) +// ALL VALUES are without 2 LSBits AND there is required that address bit [8] is set while +// accessing this registers, otherwise the configuration header will be accessed !!! +`define PCI_CAP_PTR_VAL 8'h80 +`define P_IMG_CTRL0_ADDR 6'h00 // Address offset = h 100 +`define P_BA0_ADDR 6'h01 // Address offset = h 104 +`define P_AM0_ADDR 6'h02 // Address offset = h 108 +`define P_TA0_ADDR 6'h03 // Address offset = h 10c +`define P_IMG_CTRL1_ADDR 6'h04 // Address offset = h 110 +`define P_BA1_ADDR 6'h05 // Address offset = h 114 +`define P_AM1_ADDR 6'h06 // Address offset = h 118 +`define P_TA1_ADDR 6'h07 // Address offset = h 11c +`define P_IMG_CTRL2_ADDR 6'h08 // Address offset = h 120 +`define P_BA2_ADDR 6'h09 // Address offset = h 124 +`define P_AM2_ADDR 6'h0a // Address offset = h 128 +`define P_TA2_ADDR 6'h0b // Address offset = h 12c +`define P_IMG_CTRL3_ADDR 6'h0c // Address offset = h 130 +`define P_BA3_ADDR 6'h0d // Address offset = h 134 +`define P_AM3_ADDR 6'h0e // Address offset = h 138 +`define P_TA3_ADDR 6'h0f // Address offset = h 13c +`define P_IMG_CTRL4_ADDR 6'h10 // Address offset = h 140 +`define P_BA4_ADDR 6'h11 // Address offset = h 144 +`define P_AM4_ADDR 6'h12 // Address offset = h 148 +`define P_TA4_ADDR 6'h13 // Address offset = h 14c +`define P_IMG_CTRL5_ADDR 6'h14 // Address offset = h 150 +`define P_BA5_ADDR 6'h15 // Address offset = h 154 +`define P_AM5_ADDR 6'h16 // Address offset = h 158 +`define P_TA5_ADDR 6'h17 // Address offset = h 15c +`define P_ERR_CS_ADDR 6'h18 // Address offset = h 160 +`define P_ERR_ADDR_ADDR 6'h19 // Address offset = h 164 +`define P_ERR_DATA_ADDR 6'h1a // Address offset = h 168 + +`define WB_CONF_SPC_BAR_ADDR 6'h20 // Address offset = h 180 +`define W_IMG_CTRL1_ADDR 6'h21 // Address offset = h 184 +`define W_BA1_ADDR 6'h22 // Address offset = h 188 +`define W_AM1_ADDR 6'h23 // Address offset = h 18c +`define W_TA1_ADDR 6'h24 // Address offset = h 190 +`define W_IMG_CTRL2_ADDR 6'h25 // Address offset = h 194 +`define W_BA2_ADDR 6'h26 // Address offset = h 198 +`define W_AM2_ADDR 6'h27 // Address offset = h 19c +`define W_TA2_ADDR 6'h28 // Address offset = h 1a0 +`define W_IMG_CTRL3_ADDR 6'h29 // Address offset = h 1a4 +`define W_BA3_ADDR 6'h2a // Address offset = h 1a8 +`define W_AM3_ADDR 6'h2b // Address offset = h 1ac +`define W_TA3_ADDR 6'h2c // Address offset = h 1b0 +`define W_IMG_CTRL4_ADDR 6'h2d // Address offset = h 1b4 +`define W_BA4_ADDR 6'h2e // Address offset = h 1b8 +`define W_AM4_ADDR 6'h2f // Address offset = h 1bc +`define W_TA4_ADDR 6'h30 // Address offset = h 1c0 +`define W_IMG_CTRL5_ADDR 6'h31 // Address offset = h 1c4 +`define W_BA5_ADDR 6'h32 // Address offset = h 1c8 +`define W_AM5_ADDR 6'h33 // Address offset = h 1cc +`define W_TA5_ADDR 6'h34 // Address offset = h 1d0 +`define W_ERR_CS_ADDR 6'h35 // Address offset = h 1d4 +`define W_ERR_ADDR_ADDR 6'h36 // Address offset = h 1d8 +`define W_ERR_DATA_ADDR 6'h37 // Address offset = h 1dc +`define CNF_ADDR_ADDR 6'h38 // Address offset = h 1e0 +// Following two registers are not implemented in a configuration space but in a WishBone unit! +`define CNF_DATA_ADDR 6'h39 // Address offset = h 1e4 +`define INT_ACK_ADDR 6'h3a // Address offset = h 1e8 +// ------------------------------------- +`define ICR_ADDR 6'h3b // Address offset = h 1ec +`define ISR_ADDR 6'h3c // Address offset = h 1f0 + +`ifdef PCI33 + `define HEADER_66MHz 1'b0 +`else +`ifdef PCI66 + `define HEADER_66MHz 1'b1 +`endif +`endif + +// all flip-flops in the design have this inter-assignment delay +`define FF_DELAY 1 + diff --git a/ethernet/source/pci/pci_cur_out_reg.v b/ethernet/source/pci/pci_cur_out_reg.v new file mode 100644 index 0000000..e95e2c4 --- /dev/null +++ b/ethernet/source/pci/pci_cur_out_reg.v @@ -0,0 +1,274 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "cur_out_reg.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_cur_out_reg.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "pci_constants.v" + +// module is only a backup copy of relevant output registers +// used in some arhitectures that support IOB registers, which have to have a +// fanout of 1 +// Otherwise nothing special in this module +module pci_cur_out_reg +( + reset_in, + clk_in, + frame_in, + frame_load_in, + irdy_in, + devsel_in, + trdy_in, + trdy_en_in, + stop_in, + ad_load_in, + cbe_in, + cbe_en_in, + mas_ad_in, + tar_ad_in, + frame_en_in, + irdy_en_in, + + mas_ad_en_in, + tar_ad_en_in, + ad_en_unregistered_in, + + par_in, + par_en_in, + perr_in, + perr_en_in, + serr_in, + serr_en_in, + + frame_out, + irdy_out, + devsel_out, + trdy_out, + stop_out, + cbe_out, + cbe_en_out, + ad_out, + frame_en_out, + irdy_en_out, + ad_en_out, + mas_ad_en_out, + tar_ad_en_out, + trdy_en_out, + + par_out, + par_en_out, + perr_out, + perr_en_out, + serr_out, + serr_en_out +) ; + +input reset_in, clk_in ; + +input frame_in ; +input frame_load_in ; +input irdy_in ; +input devsel_in ; +input trdy_in ; +input stop_in ; +input ad_load_in ; + +input [3:0] cbe_in ; +input cbe_en_in ; +input [31:0] mas_ad_in ; +input [31:0] tar_ad_in ; + +input mas_ad_en_in ; +input tar_ad_en_in ; +input ad_en_unregistered_in ; + +input frame_en_in, + irdy_en_in ; + +input trdy_en_in ; + +input par_in ; +input par_en_in ; +input perr_in ; +input perr_en_in ; +input serr_in ; +input serr_en_in ; + +output frame_out ; +reg frame_out ; +output irdy_out ; +reg irdy_out ; +output devsel_out ; +reg devsel_out ; +output trdy_out ; +reg trdy_out ; +output stop_out ; +reg stop_out ; +output [3:0] cbe_out ; +reg [3:0] cbe_out ; +output [31:0] ad_out ; +reg [31:0] ad_out ; + +output frame_en_out, + irdy_en_out, + ad_en_out, + cbe_en_out, + mas_ad_en_out, + tar_ad_en_out, + trdy_en_out ; + +reg frame_en_out, + irdy_en_out, + cbe_en_out, + mas_ad_en_out, + tar_ad_en_out, + trdy_en_out; + +output par_out ; +output par_en_out ; +output perr_out ; +output perr_en_out ; +output serr_out ; +output serr_en_out ; + +reg par_out ; +reg par_en_out ; +reg perr_out ; +reg perr_en_out ; +reg serr_out ; +reg serr_en_out ; + +assign ad_en_out = mas_ad_en_out || tar_ad_en_out ; + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + begin + irdy_out <= #`FF_DELAY 1'b1 ; + devsel_out <= #`FF_DELAY 1'b1 ; + trdy_out <= #`FF_DELAY 1'b1 ; + stop_out <= #`FF_DELAY 1'b1 ; + frame_en_out <= #`FF_DELAY 1'b0 ; + irdy_en_out <= #`FF_DELAY 1'b0 ; + mas_ad_en_out<= #`FF_DELAY 1'b0 ; + tar_ad_en_out<= #`FF_DELAY 1'b0 ; + trdy_en_out <= #`FF_DELAY 1'b0 ; + par_out <= #`FF_DELAY 1'b0 ; + par_en_out <= #`FF_DELAY 1'b0 ; + perr_out <= #`FF_DELAY 1'b1 ; + perr_en_out <= #`FF_DELAY 1'b0 ; + serr_out <= #`FF_DELAY 1'b1 ; + serr_en_out <= #`FF_DELAY 1'b0 ; + cbe_en_out <= #`FF_DELAY 1'b0 ; + + end + else + begin + irdy_out <= #`FF_DELAY irdy_in ; + devsel_out <= #`FF_DELAY devsel_in ; + trdy_out <= #`FF_DELAY trdy_in ; + stop_out <= #`FF_DELAY stop_in ; + frame_en_out <= #`FF_DELAY frame_en_in ; + irdy_en_out <= #`FF_DELAY irdy_en_in ; + mas_ad_en_out<= #`FF_DELAY mas_ad_en_in && ad_en_unregistered_in ; + tar_ad_en_out<= #`FF_DELAY tar_ad_en_in && ad_en_unregistered_in ; + trdy_en_out <= #`FF_DELAY trdy_en_in ; + + par_out <= #`FF_DELAY par_in ; + par_en_out <= #`FF_DELAY par_en_in ; + perr_out <= #`FF_DELAY perr_in ; + perr_en_out <= #`FF_DELAY perr_en_in ; + serr_out <= #`FF_DELAY serr_in ; + serr_en_out <= #`FF_DELAY serr_en_in ; + cbe_en_out <= #`FF_DELAY cbe_en_in ; + end +end + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + cbe_out <= #`FF_DELAY 4'hF ; + else if ( ad_load_in ) + cbe_out <= #`FF_DELAY cbe_in ; + +end + +wire [31:0] ad_source = tar_ad_en_out ? tar_ad_in : mas_ad_in ; + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + ad_out <= #`FF_DELAY 32'h0000_0000 ; + else if ( ad_load_in ) + ad_out <= #`FF_DELAY ad_source ; + +end + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + frame_out <= #`FF_DELAY 1'b1 ; + else if ( frame_load_in ) + frame_out <= #`FF_DELAY frame_in ; + +end + +endmodule diff --git a/ethernet/source/pci/pci_delayed_sync.v b/ethernet/source/pci/pci_delayed_sync.v new file mode 100644 index 0000000..266e89a --- /dev/null +++ b/ethernet/source/pci/pci_delayed_sync.v @@ -0,0 +1,472 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "delayed_sync.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_delayed_sync.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.3 2003/08/14 13:06:02 simons +// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. +// +// Revision 1.2 2003/03/26 13:16:18 mihad +// Added the reset value parameter to the synchronizer flop module. +// Added resets to all synchronizer flop instances. +// Repaired initial sync value in fifos. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.5 2002/09/25 09:54:50 mihad +// Added completion expiration test for WB Slave unit. Changed expiration signalling +// +// Revision 1.4 2002/03/05 11:53:47 mihad +// Added some testcases, removed un-needed fifo signals +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module provides synchronization mechanism between requesting and completing side of the bridge +`include "pci_constants.v" +`include "bus_commands.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_delayed_sync +( + reset_in, + req_clk_in, + comp_clk_in, + req_in, + comp_in, + done_in, + in_progress_in, + comp_req_pending_out, + req_req_pending_out, + req_comp_pending_out, + comp_comp_pending_out, + addr_in, + be_in, + addr_out, + be_out, + we_in, + we_out, + bc_in, + bc_out, + status_in, + status_out, + comp_flush_out, + burst_in, + burst_out, + retry_expired_in +); + +// system inputs +input reset_in, // reset input + req_clk_in, // requesting clock input + comp_clk_in ; // completing clock input + +// request, completion, done and in progress indication inputs +input req_in, // request qualifier - when 1 it indicates that valid request data is provided on inputs + comp_in, // completion qualifier - when 1, completing side indicates that request has completed + done_in, // done input - when 1 indicates that requesting side of the bridge has completed a transaction on requesting bus + in_progress_in ; // in progress indicator - indicates that current completion is in progress on requesting side of the bridge + +// pending indication outputs +output comp_req_pending_out, // completion side request output - resynchronized from requesting clock to completing clock + req_req_pending_out, // request pending output for requesting side + req_comp_pending_out, // completion pending output for requesting side of the bridge - it indicates when completion is ready for completing on requesting bus + comp_comp_pending_out ; // completion pending output for completing side of the bridge + +// additional signals and wires for clock domain passage of signals +reg comp_req_pending, + req_req_pending, + req_comp_pending, + req_comp_pending_sample, + comp_comp_pending, + req_done_reg, + comp_done_reg_main, + comp_done_reg_clr, + req_rty_exp_reg, + req_rty_exp_clr, + comp_rty_exp_reg, + comp_rty_exp_clr ; + +wire sync_comp_req_pending, + sync_req_comp_pending, + sync_comp_done, + sync_req_rty_exp, + sync_comp_rty_exp_clr ; + +// inputs from requesting side - only this side can set address, bus command, byte enables, write enable and burst - outputs are common for both sides +// all signals that identify requests are stored in this module + +input [31:0] addr_in ; // address bus input +input [3:0] be_in ; // byte enable input +input we_in ; // write enable input - read/write request indication 1 = write request / 0 = read request +input [3:0] bc_in ; // bus command input +input burst_in ; // burst indicator - qualifies operation as burst/single transfer 1 = burst / 0 = single transfer + +// common request outputs used both by completing and requesting sides +// this outputs are not resynchronized, since flags determine the request status +output [31:0] addr_out ; +output [3:0] be_out ; +output we_out ; +output [3:0] bc_out ; +output burst_out ; + +// completion side signals encoded termination status - 0 = normal completion / 1 = error terminated completion +input status_in ; +output status_out ; + +// input signals that delayed transaction has been retried for max number of times +// on this signal request is ditched, otherwise it would cause a deadlock +// requestor can issue another request and procedure will be repeated +input retry_expired_in ; + +// completion flush output - if in 2^^16 clock cycles transaction is not repeated by requesting agent - flush completion data +output comp_flush_out ; + +// output registers for common signals +reg [31:0] addr_out ; +reg [3:0] be_out ; +reg we_out ; +reg [3:0] bc_out ; +reg burst_out ; + +// delayed transaction information is stored only when request is issued and request nor completion are pending +wire new_request = req_in && ~req_comp_pending_out && ~req_req_pending_out ; +always@(posedge req_clk_in or posedge reset_in) +begin + if (reset_in) + begin + addr_out <= #`FF_DELAY 32'h0000_0000 ; + be_out <= #`FF_DELAY 4'h0 ; + we_out <= #`FF_DELAY 1'b0 ; + bc_out <= #`FF_DELAY `BC_RESERVED0 ; + burst_out <= #`FF_DELAY 1'b0 ; + end + else + if (new_request) + begin + addr_out <= #`FF_DELAY addr_in ; + be_out <= #`FF_DELAY be_in ; + we_out <= #`FF_DELAY we_in ; + bc_out <= #`FF_DELAY bc_in ; + burst_out <= #`FF_DELAY burst_in ; + end +end + +// completion pending cycle counter +reg [16:0] comp_cycle_count ; + +/*================================================================================================================================= +Passing of requests between clock domains: +request originates on requesting side. It's then synchronized with two flip-flops to cross to completing clock domain +=================================================================================================================================*/ +// main request flip-flop triggered on requesting side's clock +// request is cleared whenever completion or retry expired is signalled from opposite side of the bridge +wire req_req_clear = req_comp_pending || (req_rty_exp_reg && ~req_rty_exp_clr) ; +always@(posedge req_clk_in or posedge reset_in) +begin + if ( reset_in ) + req_req_pending <= #`FF_DELAY 1'b0 ; + else + if ( req_req_clear ) + req_req_pending <= #`FF_DELAY 1'b0 ; + else + if ( req_in ) + req_req_pending <= #`FF_DELAY 1'b1 ; +end + +// interemediate stage request synchronization flip - flop - this one is prone to metastability +// and should have setup and hold times disabled during simulation +pci_synchronizer_flop #(1, 0) req_sync +( + .data_in (req_req_pending), + .clk_out (comp_clk_in), + .sync_data_out (sync_comp_req_pending), + .async_reset (reset_in) +) ; + +// wire for clearing completion side request flag - whenever completion or retry expired are signalled +wire comp_req_pending_clear = comp_req_pending && ( comp_in || retry_expired_in) ; + +// wire for enabling request flip - flop - it is enabled when completion is not active and done is not active +wire comp_req_pending_ena = ~comp_comp_pending && ~comp_done_reg_main && ~comp_rty_exp_reg ; + +// completion side request flip flop - gets a value from intermediate stage sync flip flop +always@(posedge comp_clk_in or posedge reset_in) +begin + if ( reset_in ) + comp_req_pending <= #`FF_DELAY 1'b0 ; + else + if ( comp_req_pending_clear ) + comp_req_pending <= #`FF_DELAY 1'b0 ; + else + if ( comp_req_pending_ena ) + comp_req_pending <= #`FF_DELAY sync_comp_req_pending ; +end + +// completion side request output assignment - when request ff is set and completion ff is not set +assign comp_req_pending_out = comp_req_pending ; + +// requesting side request pending output +assign req_req_pending_out = req_req_pending ; +/*================================================================================================================================= +Passing of completions between clock domains: +completion originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain +=================================================================================================================================*/ +// main completion Flip - Flop - triggered by completing side's clock +// completion side completion pending flag is cleared when done flag propagates through clock domains +wire comp_comp_clear = comp_done_reg_main && ~comp_done_reg_clr ; +always@(posedge comp_clk_in or posedge reset_in) +begin + if ( reset_in ) + comp_comp_pending <= #`FF_DELAY 1'b0 ; + else + if ( comp_comp_clear ) + comp_comp_pending <= #`FF_DELAY 1'b0 ; + else + if ( comp_in && comp_req_pending ) + comp_comp_pending <= #`FF_DELAY 1'b1 ; +end + +assign comp_comp_pending_out = comp_comp_pending ; + +// interemediate stage completion synchronization flip - flop - this one is prone to metastability +pci_synchronizer_flop #(1, 0) comp_sync +( + .data_in (comp_comp_pending), + .clk_out (req_clk_in), + .sync_data_out (sync_req_comp_pending), + .async_reset (reset_in) +) ; + +// request side completion pending flip flop is cleared whenever done is signalled or completion counter expires - 2^^16 clock cycles +wire req_comp_pending_clear = done_in || comp_cycle_count[16]; + +// request side completion pending flip flop is disabled while done flag is set +wire req_comp_pending_ena = ~req_done_reg ; + +// request side completion flip flop - gets a value from intermediate stage sync flip flop +always@(posedge req_clk_in or posedge reset_in) +begin + if ( reset_in ) + req_comp_pending <= #`FF_DELAY 1'b0 ; + else + if ( req_comp_pending_clear ) + req_comp_pending <= #`FF_DELAY 1'b0 ; + else + if ( req_comp_pending_ena ) + req_comp_pending <= #`FF_DELAY sync_req_comp_pending ; +end + +// sampling FF - used for sampling incoming completion flag from completing side +always@(posedge req_clk_in or posedge reset_in) +begin + if ( reset_in ) + req_comp_pending_sample <= #`FF_DELAY 1'b0 ; + else + req_comp_pending_sample <= #`FF_DELAY sync_req_comp_pending ; +end + +// requesting side completion pending output assignment +assign req_comp_pending_out = req_comp_pending && ~req_req_pending ; + +/*================================================================================================================================== +Passing of delayed transaction done signal between clock domains. +Done is signalled by requesting side of the bridge and is passed to completing side of the bridge +==================================================================================================================================*/ +// main done flip-flop triggered on requesting side's clock +// when completing side removes completion flag, done flag is also removed, so requests can proceede +wire req_done_clear = ~req_comp_pending_sample ; +always@(posedge req_clk_in or posedge reset_in) +begin + if ( reset_in ) + req_done_reg <= #`FF_DELAY 1'b0 ; + else + if ( req_done_clear ) + req_done_reg <= #`FF_DELAY 1'b0 ; + else + if ( done_in || comp_cycle_count[16] ) + req_done_reg <= #`FF_DELAY 1'b1 ; +end + +pci_synchronizer_flop #(1, 0) done_sync +( + .data_in (req_done_reg), + .clk_out (comp_clk_in), + .sync_data_out (sync_comp_done), + .async_reset (reset_in) +) ; + +always@(posedge comp_clk_in or posedge reset_in) +begin + if ( reset_in ) + comp_done_reg_main <= #`FF_DELAY 1'b0 ; + else + comp_done_reg_main <= #`FF_DELAY sync_comp_done ; +end + +always@(posedge comp_clk_in or posedge reset_in) +begin + if ( reset_in ) + comp_done_reg_clr <= #`FF_DELAY 1'b0 ; + else + comp_done_reg_clr <= #`FF_DELAY comp_done_reg_main ; +end + +/*================================================================================================================================= +Passing of retry expired signal between clock domains +Retry expiration originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain +=================================================================================================================================*/ +// main retry expired Flip - Flop - triggered by completing side's clock +wire comp_rty_exp_clear = comp_rty_exp_clr && comp_rty_exp_reg ; + +// retry expired is a special case of transaction removal - retry expired propagates from completing +// clock domain to requesting clock domain to remove all pending requests and than propagates back +// to completing side to qualify valid new requests + +always@(posedge comp_clk_in or posedge reset_in) +begin + if ( reset_in ) + comp_rty_exp_reg <= #`FF_DELAY 1'b0 ; + else + if ( comp_rty_exp_clear ) + comp_rty_exp_reg <= #`FF_DELAY 1'b0 ; + else + if ( retry_expired_in && comp_req_pending) + comp_rty_exp_reg <= #`FF_DELAY 1'b1 ; +end + +// interemediate stage retry expired synchronization flip - flop - this one is prone to metastability +pci_synchronizer_flop #(1, 0) rty_exp_sync +( + .data_in (comp_rty_exp_reg), + .clk_out (req_clk_in), + .sync_data_out (sync_req_rty_exp), + .async_reset (reset_in) +) ; + +// request retry expired flip flop - gets a value from intermediate stage sync flip flop +always@(posedge req_clk_in or posedge reset_in) +begin + if ( reset_in ) + req_rty_exp_reg <= #`FF_DELAY 1'b0 ; + else + req_rty_exp_reg <= #`FF_DELAY sync_req_rty_exp ; +end + +always@(posedge req_clk_in or posedge reset_in) +begin + if ( reset_in ) + req_rty_exp_clr <= #`FF_DELAY 1'b0 ; + else + req_rty_exp_clr <= #`FF_DELAY req_rty_exp_reg ; +end + +pci_synchronizer_flop #(1, 0) rty_exp_back_prop_sync +( + .data_in (req_rty_exp_reg && req_rty_exp_clr), + .clk_out (comp_clk_in), + .sync_data_out (sync_comp_rty_exp_clr), + .async_reset (reset_in) +) ; + +always@(posedge comp_clk_in or posedge reset_in) +begin + if ( reset_in ) + comp_rty_exp_clr <= #`FF_DELAY 1'b0 ; + else + comp_rty_exp_clr <= #`FF_DELAY sync_comp_rty_exp_clr ; +end + +// completion status flip flop - if 0 when completion is signalled it's finished OK otherwise it means error +reg status_out ; +always@(posedge comp_clk_in or posedge reset_in) +begin + if (reset_in) + status_out <= #`FF_DELAY 1'b0 ; + else + if (comp_in && comp_req_pending) + status_out <= #`FF_DELAY status_in ; +end + +// clocks counter - it counts how many clock cycles completion is present without beeing repeated +// if it counts to 2^^16 cycles the completion must be ditched + +// wire for clearing this counter +wire clear_count = in_progress_in || ~req_comp_pending_out || comp_cycle_count[16] ; +always@(posedge req_clk_in or posedge reset_in) +begin + if (reset_in) + comp_cycle_count <= #`FF_DELAY 17'h0_0000 ; + else + if (clear_count) + comp_cycle_count <= #`FF_DELAY 17'h0_0000 ; + else + comp_cycle_count <= #`FF_DELAY comp_cycle_count + 1'b1 ; +end + +// completion flush output - used for flushing fifos when counter expires +// if counter doesn't expire, fifo flush is up to WISHBONE slave or PCI target state machines +reg comp_flush_out ; +always@(posedge req_clk_in or posedge reset_in) +begin + if (reset_in) + comp_flush_out <= #`FF_DELAY 1'b0 ; + else + comp_flush_out <= #`FF_DELAY comp_cycle_count[16] ; +end + +endmodule //delayed_sync diff --git a/ethernet/source/pci/pci_delayed_write_reg.v b/ethernet/source/pci/pci_delayed_write_reg.v new file mode 100644 index 0000000..d9c150e --- /dev/null +++ b/ethernet/source/pci/pci_delayed_write_reg.v @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "delayed_write_reg.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_delayed_write_reg.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_delayed_write_reg +( + reset_in, + req_clk_in, + comp_wdata_out, + req_we_in, + req_wdata_in +); + +// system inputs +input reset_in, + req_clk_in ; // request clock input + +output [31:0] comp_wdata_out ; // data output + +input req_we_in ; // write enable input +input [31:0] req_wdata_in ; // data input - latched with posedge of req_clk_in when req_we_in is high + +reg [31:0] comp_wdata_out ; + +// write request operation +always@(posedge req_clk_in or posedge reset_in) +begin + if (reset_in) + comp_wdata_out <= #`FF_DELAY 32'h0000_0000 ; + else + if (req_we_in) + comp_wdata_out <= #`FF_DELAY req_wdata_in ; +end + +endmodule // DELAYED_WRITE_REG diff --git a/ethernet/source/pci/pci_frame_crit.v b/ethernet/source/pci/pci_frame_crit.v new file mode 100644 index 0000000..2883066 --- /dev/null +++ b/ethernet/source/pci/pci_frame_crit.v @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "frame_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_frame_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// this one is used in master state machine for driving correct value of frame output + +module pci_frame_crit +( + pci_frame_out, + force_frame_in, + slow_frame_in, + pci_stop_in +) ; + +output pci_frame_out ; +input force_frame_in, + slow_frame_in, + pci_stop_in ; + +assign pci_frame_out = force_frame_in && (slow_frame_in || ~pci_stop_in) ; + +endmodule diff --git a/ethernet/source/pci/pci_frame_en_crit.v b/ethernet/source/pci/pci_frame_en_crit.v new file mode 100644 index 0000000..6f9bfff --- /dev/null +++ b/ethernet/source/pci/pci_frame_en_crit.v @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "frame_en_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_frame_en_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// This one is used in master state machine for frame output enable driving + +module pci_frame_en_crit +( + pci_frame_en_out, + frame_en_slow_in, + frame_en_keep_in, + pci_stop_in, + pci_trdy_in +) ; + +output pci_frame_en_out ; +input frame_en_slow_in, + frame_en_keep_in, + pci_stop_in, + pci_trdy_in ; + +assign pci_frame_en_out = frame_en_slow_in || frame_en_keep_in && pci_stop_in && pci_trdy_in ; + +endmodule diff --git a/ethernet/source/pci/pci_frame_load_crit.v b/ethernet/source/pci/pci_frame_load_crit.v new file mode 100644 index 0000000..24d8832 --- /dev/null +++ b/ethernet/source/pci/pci_frame_load_crit.v @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "frame_load_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_frame_load_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// This one is used in master state machine for frame output flip flop clock enable driving +module pci_frame_load_crit +( + pci_frame_load_out, + sm_data_phases_in, + frame_load_slow_in, + pci_trdy_in, + pci_stop_in +) ; + +output pci_frame_load_out ; +input sm_data_phases_in, + frame_load_slow_in, + pci_trdy_in, + pci_stop_in ; + +assign pci_frame_load_out = frame_load_slow_in || sm_data_phases_in && (~(pci_trdy_in && pci_stop_in)) ; + +endmodule diff --git a/ethernet/source/pci/pci_in_reg.v b/ethernet/source/pci/pci_in_reg.v new file mode 100644 index 0000000..e6f3186 --- /dev/null +++ b/ethernet/source/pci/pci_in_reg.v @@ -0,0 +1,163 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_in_reg.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_in_reg.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.5 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.4 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:29 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "pci_constants.v" +// Module is used for registering PCI input signals +// It provides data flip flops with reset +module pci_in_reg +( + reset_in, + clk_in, + init_complete_in, + + pci_gnt_in, + pci_frame_in, + pci_irdy_in, + pci_trdy_in, + pci_stop_in, + pci_devsel_in, + pci_idsel_in, + pci_ad_in, + pci_cbe_in, + + pci_gnt_reg_out, + pci_frame_reg_out, + pci_irdy_reg_out, + pci_trdy_reg_out, + pci_stop_reg_out, + pci_devsel_reg_out, + pci_idsel_reg_out, + pci_ad_reg_out, + pci_cbe_reg_out + +); + +input reset_in, clk_in, init_complete_in ; + +input pci_gnt_in ; +input pci_frame_in ; +input pci_irdy_in ; +input pci_trdy_in ; +input pci_stop_in ; +input pci_devsel_in ; +input pci_idsel_in ; +input [31:0] pci_ad_in ; +input [3:0] pci_cbe_in ; + +output pci_gnt_reg_out ; +output pci_frame_reg_out ; +output pci_irdy_reg_out ; +output pci_trdy_reg_out ; +output pci_stop_reg_out ; +output pci_devsel_reg_out ; +output pci_idsel_reg_out ; +output [31:0] pci_ad_reg_out ; +output [3:0] pci_cbe_reg_out ; + + +reg pci_gnt_reg_out ; +reg pci_frame_reg_out ; +reg pci_irdy_reg_out ; +reg pci_trdy_reg_out ; +reg pci_stop_reg_out ; +reg pci_devsel_reg_out ; +reg pci_idsel_reg_out ; +reg [31:0] pci_ad_reg_out ; +reg [3:0] pci_cbe_reg_out ; + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + begin + pci_gnt_reg_out <= #`FF_DELAY 1'b1 ; + pci_frame_reg_out <= #`FF_DELAY 1'b0 ; + pci_irdy_reg_out <= #`FF_DELAY 1'b1 ; + pci_trdy_reg_out <= #`FF_DELAY 1'b1 ; + pci_stop_reg_out <= #`FF_DELAY 1'b1 ; + pci_devsel_reg_out <= #`FF_DELAY 1'b1 ; + pci_idsel_reg_out <= #`FF_DELAY 1'b0 ; // active high! + pci_ad_reg_out <= #`FF_DELAY 32'h0000_0000 ; + pci_cbe_reg_out <= #`FF_DELAY 4'h0 ; + end + else if (init_complete_in) + begin + pci_gnt_reg_out <= #`FF_DELAY pci_gnt_in ; + pci_frame_reg_out <= #`FF_DELAY pci_frame_in ; + pci_irdy_reg_out <= #`FF_DELAY pci_irdy_in ; + pci_trdy_reg_out <= #`FF_DELAY pci_trdy_in ; + pci_stop_reg_out <= #`FF_DELAY pci_stop_in ; + pci_devsel_reg_out <= #`FF_DELAY pci_devsel_in ; + pci_idsel_reg_out <= #`FF_DELAY pci_idsel_in ; + pci_ad_reg_out <= #`FF_DELAY pci_ad_in ; + pci_cbe_reg_out <= #`FF_DELAY pci_cbe_in ; + end +end + +endmodule diff --git a/ethernet/source/pci/pci_io_mux.v b/ethernet/source/pci/pci_io_mux.v new file mode 100644 index 0000000..b4790ea --- /dev/null +++ b/ethernet/source/pci/pci_io_mux.v @@ -0,0 +1,858 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_io_mux.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_io_mux.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.5 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.4 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:29 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// this module instantiates output flip flops for PCI interface and +// some fanout downsizing logic because of heavily constrained PCI signals + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_io_mux +( + reset_in, + clk_in, + frame_in, + frame_en_in, + frame_load_in, + irdy_in, + irdy_en_in, + devsel_in, + devsel_en_in, + trdy_in, + trdy_en_in, + stop_in, + stop_en_in, + master_load_in, + master_load_on_transfer_in, + target_load_in, + target_load_on_transfer_in, + cbe_in, + cbe_en_in, + mas_ad_in, + tar_ad_in, + + par_in, + par_en_in, + perr_in, + perr_en_in, + serr_in, + serr_en_in, + + req_in, + + mas_ad_en_in, + tar_ad_en_in, + tar_ad_en_reg_in, + + ad_en_out, + frame_en_out, + irdy_en_out, + devsel_en_out, + trdy_en_out, + stop_en_out, + cbe_en_out, + + frame_out, + irdy_out, + devsel_out, + trdy_out, + stop_out, + cbe_out, + ad_out, + ad_load_out, + ad_en_unregistered_out, + + par_out, + par_en_out, + perr_out, + perr_en_out, + serr_out, + serr_en_out, + + req_out, + req_en_out, + pci_trdy_in, + pci_irdy_in, + pci_frame_in, + pci_stop_in, + + init_complete_in +); + +input reset_in, clk_in ; + +input frame_in ; +input frame_en_in ; +input frame_load_in ; +input irdy_in ; +input irdy_en_in ; +input devsel_in ; +input devsel_en_in ; +input trdy_in ; +input trdy_en_in ; +input stop_in ; +input stop_en_in ; +input master_load_in ; +input target_load_in ; + +input [3:0] cbe_in ; +input cbe_en_in ; +input [31:0] mas_ad_in ; +input [31:0] tar_ad_in ; + +input mas_ad_en_in ; +input tar_ad_en_in ; +input tar_ad_en_reg_in ; + +input par_in ; +input par_en_in ; +input perr_in ; +input perr_en_in ; +input serr_in ; +input serr_en_in ; + +output frame_en_out ; +output irdy_en_out ; +output devsel_en_out ; +output trdy_en_out ; +output stop_en_out ; +output [31:0] ad_en_out ; +output [3:0] cbe_en_out ; + +output frame_out ; +output irdy_out ; +output devsel_out ; +output trdy_out ; +output stop_out ; +output [3:0] cbe_out ; +output [31:0] ad_out ; +output ad_load_out ; +output ad_en_unregistered_out ; + +output par_out ; +output par_en_out ; +output perr_out ; +output perr_en_out ; +output serr_out ; +output serr_en_out ; + +input req_in ; + +output req_out ; +output req_en_out ; + +input pci_trdy_in, + pci_irdy_in, + pci_frame_in, + pci_stop_in ; + +input master_load_on_transfer_in ; +input target_load_on_transfer_in ; + +input init_complete_in ; + +wire [31:0] temp_ad = tar_ad_en_reg_in ? tar_ad_in : mas_ad_in ; + +wire ad_en_ctrl_low ; + +wire ad_en_ctrl_mlow ; + +wire ad_en_ctrl_mhigh ; + +wire ad_en_ctrl_high ; + +wire ad_enable_internal = mas_ad_en_in || tar_ad_en_in ; + +pci_io_mux_ad_en_crit ad_en_low_gen +( + .ad_en_in (ad_enable_internal), + .pci_frame_in (pci_frame_in), + .pci_trdy_in (pci_trdy_in), + .pci_stop_in (pci_stop_in), + .ad_en_out (ad_en_ctrl_low) +); + +pci_io_mux_ad_en_crit ad_en_mlow_gen +( + .ad_en_in (ad_enable_internal), + .pci_frame_in (pci_frame_in), + .pci_trdy_in (pci_trdy_in), + .pci_stop_in (pci_stop_in), + .ad_en_out (ad_en_ctrl_mlow) +); + +pci_io_mux_ad_en_crit ad_en_mhigh_gen +( + .ad_en_in (ad_enable_internal), + .pci_frame_in (pci_frame_in), + .pci_trdy_in (pci_trdy_in), + .pci_stop_in (pci_stop_in), + .ad_en_out (ad_en_ctrl_mhigh) +); + +pci_io_mux_ad_en_crit ad_en_high_gen +( + .ad_en_in (ad_enable_internal), + .pci_frame_in (pci_frame_in), + .pci_trdy_in (pci_trdy_in), + .pci_stop_in (pci_stop_in), + .ad_en_out (ad_en_ctrl_high) +); + +assign ad_en_unregistered_out = ad_en_ctrl_high ; + +wire load = master_load_in || target_load_in ; +wire load_on_transfer = master_load_on_transfer_in || target_load_on_transfer_in ; + +wire ad_load_ctrl_low ; +wire ad_load_ctrl_mlow ; +wire ad_load_ctrl_mhigh ; +wire ad_load_ctrl_high ; + +assign ad_load_out = ad_load_ctrl_high ; + +pci_io_mux_ad_load_crit ad_load_low_gen +( + .load_in(load), + .load_on_transfer_in(load_on_transfer), + .pci_irdy_in(pci_irdy_in), + .pci_trdy_in(pci_trdy_in), + .load_out(ad_load_ctrl_low) +); + +pci_io_mux_ad_load_crit ad_load_mlow_gen +( + .load_in(load), + .load_on_transfer_in(load_on_transfer), + .pci_irdy_in(pci_irdy_in), + .pci_trdy_in(pci_trdy_in), + .load_out(ad_load_ctrl_mlow) +); + +pci_io_mux_ad_load_crit ad_load_mhigh_gen +( + .load_in(load), + .load_on_transfer_in(load_on_transfer), + .pci_irdy_in(pci_irdy_in), + .pci_trdy_in(pci_trdy_in), + .load_out(ad_load_ctrl_mhigh) +); + +pci_io_mux_ad_load_crit ad_load_high_gen +( + .load_in(load), + .load_on_transfer_in(load_on_transfer), + .pci_irdy_in(pci_irdy_in), + .pci_trdy_in(pci_trdy_in), + .load_out(ad_load_ctrl_high) +); + +pci_out_reg ad_iob0 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_low ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[0] ) , + .en_in ( ad_en_ctrl_low ) , + .en_out ( ad_en_out[0] ), + .dat_out ( ad_out[0] ) +); + +pci_out_reg ad_iob1 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_low ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[1] ) , + .en_in ( ad_en_ctrl_low ) , + .en_out ( ad_en_out[1] ), + .dat_out ( ad_out[1] ) +); + +pci_out_reg ad_iob2 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_low ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[2] ) , + .en_in ( ad_en_ctrl_low ) , + .en_out ( ad_en_out[2] ), + .dat_out ( ad_out[2] ) +); + +pci_out_reg ad_iob3 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_low ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[3] ) , + .en_in ( ad_en_ctrl_low ) , + .en_out ( ad_en_out[3] ), + .dat_out ( ad_out[3] ) +); + +pci_out_reg ad_iob4 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_low ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[4] ) , + .en_in ( ad_en_ctrl_low ) , + .en_out ( ad_en_out[4] ), + .dat_out ( ad_out[4] ) +); + +pci_out_reg ad_iob5 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_low ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[5] ) , + .en_in ( ad_en_ctrl_low ) , + .en_out ( ad_en_out[5] ), + .dat_out ( ad_out[5] ) +); + +pci_out_reg ad_iob6 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_low ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[6] ) , + .en_in ( ad_en_ctrl_low ) , + .en_out ( ad_en_out[6] ), + .dat_out ( ad_out[6] ) +); + +pci_out_reg ad_iob7 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_low ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[7] ) , + .en_in ( ad_en_ctrl_low ) , + .en_out ( ad_en_out[7] ), + .dat_out ( ad_out[7] ) +); + +pci_out_reg ad_iob8 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mlow ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[8] ) , + .en_in ( ad_en_ctrl_mlow ) , + .en_out ( ad_en_out[8] ), + .dat_out ( ad_out[8] ) +); + +pci_out_reg ad_iob9 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mlow ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[9] ) , + .en_in ( ad_en_ctrl_mlow ) , + .en_out ( ad_en_out[9] ), + .dat_out ( ad_out[9] ) +); + +pci_out_reg ad_iob10 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mlow ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[10] ) , + .en_in ( ad_en_ctrl_mlow ) , + .en_out ( ad_en_out[10] ), + .dat_out ( ad_out[10] ) +); + +pci_out_reg ad_iob11 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mlow ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[11] ) , + .en_in ( ad_en_ctrl_mlow ) , + .en_out ( ad_en_out[11] ), + .dat_out ( ad_out[11] ) +); + +pci_out_reg ad_iob12 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mlow ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[12] ) , + .en_in ( ad_en_ctrl_mlow ) , + .en_out ( ad_en_out[12] ), + .dat_out ( ad_out[12] ) +); + +pci_out_reg ad_iob13 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mlow ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[13] ) , + .en_in ( ad_en_ctrl_mlow ) , + .en_out ( ad_en_out[13] ), + .dat_out ( ad_out[13] ) +); + +pci_out_reg ad_iob14 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mlow ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[14] ) , + .en_in ( ad_en_ctrl_mlow ) , + .en_out ( ad_en_out[14] ), + .dat_out ( ad_out[14] ) +); + +pci_out_reg ad_iob15 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mlow ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[15] ) , + .en_in ( ad_en_ctrl_mlow ) , + .en_out ( ad_en_out[15] ), + .dat_out ( ad_out[15] ) +); + +pci_out_reg ad_iob16 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mhigh ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[16] ) , + .en_in ( ad_en_ctrl_mhigh ) , + .en_out ( ad_en_out[16] ), + .dat_out ( ad_out[16] ) +); + +pci_out_reg ad_iob17 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mhigh ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[17] ) , + .en_in ( ad_en_ctrl_mhigh ) , + .en_out ( ad_en_out[17] ), + .dat_out ( ad_out[17] ) +); + +pci_out_reg ad_iob18 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mhigh ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[18] ) , + .en_in ( ad_en_ctrl_mhigh ) , + .en_out ( ad_en_out[18] ), + .dat_out ( ad_out[18] ) +); + +pci_out_reg ad_iob19 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mhigh ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[19] ) , + .en_in ( ad_en_ctrl_mhigh ) , + .en_out ( ad_en_out[19] ), + .dat_out ( ad_out[19] ) +); + +pci_out_reg ad_iob20 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mhigh ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[20] ) , + .en_in ( ad_en_ctrl_mhigh ) , + .en_out ( ad_en_out[20] ), + .dat_out ( ad_out[20] ) +); + +pci_out_reg ad_iob21 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mhigh ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[21] ) , + .en_in ( ad_en_ctrl_mhigh ) , + .en_out ( ad_en_out[21] ), + .dat_out ( ad_out[21] ) +); + +pci_out_reg ad_iob22 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mhigh ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[22] ) , + .en_in ( ad_en_ctrl_mhigh ) , + .en_out ( ad_en_out[22] ), + .dat_out ( ad_out[22] ) +); + +pci_out_reg ad_iob23 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_mhigh ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[23] ) , + .en_in ( ad_en_ctrl_mhigh ) , + .en_out ( ad_en_out[23] ), + .dat_out ( ad_out[23] ) +); + +pci_out_reg ad_iob24 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_high ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[24] ) , + .en_in ( ad_en_ctrl_high ) , + .en_out ( ad_en_out[24] ), + .dat_out ( ad_out[24] ) +); + +pci_out_reg ad_iob25 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_high ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[25] ) , + .en_in ( ad_en_ctrl_high ) , + .en_out ( ad_en_out[25] ), + .dat_out ( ad_out[25] ) +); + +pci_out_reg ad_iob26 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_high ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[26] ) , + .en_in ( ad_en_ctrl_high ) , + .en_out ( ad_en_out[26] ), + .dat_out ( ad_out[26] ) +); + +pci_out_reg ad_iob27 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_high ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[27] ) , + .en_in ( ad_en_ctrl_high ) , + .en_out ( ad_en_out[27] ), + .dat_out ( ad_out[27] ) +); + +pci_out_reg ad_iob28 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_high ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[28] ) , + .en_in ( ad_en_ctrl_high ) , + .en_out ( ad_en_out[28] ), + .dat_out ( ad_out[28] ) +); + +pci_out_reg ad_iob29 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_high ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[29] ) , + .en_in ( ad_en_ctrl_high ) , + .en_out ( ad_en_out[29] ), + .dat_out ( ad_out[29] ) +); + +pci_out_reg ad_iob30 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_high ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[30] ) , + .en_in ( ad_en_ctrl_high ) , + .en_out ( ad_en_out[30] ), + .dat_out ( ad_out[30] ) +); + +pci_out_reg ad_iob31 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( ad_load_ctrl_high ), + .en_en_in ( 1'b1 ), + .dat_in ( temp_ad[31] ) , + .en_in ( ad_en_ctrl_high ) , + .en_out ( ad_en_out[31] ), + .dat_out ( ad_out[31] ) +); + +wire [3:0] cbe_load_ctrl = {4{ master_load_in }} ; +wire [3:0] cbe_en_ctrl = {4{ cbe_en_in }} ; + +pci_out_reg cbe_iob0 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( cbe_load_ctrl[0] ), + .en_en_in ( 1'b1 ), + .dat_in ( cbe_in[0] ) , + .en_in ( cbe_en_ctrl[0] ) , + .en_out ( cbe_en_out[0] ), + .dat_out ( cbe_out[0] ) +); + +pci_out_reg cbe_iob1 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( cbe_load_ctrl[1] ), + .en_en_in ( 1'b1 ), + .dat_in ( cbe_in[1] ) , + .en_in ( cbe_en_ctrl[1] ) , + .en_out ( cbe_en_out[1] ), + .dat_out ( cbe_out[1] ) +); + +pci_out_reg cbe_iob2 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( cbe_load_ctrl[2] ), + .en_en_in ( 1'b1 ), + .dat_in ( cbe_in[2] ) , + .en_in ( cbe_en_ctrl[2] ) , + .en_out ( cbe_en_out[2] ), + .dat_out ( cbe_out[2] ) +); + +pci_out_reg cbe_iob3 +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( cbe_load_ctrl[3] ), + .en_en_in ( 1'b1 ), + .dat_in ( cbe_in[3] ) , + .en_in ( cbe_en_ctrl[3] ) , + .en_out ( cbe_en_out[3] ), + .dat_out ( cbe_out[3] ) +); + +pci_out_reg frame_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( frame_load_in ), + .en_en_in ( 1'b1 ), + .dat_in ( frame_in ) , + .en_in ( frame_en_in ) , + .en_out ( frame_en_out ), + .dat_out ( frame_out ) +); + +pci_out_reg irdy_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( 1'b1 ), + .en_en_in ( 1'b1 ), + .dat_in ( irdy_in ) , + .en_in ( irdy_en_in ) , + .en_out ( irdy_en_out ), + .dat_out ( irdy_out ) +); + +pci_out_reg trdy_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( 1'b1 ), + .en_en_in ( 1'b1 ), + .dat_in ( trdy_in ) , + .en_in ( trdy_en_in ) , + .en_out ( trdy_en_out ), + .dat_out ( trdy_out ) +); + +pci_out_reg stop_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( 1'b1 ), + .en_en_in ( 1'b1 ), + .dat_in ( stop_in ) , + .en_in ( stop_en_in ) , + .en_out ( stop_en_out ), + .dat_out ( stop_out ) +); + +pci_out_reg devsel_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( 1'b1 ), + .en_en_in ( 1'b1 ), + .dat_in ( devsel_in ) , + .en_in ( devsel_en_in ) , + .en_out ( devsel_en_out ), + .dat_out ( devsel_out ) +); + +pci_out_reg par_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( 1'b1 ), + .en_en_in ( 1'b1 ), + .dat_in ( par_in ) , + .en_in ( par_en_in ) , + .en_out ( par_en_out ), + .dat_out ( par_out ) +); + +pci_out_reg perr_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( 1'b1 ), + .en_en_in ( 1'b1 ), + .dat_in ( perr_in ) , + .en_in ( perr_en_in ) , + .en_out ( perr_en_out ), + .dat_out ( perr_out ) +); + +pci_out_reg serr_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( 1'b1 ), + .en_en_in ( 1'b1 ), + .dat_in ( serr_in ) , + .en_in ( serr_en_in ) , + .en_out ( serr_en_out ), + .dat_out ( serr_out ) +); + +pci_out_reg req_iob +( + .reset_in ( reset_in ), + .clk_in ( clk_in) , + .dat_en_in ( 1'b1 ), + .en_en_in ( 1'b1 ), + .dat_in ( req_in ) , + .en_in ( init_complete_in ) , + .en_out ( req_en_out ), + .dat_out ( req_out ) +); + +endmodule diff --git a/ethernet/source/pci/pci_io_mux_ad_en_crit.v b/ethernet/source/pci/pci_io_mux_ad_en_crit.v new file mode 100644 index 0000000..c17d6bf --- /dev/null +++ b/ethernet/source/pci/pci_io_mux_ad_en_crit.v @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_io_mux_ad_en_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_io_mux_ad_en_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.2 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// +// + +// module provides equation for ad output enables, which uses critical pci bus inputs + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// module is provided for ad bus output enable Flip-Flops values +module pci_io_mux_ad_en_crit +( + ad_en_in, + pci_frame_in, + pci_trdy_in, + pci_stop_in, + ad_en_out +); +input ad_en_in, + pci_frame_in, + pci_trdy_in, + pci_stop_in ; +output ad_en_out ; + +assign ad_en_out = ad_en_in && ( ~pci_frame_in || (pci_trdy_in && pci_stop_in) ) ; +endmodule diff --git a/ethernet/source/pci/pci_io_mux_ad_load_crit.v b/ethernet/source/pci/pci_io_mux_ad_load_crit.v new file mode 100644 index 0000000..918cdb4 --- /dev/null +++ b/ethernet/source/pci/pci_io_mux_ad_load_crit.v @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_io_mux_ad_load_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_io_mux_ad_load_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.2 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// module is provided for last level of logic for loading AD output flip-flops +// and output backup flip - flops +module pci_io_mux_ad_load_crit +( + load_in, + load_on_transfer_in, + pci_irdy_in, + pci_trdy_in, + load_out +); + +input load_in, + load_on_transfer_in, + pci_irdy_in, + pci_trdy_in ; + +output load_out ; + +assign load_out = load_in || (load_on_transfer_in && ~pci_irdy_in && ~pci_trdy_in) ; + +endmodule diff --git a/ethernet/source/pci/pci_irdy_out_crit.v b/ethernet/source/pci/pci_irdy_out_crit.v new file mode 100644 index 0000000..5f042ee --- /dev/null +++ b/ethernet/source/pci/pci_irdy_out_crit.v @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "irdy_out_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_irdy_out_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// This module is used in master state machine for IRDY output driving + +module pci_irdy_out_crit +( + pci_irdy_out, + irdy_slow_in, + pci_frame_out_in, + pci_trdy_in, + pci_stop_in +) ; + +output pci_irdy_out ; +input irdy_slow_in, + pci_frame_out_in, + pci_trdy_in, + pci_stop_in ; + +assign pci_irdy_out = irdy_slow_in || (pci_frame_out_in && ~(pci_trdy_in && pci_stop_in)) ; + +endmodule diff --git a/ethernet/source/pci/pci_mas_ad_en_crit.v b/ethernet/source/pci/pci_mas_ad_en_crit.v new file mode 100644 index 0000000..46dce56 --- /dev/null +++ b/ethernet/source/pci/pci_mas_ad_en_crit.v @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "mas_ad_en_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_mas_ad_en_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// This module is used in master state machine for AD lines output enable driving +module pci_mas_ad_en_crit +( + pci_ad_en_out, + ad_en_slow_in, + ad_en_on_grant_in, + pci_gnt_in +) ; + +output pci_ad_en_out ; +input ad_en_slow_in, + ad_en_on_grant_in, + pci_gnt_in ; + +assign pci_ad_en_out = ad_en_slow_in || (ad_en_on_grant_in && !pci_gnt_in) ; + +endmodule diff --git a/ethernet/source/pci/pci_mas_ad_load_crit.v b/ethernet/source/pci/pci_mas_ad_load_crit.v new file mode 100644 index 0000000..836b2ea --- /dev/null +++ b/ethernet/source/pci/pci_mas_ad_load_crit.v @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "mas_ad_load_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_mas_ad_load_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// module is included for loading output flip - flops by monitoring timing critical GNT pci input +module pci_mas_ad_load_crit +( + ad_load_out, + ad_load_in, + ad_load_on_grant_in, + pci_gnt_in +); +output ad_load_out ; +input ad_load_in, + ad_load_on_grant_in, + pci_gnt_in ; + +assign ad_load_out = ad_load_in || ( ad_load_on_grant_in && !pci_gnt_in ) ; +endmodule diff --git a/ethernet/source/pci/pci_mas_ch_state_crit.v b/ethernet/source/pci/pci_mas_ch_state_crit.v new file mode 100644 index 0000000..5d96449 --- /dev/null +++ b/ethernet/source/pci/pci_mas_ch_state_crit.v @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "mas_ch_state_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_mas_ch_state_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// Module is used in master state machine for state machine clock enable driving + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_mas_ch_state_crit +( + change_state_out, + ch_state_med_in, + sm_data_phases_in, + pci_trdy_in, + pci_stop_in +) ; + +output change_state_out ; +input ch_state_med_in, + sm_data_phases_in, + pci_trdy_in, + pci_stop_in ; + +assign change_state_out = ch_state_med_in || sm_data_phases_in && (~(pci_trdy_in && pci_stop_in)) ; + +endmodule diff --git a/ethernet/source/pci/pci_master32_sm.v b/ethernet/source/pci/pci_master32_sm.v new file mode 100644 index 0000000..29fdf08 --- /dev/null +++ b/ethernet/source/pci/pci_master32_sm.v @@ -0,0 +1,618 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_master32_sm.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_master32_sm.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.5 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.4 2003/01/21 16:06:56 mihad +// Bug fixes, testcases added. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:29 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module includes pci master state machine and surrounding logic + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "pci_constants.v" + +module pci_master32_sm +( + // system inputs + clk_in, + reset_in, + // arbitration + pci_req_out, + pci_gnt_in, + // master in/outs + pci_frame_in, + pci_frame_out, + pci_frame_out_in, + pci_frame_load_out, + pci_frame_en_in, + pci_frame_en_out, + pci_irdy_in, + pci_irdy_out, + pci_irdy_en_out, + + // target response inputs + pci_trdy_in, + pci_trdy_reg_in, + pci_stop_in, + pci_stop_reg_in, + pci_devsel_in, + pci_devsel_reg_in, + + // address, data, bus command, byte enable in/outs + pci_ad_reg_in, + pci_ad_out, + pci_ad_en_out, + pci_cbe_out, + pci_cbe_en_out, + + // other side of state machine + address_in, + bc_in, + data_in, + data_out, + be_in, + req_in, + rdy_in, + last_in, + next_data_in, + next_be_in, + next_last_in, + ad_load_out, + ad_load_on_transfer_out, + wait_out, + wtransfer_out, + rtransfer_out, + retry_out, + rerror_out, + first_out, + mabort_out, + latency_tim_val_in +) ; + +// system inputs +input clk_in, + reset_in ; + +/*================================================================================================================== +PCI interface signals - bidirectional signals are divided to inputs and outputs in I/O cells instantiation +module. Enables are separate signals. +==================================================================================================================*/ +// arbitration +output pci_req_out ; + +input pci_gnt_in ; + +// master in/outs +input pci_frame_in ; +input pci_frame_en_in ; +input pci_frame_out_in ; + +output pci_frame_out, + pci_frame_en_out ; + +output pci_frame_load_out ; + +input pci_irdy_in ; +output pci_irdy_out, + pci_irdy_en_out; + +// target response inputs +input pci_trdy_in, + pci_trdy_reg_in, + pci_stop_in, + pci_stop_reg_in, + pci_devsel_in, + pci_devsel_reg_in ; + +// address, data, bus command, byte enable in/outs +input [31:0] pci_ad_reg_in ; +output [31:0] pci_ad_out ; + +reg [31:0] pci_ad_out ; + +output pci_ad_en_out ; + +output [3:0] pci_cbe_out ; + +reg [3:0] pci_cbe_out ; + +output pci_cbe_en_out ; + +input [31:0] address_in ; // current request address input + +input [3:0] bc_in ; // current request bus command input + +input [31:0] data_in ; // current dataphase data input + +output [31:0] data_out ; // for read operations - current request data output + +reg [31:0] data_out ; + +input [3:0] be_in ; // current dataphase byte enable inputs + +input req_in ; // initiator cycle is requested +input rdy_in ; // requestor indicates that data is ready to be sent for write transaction and ready to + // be received on read transaction +input last_in ; // last dataphase in current transaction indicator + +// status outputs +output wait_out, // wait indicates to the backend that dataphases are not in progress on PCI bus + wtransfer_out, // on any rising clock edge that this status is 1, data is transferred - heavy constraints here + rtransfer_out, // registered transfer indicator - when 1 indicates that data was transfered on previous clock cycle + retry_out, // retry status output - when target signals a retry + rerror_out, // registered error output - when 1 indicates that error was signalled by a target on previous clock cycle + first_out , // indicates whether or not any data was transfered in current transaction + mabort_out; // master abort indicator + +reg wait_out ; + +// latency timer value input - state machine starts latency timer whenever it starts a transaction and last is not +// asserted ( meaning burst transfer ). +input [7:0] latency_tim_val_in ; + +// next data, byte enable and last inputs +input [31:0] next_data_in ; +input [3:0] next_be_in ; +input next_last_in ; + +// clock enable for data output flip-flops - whenever data is transfered, sm loads next data to those flip flops +output ad_load_out, + ad_load_on_transfer_out ; + +// parameters - states - one hot +// idle state +parameter S_IDLE = 4'h1 ; + +// address state +parameter S_ADDRESS = 4'h2 ; + +// transfer state - dataphases +parameter S_TRANSFER = 4'h4 ; + +// turn arround state +parameter S_TA_END = 4'h8 ; + +// change state - clock enable for sm state register +wire change_state ; +// next state for state machine +reg [3:0] next_state ; +// SM state register +reg [3:0] cur_state ; + +// variables for indicating which state state machine is in +// this variables are used to reduce logic levels in case of heavily constrained PCI signals +reg sm_idle ; +reg sm_address ; +reg sm_data_phases ; +reg sm_turn_arround ; + +// state machine register control logic with clock enable +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + cur_state <= #`FF_DELAY S_IDLE ; + else + if ( change_state ) + cur_state <= #`FF_DELAY next_state ; +end + +// parameters - data selector - ad and bc lines switch between address/data and bus command/byte enable respectively +parameter SEL_ADDR_BC = 2'b01 ; +parameter SEL_DATA_BE = 2'b00 ; +parameter SEL_NEXT_DATA_BE = 2'b11 ; + +reg [1:0] wdata_selector ; + +wire u_dont_have_pci_bus = pci_gnt_in || ~pci_frame_in || ~pci_irdy_in ; // pci master can't start a transaction when GNT is deasserted ( 1 ) or + // bus is not in idle state ( FRAME and IRDY both 1 ) +wire u_have_pci_bus = ~pci_gnt_in && pci_frame_in && pci_irdy_in ; + +// decode count enable - counter that counts cycles passed since address phase +wire sm_decode_count_enable = sm_data_phases ; // counter is enabled when master wants to transfer +wire decode_count_enable = sm_decode_count_enable && pci_trdy_in && pci_stop_in && pci_devsel_in ; // and target is not responding +wire decode_count_load = ~decode_count_enable ; +reg [2:0] decode_count ; + +wire decode_to = ~( decode_count[2] || decode_count[1]) ; + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + // initial value of counter is 4 + decode_count <= #`FF_DELAY 3'h4 ; + else + if ( decode_count_load ) + decode_count <= #`FF_DELAY 3'h4 ; + else + if ( decode_count_enable ) + decode_count <= #`FF_DELAY decode_count - 1'b1 ; +end + +// Bus commands LSbit indicates whether operation is a read or a write +wire do_write = bc_in[0] ; + +// latency timer +reg [7:0] latency_timer ; + +wire latency_time_out = ~( + (latency_timer[7] || latency_timer[6] || latency_timer[5] || latency_timer[4]) || + (latency_timer[3] || latency_timer[2] || latency_timer[1] ) + ) ; + +wire latency_timer_enable = (sm_address || sm_data_phases) && ~latency_time_out ; +wire latency_timer_load = ~sm_address && ~sm_data_phases ; + +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + latency_timer <= #`FF_DELAY 8'h00 ; + else + if ( latency_timer_load ) + latency_timer <= #`FF_DELAY latency_tim_val_in ; + else + if ( latency_timer_enable) // latency timer counts down until it expires - then it stops + latency_timer <= #`FF_DELAY latency_timer - 1'b1 ; +end + +// master abort indicators - when decode time out occurres and still no target response is received +wire do_master_abort = decode_to && pci_trdy_in && pci_stop_in && pci_devsel_in ; +reg mabort1 ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + mabort1 <= #`FF_DELAY 1'b0 ; + else + mabort1 <= #`FF_DELAY do_master_abort ; +end + +reg mabort2 ; +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + mabort2 <= #`FF_DELAY 1'b0 ; + else + mabort2 <= #`FF_DELAY mabort1 ; +end + +// master abort is only asserted for one clock cycle +assign mabort_out = mabort1 && ~mabort2 ; + +// register indicating when master should do timeout termination (latency timer expires) +reg timeout ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + timeout <= #`FF_DELAY 1'b0 ; + else + timeout <= #`FF_DELAY (latency_time_out && ~pci_frame_out_in && pci_gnt_in || timeout ) && ~wait_out ; +end + +wire timeout_termination = sm_turn_arround && timeout && pci_stop_reg_in ; + +// frame control logic +// frame is forced to 0 (active) when state machine is in idle state, since only possible next state is address state which always drives frame active +wire force_frame = ~sm_idle ; +// slow signal for frame calculated from various registers in the core +wire slow_frame = last_in || (latency_time_out && pci_gnt_in) || (next_last_in && sm_data_phases) || mabort1 ; +// critical timing frame logic in separate module - some combinations of target signals force frame to inactive state immediately after sampled asserted +// (STOP) +pci_frame_crit frame_iob_feed +( + .pci_frame_out (pci_frame_out), + .force_frame_in (force_frame), + .slow_frame_in (slow_frame), + .pci_stop_in (pci_stop_in) +) ; + +// frame IOB flip flop's clock enable signal +// slow clock enable - calculated from internal - non critical paths +wire frame_load_slow = sm_idle || sm_address || mabort1 ; + +// critical clock enable for frame IOB in separate module - target response signals actually allow frame value change - critical timing +pci_frame_load_crit frame_iob_ce +( + .pci_frame_load_out (pci_frame_load_out), + .sm_data_phases_in (sm_data_phases), + .frame_load_slow_in (frame_load_slow), + .pci_trdy_in (pci_trdy_in), + .pci_stop_in (pci_stop_in) +) ; + +// IRDY driving +// non critical path for IRDY calculation +wire irdy_slow = pci_frame_out_in && mabort1 || mabort2 ; + +// critical path in separate module +pci_irdy_out_crit irdy_iob_feed +( + .pci_irdy_out (pci_irdy_out), + .irdy_slow_in (irdy_slow), + .pci_frame_out_in (pci_frame_out_in), + .pci_trdy_in (pci_trdy_in), + .pci_stop_in (pci_stop_in) +) ; + +// transfer FF indicator - when first transfer occurs it is set to 1 so backend can distinguish between disconnects and retries. +wire sm_transfer = sm_data_phases ; +reg transfer ; + +wire transfer_input = sm_transfer && (~(pci_trdy_in || pci_devsel_in) || transfer) ; + +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + transfer <= #`FF_DELAY 1'b0 ; + else + transfer <= #`FF_DELAY transfer_input ; +end + +assign first_out = ~transfer ; + +// fast transfer status output - it's only negated target ready, since wait indicator qualifies valid transfer +assign wtransfer_out = ~pci_trdy_in ; + +// registered transfer status output - calculated from registered target response inputs +assign rtransfer_out = ~(pci_trdy_reg_in || pci_devsel_reg_in) ; + +// registered error status - calculated from registered target response inputs +assign rerror_out = (~pci_stop_reg_in && pci_devsel_reg_in) ; + +// retry is signalled to backend depending on registered target response or when latency timer expires +assign retry_out = timeout_termination || (~pci_stop_reg_in && ~pci_devsel_reg_in) ; + +// AD output flip flops' clock enable +// new data is loaded to AD outputs whenever state machine is idle, bus was granted and bus is in idle state or +// when address phase is about to be finished +wire ad_load_slow = sm_address ; +wire ad_load_on_grant = sm_idle && pci_frame_in && pci_irdy_in ; + +pci_mas_ad_load_crit mas_ad_load_feed +( + .ad_load_out (ad_load_out), + .ad_load_in (ad_load_slow), + .ad_load_on_grant_in (ad_load_on_grant), + .pci_gnt_in (pci_gnt_in) +); + +// next data loading is allowed when state machine is in transfer state and operation is a write +assign ad_load_on_transfer_out = sm_data_phases && do_write ; + +// request for a bus is issued anytime when backend is requesting a transaction and state machine is in idle state +assign pci_req_out = ~(req_in && sm_idle) ; + +// change state signal is actually clock enable for state register +// Non critical path for state change enable: +// state is always changed when: +// - address phase is finishing +// - state machine is in turn arround state +// - state machine is in transfer state and master abort termination is in progress + +wire ch_state_slow = sm_address || sm_turn_arround || sm_data_phases && ( pci_frame_out_in && mabort1 || mabort2 ) ; + +// a bit more critical change state enable is calculated with GNT signal +wire ch_state_med = ch_state_slow || sm_idle && u_have_pci_bus && req_in && rdy_in ; + +// most critical change state enable - calculated from target response signals +pci_mas_ch_state_crit state_machine_ce +( + .change_state_out (change_state), + .ch_state_med_in (ch_state_med), + .sm_data_phases_in (sm_data_phases), + .pci_trdy_in (pci_trdy_in), + .pci_stop_in (pci_stop_in) +) ; + +// ad enable driving +// also divided in several categories - from less critical to most critical in separate module +//wire ad_en_slowest = do_write && (sm_address || sm_data_phases && ~pci_frame_out_in) ; +//wire ad_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ; +//wire ad_en_slow = ad_en_on_grant && ~pci_gnt_in || ad_en_slowest ; +//wire ad_en_keep = sm_data_phases && do_write && (pci_frame_out_in && ~mabort1 && ~mabort2) ; + +wire ad_en_slow = do_write && ( sm_address || ( sm_data_phases && !( ( pci_frame_out_in && mabort1 ) || mabort2 ) ) ) ; +wire ad_en_on_grant = ( sm_idle && pci_frame_in && pci_irdy_in ) || sm_turn_arround ; + +// critical timing ad enable - calculated from grant input +pci_mas_ad_en_crit ad_iob_oe_feed +( + .pci_ad_en_out (pci_ad_en_out), + .ad_en_slow_in (ad_en_slow), + .ad_en_on_grant_in (ad_en_on_grant), + .pci_gnt_in (pci_gnt_in) +) ; + +// cbe enable driving +wire cbe_en_on_grant = sm_idle && pci_frame_in && pci_irdy_in || sm_turn_arround ; +wire cbe_en_slow = cbe_en_on_grant && ~pci_gnt_in || sm_address || sm_data_phases && ~pci_frame_out_in ; +wire cbe_en_keep = sm_data_phases && pci_frame_out_in && ~mabort1 && ~mabort2 ; + +// most critical cbe enable in separate module - calculated with most critical target inputs +pci_cbe_en_crit cbe_iob_feed +( + .pci_cbe_en_out (pci_cbe_en_out), + .cbe_en_slow_in (cbe_en_slow), + .cbe_en_keep_in (cbe_en_keep), + .pci_stop_in (pci_stop_in), + .pci_trdy_in (pci_trdy_in) + +) ; + +// IRDY enable is equal to FRAME enable delayed for one clock +assign pci_irdy_en_out = pci_frame_en_in ; + +// frame enable driving - sometimes it's calculated from non critical paths +wire frame_en_slow = (sm_idle && u_have_pci_bus && req_in && rdy_in) || sm_address || (sm_data_phases && ~pci_frame_out_in) ; +wire frame_en_keep = sm_data_phases && pci_frame_out_in && ~mabort1 && ~mabort2 ; + +// most critical frame enable - calculated from heavily constrained target inputs in separate module +pci_frame_en_crit frame_iob_en_feed +( + .pci_frame_en_out (pci_frame_en_out), + .frame_en_slow_in (frame_en_slow), + .frame_en_keep_in (frame_en_keep), + .pci_stop_in (pci_stop_in), + .pci_trdy_in (pci_trdy_in) +) ; + +// state machine next state definitions +always@( + cur_state or + do_write or + pci_frame_out_in +) +begin + // default values for state machine outputs + wait_out = 1'b1 ; + wdata_selector = SEL_ADDR_BC ; + sm_idle = 1'b0 ; + sm_address = 1'b0 ; + sm_data_phases = 1'b0 ; + sm_turn_arround = 1'b0 ; + + case ( cur_state ) + + S_IDLE: begin + // indicate the state + sm_idle = 1'b1 ; + // assign next state - only possible is address - if state machine is supposed to stay in idle state + // outside signals disable the clock + next_state = S_ADDRESS ; + wdata_selector = SEL_DATA_BE ; + end + + S_ADDRESS: begin + // indicate the state + sm_address = 1'b1 ; + // select appropriate data/be for outputs + wdata_selector = SEL_NEXT_DATA_BE ; + // only possible next state is transfer state + next_state = S_TRANSFER ; + end + + S_TRANSFER: begin + // during transfers wait indicator is inactive - all status signals are now valid + wait_out = 1'b0 ; + // indicate the state + sm_data_phases = 1'b1 ; + // select appropriate data/be for outputs + wdata_selector = SEL_NEXT_DATA_BE ; + if ( pci_frame_out_in ) + begin + // when frame is inactive next state will be turn arround + next_state = S_TA_END ; + end + else + // while frame is active state cannot be anything else then transfer + next_state = S_TRANSFER ; + end + + S_TA_END: begin + // wait is still inactive because of registered statuses + wait_out = 1'b0 ; + // indicate the state + sm_turn_arround = 1'b1 ; + // next state is always idle + next_state = S_IDLE ; + end + default: next_state = S_IDLE ; + endcase +end + +// ad and cbe lines multiplexer for write data +reg [1:0] rdata_selector ; +always@(posedge clk_in or posedge reset_in) +begin + if ( reset_in ) + rdata_selector <= #`FF_DELAY SEL_ADDR_BC ; + else + if ( change_state ) + rdata_selector <= #`FF_DELAY wdata_selector ; +end + +always@(rdata_selector or address_in or bc_in or data_in or be_in or next_data_in or next_be_in) +begin + case ( rdata_selector ) + SEL_ADDR_BC: begin + pci_ad_out = address_in ; + pci_cbe_out = bc_in ; + end + + SEL_DATA_BE: begin + pci_ad_out = data_in ; + pci_cbe_out = be_in ; + end + SEL_NEXT_DATA_BE, + 2'b10: begin + pci_ad_out = next_data_in ; + pci_cbe_out = next_be_in ; + end + endcase +end + +// data output mux for reads +always@(mabort_out or pci_ad_reg_in) +begin + if ( mabort_out ) + data_out = 32'hFFFF_FFFF ; + else + data_out = pci_ad_reg_in ; +end +endmodule diff --git a/ethernet/source/pci/pci_master32_sm_if.v b/ethernet/source/pci/pci_master32_sm_if.v new file mode 100644 index 0000000..3dd959c --- /dev/null +++ b/ethernet/source/pci/pci_master32_sm_if.v @@ -0,0 +1,849 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_master32_sm_if.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_master32_sm_if.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.7 2004/03/19 16:36:55 mihad +// Single PCI Master write fix. +// +// Revision 1.6 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.5 2003/06/12 10:12:22 mihad +// Changed one critical PCI bus signal logic. +// +// Revision 1.4 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:29 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +`include "pci_constants.v" +`include "bus_commands.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +/*==================================================================== +Module provides interface between PCI bridge internals and PCI master +state machine +====================================================================*/ +module pci_master32_sm_if +( + clk_in, + reset_in, + + // interconnect to pci master state machine + address_out, + bc_out, + data_out, + data_in, + be_out, + req_out, + rdy_out, + last_out, + + next_data_out, + next_be_out, + next_last_out, + + // status inputs from master SM + wait_in, + wtransfer_in, + rtransfer_in, + retry_in, + rerror_in, + first_in , + mabort_in, + + + // WISHBONE WRITE fifo inputs and outputs + wbw_renable_out, + wbw_fifo_addr_data_in, + wbw_fifo_cbe_in, + wbw_fifo_control_in, + wbw_fifo_empty_in, + wbw_fifo_transaction_ready_in, + + // WISHBONE READ fifo inputs and outputs + wbr_fifo_wenable_out, + wbr_fifo_data_out, + wbr_fifo_be_out, + wbr_fifo_control_out, + + // delayed transaction control logic inputs and outputs + del_wdata_in, + del_complete_out, + del_req_in, + del_addr_in, + del_bc_in, + del_be_in, + del_burst_in, + del_error_out, + del_rty_exp_out, + del_we_in, + + // configuration space interconnect + // error reporting + err_addr_out, + err_bc_out, + err_signal_out, + err_source_out, + err_rty_exp_out, + + cache_line_size_in, + + // two signals for pci control and status + mabort_received_out, + tabort_received_out, + + posted_write_not_present_out +); + +// system inputs +input clk_in ; +input reset_in ; + +// PCI master state machine interconnect +output [31:0] address_out ; // address output + +output [3:0] bc_out ; // bus command output +reg [3:0] bc_out ; + +output [31:0] data_out ; // data output for writes +reg [31:0] data_out ; + +input [31:0] data_in ; // data input for reads +output [3:0] be_out ; // byte enable output +reg [3:0] be_out ; + +output req_out ; // request output + +output rdy_out ; // ready output +reg rdy_out ; + +output last_out ; // last data indicator output + +output [31:0] next_data_out ; // next data output +output [3:0] next_be_out ; // next byte enable output +output next_last_out ; // next transfer last indicator + +input wait_in, + wtransfer_in, + rtransfer_in, + retry_in, + rerror_in, + first_in , + mabort_in ; + +// WISHBONE write fifo interconnect +output wbw_renable_out ; // WBW_FIFO read enable signal + +input [31:0] wbw_fifo_addr_data_in ; // WBW_FIFO address/data bus +input [3:0] wbw_fifo_cbe_in ; // WBW_FIFO command/byte enable bus +input [3:0] wbw_fifo_control_in ; // WBW_FIFO control bus +input wbw_fifo_empty_in ; // WBW_FIFO's empty status indicator +input wbw_fifo_transaction_ready_in ; // WBW_FIFO transaction ready indicator + +// WISHBONE read FIFO interconnect +output wbr_fifo_wenable_out ; // write enable for WBR_FIFO + +output [31:0] wbr_fifo_data_out ; // data output to WBR_FIFO + +output [3:0] wbr_fifo_be_out ; // byte enable output for WBR_FIFO + +output [3:0] wbr_fifo_control_out ; // WBR_FIFO control output + +// delayed transaction control logic inputs and outputs +input [31:0] del_wdata_in ; // delayed write data input +output del_complete_out ; // delayed transaction completed output + +input del_req_in ; // delayed transaction request +input [31:0] del_addr_in ; // delayed transaction address +input [3:0] del_bc_in ; // delayed transaction bus command input +input [3:0] del_be_in ; // delayed transaction byte enables input +input del_burst_in ; // delayed transaction burst req. indicator +output del_error_out ; // delayed transation error termination signal + +output del_rty_exp_out ; // retry expired output for delayed transactions + +input del_we_in ; // delayed write request indicator + +output [31:0] err_addr_out ; // erroneous address output +output [3:0] err_bc_out ; // erroneous bus command output + +output err_signal_out ; // error signalization + +output err_source_out ; // error source indicator + +input [7:0] cache_line_size_in ; // cache line size value input + +output err_rty_exp_out ; // retry expired error output + +output mabort_received_out ; // master abort signaled to status register +output tabort_received_out ; // target abort signaled to status register + +output posted_write_not_present_out ; // used in target state machine - must deny read completions when this signal is 0 + + +assign err_bc_out = bc_out ; + +// assign read outputs +/*================================================================================================================== +WISHBONE read FIFO data outputs - just link them to SM data outputs and delayed BE input +==================================================================================================================*/ +assign wbr_fifo_data_out = data_in ; +assign wbr_fifo_be_out = del_be_in ; + +// decode if current bus command is configuration command +wire conf_cyc_bc = ( bc_out[3:1] == `BC_CONF_RW ) ; + +// register for indicating that current data is also last in transfer +reg current_last ; + +// register indicating that last data was transfered OK +reg last_transfered ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + last_transfered <= #`FF_DELAY 1'b0 ; + else + last_transfered <= #`FF_DELAY ~wait_in && last_out && wtransfer_in ; +end + +// status signals output assignement +assign mabort_received_out = mabort_in ; + +wire tabort_ff_in = ~wait_in && rerror_in ; + +reg tabort_received_out ; +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + tabort_received_out <= #`FF_DELAY 1'b0 ; + else + tabort_received_out <= #`FF_DELAY tabort_ff_in ; +end + +// error recovery indicator +reg err_recovery ; + +// operation is locked until error recovery is in progress or error bit is not cleared in configuration space +wire err_lock = err_recovery ; + +// three requests are possible - posted write, delayed write and delayed read +reg del_write_req ; +reg posted_write_req ; +reg del_read_req ; + +// assign request output +assign req_out = del_write_req || posted_write_req || del_read_req ; + +// posted write is not present, when WB Write Fifo is empty and posted write transaction is not beeing requested at present time +assign posted_write_not_present_out = !posted_write_req && wbw_fifo_empty_in ; + +// write requests are staged, so data is read from source into current data register and next data register +reg write_req_int ; +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + write_req_int <= #`FF_DELAY 1'b0 ; + else + write_req_int <= #`FF_DELAY posted_write_req || del_write_req ; + +end + +// ready output is generated one clock after request for reads and two after for writes +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + rdy_out <= #`FF_DELAY 1'b0 ; + else + rdy_out <= #`FF_DELAY del_read_req || ( (posted_write_req || del_write_req) && write_req_int) ; +end + +// wires with logic used as inputs to request FFs +wire do_posted_write = ( wbw_fifo_transaction_ready_in && ~wbw_fifo_empty_in && ~err_lock ) ; +wire do_del = ( del_req_in && ~err_lock && wbw_fifo_empty_in ) ; +wire do_del_write = do_del && del_we_in ; +wire do_del_read = do_del && ~del_we_in ; + +// register for indicating current operation's data source +parameter DELAYED_WRITE = 1'b1 ; +parameter POSTED_WRITE = 1'b0 ; + +// new data source - depending on which transaction will be processed next - delayed read is here because source of byte enables must +// be specified for delayed reads also - data source is not relevant for delayed reads, so value is don't care anyway +wire new_data_source = (do_del_write || do_del_read) ? DELAYED_WRITE : POSTED_WRITE ; // input to data source register +wire data_source_change = ~req_out ; // change (enable) for data source register - when no requests are in progress + +reg data_source ; // data source value +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + // default value is posted write source - wbw_fifo + data_source <= #`FF_DELAY POSTED_WRITE ; + else + if (data_source_change) + // change data source on rising clock edge + data_source <= #`FF_DELAY new_data_source ; +end + +// multiplexer for data output to PCI MASTER state machine +reg [31:0] source_data ; +reg [3:0] source_be ; +always@(data_source or wbw_fifo_addr_data_in or wbw_fifo_cbe_in or del_wdata_in or del_be_in or del_burst_in) +begin + case (data_source) + POSTED_WRITE: begin + source_data = wbw_fifo_addr_data_in ; + source_be = wbw_fifo_cbe_in ; + end + DELAYED_WRITE: begin + source_data = del_wdata_in ; + // read all bytes during delayed burst read! + source_be = ~( del_be_in | {4{del_burst_in}} ) ; + end + endcase +end + +wire waddr = wbw_fifo_control_in[`ADDR_CTRL_BIT] ; + +// address change indicator - address is allowed to be loaded only when no transaction is in progress! +wire address_change = ~req_out ; // address change - whenever there is no request in progress + +// new address - input to register storing address of current request - if posted write request will be next, +// load address and bus command from wbw_fifo, else load data from delayed transaction logic +wire [31:0] new_address = ( ~req_out && do_posted_write ) ? wbw_fifo_addr_data_in[31:0] : del_addr_in[31:0] ; +wire [3:0] new_bc = ( ~req_out && do_posted_write ) ? wbw_fifo_cbe_in : del_bc_in ; + +// address counter enable - only for posted writes when data is actually transfered +wire addr_count_en = !wait_in && posted_write_req && rtransfer_in ; + +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + bc_out <= #`FF_DELAY `BC_RESERVED0 ; + else + if (address_change) + bc_out <= #`FF_DELAY new_bc ; +end + +reg [29:0] current_dword_address ; + +// DWORD address counter with load +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + current_dword_address <= #`FF_DELAY 30'h0000_0000 ; + else + if (address_change) + current_dword_address <= #`FF_DELAY new_address[31:2] ; + else + if (addr_count_en) + current_dword_address <= #`FF_DELAY current_dword_address + 1'b1 ; +end + +reg [1:0] current_byte_address ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + current_byte_address <= #`FF_DELAY 2'b00 ; + else + if (address_change) + current_byte_address <= #`FF_DELAY new_address[1:0] ; +end + +// byte address generation logic +reg [ 1: 0] generated_byte_adr ; +reg [ 1: 0] pci_byte_adr ; + +always@(be_out) +begin + casex(be_out) + 4'bxxx0:generated_byte_adr = 2'b00 ; + 4'bxx01:generated_byte_adr = 2'b01 ; + 4'bx011:generated_byte_adr = 2'b10 ; + 4'b0111:generated_byte_adr = 2'b11 ; + 4'b1111:generated_byte_adr = 2'b00 ; + endcase +end + +always@(generated_byte_adr or bc_out or current_byte_address) +begin + // for memory access commands, set lower 2 address bits to 0 + if ((bc_out == `BC_MEM_READ) | (bc_out == `BC_MEM_WRITE) | + (bc_out == `BC_MEM_READ_MUL) | (bc_out == `BC_MEM_READ_LN) | + (bc_out == `BC_MEM_WRITE_INVAL)) + begin + pci_byte_adr = 2'b00 ; + end + else if ((bc_out == `BC_IO_WRITE) | (bc_out == `BC_IO_READ)) + begin + pci_byte_adr = generated_byte_adr ; + end + else + begin + pci_byte_adr = current_byte_address ; + end +end + +// address output to PCI master state machine assignment +assign address_out = { current_dword_address, pci_byte_adr } ; + +// the same for erroneous address assignement +assign err_addr_out = { current_dword_address, pci_byte_adr } ; + +// cacheline size counter - for read transaction length control +// cache line count is enabled during burst reads when data is actually transfered +wire read_count_enable = ~wait_in && del_read_req && del_burst_in && wtransfer_in ; + +// cache line counter is loaded when del read request is not in progress +wire read_count_load = ~del_read_req ; + +reg [(`WBR_ADDR_LENGTH - 1):0] max_read_count ; +always@(cache_line_size_in or del_bc_in) +begin + if ( (cache_line_size_in >= `WBR_DEPTH) || (~del_bc_in[1] && ~del_bc_in[0]) ) + max_read_count = `WBR_DEPTH - 1'b1; + else + max_read_count = cache_line_size_in ; +end + +reg [(`WBR_ADDR_LENGTH - 1):0] read_count ; + +// cache line bound indicator - it signals when data for one complete cacheline was read +wire read_bound_comb = ~|(read_count[(`WBR_ADDR_LENGTH - 1):2]) ; +reg read_bound ; +always@(posedge clk_in or posedge reset_in) +begin + if ( reset_in ) + read_bound <= #`FF_DELAY 1'b0 ; + else if (read_count_load) + read_bound <= #`FF_DELAY 1'b0 ; + else if ( read_count_enable ) + read_bound <= #`FF_DELAY read_bound_comb ; +end + +wire read_count_change_val = read_count_load | read_count_enable ; + +wire [(`WBR_ADDR_LENGTH - 1):0] read_count_next = read_count_load ? max_read_count : (read_count - 1'b1) ; + +// down counter with load +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + read_count <= #`FF_DELAY 0 ; + else +/* if (read_count_load) + read_count <= #`FF_DELAY max_read_count ; + else + if (read_count_enable) + read_count <= #`FF_DELAY read_count - 1'b1 ; +*/ if (read_count_change_val) + read_count <= #`FF_DELAY read_count_next ; +end + +// flip flop indicating error recovery is in progress +reg err_recovery_in ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + err_recovery <= #`FF_DELAY 1'b0 ; + else + err_recovery <= #`FF_DELAY err_recovery_in ; +end + +/*// retry counter implementation +reg [7:0] retry_count ; + +wire retry_expired = ~|(retry_count[7:1]) ; + +// loading of retry counter - whenever no request is present or other termination than retry or wait is signalled +wire retry_load = ~req_out || (~wait_in && rtransfer_in) ; + +// retry DOWN counter with load +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + retry_count <= #`FF_DELAY 8'hFF ; + else + if ( retry_load ) + retry_count <= #`FF_DELAY `PCI_RTY_CNT_MAX ; + else + if (retry_in) + retry_count <= #`FF_DELAY retry_count - 1'b1 ; +end*/ + +/*================================================================================================================== +Delayed write requests are always single transfers! +Delayed write request starts, when no request is currently beeing processed and it is signaled from other side +of the bridge. +==================================================================================================================*/ +// delayed write request FF input control +reg del_write_req_input ; + +always@( + do_del_write or + del_write_req or + posted_write_req or + del_read_req or + wait_in or + //retry_in or + //retry_expired or + rtransfer_in or + rerror_in or + mabort_in +) +begin + if (~del_write_req) + begin + // delayed write is not in progress and is requested + // delayed write can be requested when no other request is in progress + del_write_req_input = ~posted_write_req && ~del_read_req && do_del_write ; + end + else + begin + // delayed write request is in progress - assign input + del_write_req_input = wait_in || + ( /*~( retry_in && retry_expired) &&*/ + ~rtransfer_in && ~rerror_in && ~mabort_in + ); + end +end + +// delayed write request FLIP-FLOP +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + del_write_req <= #`FF_DELAY 1'b0 ; + else + del_write_req <= #`FF_DELAY del_write_req_input ; +end + +/*================================================================================================ +Posted write request indicator. +Posted write starts whenever no request is in progress and one whole posted write is +stored in WBW_FIFO. It ends on error terminations ( master, target abort, retry expired) or +data transfer terminations if last data is on top of FIFO. +Continues on wait, retry, and disconnect without data. +================================================================================================*/ +// posted write request FF input control +reg posted_write_req_input ; +always@( + do_posted_write or + del_write_req or + posted_write_req or + del_read_req or + wait_in or + //retry_in or + rerror_in or + mabort_in or + //retry_expired or + rtransfer_in or + last_transfered +) +begin + if (~posted_write_req) + begin + // posted write is not in progress + posted_write_req_input = ~del_write_req && ~del_read_req && do_posted_write ; + end + else + begin + posted_write_req_input = wait_in || + (/*~(retry_in && retry_expired && ~rtransfer_in) &&*/ + ~rerror_in && ~mabort_in && + ~(last_transfered) + ) ; + + end +end + +// posted write request flip flop +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + posted_write_req <= #`FF_DELAY 1'b0 ; + else + posted_write_req <= #`FF_DELAY posted_write_req_input ; + +end + +/*================================================================================================ +Delayed read request indicator. +Delayed read starts whenever no request is in progress and delayed read request is signaled from +other side of bridge. It ends on error terminations ( master, target abort, retry expired) or +data transfer terminations if it is not burst transfer or on cache line bounds on burst transfer. +It also ends on disconnects. +Continues on wait and retry. +================================================================================================*/ +// delayed read FF input control +reg del_read_req_input ; +always@( + do_del_read or + del_write_req or + posted_write_req or + del_read_req or + last_transfered or + wait_in or + retry_in or + //retry_expired or + mabort_in or + rtransfer_in or + rerror_in or + first_in or + del_complete_out +) +begin + if (~del_read_req) + begin + del_read_req_input = ~del_write_req && ~posted_write_req && ~del_complete_out && do_del_read ; + end + else + begin + del_read_req_input = wait_in || + ( ~(retry_in && (~first_in /*|| retry_expired */)) && + ~mabort_in && ~rerror_in && + ~(last_transfered) + ) ; + end +end + +// delayed read request FF +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + del_read_req <= #`FF_DELAY 1'b0 ; + else + del_read_req <= #`FF_DELAY del_read_req_input ; +end + +// wire indicating last entry of transaction on top of fifo +wire wlast = wbw_fifo_control_in[`LAST_CTRL_BIT] ; + +wire last_int = posted_write_req && wlast || del_write_req ; + +// intermidiate data, byte enable and last registers +reg [31:0] intermediate_data ; +reg [3:0] intermediate_be ; +reg intermediate_last ; + +wire intermediate_enable = ( posted_write_req || del_write_req ) && ( ~write_req_int || (( ~rdy_out || ~wait_in && rtransfer_in ) && ~intermediate_last)) ; + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + begin + intermediate_data <= #`FF_DELAY 32'h0000_0000 ; + intermediate_be <= #`FF_DELAY 4'h0 ; + intermediate_last <= #`FF_DELAY 1'b0 ; + end + else + if ( intermediate_enable ) + begin + intermediate_data <= #`FF_DELAY source_data ; + intermediate_be <= #`FF_DELAY source_be ; + intermediate_last <= #`FF_DELAY last_int ; + end +end + +// multiplexer for next data +reg [31:0] next_data_out ; +reg [3:0] next_be_out ; +reg write_next_last ; +reg [3:0] write_next_be ; + +always@ +( + rtransfer_in or + intermediate_data or + intermediate_be or + intermediate_last or + wbw_fifo_addr_data_in or + wbw_fifo_cbe_in or + wlast or + wait_in +) +begin + if( rtransfer_in & ~wait_in ) + begin + next_data_out = wbw_fifo_addr_data_in ; + write_next_last = wlast ; + write_next_be = wbw_fifo_cbe_in ; + end + else + begin + next_data_out = intermediate_data ; + write_next_last = intermediate_last ; + write_next_be = intermediate_be ; + end +end + +always@(del_read_req or source_be or write_next_be) +begin + if (del_read_req) + next_be_out = source_be ; + else + next_be_out = write_next_be ; +end +/*================================================================================================ +WBW_FIFO read enable - read from WBW_FIFO is performed on posted writes, when data transfer +termination is received - transfer or disconnect with data. Reads are enabled during error +recovery also, since erroneous transaction must be pulled out of FIFO! +================================================================================================*/ +// wbw_fifo read enable input control + +assign wbw_renable_out = ~req_out && (do_posted_write || err_recovery) || + posted_write_req && ( ~write_req_int || (~rdy_out && ~intermediate_last) || (~wait_in && rtransfer_in && ~intermediate_last)) ; + +/*================================================================================================ +WBR_FIFO write enable control - +writes to FIFO are possible only when delayed read request is in progress and data transfer +or error termination is signalled. It is not enabled on retry or disconnect without data. +================================================================================================*/ +// wbr_fifo write enable control - enabled when transfer is in progress and data is transfered or error is signalled +assign wbr_fifo_wenable_out = del_read_req && ~wait_in && ( rtransfer_in || mabort_in || rerror_in ) ; + +/*================================================================================================ +WBR_FIFO control output for identifying data entries. +This is necesary because of prefetched reads, which partially succeed. On error, error entry +gets in to signal it on WISHBONE bus if WISHBONE master reads up to this entry. +================================================================================================*/ +assign wbr_fifo_control_out[`ADDR_CTRL_BIT] = 1'b0 ; +assign wbr_fifo_control_out[`LAST_CTRL_BIT] = last_transfered ; +assign wbr_fifo_control_out[`DATA_ERROR_CTRL_BIT] = rerror_in || (mabort_in && ~conf_cyc_bc) ; +assign wbr_fifo_control_out[`UNUSED_CTRL_BIT] = 1'b0 ; + +// retry expired error for posted writes control +//assign err_rty_exp_out = posted_write_req && ~wait_in && retry_in && retry_expired && ~rtransfer_in; +assign err_rty_exp_out = 1'b0 ; + +// error source and error signal output control logic - only for posted writes +assign err_source_out = mabort_in /*|| err_rty_exp_out*/ ; + +assign err_signal_out = /*err_rty_exp_out || */ posted_write_req && ~wait_in && (mabort_in || rerror_in) ; + +//assign del_rty_exp_out = (~wait_in && (del_read_req || del_write_req)) && (retry_in && retry_expired && ~rtransfer_in) ; +assign del_rty_exp_out = 1'b0 ; + +assign del_error_out = ~wait_in && (del_write_req || del_read_req) && ( (mabort_in && ~conf_cyc_bc) || rerror_in ) ; + +wire del_write_complete = del_write_req && ~wait_in && ( rtransfer_in || rerror_in || mabort_in ) ; +wire del_read_complete = del_read_req && ~wait_in && ( rerror_in || mabort_in || last_transfered || ( retry_in && ~first_in ) ) ; + +assign del_complete_out = ~wait_in && ( del_write_complete || del_read_complete ) ; + +// next last output generation +assign next_last_out = del_write_req || del_read_req && ( ~del_burst_in || read_bound ) || posted_write_req && ( write_next_last ) ; +/*================================================================================================================== +Error recovery FF gets a value of one, when during posted write error occurs. It is cleared when all the data provided +for erroneous transaction is pulled out of WBW_FIFO +==================================================================================================================*/ + +// error recovery flip flop input - used when posted write is terminated with an error +always@( + err_recovery or + last_out or + wlast or + err_signal_out or + intermediate_last +) +begin + // when error recovery is not set - drive its input so it gets set + if ( ~err_recovery ) + err_recovery_in = ~last_out && ~intermediate_last && err_signal_out ; + else + // when error recovery is set, wbw_fifo is enabled - clear err_recovery when last data entry of erroneous transaction is pulled out of fifo + err_recovery_in = ~wlast ; +end + +wire data_out_load = (posted_write_req || del_write_req) && ( !rdy_out || ( !wait_in && rtransfer_in ) ) ; + +wire be_out_load = (req_out && !rdy_out) || ( posted_write_req && !wait_in && rtransfer_in ) ; + +wire last_load = req_out && ( ~rdy_out || ~wait_in && wtransfer_in ) ; + +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + data_out <= #`FF_DELAY 32'h0000_0000 ; + else + if ( data_out_load ) + data_out <= #`FF_DELAY intermediate_data ; +end + +always@(posedge clk_in or posedge reset_in) +begin + if ( reset_in ) + be_out <= #`FF_DELAY 4'hF ; + else + if ( be_out_load ) + be_out <= #`FF_DELAY posted_write_req ? intermediate_be : source_be ; +end + +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + current_last <= #`FF_DELAY 1'b0 ; + else + if ( last_load ) + current_last <= #`FF_DELAY next_last_out ; +end + +assign last_out = current_last ; +endmodule diff --git a/ethernet/source/pci/pci_out_reg.v b/ethernet/source/pci/pci_out_reg.v new file mode 100644 index 0000000..909e87f --- /dev/null +++ b/ethernet/source/pci/pci_out_reg.v @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "out_reg.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_out_reg.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// module inferes a single IOB output block as known in FPGA architectures +// It provides data flip flop with clock enable and output enable flip flop with clock enable +// This is tested in Xilinx FPGA - active low output enable +// Check polarity of output enable flip flop for specific architecure. +module pci_out_reg +( + reset_in, + clk_in, + dat_en_in, + en_en_in, + dat_in, + en_in, + en_out, + dat_out +); + +input reset_in, + clk_in, + dat_en_in, + en_en_in, + dat_in, + en_in ; + +output dat_out ; +output en_out ; + +reg dat_out, + en_out ; + +`ifdef ACTIVE_LOW_OE +wire en = ~en_in ; +`else +`ifdef ACTIVE_HIGH_OE +wire en = en_in ; +`endif +`endif + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + dat_out <= #`FF_DELAY 1'b0 ; + else if ( dat_en_in ) + dat_out <= #`FF_DELAY dat_in ; +end + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + `ifdef ACTIVE_LOW_OE + en_out <= #`FF_DELAY 1'b1 ; + `else + `ifdef ACTIVE_HIGH_OE + en_out <= #`FF_DELAY 1'b0 ; + `endif + `endif + else if ( en_en_in ) + en_out <= #`FF_DELAY en ; +end + +endmodule diff --git a/ethernet/source/pci/pci_par_crit.v b/ethernet/source/pci/pci_par_crit.v new file mode 100644 index 0000000..704f66f --- /dev/null +++ b/ethernet/source/pci/pci_par_crit.v @@ -0,0 +1,93 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "par_crit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_par_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.2 2003/02/13 18:26:33 mihad +// Cleaned up the code. No functional changes. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// this one is used in parity generator/checker for calculating parity signal + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_par_crit +( + par_out, + par_out_in, + pci_cbe_en_in, + data_par_in, + pci_cbe_in +) ; + +output par_out ; + +input par_out_in, + pci_cbe_en_in, + data_par_in ; + +input [3:0] pci_cbe_in ; + +assign par_out = pci_cbe_en_in ? par_out_in : ( pci_cbe_in[3] ^ pci_cbe_in[2] ^ pci_cbe_in[1] ^ pci_cbe_in[0] ^ data_par_in) ; + +endmodule diff --git a/ethernet/source/pci/pci_parity_check.v b/ethernet/source/pci/pci_parity_check.v new file mode 100644 index 0000000..ac1f253 --- /dev/null +++ b/ethernet/source/pci/pci_parity_check.v @@ -0,0 +1,339 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_parity_check.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_parity_check.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2003/02/13 18:26:33 mihad +// Cleaned up the code. No functional changes. +// +// Revision 1.5 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.4 2002/08/13 11:03:53 mihad +// Added a few testcases. Repaired wrong reset value for PCI_AM5 register. Repaired Parity Error Detected bit setting. Changed PCI_AM0 to always enabled(regardles of PCI_AM0 define), if image 0 is used as configuration image +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "pci_constants.v" +`include "bus_commands.v" + +module pci_parity_check +( + reset_in, + clk_in, + pci_par_in, + pci_par_out, + pci_par_en_out, + pci_perr_in, + pci_perr_out, + pci_perr_out_in, + pci_perr_en_out, + pci_serr_en_in, + pci_serr_out, + pci_serr_out_in, + pci_serr_en_out, + pci_frame_reg_in, + pci_frame_en_in, + pci_irdy_en_in, + pci_irdy_reg_in, + pci_trdy_reg_in, + pci_trdy_en_in, + pci_par_en_in, + pci_ad_out_in, + pci_ad_reg_in, + pci_cbe_in_in, + pci_cbe_reg_in, + pci_cbe_out_in, + pci_cbe_en_in, + pci_ad_en_in, + par_err_response_in, + par_err_detect_out, + perr_mas_detect_out, + + serr_enable_in, + sig_serr_out + +); + +// system inputs +input reset_in ; +input clk_in ; + +// pci signals that are monitored or generated by parity error checker +input pci_par_in ; // pci PAR input +output pci_par_out ; // pci_PAR output +output pci_par_en_out ; // pci PAR enable output +input pci_perr_in ; // PERR# input +output pci_perr_out ; // PERR# output +output pci_perr_en_out ; // PERR# buffer enable output +input pci_serr_en_in ; // SERR enable input +output pci_serr_out ; // SERR# output +input pci_serr_out_in ; // SERR# output value input +input pci_perr_out_in ; // PERR# output value input +output pci_serr_en_out ; // SERR# buffer enable output +input pci_frame_reg_in ; // frame from pci bus input +input pci_frame_en_in ; // frame enable driven by master state machine +input pci_irdy_en_in ; // irdy enable input from PCI master +input pci_irdy_reg_in ; // irdy from PCI bus +input pci_trdy_reg_in ; // target ready from PCI bus +input pci_trdy_en_in ; // target ready output enable +input pci_par_en_in ; // par enable input +input [31:0] pci_ad_out_in ; // data driven by bridge to PCI +input [31:0] pci_ad_reg_in ; // data driven by other agents on PCI +input [3:0] pci_cbe_in_in ; // cbe driven by outside agents +input [3:0] pci_cbe_reg_in ; // registered cbe driven by outside agents +input [3:0] pci_cbe_out_in ; // cbe driven by pci master state machine +input pci_ad_en_in ; // ad enable input +input par_err_response_in ; // parity error response bit from conf.space +output par_err_detect_out ; // parity error detected signal out +output perr_mas_detect_out ; // master asserted PERR or sampled PERR asserted +input serr_enable_in ; // system error enable bit from conf.space +output sig_serr_out ; // signalled system error output for configuration space +input pci_cbe_en_in ; + +// FFs for frame input - used for determining whether PAR is sampled for address phase or for data phase +reg frame_dec2 ; +reg check_perr ; + +/*======================================================================================================================= +CBE lines' parity is needed for overall parity calculation +=======================================================================================================================*/ +wire par_cbe_out = pci_cbe_out_in[3] ^ pci_cbe_out_in[2] ^ pci_cbe_out_in[1] ^ pci_cbe_out_in[0] ; +wire par_cbe_in = pci_cbe_reg_in[3] ^ pci_cbe_reg_in[2] ^ pci_cbe_reg_in[1] ^ pci_cbe_reg_in[0] ; + +/*======================================================================================================================= +Parity generator - parity is generated and assigned to output on every clock edge. PAR output enable is active +one clock cycle after data output enable. Depending on whether master is performing access or target is responding, +apropriate cbe data is included in parity generation. Non - registered CBE is used during reads through target SM +=======================================================================================================================*/ + +// generate appropriate par signal +wire data_par = (pci_ad_out_in[31] ^ pci_ad_out_in[30] ^ pci_ad_out_in[29] ^ pci_ad_out_in[28]) ^ + (pci_ad_out_in[27] ^ pci_ad_out_in[26] ^ pci_ad_out_in[25] ^ pci_ad_out_in[24]) ^ + (pci_ad_out_in[23] ^ pci_ad_out_in[22] ^ pci_ad_out_in[21] ^ pci_ad_out_in[20]) ^ + (pci_ad_out_in[19] ^ pci_ad_out_in[18] ^ pci_ad_out_in[17] ^ pci_ad_out_in[16]) ^ + (pci_ad_out_in[15] ^ pci_ad_out_in[14] ^ pci_ad_out_in[13] ^ pci_ad_out_in[12]) ^ + (pci_ad_out_in[11] ^ pci_ad_out_in[10] ^ pci_ad_out_in[9] ^ pci_ad_out_in[8]) ^ + (pci_ad_out_in[7] ^ pci_ad_out_in[6] ^ pci_ad_out_in[5] ^ pci_ad_out_in[4]) ^ + (pci_ad_out_in[3] ^ pci_ad_out_in[2] ^ pci_ad_out_in[1] ^ pci_ad_out_in[0]) ; + +wire par_out_only = data_par ^ par_cbe_out ; + +pci_par_crit par_gen +( + .par_out (pci_par_out), + .par_out_in (par_out_only), + .pci_cbe_en_in (pci_cbe_en_in), + .data_par_in (data_par), + .pci_cbe_in (pci_cbe_in_in) +) ; + +// PAR enable = ad output enable delayed by one clock +assign pci_par_en_out = pci_ad_en_in ; + +/*======================================================================================================================= +Parity checker - parity is checked on every clock cycle. When parity error is detected, appropriate action is taken +to signal address parity errors on SERR if enabled and data parity errors on PERR# if enabled. Logic also drives +outputs to configuration space to set appropriate status bits if parity error is detected. PAR signal is checked on +master read operations or writes through pci target. Master read is performed when master drives irdy output and +doesn't drive ad lines. Writes through target are performed when target is driving trdy and doesn't drive ad lines. +=======================================================================================================================*/ + +// equation indicating whether to check and generate or not PERR# signal on next cycle +wire perr_generate = ~pci_par_en_in && ~pci_ad_en_in // par was not generated on this cycle, so it should be checked + && ((pci_irdy_en_in && ~pci_trdy_reg_in) || // and master is driving irdy and target is signaling ready + (pci_trdy_en_in && ~pci_irdy_reg_in)) ; // or target is driving trdy and master is signaling ready + +wire data_in_par = (pci_ad_reg_in[31] ^ pci_ad_reg_in[30] ^ pci_ad_reg_in[29] ^ pci_ad_reg_in[28]) ^ + (pci_ad_reg_in[27] ^ pci_ad_reg_in[26] ^ pci_ad_reg_in[25] ^ pci_ad_reg_in[24]) ^ + (pci_ad_reg_in[23] ^ pci_ad_reg_in[22] ^ pci_ad_reg_in[21] ^ pci_ad_reg_in[20]) ^ + (pci_ad_reg_in[19] ^ pci_ad_reg_in[18] ^ pci_ad_reg_in[17] ^ pci_ad_reg_in[16]) ^ + (pci_ad_reg_in[15] ^ pci_ad_reg_in[14] ^ pci_ad_reg_in[13] ^ pci_ad_reg_in[12]) ^ + (pci_ad_reg_in[11] ^ pci_ad_reg_in[10] ^ pci_ad_reg_in[9] ^ pci_ad_reg_in[8]) ^ + (pci_ad_reg_in[7] ^ pci_ad_reg_in[6] ^ pci_ad_reg_in[5] ^ pci_ad_reg_in[4]) ^ + (pci_ad_reg_in[3] ^ pci_ad_reg_in[2] ^ pci_ad_reg_in[1] ^ pci_ad_reg_in[0]) ; + +//wire perr = (cbe_par_reg ^ pci_par_in ^ data_in_par) ; +wire perr ; +wire perr_n ; +wire perr_en ; + +assign pci_perr_out = perr_n ; + +// parity error output assignment +//assign pci_perr_out = ~(perr && perr_generate) ; + +wire non_critical_par = par_cbe_in ^ data_in_par ; + +pci_perr_crit perr_crit_gen +( + .perr_out (perr), + .perr_n_out (perr_n), + .non_critical_par_in(non_critical_par), + .pci_par_in (pci_par_in), + .perr_generate_in (perr_generate) +) ; + +// PERR# enable +wire pci_perr_en_reg ; +pci_perr_en_crit perr_en_crit_gen +( + .reset_in (reset_in), + .clk_in (clk_in), + .perr_en_out (pci_perr_en_out), + .perr_en_reg_out (pci_perr_en_reg), + .non_critical_par_in (non_critical_par), + .pci_par_in (pci_par_in), + .perr_generate_in (perr_generate), + .par_err_response_in (par_err_response_in) +) ; + +// address phase decoding +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + frame_dec2 <= #`FF_DELAY 1'b0 ; + else + frame_dec2 <= #`FF_DELAY pci_frame_reg_in ; +end + +// address phase parity error checking - done after address phase is detected - which is - when bridge's master is not driving frame, +// frame was asserted on previous cycle and was not asserted two cycles before. +wire check_for_serr_on_first = ~pci_frame_reg_in && frame_dec2 && ~pci_frame_en_in ; + +reg check_for_serr_on_second ; +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + check_for_serr_on_second <= #`FF_DELAY 1'b0 ; + else + check_for_serr_on_second <= #`FF_DELAY check_for_serr_on_first && ( pci_cbe_reg_in == `BC_DUAL_ADDR_CYC ) ; +end + +wire check_for_serr = check_for_serr_on_first || check_for_serr_on_second ; + +wire serr_generate = check_for_serr && serr_enable_in && par_err_response_in ; + +pci_serr_en_crit serr_en_crit_gen +( + .serr_en_out (pci_serr_en_out), + .pci_par_in (pci_par_in), + .non_critical_par_in(non_critical_par), + .serr_generate_in (serr_generate) +); + + +// serr is enabled only for reporting errors - route this signal to configuration space +assign sig_serr_out = pci_serr_en_in ; + +// SERR# output is always 0, just enable is driven apropriately +pci_serr_crit serr_crit_gen +( + .serr_out (pci_serr_out), + .non_critical_par_in (non_critical_par), + .pci_par_in (pci_par_in), + .serr_check_in (check_for_serr) +); + +/*======================================================================================================================================= + Synchronizing mechanism detecting what is supposed to be done - PERR# generation or PERR# checking +=======================================================================================================================================*/ +// perr should be checked one clock after PAR is generated +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + check_perr <= #`FF_DELAY 1'b0 ; + else + check_perr <= #`FF_DELAY pci_par_en_in ; +end + +wire perr_sampled_in = ~pci_perr_in && check_perr ; +reg perr_sampled ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + perr_sampled <= #`FF_DELAY 1'b0 ; + else + perr_sampled <= #`FF_DELAY perr_sampled_in ; +end + +// assign output for parity error detected bit +assign par_err_detect_out = ~pci_serr_out_in || ~pci_perr_out_in ;//|| perr_sampled ; MihaD - removed - detected parity error is set only during Master Reads or Target Writes + +// FF indicating that that last operation was done as bus master +reg frame_and_irdy_en_prev ; +reg frame_and_irdy_en_prev_prev ; +reg master_perr_report ; +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + begin + master_perr_report <= #`FF_DELAY 1'b0 ; + frame_and_irdy_en_prev <= #`FF_DELAY 1'b0 ; + frame_and_irdy_en_prev_prev <= #`FF_DELAY 1'b0 ; + end + else + begin + master_perr_report <= #`FF_DELAY frame_and_irdy_en_prev_prev ; + frame_and_irdy_en_prev <= #`FF_DELAY pci_irdy_en_in && pci_frame_en_in ; + frame_and_irdy_en_prev_prev <= #`FF_DELAY frame_and_irdy_en_prev ; + end +end + +assign perr_mas_detect_out = master_perr_report && ( (par_err_response_in && perr_sampled) || pci_perr_en_reg ) ; + +endmodule diff --git a/ethernet/source/pci/pci_pci_decoder.v b/ethernet/source/pci/pci_pci_decoder.v new file mode 100644 index 0000000..724c2b4 --- /dev/null +++ b/ethernet/source/pci/pci_pci_decoder.v @@ -0,0 +1,204 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_decoder.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_pci_decoder.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_pci_decoder (hit, addr_out, + addr_in, bc_in, + base_addr, mask_addr, tran_addr, at_en, + mem_io_space, mem_en, io_en) ; + +// Decoding address size parameter - for FPGAs 1MegByte is recommended +// MAXIMUM is 20 (4KBytes), length 12 is 1 MByte !!! +parameter decode_len = 12 ; + +//########################################################################################################### +// ALL COMMENTS are written as there were decode_len 20. This number and 12 (32 - 20) are assigning the +// numbers of decoded and compared bits, etc. +//########################################################################################################### + +/*----------------------------------------------------------------------------------------------------------- +DECODER interface decodes input address (ADDR_IN); what means that it validates (HIT), if input address +falls within the defined image space boundaries. Image space boundarie is defined with image base address +register (BASE_ADDR) and address mask register (MASK_ADDR). +Beside that, it also translates (maps) the input address to the output address (ADDR_OUT), regarding the +translation address register (TRAN_ADDR) and the address mask register. +-----------------------------------------------------------------------------------------------------------*/ + +// output control +output hit ; +// output address +output [31:0] addr_out ; +// input address and bus command +input [31:0] addr_in ; +input [3:0] bc_in ; + +// input registers - 12 LSbits are not valid since the smallest possible size is 4KB ! +input [31:(32-decode_len)] base_addr ; +input [31:(32-decode_len)] mask_addr ; +input [31:(32-decode_len)] tran_addr ; + +// input bit[2] of the Image Control register used to enable the address translation ! +input at_en ; + +// memory or io space selection and its enable signals ! +input mem_io_space ; +input mem_en ; +input io_en ; + +/*----------------------------------------------------------------------------------------------------------- +Internal signals ! +-----------------------------------------------------------------------------------------------------------*/ + +// bit[31] if address mask register is IMAGE ENABLE bit (img_en) +wire img_en ; + +// addr_in_compare are masked input address bits that are compared with masked base_addr +wire [31:(32-decode_len)] addr_in_compare ; +// base_addr_compare are masked base address bits that are compared with masked addr_in +wire [31:(32-decode_len)] base_addr_compare ; + +/*----------------------------------------------------------------------------------------------------------- +Decoding the input address! +This logic produces the loghest path in this module! + +20 MSbits of input addres are as well as base address (20 bits) masked with corrected address mask. Only +masked bits of each vector are actually logically compared. +Bit[31] of address mask register is used to enable the image space ! +Because of PCI bus specifications, there is also the comparison of memory/io selection (mem_io_space) and +its appropriate enable bit (mem_en / io_en). +-----------------------------------------------------------------------------------------------------------*/ + +assign addr_in_compare = (addr_in[31:(32-decode_len)] & mask_addr) ; + +assign base_addr_compare = (base_addr & mask_addr) ; + +assign img_en = mask_addr[31] ; + +wire addr_hit = (addr_in_compare == base_addr_compare) ; + +wire space_hit = (!mem_io_space && mem_en && img_en) || (mem_io_space && io_en && img_en) ; + +reg bc_hit ; +always@(bc_in or mem_io_space) +begin // Allowed bus commands for accesses through IMAGEs to WB bus - BC_CONF_WRITE/READ are not used with address claim!!! + case ( {bc_in[3:1], mem_io_space} ) + 4'b001_1, // BC_IO_READ or BC_IO_WRITE and IO space + 4'b011_0, // BC_MEM_READ or BC_MEM_WRITE and MEM space + 4'b110_0, // BC_MEM_READ_MUL and MEM space - BC_DUAL_ADDR_CYC must NOT be allowed! + 4'b111_0: // BC_MEM_READ_LN or BC_MEM_WRITE_INVAL and MEM space + bc_hit <= 1'b1 ; + default: + bc_hit <= 1'b0 ; + endcase +end + +wire bc_forbid = bc_in[3] && bc_in[2] && !bc_in[1] && bc_in[0] ; // BC_DUAL_ADDR_CYC must NOT be allowed! + + +assign hit = (addr_hit && space_hit && bc_hit && !bc_forbid) ; + +/*----------------------------------------------------------------------------------------------------------- +Translating the input address! + +Translation of input address is not implemented if ADDR_TRAN_IMPL is not defined + +20 MSbits of input address are masked with negated value of the corrected address mask in order to get +address bits of the input address which won't be replaced with translation address bits. +Translation address bits (20 bits) are masked with corrected address mask. Only masked bits of vector are +actually valid, all others are zero. +Boath vectors are bit-wise ORed in order to get the valid translation address with an offset of an input +address. +12 LSbits of an input address are assigned to 12 LSbits of an output addres. +-----------------------------------------------------------------------------------------------------------*/ + +`ifdef ADDR_TRAN_IMPL + // if Address Translation Enable bit is set, then translation address is used othervise input address is used! + // addr_in_combine input address bits are not replaced with translation address! + wire [31:(32-decode_len)] addr_in_combine ; + // tran_addr_combine are masked and combined with addr_in_combine! + reg [31:(32-decode_len)] tran_addr_combine ; + + assign addr_in_combine = (addr_in[31:(32-decode_len)] & ~mask_addr) ; + always@(at_en or tran_addr or mask_addr or addr_in) + begin + if (at_en) + begin + tran_addr_combine <= (tran_addr & mask_addr) ; + end + else + begin + tran_addr_combine <= (addr_in[31:(32-decode_len)] & mask_addr) ; + end + end + + assign addr_out[31:(32-decode_len)] = (addr_in_combine | tran_addr_combine) ; + assign addr_out[(31-decode_len):0] = addr_in [(31-decode_len):0] ; +`else + assign addr_out = addr_in ; +`endif + +endmodule + diff --git a/ethernet/source/pci/pci_pci_tpram.v b/ethernet/source/pci/pci_pci_tpram.v new file mode 100644 index 0000000..9db2a75 --- /dev/null +++ b/ethernet/source/pci/pci_pci_tpram.v @@ -0,0 +1,467 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// Generic Two-Port Synchronous RAM //// +//// //// +//// This file is part of pci bridge project //// +//// http://www.opencores.org/cvsweb.shtml/pci/ //// +//// //// +//// Description //// +//// This block is a wrapper with common two-port //// +//// synchronous memory interface for different //// +//// types of ASIC and FPGA RAMs. Beside universal memory //// +//// interface it also provides behavioral model of generic //// +//// two-port synchronous RAM. //// +//// It should be used in all OPENCORES designs that want to be //// +//// portable accross different target technologies and //// +//// independent of target memory. //// +//// //// +//// Supported ASIC RAMs are: //// +//// - Artisan Double-Port Sync RAM //// +//// - Avant! Two-Port Sync RAM (*) //// +//// - Virage 2-port Sync RAM //// +//// //// +//// Supported FPGA RAMs are: //// +//// - Xilinx Virtex RAMB4_S16_S16 //// +//// //// +//// To Do: //// +//// - fix Avant! //// +//// - xilinx rams need external tri-state logic //// +//// - add additional RAMs (Altera, VS etc) //// +//// //// +//// Author(s): //// +//// - Damjan Lampret, lampret@opencores.org //// +//// - Miha Dolenc, mihad@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_pci_tpram.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2004/08/19 15:27:34 mihad +// Changed minimum pci image size to 256 bytes because +// of some PC system problems with size of IO images. +// +// Revision 1.3 2003/10/17 09:11:52 markom +// mbist signals updated according to newest convention +// +// Revision 1.2 2003/08/14 13:06:03 simons +// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.7 2002/10/18 03:36:37 tadejm +// Changed wrong signal name mbist_sen into mbist_ctrl_i. +// +// Revision 1.6 2002/10/17 22:51:08 tadejm +// Changed BIST signals for RAMs. +// +// Revision 1.5 2002/10/11 10:09:01 mihad +// Added additional testcase and changed rst name in BIST to trst +// +// Revision 1.4 2002/10/08 17:17:06 mihad +// Added BIST signals for RAMs. +// +// Revision 1.3 2002/09/30 17:22:27 mihad +// Added support for Virtual Silicon two port RAM. Didn't run regression on it yet! +// +// Revision 1.2 2002/08/19 16:51:36 mihad +// Extracted distributed RAM module from wb/pci_tpram.v to its own file, got rid of undef directives +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "pci_constants.v" + +module pci_pci_tpram +( + // Generic synchronous two-port RAM interface + clk_a, + rst_a, + ce_a, + we_a, + oe_a, + addr_a, + di_a, + do_a, + clk_b, + rst_b, + ce_b, + we_b, + oe_b, + addr_b, + di_b, + do_b +`ifdef PCI_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif +); + +// +// Default address and data buses width +// +parameter aw = 8; +parameter dw = 40; + +// +// Generic synchronous two-port RAM interface +// +input clk_a; // Clock +input rst_a; // Reset +input ce_a; // Chip enable input +input we_a; // Write enable input +input oe_a; // Output enable input +input [aw-1:0] addr_a; // address bus inputs +input [dw-1:0] di_a; // input data bus +output [dw-1:0] do_a; // output data bus +input clk_b; // Clock +input rst_b; // Reset +input ce_b; // Chip enable input +input we_b; // Write enable input +input oe_b; // Output enable input +input [aw-1:0] addr_b; // address bus inputs +input [dw-1:0] di_b; // input data bus +output [dw-1:0] do_b; // output data bus + +`ifdef PCI_BIST +// debug chain signals +input mbist_si_i; // bist scan serial in +output mbist_so_o; // bist scan serial out +input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + +// +// Internal wires and registers +// + +`ifdef PCI_VS_STP + `define PCI_PCI_RAM_SELECTED + `ifdef PCI_BIST + vs_hdtp_64x40_bist i_vs_hdtp_64x40_bist + `else + vs_hdtp_64x40 i_vs_hdtp_64x40 + `endif + ( + .RCK (clk_b), + .WCK (clk_a), + .RADR (addr_b), + .WADR (addr_a), + .DI (di_a), + .DOUT (do_b), + .REN (1'b0), + .WEN (!we_a) + `ifdef PCI_BIST + , + // debug chain signals + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) + `endif + ); + + assign do_a = 0 ; +`endif + +`ifdef PCI_ARTISAN_SDP + `define PCI_PCI_RAM_SELECTED + // + // Instantiation of ASIC memory: + // + // Artisan Synchronous Double-Port RAM (ra2sh) + // + `ifdef PCI_BIST + art_hsdp_64x40_bist /*#(dw, 1<> 1)) + begin + start_sent = 1'b1 ; + sda_oe_en = 1'b1 ; + end + + // after half clock period of driving the sda low, the only possible + // transition is to send state. + // if send bit is not active, stop the procedure - undrive sda + if (clk_gen_cnt == period_cnt) + begin + clk_gen_cnt_clr = 1'b1 ; + if (send_bit) + begin + tx_rx_next_state = tx_rx_send_bits ; + end + else + begin + sda_oe = 1'b0 ; + sda_oe_en = 1'b1 ; + tx_rx_next_state = tx_rx_idle ; + end + end + end + + tx_rx_send_bits: + begin + clk_gen_cnt_en = 1'b1 ; + + // generate high to low transition on the scl line immediately + if (clk_gen_cnt == 'h0) + begin + scl_oe = 1'b1 ; + scl_oe_en = 1'b1 ; + end + + // after half of clock low time, load new value for sda oe, depending on the + // msb bit in the shift register + if (clk_gen_cnt == (period_cnt >> 2)) + begin + sda_oe = ~tx_shift_reg[7] ; + sda_oe_en = 1'b1 ; + bit_sent = 1'b1 ; + end + + // after clock low time, generate low to high transition on the scl line + if (clk_gen_cnt == (period_cnt >> 1)) + begin + scl_oe = 1'b0 ; + scl_oe_en = 1'b1 ; + end + + // after clock high time, check what to do next + if (clk_gen_cnt == (period_cnt)) + begin + clk_gen_cnt_clr = 1'b1 ; + + if (~send_bit) + begin + // after transmiting all the bits, the only possible transition is to the state + // that checks the eprom acknowledge + if (rec_ack) + tx_rx_next_state = tx_rx_rec_ack ; + else + begin + sda_oe = 1'b0 ; + sda_oe_en = 1'b1 ; + tx_rx_next_state = tx_rx_idle ; + end + end + end + end + + tx_rx_rec_bits: + begin + clk_gen_cnt_en = 1'b1 ; + sda_i_reg_en = 1'b1 ; + + // generate high to low transition on the scl line immediately + if (clk_gen_cnt == 'h0) + begin + scl_oe = 1'b1 ; + scl_oe_en = 1'b1 ; + end + + // after half of clock low time, disable sda driver + if (clk_gen_cnt == (period_cnt >> 2)) + begin + sda_oe = 1'b0 ; + sda_oe_en = 1'b1 ; + end + + // after clock low time, generate low to high transition on the scl line + if (clk_gen_cnt == (period_cnt >> 1)) + begin + scl_oe = 1'b0 ; + scl_oe_en = 1'b1 ; + end + + // after half of clock high time, report received bit + if (clk_gen_cnt == ((period_cnt >> 1) + (period_cnt >> 2)) ) + begin + bit_rec = 1'b1 ; + end + + // after clock period is finished, check the next operation + if (clk_gen_cnt == (period_cnt)) + begin + clk_gen_cnt_clr = 1'b1 ; + + if (~rec_bit) + begin + // when all bits are received, only nack or ack next states are possible + if (send_ack) + tx_rx_next_state = tx_rx_send_ack ; + else if (send_nack) + tx_rx_next_state = tx_rx_send_nack ; + else + begin + tx_rx_next_state = tx_rx_idle ; + end + end + end + end + + tx_rx_send_ack: + begin + clk_gen_cnt_en = 1'b1 ; + + // generate high to low transition on the scl line + if (clk_gen_cnt == 'h0) + begin + scl_oe = 1'b1 ; + scl_oe_en = 1'b1 ; + end + + // after half of clock low time, enable the sda driver + if (clk_gen_cnt == (period_cnt >> 2)) + begin + sda_oe = 1'b1 ; + sda_oe_en = 1'b1 ; + ack_sent = 1'b1 ; + end + + // after clock low time, disable the scl driver - generate low to high transition on the scl line + if (clk_gen_cnt == (period_cnt >> 1)) + begin + scl_oe = 1'b0 ; + scl_oe_en = 1'b1 ; + end + + // after clock period time expires, check what to do next + if (clk_gen_cnt == period_cnt) + begin + clk_gen_cnt_clr = 1'b1 ; + + // after the byte is acknowledged, the only possible next state is receive bits + // state + if (rec_bit) + tx_rx_next_state = tx_rx_rec_bits ; + else + begin + // this should never happen + sda_oe = 1'b0 ; + sda_oe_en = 1'b1 ; + + tx_rx_next_state = tx_rx_idle ; + end + end + end + + tx_rx_rec_ack: + begin + + clk_gen_cnt_en = 1'b1 ; + sda_i_reg_en = 1'b1 ; + + // generate high to low transition on the scl line + if (clk_gen_cnt == 'h0) + begin + scl_oe = 1'b1 ; + scl_oe_en = 1'b1 ; + end + + // after half of clock low time, disable the sda driver + if (clk_gen_cnt == (period_cnt >> 2)) + begin + sda_oe = 1'b0 ; + sda_oe_en = 1'b1 ; + end + + // after clock low time, disable the scl driver - generate low to high transition on the scl line + if (clk_gen_cnt == (period_cnt >> 1)) + begin + scl_oe = 1'b0 ; + scl_oe_en = 1'b1 ; + end + + // after 1/2 clock high time, report ack or nack condition, depending on the sda input state + if (clk_gen_cnt == ((period_cnt >> 1) + (period_cnt >> 2)) ) + begin + ack_rec = ~sda_i_reg ; + nack_rec = sda_i_reg ; + end + + // after clock period time expires, check what to do next + if (clk_gen_cnt == period_cnt) + begin + clk_gen_cnt_clr = 1'b1 ; + + if (send_bit) + tx_rx_next_state = tx_rx_send_bits ; + else if (rec_bit) + tx_rx_next_state = tx_rx_rec_bits ; + else if (send_stop) + tx_rx_next_state = tx_rx_stop ; + else if (send_start) + tx_rx_next_state = tx_rx_restart ; + else + begin + // this should never happen + tx_rx_next_state = tx_rx_idle ; + end + end + end + + tx_rx_send_nack: + begin + clk_gen_cnt_en = 1'b1 ; + + // generate high to low transition on the scl line + if (clk_gen_cnt == 'h0) + begin + scl_oe = 1'b1 ; + scl_oe_en = 1'b1 ; + end + + // after half of clock low time, disable the sda driver + if (clk_gen_cnt == (period_cnt >> 2)) + begin + sda_oe = 1'b0 ; + sda_oe_en = 1'b1 ; + nack_sent = 1'b1 ; + end + + // after clock low time, disable the scl driver - generate low to high transition on the scl line + if (clk_gen_cnt == (period_cnt >> 1)) + begin + scl_oe = 1'b0 ; + scl_oe_en = 1'b1 ; + end + + // after clock period time expires, check what to do next + if (clk_gen_cnt == period_cnt) + begin + clk_gen_cnt_clr = 1'b1 ; + + // after the no acknowledge is sent, the only possible next state is stop + // state + if (send_stop) + tx_rx_next_state = tx_rx_stop ; + else + begin + // this should never happen + tx_rx_next_state = tx_rx_idle ; + end + end + end + + tx_rx_restart: + begin + clk_gen_cnt_en = 1'b1 ; + + // generate high to low transition + if (clk_gen_cnt == 'h0) + begin + scl_oe = 1'b1 ; + scl_oe_en = 1'b1 ; + end + + // after half of clock low time, release sda line + if (clk_gen_cnt == (period_cnt >> 2)) + begin + sda_oe = 1'b0 ; + sda_oe_en = 1'b1 ; + end + + // generate low to high transition + if (clk_gen_cnt == (period_cnt >> 1)) + begin + clk_gen_cnt_clr = 1'b1 ; + + scl_oe = 1'b0 ; + scl_oe_en = 1'b1 ; + + if (send_start) + tx_rx_next_state = tx_rx_start ; + else + tx_rx_next_state = tx_rx_idle ; + end + end + + tx_rx_stop: + begin + clk_gen_cnt_en = 1'b1 ; + + // generate high to low transition + if (clk_gen_cnt == 'h0) + begin + scl_oe = 1'b1 ; + scl_oe_en = 1'b1 ; + end + + // after half of clock low time, drive sda line low + if (clk_gen_cnt == (period_cnt >> 2)) + begin + sda_oe = 1'b1 ; + sda_oe_en = 1'b1 ; + end + + // generate low to high transition + if (clk_gen_cnt == (period_cnt >> 1)) + begin + scl_oe = 1'b0 ; + scl_oe_en = 1'b1 ; + end + + // after full clock period, release the sda line + if (clk_gen_cnt == period_cnt) + begin + sda_oe = 1'b0 ; + sda_oe_en = 1'b1 ; + stop_sent = 1'b1 ; + + tx_rx_next_state = tx_rx_idle ; + end + end + + endcase +end + +reg [rw_seq_state_width - 1:0] rw_seq_state ; + +reg doing_read , + doing_write , + doing_seq_read , + adr_set ; + +reg [ 3: 0] bits_transfered ; + +always@(posedge clk_i or posedge reset_i) +begin + if (reset_i) + begin + rw_seq_state <= rw_seq_idle ; + adr_set <= 1'b0 ; + doing_read <= 1'b0 ; + doing_write <= 1'b0 ; + doing_seq_read <= 1'b0 ; + dat_o <= 'h0 ; + tx_shift_reg <= 'h0 ; + send_start <= 'h0 ; + send_stop <= 'h0 ; + send_bit <= 'h0 ; + send_nack <= 'h0 ; + rec_ack <= 'h0 ; + no_ack_o <= 'h0 ; + bits_transfered <= 'h0 ; + write_done_o <= 'h0 ; + dat_rdy_o <= 'h0 ; + send_ack <= 'h0 ; + rec_bit <= 'h0 ; + end + else + begin + + case (rw_seq_state) + + rw_seq_idle: + begin + tx_shift_reg <= {4'b1010, adr_i[10: 8], 1'b0} ; + adr_set <= 1'b0 ; + + if ( tx_rx_sm_idle & ~(doing_write | doing_read | doing_seq_read) ) + begin + if (do_write_i | do_rnd_read_i | do_seq_read_i) + begin + rw_seq_state <= rw_seq_tx_ctrl ; + send_start <= 1'b1 ; + end + + if (do_write_i) + doing_write <= 1'b1 ; + else if (do_rnd_read_i) + doing_read <= 1'b1 ; + else if (do_seq_read_i) + doing_seq_read <= 1'b1 ; + end + else + begin + doing_write <= 1'b0 ; + doing_read <= 1'b0 ; + doing_seq_read <= 1'b0 ; + end + end + + rw_seq_tx_ctrl: + begin + if (send_start) + begin + bits_transfered <= 'h0 ; + + if (start_sent) + begin + send_start <= 1'b0 ; + send_bit <= 1'b1 ; + end + end + else if (send_bit) + begin + if (bit_sent) + begin + bits_transfered <= bits_transfered + 1'b1 ; + tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ; + end + + if (bits_transfered == 'h8) + begin + send_bit <= 1'b0 ; + rec_ack <= 1'b1 ; + end + end + else if (rec_ack) + begin + bits_transfered <= 'h0 ; + + if (ack_rec | nack_rec) + rec_ack <= 1'b0 ; + + if (ack_rec) + begin + if (doing_write | ~adr_set) + begin + rw_seq_state <= rw_seq_tx_adr ; + tx_shift_reg <= adr_i[ 7: 0] ; + send_bit <= 1'b1 ; + end + else + begin + rw_seq_state <= rw_seq_rx_byte ; + rec_bit <= 1'b1 ; + end + end + else if (nack_rec) + begin + no_ack_o <= 1'b1 ; + send_stop <= 1'b1 ; + end + end + else if (send_stop) + begin + no_ack_o <= 1'b0 ; + + if (stop_sent) + begin + send_stop <= 1'b0 ; + rw_seq_state <= rw_seq_idle ; + end + end + end + + rw_seq_tx_adr: + begin + if (send_bit) + begin + if (bit_sent) + begin + bits_transfered <= bits_transfered + 1'b1 ; + tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ; + end + + if (bits_transfered == 'h8) + begin + send_bit <= 1'b0 ; + rec_ack <= 1'b1 ; + end + end + else if (rec_ack) + begin + bits_transfered <= 'h0 ; + + if (ack_rec | nack_rec) + rec_ack <= 1'b0 ; + + if (ack_rec) + begin + + adr_set <= 1'b1 ; + + if (doing_write) + begin + send_bit <= 1'b1 ; + rw_seq_state <= rw_seq_tx_byte ; + tx_shift_reg <= dat_i ; + end + else if (doing_read | doing_seq_read) + begin + send_start <= 1'b1 ; + rw_seq_state <= rw_seq_tx_ctrl ; + tx_shift_reg <= 8'b10100001 ; + end + end + else if (nack_rec) + begin + no_ack_o <= 1'b1 ; + send_stop <= 1'b1 ; + end + end + else if (send_stop) + begin + no_ack_o <= 1'b0 ; + + if (stop_sent) + begin + send_stop <= 1'b0 ; + rw_seq_state <= rw_seq_idle ; + end + end + end + + rw_seq_tx_byte: + begin + if (send_bit) + begin + if (bit_sent) + begin + bits_transfered <= bits_transfered + 1'b1 ; + tx_shift_reg <= {tx_shift_reg[6:0], tx_shift_reg[0]} ; + end + + if (bits_transfered == 'h8) + begin + send_bit <= 1'b0 ; + rec_ack <= 1'b1 ; + end + end + else if (rec_ack) + begin + bits_transfered <= 'h0 ; + + if (ack_rec | nack_rec) + begin + rec_ack <= 1'b0 ; + send_stop <= 1'b1 ; + end + + if (nack_rec) + no_ack_o <= 1'b1 ; + + if (ack_rec) + write_done_o <= 1'b1 ; + end + else if (send_stop) + begin + no_ack_o <= 1'b0 ; + write_done_o <= 1'b0 ; + + if (stop_sent) + begin + send_stop <= 1'b0 ; + rw_seq_state <= rw_seq_idle ; + end + end + end + + rw_seq_rx_byte: + begin + if (rec_bit) + begin + if (bit_rec) + begin + bits_transfered <= bits_transfered + 1'b1 ; + dat_o <= {dat_o[6:0], sda_i_reg} ; + end + + if (bits_transfered == 'h8) + begin + rec_bit <= 1'b0 ; + dat_rdy_o <= 1'b1 ; + if (doing_read) + send_nack <= 1'b1 ; + else + send_ack <= 1'b1 ; + end + end + else if (send_nack) + begin + dat_rdy_o <= 1'b0 ; + bits_transfered <= 'h0 ; + + if (nack_sent) + begin + send_stop <= 1'b1 ; + send_nack <= 1'b0 ; + end + end + else if (send_ack) + begin + dat_rdy_o <= 1'b0 ; + bits_transfered <= 'h0 ; + + if (~do_seq_read_i) + begin + send_ack <= 1'b0 ; + send_nack <= 1'b1 ; + end + else if (ack_sent) + begin + send_ack <= 1'b0 ; + rec_bit <= 1'b1 ; + end + end + else if (send_stop) + begin + if (stop_sent) + begin + send_stop <= 1'b0 ; + rw_seq_state <= rw_seq_idle ; + end + end + end + endcase + end +end + +endmodule // pci_spoci_ctrl \ No newline at end of file diff --git a/ethernet/source/pci/pci_sync_module.v b/ethernet/source/pci/pci_sync_module.v new file mode 100644 index 0000000..bffc876 --- /dev/null +++ b/ethernet/source/pci/pci_sync_module.v @@ -0,0 +1,170 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "sync_module.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_sync_module.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.3 2003/08/14 13:06:03 simons +// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. +// +// Revision 1.2 2003/03/26 13:16:18 mihad +// Added the reset value parameter to the synchronizer flop module. +// Added resets to all synchronizer flop instances. +// Repaired initial sync value in fifos. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_sync_module +( + set_clk_in, + delete_clk_in, + reset_in, + delete_set_out, + block_set_out, + delete_in +); + +// system inputs from two clock domains +input set_clk_in; +input delete_clk_in; +input reset_in; +// control outputs +output delete_set_out; +output block_set_out; +// control input +input delete_in; + +// internal signals +reg del_bit; +wire meta_del_bit; +reg sync_del_bit; +reg delayed_del_bit; +wire meta_bckp_bit; +reg sync_bckp_bit; +reg delayed_bckp_bit; + + +// DELETE_IN input FF - when set must be active, until it is sinchronously cleared +always@(posedge delete_clk_in or posedge reset_in) +begin + if (reset_in) + del_bit <= 1'b0; + else + begin + if (!delayed_bckp_bit && sync_bckp_bit) + del_bit <= 1'b0; + else if (delete_in) + del_bit <= 1'b1; + end +end +assign block_set_out = del_bit; + +// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability +pci_synchronizer_flop #(1, 0) delete_sync +( + .data_in (del_bit), + .clk_out (set_clk_in), + .sync_data_out (meta_del_bit), + .async_reset (reset_in) +) ; + +// Final synchronization of del_bit signal to the set clock domain +always@(posedge set_clk_in or posedge reset_in) +begin + if (reset_in) + sync_del_bit <= 1'b0; + else + sync_del_bit <= meta_del_bit; +end + +// Delayed sync_del_bit signal for one clock period pulse generation +always@(posedge set_clk_in or posedge reset_in) +begin + if (reset_in) + delayed_del_bit <= 1'b0; + else + delayed_del_bit <= sync_del_bit; +end + +assign delete_set_out = !delayed_del_bit && sync_del_bit; + +// interemediate stage to clk synchronization flip - flops - this ones are prone to metastability +pci_synchronizer_flop #(1, 0) clear_delete_sync +( + .data_in (sync_del_bit), + .clk_out (delete_clk_in), + .sync_data_out (meta_bckp_bit), + .async_reset (reset_in) +) ; + +// Final synchronization of sync_del_bit signal to the delete clock domain +always@(posedge delete_clk_in or posedge reset_in) +begin + if (reset_in) + sync_bckp_bit <= 1'b0; + else + sync_bckp_bit <= meta_bckp_bit; +end + +// Delayed sync_bckp_bit signal for one clock period pulse generation +always@(posedge delete_clk_in or posedge reset_in) +begin + if (reset_in) + delayed_bckp_bit <= 1'b0; + else + delayed_bckp_bit <= sync_bckp_bit; +end + +endmodule diff --git a/ethernet/source/pci/pci_synchronizer_flop.v b/ethernet/source/pci/pci_synchronizer_flop.v new file mode 100644 index 0000000..692ee2f --- /dev/null +++ b/ethernet/source/pci/pci_synchronizer_flop.v @@ -0,0 +1,106 @@ +//=========================================================================== +// $Id: pci_synchronizer_flop.v,v 1.1 2007-03-20 17:50:56 sithglan Exp $ +// +////////////////////////////////////////////////////////////////////// +//// //// +//// pci_synchronizer_flop //// +//// //// +//// This file is part of the general opencores effort. //// +//// //// +//// //// +//// Module Description: //// +//// //// +//// Make a rising-edge triggered flop with async reset with a //// +//// distinguished name so that it can be replaced with a flop //// +//// which does not make X's during simulation. //// +//// //// +//// This flop should be used instead of a regular flop for ALL //// +//// cross-clock-domain flops. Manually instantiating this //// +//// flop for all signals which must NEVER go to 1'bX during //// +//// simulation will make it possible for the user to //// +//// substitute a simulation model which does NOT have setup //// +//// and hold checks. //// +//// //// +//// If a target device library has a component which is //// +//// especially well suited to perform this function, it should //// +//// be instantiated by name in this file. Otherwise, the //// +//// behaviorial version of this module will be used. //// +//// //// +//// To Do: //// +//// Nothing //// +//// //// +//// Author(s): //// +//// - anynomous //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_synchronizer_flop.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/08/14 13:08:58 simons +// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +// If the vendor has a flop which is particularly good at settling out of +// metastability, it should be used here. +module pci_synchronizer_flop ( + data_in, clk_out, sync_data_out, async_reset +); +parameter width = 1 ; +parameter reset_val = 0 ; + + input [width-1:0] data_in; + input clk_out; + output [width-1:0] sync_data_out; + input async_reset; + + reg [width-1:0] sync_data_out; + + always @(posedge clk_out or posedge async_reset) + begin + if (async_reset == 1'b1) + begin + sync_data_out <= reset_val; + end + else + begin +// In gate-level simulation, must only go to 1'bX if the input is 1'bX or 1'bZ. +// This should NEVER go to 1'bX due to setup or hold violations. + sync_data_out <= data_in; + end + end +endmodule + diff --git a/ethernet/source/pci/pci_target32_clk_en.v b/ethernet/source/pci/pci_target32_clk_en.v new file mode 100644 index 0000000..4146689 --- /dev/null +++ b/ethernet/source/pci/pci_target32_clk_en.v @@ -0,0 +1,107 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_target32_clk_en.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_target32_clk_en.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_target32_clk_en +( + addr_phase, + config_access, + addr_claim_in, + pci_frame_in, + state_wait, + state_transfere, + state_default, + clk_enable +); + +input addr_phase ; // indicates registered address phase on PCI bus +input config_access ; // indicates configuration access +input addr_claim_in ; // indicates claimed input PCI address +input pci_frame_in ; // critical constrained input signal +input state_wait ; // indicates WAIT state of FSM +input state_transfere ; // indicates TRANSFERE state of FSM +input state_default ; // indicates DEFAULT state of FSM + +output clk_enable ; // FSM clock enable output + + +// clock enable signal when FSM is in IDLE state +wire s_idle_clk_en = ((addr_phase && config_access) || + (addr_phase && ~config_access && addr_claim_in)) ; + +// clock enable signal when FSM is in WAIT state or in DEFAULT state +wire s_wait_clk_en = (state_wait || state_default) ; + +// clock enable signal when FSM is in TRANSFERE state +wire s_tran_clk_en = (state_transfere && pci_frame_in) ; + + +// Clock enable signal for FSM with preserved hierarchy for minimum delay! +assign clk_enable = (s_idle_clk_en || s_wait_clk_en || s_tran_clk_en) ; + + +endmodule diff --git a/ethernet/source/pci/pci_target32_devs_crit.v b/ethernet/source/pci/pci_target32_devs_crit.v new file mode 100644 index 0000000..8968ab5 --- /dev/null +++ b/ethernet/source/pci/pci_target32_devs_crit.v @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_target32_devs_crit.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_target32_devs_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_target32_devs_crit +( + devs_w, + devs_w_frm, + devs_w_frm_irdy, + pci_frame_in, + pci_irdy_in, + pci_devsel_out +); + +input devs_w ; // devsel signal (composed without critical signals) that do not need critical inputs +input devs_w_frm ; // devsel signal (composed without critical signals) that needs AND with critical FRAME input +input devs_w_frm_irdy ; // devsel signal (composed without critical signals) that needs AND with critical FRAME and + // IRDY inputs +input pci_frame_in ; // critical constrained input signal +input pci_irdy_in ; // critical constrained input signal + +output pci_devsel_out ; // PCI devsel output + +// PCI devsel output with preserved hierarchy for minimum delay! +assign pci_devsel_out = ~(devs_w || (devs_w_frm && ~pci_frame_in) || (devs_w_frm_irdy && ~pci_frame_in && pci_irdy_in)) ; + + +endmodule diff --git a/ethernet/source/pci/pci_target32_interface.v b/ethernet/source/pci/pci_target32_interface.v new file mode 100644 index 0000000..754e58f --- /dev/null +++ b/ethernet/source/pci/pci_target32_interface.v @@ -0,0 +1,965 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_target32_interface.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_target32_interface.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.11 2004/08/19 15:27:34 mihad +// Changed minimum pci image size to 256 bytes because +// of some PC system problems with size of IO images. +// +// Revision 1.10 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.9 2003/08/21 20:55:14 tadejm +// Corrected bug when writing to FIFO (now it is registered). +// +// Revision 1.8 2003/08/08 16:36:33 tadejm +// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. +// +// Revision 1.7 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.6 2003/01/21 16:06:56 mihad +// Bug fixes, testcases added. +// +// Revision 1.5 2002/08/22 13:28:04 mihad +// Updated for synthesis purposes. Gate level simulation was failing in some configurations +// +// Revision 1.4 2002/02/19 16:32:37 mihad +// Modified testbench and fixed some bugs +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +`include "bus_commands.v" +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_target32_interface +( + // system inputs + clk_in, + reset_in, + + // PCI Target side of INTERFACE + address_in, + addr_claim_out, + bc_in, + bc0_in, + data_in, + data_out, + be_in, + next_be_in, + req_in, + rdy_in, + addr_phase_in, + bckp_devsel_in, + bckp_trdy_in, + bckp_stop_in, + last_reg_in, + frame_reg_in, + fetch_pcir_fifo_in, + load_medium_reg_in, + sel_fifo_mreg_in, + sel_conf_fifo_in, + load_to_pciw_fifo_in, + load_to_conf_in, + same_read_out, + + norm_access_to_config_out, + read_completed_out, + read_processing_out, + target_abort_out, + disconect_wo_data_out, + disconect_w_data_out, + pciw_fifo_full_out, + pcir_fifo_data_err_out, + wbw_fifo_empty_out, + wbu_del_read_comp_pending_out, + + // Delayed synchronizacion module signals + req_out, + done_out, + in_progress_out, + req_req_pending_in, + req_comp_pending_in, + addr_out, + be_out, + we_out, + bc_out, + burst_ok_out, + strd_addr_in, + strd_bc_in, + status_in, + comp_flush_in, + + // FIFO signals + pcir_fifo_renable_out, + pcir_fifo_data_in, + pcir_fifo_be_in, + pcir_fifo_control_in, + pcir_fifo_flush_out, + pcir_fifo_almost_empty_in, + pcir_fifo_empty_in, + pciw_fifo_wenable_out, + pciw_fifo_addr_data_out, + pciw_fifo_cbe_out, + pciw_fifo_control_out, + pciw_fifo_three_left_in, + pciw_fifo_two_left_in, + pciw_fifo_almost_full_in, + pciw_fifo_full_in, + wbw_fifo_empty_in, + wbu_del_read_comp_pending_in, + + // Configuration space signals + conf_addr_out, + conf_data_out, + conf_data_in, + conf_be_out, + conf_we_out, + conf_re_out, + mem_enable_in, + io_enable_in, + mem_io_addr_space0_in, + mem_io_addr_space1_in, + mem_io_addr_space2_in, + mem_io_addr_space3_in, + mem_io_addr_space4_in, + mem_io_addr_space5_in, + pre_fetch_en0_in, + pre_fetch_en1_in, + pre_fetch_en2_in, + pre_fetch_en3_in, + pre_fetch_en4_in, + pre_fetch_en5_in, + pci_base_addr0_in, + pci_base_addr1_in, + pci_base_addr2_in, + pci_base_addr3_in, + pci_base_addr4_in, + pci_base_addr5_in, + pci_addr_mask0_in, + pci_addr_mask1_in, + pci_addr_mask2_in, + pci_addr_mask3_in, + pci_addr_mask4_in, + pci_addr_mask5_in, + pci_tran_addr0_in, + pci_tran_addr1_in, + pci_tran_addr2_in, + pci_tran_addr3_in, + pci_tran_addr4_in, + pci_tran_addr5_in, + addr_tran_en0_in, + addr_tran_en1_in, + addr_tran_en2_in, + addr_tran_en3_in, + addr_tran_en4_in, + addr_tran_en5_in +) ; + +`ifdef HOST + `ifdef NO_CNF_IMAGE + parameter pci_ba0_width = `PCI_NUM_OF_DEC_ADDR_LINES ; + `else + parameter pci_ba0_width = 20 ; + `endif +`endif + +`ifdef GUEST + parameter pci_ba0_width = 20 ; +`endif + +parameter pci_ba1_5_width = `PCI_NUM_OF_DEC_ADDR_LINES ; + +/*================================================================================================================== +System inputs. +==================================================================================================================*/ +// PCI side clock and reset +input clk_in, + reset_in ; + + +/*================================================================================================================== +Side of the PCI Target state machine +==================================================================================================================*/ +// Data, byte enables, bus commands and address ports +input [31:0] address_in ; // current request address input - registered +output addr_claim_out ; // current request address claim output +input [3:0] bc_in ; // current request bus command input - registered +input bc0_in ; // current cycle RW signal +output [31:0] data_out ; // for read operations - current dataphase data output +input [31:0] data_in ; // for write operations - current request data input - registered +input [3:0] be_in ; // current dataphase byte enable inputs - registered +input [3:0] next_be_in ; // next dataphase byte enable inputs - NOT registered +// Port connection control signals from PCI FSM +input req_in ; // Read is requested to WB master from PCI side +input rdy_in ; // DATA / ADDRESS selection from PCI side when read or write - registered +input addr_phase_in ; // Indicates address phase and also fast-back-to-back address phase - registered +input bckp_devsel_in ; // DEVSEL input (which is registered) equivalent +input bckp_trdy_in ; // TRDY input (which is registered) equivalent +input bckp_stop_in ; // STOP input (which is registered) equivalent +input last_reg_in ; // Indicates last data phase - registered +input frame_reg_in ; // FRAME input signal - registered +input fetch_pcir_fifo_in ;// Read enable for PCIR_FIFO when when read is finishen on WB side +input load_medium_reg_in ;// Load data from PCIR_FIFO to medium register (first data must be prepared on time) +input sel_fifo_mreg_in ; // Read data selection between PCIR_FIFO and medium register +input sel_conf_fifo_in ; // Read data selection between Configuration registers and "FIFO" +input load_to_pciw_fifo_in ;// Write enable to PCIW_FIFO +input load_to_conf_in ; // Write enable to Configuration space registers + + +/*================================================================================================================== +Status outputs to PCI side (FSM) +==================================================================================================================*/ +output same_read_out ; // Indicates the same read request (important when read is finished on WB side) +output norm_access_to_config_out ; // Indicates the access to Configuration space with MEMORY commands +output read_completed_out ; // Indicates that read request is completed on WB side +output read_processing_out ; // Indicates that read request is processing on WB side +output target_abort_out ; // Indicates target abort termination +output disconect_wo_data_out ; // Indicates disconnect without data termination +output disconect_w_data_out ; // Indicates disconnect with data termination +output pciw_fifo_full_out ; // Indicates that write PCIW_FIFO is full +output pcir_fifo_data_err_out ; // Indicates data error on current data read from PCIR_FIFO +output wbw_fifo_empty_out ; // Indicates that WB SLAVE has no data to be written to PCI bus +output wbu_del_read_comp_pending_out ; // Indicates that WB Unit has a delayed read poending! + +/*================================================================================================================== +Read request interface through Delayed sinchronization module to WB Master +==================================================================================================================*/ +// request, completion, done and progress indicator outputs for delayed_sync module where they are synchronized +output req_out, // request qualifier - when 1 it indicates that valid data is provided on outputs + done_out, // done output - when 1 indicates that PCI Target has completed a cycle on its bus + in_progress_out ; // out progress indicator - indicates that current completion is in progress on + // PCI Target side +// pending indication inputs - PCI Target side must know about requests and completions +input req_req_pending_in ; // request pending input for PCI Target side +input req_comp_pending_in ; // completion pending input for PCI Target side - it indicates when completion + // is ready for completing on PCI Target bus +// various data outputs - PCI Target sets address, bus command, byte enables, write enable and burst +output [31:0] addr_out ; // address bus output +output [3:0] be_out ; // byte enable output +output we_out ; // write enable output - read/write request indication 1 = write request / 0 = read request +output [3:0] bc_out ; // bus command output +output burst_ok_out ; // pre-fetch enable & burst read - qualifies pre-fetch for access to current image space + +// completion side signals encoded termination status - 0 = normal completion / 1 = error terminated completion +input [31:0] strd_addr_in ; // Stored requested read access address +input [3:0] strd_bc_in ; // Stored requested read access bus command +input status_in ; // Error status reported - NOT USED because FIFO control bits determin data error status +input comp_flush_in ; // If completition counter (2^16 clk periods) has expired, PCIR_FIFO must flush data + + +/*================================================================================================================== +PCIR_PCIW_FIFO signals from pci side +==================================================================================================================*/ +// PCIR_FIFO control signals used for fetching data from PCIR_FIFO +output pcir_fifo_renable_out ; // read enable output to PCIR_FIFO +input [31:0] pcir_fifo_data_in ; // data input from PCIR_FIFO +input [3:0] pcir_fifo_be_in ; // byte enable input from PCIR_FIFO +input [3:0] pcir_fifo_control_in ; // control signals input from PCIR_FIFO +output pcir_fifo_flush_out ; // flush PCIR_FIFO +input pcir_fifo_almost_empty_in ; // almost empty indicator from PCIR_FIFO +input pcir_fifo_empty_in ; // empty indicator + +// PCIW_FIFO control signals used for sinking data into PCIW_FIFO and status monitoring +output pciw_fifo_wenable_out ; // write enable output to PCIW_FIFO +wire pciw_fifo_wenable ; // not registered we +output [31:0] pciw_fifo_addr_data_out ; // address / data output signals to PCIW_FIFO +output [3:0] pciw_fifo_cbe_out ; // command / byte enable signals to PCIW_FIFO +output [3:0] pciw_fifo_control_out ; // control signals to PCIW_FIFO +input pciw_fifo_three_left_in ; // three data spaces left in PCIW_FIFO +input pciw_fifo_two_left_in ; // two data spaces left in PCIW_FIFO +input pciw_fifo_almost_full_in ; // almost full indicator from PCIW_FIFO +input pciw_fifo_full_in ; // full indicator from PCIW_FIFO + +// WBW_FIFO empy control signal used when delayed read is complete in PCIR_FIFO +input wbw_fifo_empty_in ; // empty indicator from WBW_FIFO +input wbu_del_read_comp_pending_in ; // delayed read pending indicator from WB Unit + + +/*================================================================================================================== +Configuration space signals - from and to registers +==================================================================================================================*/ +// BUS for reading and writing to configuration space registers +output [11:0] conf_addr_out ; // address to configuration space when there is access to it +output [31:0] conf_data_out ; // data to configuration space - for writing to registers +input [31:0] conf_data_in ; // data from configuration space - for reading from registers +output [3:0] conf_be_out ; // byte enables used for correct writing to configuration space +output conf_we_out ; // write enable control signal - 1 for writing / 0 for nothing +output conf_re_out ; // read enable control signal - 1 for reading / 0 for nothing + +// Inputs for image control registers +input mem_enable_in ; // allowed access to memory mapped image +input io_enable_in ; // allowed access to io mapped image + +// Inputs needed for determining if image is assigned to memory or io space with pre-fetch and address translation +input mem_io_addr_space0_in ; // bit-0 in pci_base_addr0 register +input mem_io_addr_space1_in ; // bit-0 in pci_base_addr1 register +input mem_io_addr_space2_in ; // bit-0 in pci_base_addr2 register +input mem_io_addr_space3_in ; // bit-0 in pci_base_addr3 register +input mem_io_addr_space4_in ; // bit-0 in pci_base_addr4 register +input mem_io_addr_space5_in ; // bit-0 in pci_base_addr5 register +input pre_fetch_en0_in ; // bit-1 in pci_image_ctr0 register +input pre_fetch_en1_in ; // bit-1 in pci_image_ctr1 register +input pre_fetch_en2_in ; // bit-1 in pci_image_ctr2 register +input pre_fetch_en3_in ; // bit-1 in pci_image_ctr3 register +input pre_fetch_en4_in ; // bit-1 in pci_image_ctr4 register +input pre_fetch_en5_in ; // bit-1 in pci_image_ctr5 register + +// Input from image registers - register values needed for decoder to work properly +input [pci_ba0_width - 1:0] pci_base_addr0_in ; // base address from base address register +input [pci_ba1_5_width - 1:0] pci_base_addr1_in ; // base address from base address register +input [pci_ba1_5_width - 1:0] pci_base_addr2_in ; // base address from base address register +input [pci_ba1_5_width - 1:0] pci_base_addr3_in ; // base address from base address register +input [pci_ba1_5_width - 1:0] pci_base_addr4_in ; // base address from base address register +input [pci_ba1_5_width - 1:0] pci_base_addr5_in ; // base address from base address register +input [pci_ba1_5_width - 1:0] pci_addr_mask0_in ; // masking of base address from address mask register +input [pci_ba1_5_width - 1:0] pci_addr_mask1_in ; // masking of base address from address mask register +input [pci_ba1_5_width - 1:0] pci_addr_mask2_in ; // masking of base address from address mask register +input [pci_ba1_5_width - 1:0] pci_addr_mask3_in ; // masking of base address from address mask register +input [pci_ba1_5_width - 1:0] pci_addr_mask4_in ; // masking of base address from address mask register +input [pci_ba1_5_width - 1:0] pci_addr_mask5_in ; // masking of base address from address mask register +input [pci_ba1_5_width - 1:0] pci_tran_addr0_in ; // translation address from address translation register +input [pci_ba1_5_width - 1:0] pci_tran_addr1_in ; // translation address from address translation register +input [pci_ba1_5_width - 1:0] pci_tran_addr2_in ; // translation address from address translation register +input [pci_ba1_5_width - 1:0] pci_tran_addr3_in ; // translation address from address translation register +input [pci_ba1_5_width - 1:0] pci_tran_addr4_in ; // translation address from address translation register +input [pci_ba1_5_width - 1:0] pci_tran_addr5_in ; // translation address from address translation register + +input addr_tran_en0_in ; // address translation enable bit +input addr_tran_en1_in ; // address translation enable bit +input addr_tran_en2_in ; // address translation enable bit +input addr_tran_en3_in ; // address translation enable bit +input addr_tran_en4_in ; // address translation enable bit +input addr_tran_en5_in ; // address translation enable bit + +/*================================================================================================================== +END of input / output PORT DEFINITONS !!! +==================================================================================================================*/ + +// address output from address multiplexer +reg [31:0] address ; +// prefetch enable for access to selected image space +reg pre_fetch_en ; + +// Input addresses and image hits from address decoders - addresses are multiplexed to address +`ifdef HOST + `ifdef NO_CNF_IMAGE + `ifdef PCI_IMAGE0 // if PCI bridge is HOST and IMAGE0 is assigned as general image space +wire hit0_in ; +wire [31:0] address0_in ; +wire pre_fetch_en0 = pre_fetch_en0_in ; + `else +wire hit0_in = 1'b0 ; +wire [31:0] address0_in = 32'h0 ; +wire pre_fetch_en0 = 1'b0 ; + `endif + `else +wire hit0_in ; +wire [31:0] address0_in ; +wire pre_fetch_en0 = pre_fetch_en0_in ; + `endif +`else // GUEST +wire hit0_in ; +wire [31:0] address0_in ; +wire pre_fetch_en0 = pre_fetch_en0_in ; +`endif + +wire hit1_in ; +wire [31:0] address1_in ; +wire pre_fetch_en1 = pre_fetch_en1_in ; + +`ifdef PCI_IMAGE2 +wire hit2_in ; +wire [31:0] address2_in ; +wire pre_fetch_en2 = pre_fetch_en2_in ; +`else +wire hit2_in = 1'b0 ; +wire [31:0] address2_in = 32'h0 ; +wire pre_fetch_en2 = 1'b0 ; +`endif + +`ifdef PCI_IMAGE3 +wire hit3_in ; +wire [31:0] address3_in ; +wire pre_fetch_en3 = pre_fetch_en3_in ; +`else +wire hit3_in = 1'b0 ; +wire [31:0] address3_in = 32'h0 ; +wire pre_fetch_en3 = 1'b0 ; +`endif + +`ifdef PCI_IMAGE4 +wire hit4_in ; +wire [31:0] address4_in ; +wire pre_fetch_en4 = pre_fetch_en4_in ; +`else +wire hit4_in = 1'b0 ; +wire [31:0] address4_in = 32'h0 ; +wire pre_fetch_en4 = 1'b0 ; +`endif + +`ifdef PCI_IMAGE5 +wire hit5_in ; +wire [31:0] address5_in ; +wire pre_fetch_en5 = pre_fetch_en5_in ; +`else +wire hit5_in = 1'b0 ; +wire [31:0] address5_in = 32'h0 ; +wire pre_fetch_en5 = 1'b0 ; +`endif + +// Include address decoders +`ifdef HOST + `ifdef NO_CNF_IMAGE + `ifdef PCI_IMAGE0 // if PCI bridge is HOST and IMAGE0 is assigned as general image space + pci_pci_decoder #(pci_ba0_width) decoder0 + (.hit (hit0_in), + .addr_out (address0_in), + .addr_in (address_in), + .bc_in (bc_in), + .base_addr (pci_base_addr0_in), + .mask_addr (pci_addr_mask0_in), + .tran_addr (pci_tran_addr0_in), + .at_en (addr_tran_en0_in), + .mem_io_space (mem_io_addr_space0_in), + .mem_en (mem_enable_in), + .io_en (io_enable_in) + ) ; + `endif + `else + pci_pci_decoder #(pci_ba0_width) decoder0 + (.hit (hit0_in), + .addr_out (address0_in), + .addr_in (address_in), + .bc_in (bc_in), + .base_addr (pci_base_addr0_in), + .mask_addr ({pci_ba0_width{1'b1}}), + .tran_addr ({pci_ba0_width{1'b0}}), + .at_en (1'b0), + .mem_io_space (1'b0), + .mem_en (mem_enable_in), + .io_en (1'b0) + ) ; + `endif +`else // GUEST + pci_pci_decoder #(pci_ba0_width) decoder0 + (.hit (hit0_in), + .addr_out (address0_in), + .addr_in (address_in), + .bc_in (bc_in), + .base_addr (pci_base_addr0_in), + .mask_addr ({pci_ba0_width{1'b1}}), + .tran_addr ({pci_ba0_width{1'b0}}), + .at_en (1'b0), + .mem_io_space (1'b0), + .mem_en (mem_enable_in), + .io_en (1'b0) + ) ; +`endif + pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder1 + (.hit (hit1_in), + .addr_out (address1_in), + .addr_in (address_in), + .bc_in (bc_in), + .base_addr (pci_base_addr1_in), + .mask_addr (pci_addr_mask1_in), + .tran_addr (pci_tran_addr1_in), + .at_en (addr_tran_en1_in), + .mem_io_space (mem_io_addr_space1_in), + .mem_en (mem_enable_in), + .io_en (io_enable_in) + ) ; +`ifdef PCI_IMAGE2 + pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder2 + (.hit (hit2_in), + .addr_out (address2_in), + .addr_in (address_in), + .bc_in (bc_in), + .base_addr (pci_base_addr2_in), + .mask_addr (pci_addr_mask2_in), + .tran_addr (pci_tran_addr2_in), + .at_en (addr_tran_en2_in), + .mem_io_space (mem_io_addr_space2_in), + .mem_en (mem_enable_in), + .io_en (io_enable_in) + ) ; +`endif +`ifdef PCI_IMAGE3 + pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder3 + (.hit (hit3_in), + .addr_out (address3_in), + .addr_in (address_in), + .bc_in (bc_in), + .base_addr (pci_base_addr3_in), + .mask_addr (pci_addr_mask3_in), + .tran_addr (pci_tran_addr3_in), + .at_en (addr_tran_en3_in), + .mem_io_space (mem_io_addr_space3_in), + .mem_en (mem_enable_in), + .io_en (io_enable_in) + ) ; +`endif +`ifdef PCI_IMAGE4 + pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder4 + (.hit (hit4_in), + .addr_out (address4_in), + .addr_in (address_in), + .bc_in (bc_in), + .base_addr (pci_base_addr4_in), + .mask_addr (pci_addr_mask4_in), + .tran_addr (pci_tran_addr4_in), + .at_en (addr_tran_en4_in), + .mem_io_space (mem_io_addr_space4_in), + .mem_en (mem_enable_in), + .io_en (io_enable_in) + ) ; +`endif +`ifdef PCI_IMAGE5 + pci_pci_decoder #(`PCI_NUM_OF_DEC_ADDR_LINES) decoder5 + (.hit (hit5_in), + .addr_out (address5_in), + .addr_in (address_in), + .bc_in (bc_in), + .base_addr (pci_base_addr5_in), + .mask_addr (pci_addr_mask5_in), + .tran_addr (pci_tran_addr5_in), + .at_en (addr_tran_en5_in), + .mem_io_space (mem_io_addr_space5_in), + .mem_en (mem_enable_in), + .io_en (io_enable_in) + ) ; +`endif + +// Internal signals for image hit determination +reg addr_claim ;// address claim signal is asinchronous set for addr_claim_out signal to PCI Target SM + +// Determining if image 0 is assigned to configuration space or as normal pci to wb access! +// if normal access is allowed to configuration space, then hit0 is hit0_conf +`ifdef HOST + `ifdef NO_CNF_IMAGE + parameter hit0_conf = 1'b0 ; + `else + parameter hit0_conf = 1'b1 ; // if normal access is allowed to configuration space, then hit0 is hit0_conf + `endif +`else // GUEST + parameter hit0_conf = 1'b1 ; // if normal access is allowed to configuration space, then hit0 is hit0_conf +`endif + +// Logic with address mux, determining if address is still in the same image space and if it is prefetced or not +always@(hit5_in or hit4_in or hit3_in or hit2_in or hit1_in or hit0_in or + address5_in or address4_in or address3_in or address2_in or address1_in or address0_in or + pre_fetch_en5 or + pre_fetch_en4 or + pre_fetch_en3 or + pre_fetch_en2 or + pre_fetch_en1 or + pre_fetch_en0 + ) +begin + addr_claim <= (hit5_in || hit4_in) || (hit3_in || hit2_in || hit1_in || hit0_in) ; + case ({hit5_in, hit4_in, hit3_in, hit2_in, hit0_in}) + 5'b10000 : + begin + address <= address5_in ; + pre_fetch_en <= pre_fetch_en5 ; + end + 5'b01000 : + begin + address <= address4_in ; + pre_fetch_en <= pre_fetch_en4 ; + end + 5'b00100 : + begin + address <= address3_in ; + pre_fetch_en <= pre_fetch_en3 ; + end + 5'b00010 : + begin + address <= address2_in ; + pre_fetch_en <= pre_fetch_en2 ; + end + 5'b00001 : + begin + address <= address0_in ; + pre_fetch_en <= pre_fetch_en0 ; + end + default : // IMAGE 1 is always included into PCI bridge + begin + address <= address1_in ; + pre_fetch_en <= pre_fetch_en1 ; + end + endcase +end + +// Address claim output to PCI Target SM +assign addr_claim_out = addr_claim ; + +reg [31:0] norm_address ; // stored normal address (decoded and translated) for access to WB +reg norm_prf_en ; // stored pre-fetch enable +reg [3:0] norm_bc ; // stored bus-command +reg same_read_reg ; // stored SAME_READ information +reg target_rd ; // delayed registered TRDY output equivalent signal + +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + norm_address <= #`FF_DELAY 32'h0000_0000 ; + norm_prf_en <= #`FF_DELAY 1'b0 ; + norm_bc <= #`FF_DELAY 4'h0 ; + same_read_reg <= #`FF_DELAY 1'b0 ; + end + else + begin + if (addr_phase_in) + begin + norm_address <= #`FF_DELAY address ; + norm_prf_en <= #`FF_DELAY pre_fetch_en ; + norm_bc <= #`FF_DELAY bc_in ; + same_read_reg <= #`FF_DELAY same_read_out ; + end + end +end + +`ifdef HOST + `ifdef NO_CNF_IMAGE + reg [1:0] strd_address ; // stored INPUT address for accessing Configuration space registers + `else + reg [11:0] strd_address ; // stored INPUT address for accessing Configuration space registers + `endif +`else + reg [11:0] strd_address ; // stored INPUT address for accessing Configuration space registers +`endif +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + strd_address <= #`FF_DELAY 0 ; + end + else + begin + if (addr_phase_in) + begin +`ifdef HOST + `ifdef NO_CNF_IMAGE + strd_address <= #`FF_DELAY address_in[1:0] ; + `else + strd_address <= #`FF_DELAY address_in[11:0] ; + `endif +`else + strd_address <= #`FF_DELAY address_in[11:0] ; +`endif + end + end +end + +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + target_rd <= #`FF_DELAY 1'b0 ; + end + else + begin + if (same_read_reg && !bckp_trdy_in) + target_rd <= #`FF_DELAY 1'b1 ;// Signal indicates when target ready is deaserted on PCI bus + else if (same_read_reg && bckp_devsel_in && !bckp_stop_in) + target_rd <= #`FF_DELAY 1'b1 ;// Signal indicates when target ready is deaserted on PCI bus + else if ((!same_read_reg) || (last_reg_in && target_rd)) + target_rd <= #`FF_DELAY 1'b0 ;// Signal indicates when target ready is deaserted on PCI bus + end +end +// '1' indicates asserted TRDY signal when same read operation is performed +wire target_rd_completed = target_rd ; + +reg same_read_request ; + +// When delayed read is completed on WB, addres and bc must be compered, if there is the same read request +always@(address or strd_addr_in or bc_in or strd_bc_in) +begin + if ((address == strd_addr_in) & (bc_in == strd_bc_in)) + same_read_request <= 1'b1 ; + else + same_read_request <= 1'b0 ; +end + +assign same_read_out = (same_read_request) ; // && ~pcir_fifo_empty_in) ; + +// Signals for byte enable checking +reg addr_burst_ok ; +reg io_be_ok ; + +// Byte enable checking for IO, MEMORY and CONFIGURATION spaces - be_in is active low! +always@(strd_address or be_in) +begin + case (strd_address[1:0]) + 2'b11 : + begin + addr_burst_ok <= 1'b0 ; + io_be_ok <= (be_in[2] && be_in[1] && be_in[0]) ; // only be3 can be active + end + 2'b10 : + begin + addr_burst_ok <= 1'b0 ; + io_be_ok <= (~be_in[2] && be_in[1] && be_in[0]) || (be_in[3] && be_in[2] && be_in[1] && be_in[0]) ; + end + 2'b01 : + begin + addr_burst_ok <= 1'b0 ; + io_be_ok <= (~be_in[1] && be_in[0]) || (be_in[3] && be_in[2] && be_in[1] && be_in[0]) ; + end + default : // 2'b00 + begin + addr_burst_ok <= 1'b1 ; + io_be_ok <= (~be_in[0]) || (be_in[3] && be_in[2] && be_in[1] && be_in[0]) ; + end + endcase +end + +wire calc_target_abort = (norm_bc[3:1] == `BC_IO_RW) ? !io_be_ok : 1'b0 ; + +wire [3:0] pcir_fifo_control_input = pcir_fifo_empty_in ? 4'h0 : pcir_fifo_control_in ; + +// Medium registers for data and control busses from PCIR_FIFO +reg [31:0] pcir_fifo_data_reg ; +reg [3:0] pcir_fifo_ctrl_reg ; + +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + pcir_fifo_data_reg <= #`FF_DELAY 32'h0000_0000 ; + pcir_fifo_ctrl_reg <= #`FF_DELAY 4'h0 ; + end + else + begin + if (load_medium_reg_in) + begin + pcir_fifo_data_reg <= #`FF_DELAY pcir_fifo_data_in ; + pcir_fifo_ctrl_reg <= #`FF_DELAY pcir_fifo_control_input ; + end + end +end + +// when disconnect is signalled, the next data written to fifo will be the last +// also when this happens, disconnect must stay asserted until last data is written to the fifo +reg keep_desconnect_wo_data_set ; + +// selecting "fifo data" from medium registers or from PCIR_FIFO +wire [31:0] pcir_fifo_data = (sel_fifo_mreg_in && !pcir_fifo_empty_in) ? pcir_fifo_data_in : pcir_fifo_data_reg ; +wire [3:0] pcir_fifo_ctrl = (sel_fifo_mreg_in && !pcir_fifo_empty_in) ? pcir_fifo_control_input : pcir_fifo_ctrl_reg ; + +// signal assignments to PCI Target FSM +assign read_completed_out = req_comp_pending_in ; // completion pending input for requesting side of the bridge +assign read_processing_out = req_req_pending_in ; // request pending input for requesting side + // when '1', the bus command is IO command - not supported commands are checked in pci_decoder modules + wire io_memory_bus_command = !norm_bc[3] && !norm_bc[2] ; +assign disconect_wo_data_out = ( + ((/*pcir_fifo_ctrl[`LAST_CTRL_BIT] ||*/ pcir_fifo_empty_in || ~burst_ok_out/*addr_burst_ok*/ || io_memory_bus_command) && + ~bc0_in && ~frame_reg_in) || + ((pciw_fifo_full_in || pciw_fifo_almost_full_in || keep_desconnect_wo_data_set || pciw_fifo_two_left_in || + (pciw_fifo_three_left_in && pciw_fifo_wenable) || ~addr_burst_ok || io_memory_bus_command) && + bc0_in && ~frame_reg_in) + ) ; +assign disconect_w_data_out = ( + ( burst_ok_out && !io_memory_bus_command && ~bc0_in ) || + ( addr_burst_ok && !io_memory_bus_command && bc0_in ) + ) ; +assign target_abort_out = ( ~addr_phase_in && calc_target_abort ) ; + +`ifdef HOST + `ifdef NO_CNF_IMAGE + // signal assignments to PCI Target FSM + assign norm_access_to_config_out = 1'b0 ; + // control signal assignments to read request sinchronization module + assign done_out = (target_rd_completed && last_reg_in) ; + assign in_progress_out = (same_read_reg && ~bckp_trdy_in) ; + // signal used for PCIR_FIFO flush (with comp_flush_in signal) + wire pcir_fifo_flush = (target_rd_completed && last_reg_in && ~pcir_fifo_empty_in) ; + `else + // signal assignments to PCI Target FSM + assign norm_access_to_config_out = (hit0_in && hit0_conf) ; + // control signal assignments to read request sinchronization module + assign done_out = (~sel_conf_fifo_in && target_rd_completed && last_reg_in) ; + assign in_progress_out = (~sel_conf_fifo_in && same_read_reg && ~bckp_trdy_in) ; + // signal used for PCIR_FIFO flush (with comp_flush_in signal) + wire pcir_fifo_flush = (~sel_conf_fifo_in && target_rd_completed && last_reg_in && ~pcir_fifo_empty_in) ; + `endif +`else + // signal assignments to PCI Target FSM + assign norm_access_to_config_out = (hit0_in && hit0_conf) ; + // control signal assignments to read request sinchronization module + assign done_out = (~sel_conf_fifo_in && target_rd_completed && last_reg_in) ; + assign in_progress_out = (~sel_conf_fifo_in && same_read_reg && ~bckp_trdy_in) ; + // signal used for PCIR_FIFO flush (with comp_flush_in signal) + wire pcir_fifo_flush = (~sel_conf_fifo_in && target_rd_completed && last_reg_in && ~pcir_fifo_empty_in) ; +`endif + +// flush signal for PCIR_FIFO must be registered, since it asinchronously resets some status registers +wire pcir_fifo_flush_reg ; +pci_async_reset_flop async_reset_as_pcir_flush +( + .data_in (comp_flush_in || pcir_fifo_flush), + .clk_in (clk_in), + .async_reset_data_out (pcir_fifo_flush_reg), + .reset_in (reset_in) +) ; + +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + keep_desconnect_wo_data_set <= #1 1'b0 ; + else if (keep_desconnect_wo_data_set && pciw_fifo_wenable) + keep_desconnect_wo_data_set <= #1 1'b0 ; + else if (pciw_fifo_wenable && disconect_wo_data_out) + keep_desconnect_wo_data_set <= #1 1'b1 ; +end + + +// signal assignments from fifo to PCI Target FSM +assign wbw_fifo_empty_out = wbw_fifo_empty_in ; +assign wbu_del_read_comp_pending_out = wbu_del_read_comp_pending_in ; +assign pciw_fifo_full_out = (pciw_fifo_full_in || pciw_fifo_almost_full_in || pciw_fifo_two_left_in || pciw_fifo_three_left_in) ; +assign pcir_fifo_data_err_out = pcir_fifo_ctrl[`DATA_ERROR_CTRL_BIT] && !sel_conf_fifo_in ; +// signal assignments to PCIR FIFO fifo +assign pcir_fifo_flush_out = pcir_fifo_flush_reg ; +assign pcir_fifo_renable_out = fetch_pcir_fifo_in && !pcir_fifo_empty_in ; + +// signal assignments to PCIW FIFO +reg pciw_fifo_wenable_out; +assign pciw_fifo_wenable = load_to_pciw_fifo_in ; +reg [3:0] pciw_fifo_control_out; +reg [31:0] pciw_fifo_addr_data_out; +reg [3:0] pciw_fifo_cbe_out; +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + pciw_fifo_wenable_out <= #1 1'b0; + pciw_fifo_control_out <= #1 4'h0; + // data and address outputs assignments to PCIW_FIFO - correction of 2 LSBits + pciw_fifo_addr_data_out <= #1 32'h0; + pciw_fifo_cbe_out <= #1 4'h0; + end + else + begin + pciw_fifo_wenable_out <= #1 load_to_pciw_fifo_in ; + pciw_fifo_control_out[`ADDR_CTRL_BIT] <= #1 ~rdy_in ; + pciw_fifo_control_out[`BURST_BIT] <= #1 rdy_in ? ~frame_reg_in : 1'b0 ; + // if '1' then next burst BE is not equat to current one => burst will be chopped into single transfers + pciw_fifo_control_out[`DATA_ERROR_CTRL_BIT] <= #1 rdy_in && (next_be_in != be_in) && ~bckp_trdy_in; // valid comp. + pciw_fifo_control_out[`LAST_CTRL_BIT] <= #1 rdy_in && (frame_reg_in || (bckp_trdy_in && ~bckp_stop_in)); + // data and address outputs assignments to PCIW_FIFO - correction of 2 LSBits + pciw_fifo_addr_data_out <= #1 rdy_in ? data_in : {norm_address[31:2], + norm_address[1] && io_memory_bus_command, + norm_address[0] && io_memory_bus_command} ; + pciw_fifo_cbe_out <= #1 rdy_in ? be_in : norm_bc ; + end +end + +`ifdef HOST + `ifdef NO_CNF_IMAGE + // data and address outputs assignments to PCI Target FSM + assign data_out = pcir_fifo_data ; + `else + // data and address outputs assignments to PCI Target FSM + assign data_out = sel_conf_fifo_in ? conf_data_in : pcir_fifo_data ; + `endif +`else + // data and address outputs assignments to PCI Target FSM + assign data_out = sel_conf_fifo_in ? conf_data_in : pcir_fifo_data ; +`endif + +// data and address outputs assignments to read request sinchronization module +assign req_out = req_in ; + // this address is stored in delayed_sync module and is connected back as strd_addr_in +assign addr_out = norm_address[31:0] ; // correction of 2 LSBits is done in wb_master module, original address must be saved +assign be_out = be_in ; +assign we_out = 1'b0 ; +assign bc_out = norm_bc ; +// burst is OK for reads when there is ((MEM_READ_LN or MEM_READ_MUL) and AD[1:0]==2'b00) OR +// (MEM_READ and Prefetchable_IMAGE and AD[1:0]==2'b00) +assign burst_ok_out = (norm_bc[3] && addr_burst_ok) || (norm_bc[2] && norm_prf_en && addr_burst_ok) ; +// data and address outputs assignments to Configuration space +`ifdef HOST + `ifdef NO_CNF_IMAGE + assign conf_data_out = 32'h0 ; + assign conf_addr_out = 12'h0 ; + assign conf_be_out = 4'b0 ; + assign conf_we_out = 1'h0 ; + `else + assign conf_data_out = data_in ; + assign conf_addr_out = strd_address[11:0] ; + assign conf_be_out = be_in ; + assign conf_we_out = load_to_conf_in ; + `endif +`else + assign conf_data_out = data_in ; + assign conf_addr_out = strd_address[11:0] ; + assign conf_be_out = be_in ; + assign conf_we_out = load_to_conf_in ; +`endif +// NOT USED NOW, SONCE READ IS ASYNCHRONOUS +//assign conf_re_out = fetch_conf_in ; +assign conf_re_out = 1'b0 ; + +endmodule diff --git a/ethernet/source/pci/pci_target32_sm.v b/ethernet/source/pci/pci_target32_sm.v new file mode 100644 index 0000000..276933b --- /dev/null +++ b/ethernet/source/pci/pci_target32_sm.v @@ -0,0 +1,761 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_target32_sm.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_target32_sm.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.11 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.10 2003/08/08 16:36:33 tadejm +// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. +// +// Revision 1.9 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.8 2003/01/21 16:06:56 mihad +// Bug fixes, testcases added. +// +// Revision 1.7 2002/09/24 19:09:17 mihad +// Number of state bits define was removed +// +// Revision 1.6 2002/09/24 18:30:00 mihad +// Changed state machine encoding to true one-hot +// +// Revision 1.5 2002/08/22 09:07:06 mihad +// Fixed a bug and provided testcase for it. Target was responding to configuration cycle type 1 transactions. +// +// Revision 1.4 2002/02/19 16:32:37 mihad +// Modified testbench and fixed some bugs +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_target32_sm +( + // system inputs + clk_in, + reset_in, + // master inputs + pci_frame_in, + pci_irdy_in, + pci_idsel_in, + pci_frame_reg_in, + pci_irdy_reg_in, + pci_idsel_reg_in, + // target response outputs + pci_trdy_out, + pci_stop_out, + pci_devsel_out, + pci_trdy_en_out, + pci_stop_en_out, + pci_devsel_en_out, + ad_load_out, + ad_load_on_transfer_out, + // address, data, bus command, byte enable in/outs + pci_ad_reg_in, + pci_ad_out, + pci_ad_en_out, + pci_cbe_reg_in, + pci_cbe_in, + bckp_trdy_en_in, + bckp_devsel_in, + bckp_trdy_in, + bckp_stop_in, + pci_trdy_reg_in, + pci_stop_reg_in, + + // backend side of state machine with control signals to pci_io_mux ... + address_out, + addr_claim_in, + bc_out, + bc0_out, + data_out, + data_in, + be_out, + next_be_out, + req_out, + rdy_out, + addr_phase_out, + bckp_devsel_out, + bckp_trdy_out, + bckp_stop_out, + last_reg_out, + frame_reg_out, + fetch_pcir_fifo_out, + load_medium_reg_out, + sel_fifo_mreg_out, + sel_conf_fifo_out, + load_to_pciw_fifo_out, + load_to_conf_out, + same_read_in, + norm_access_to_config_in, + read_completed_in, + read_processing_in, + target_abort_in, + disconect_wo_data_in, + disconect_w_data_in, + target_abort_set_out, + pciw_fifo_full_in, + pcir_fifo_data_err_in, + wbw_fifo_empty_in, + wbu_del_read_comp_pending_in, + wbu_frame_en_in + +) ; + +/*---------------------------------------------------------------------------------------------------------------------- +Various parameters needed for state machine and other stuff +----------------------------------------------------------------------------------------------------------------------*/ +parameter S_IDLE = 3'b001 ; +parameter S_WAIT = 3'b010 ; +parameter S_TRANSFERE = 3'b100 ; + + +/*================================================================================================================== +System inputs. +==================================================================================================================*/ +// PCI side clock and reset +input clk_in, + reset_in ; + + +/*================================================================================================================== +PCI interface signals - bidirectional signals are divided to inputs and outputs in I/O cells instantiation +module. Enables are separate signals. +==================================================================================================================*/ +// master inputs +input pci_frame_in, + pci_irdy_in, + pci_idsel_in ; +input pci_frame_reg_in, + pci_irdy_reg_in, + pci_idsel_reg_in ; + +// target response outputs +output pci_trdy_out, + pci_stop_out, + pci_devsel_out ; +output pci_trdy_en_out, + pci_stop_en_out, + pci_devsel_en_out ; +output ad_load_out ; +output ad_load_on_transfer_out ; +// address, data, bus command, byte enable in/outs +input [31:0] pci_ad_reg_in ; +output [31:0] pci_ad_out ; +output pci_ad_en_out ; +input [3:0] pci_cbe_reg_in ; +input [3:0] pci_cbe_in ; +input bckp_trdy_en_in ; +input bckp_devsel_in ; +input bckp_trdy_in ; +input bckp_stop_in ; +input pci_trdy_reg_in ; +input pci_stop_reg_in ; + + +/*================================================================================================================== +Other side of PCI Target state machine +==================================================================================================================*/ +// Data, byte enables, bus commands and address ports +output [31:0] address_out ; // current request address output - registered +input addr_claim_in ; // current request address claim input +output [3:0] bc_out ; // current request bus command output - registered +output bc0_out ; // current cycle RW signal output +input [31:0] data_in ; // for read operations - current dataphase data input +output [31:0] data_out ; // for write operations - current request data output - registered +output [3:0] be_out ; // current dataphase byte enable outputs - registered +output [3:0] next_be_out ; // next dataphase byte enable outputs - NOT registered +// Port connection control signals from PCI FSM +output req_out ; // Read is requested to WB master +output rdy_out ; // DATA / ADDRESS selection when read or write - registered +output addr_phase_out ; // Indicates address phase and also fast-back-to-back address phase - registered +output bckp_devsel_out ; // DEVSEL output (which is registered) equivalent +output bckp_trdy_out ; // TRDY output (which is registered) equivalent +output bckp_stop_out ; // STOP output (which is registered) equivalent +output last_reg_out ; // Indicates last data phase - registered +output frame_reg_out ; // FRAME output signal - registered +output fetch_pcir_fifo_out ;// Read enable for PCIR_FIFO when when read is finishen on WB side +output load_medium_reg_out ;// Load data from PCIR_FIFO to medium register (first data must be prepared on time) +output sel_fifo_mreg_out ; // Read data selection between PCIR_FIFO and medium register +output sel_conf_fifo_out ; // Read data selection between Configuration registers and "FIFO" +output load_to_pciw_fifo_out ;// Write enable to PCIW_FIFO +output load_to_conf_out ; // Write enable to Configuration space registers + + +/*================================================================================================================== +Status +==================================================================================================================*/ +input same_read_in ; // Indicates the same read request (important when read is finished on WB side) +input norm_access_to_config_in ; // Indicates the access to Configuration space with MEMORY commands +input read_completed_in ; // Indicates that read request is completed on WB side +input read_processing_in ; // Indicates that read request is processing on WB side +input target_abort_in ; // Indicates target abort termination +input disconect_wo_data_in ; // Indicates disconnect without data termination +input disconect_w_data_in ; // Indicates disconnect with data termination +input pciw_fifo_full_in ; // Indicates that write PCIW_FIFO is full +input pcir_fifo_data_err_in ; // Indicates data error on current data read from PCIR_FIFO +input wbw_fifo_empty_in ; // Indicates that WB SLAVE UNIT has no data to be written to PCI bus +input wbu_del_read_comp_pending_in ; // Indicates that WB SÈAVE UNIT has a delayed read pending +input wbu_frame_en_in ; // Indicates that WB SLAVE UNIT is accessing the PCI bus (important if + // address on PCI bus is also claimed by decoder in this PCI TARGET UNIT +output target_abort_set_out ; // Signal used to be set in configuration space registers + +/*================================================================================================================== +END of input / output PORT DEFINITONS !!! +==================================================================================================================*/ + +// Delayed frame signal for determining the address phase +reg previous_frame ; +// Delayed read completed signal for preparing the data from pcir fifo +reg read_completed_reg ; +// Delayed disconnect with/without data for stop loading data to PCIW_FIFO +//reg disconect_wo_data_reg ; + +wire config_disconnect ; +wire disconect_wo_data = disconect_wo_data_in || config_disconnect ; +wire disconect_w_data = disconect_w_data_in ; +// Delayed frame signal for determining the address phase! +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + previous_frame <= #`FF_DELAY 1'b0 ; + read_completed_reg <= #`FF_DELAY 1'b0 ; + end + else + begin + previous_frame <= #`FF_DELAY pci_frame_reg_in ; + read_completed_reg <= #`FF_DELAY read_completed_in ; + end +end + +// Address phase is when previous frame was 1 and this frame is 0 and frame isn't generated from pci master (in WBU) +wire addr_phase = (previous_frame && ~pci_frame_reg_in && ~wbu_frame_en_in) ; + +`ifdef HOST + `ifdef NO_CNF_IMAGE + // Wire tells when there is configuration (read or write) command with IDSEL signal active + wire config_access = 1'b0 ; + // Write and read progresses are used for determining next state + wire write_progress = ( (read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) || + (~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ; + wire read_progress = ( (read_completed_in && wbw_fifo_empty_in) ) ; + `else + // Wire tells when there is configuration (read or write) command with IDSEL signal active + wire config_access = (pci_idsel_reg_in && pci_cbe_reg_in[3]) && (~pci_cbe_reg_in[2] && pci_cbe_reg_in[1]) && // idsel asserted with correct bus command(101x) + (pci_ad_reg_in[1:0] == 2'b00) ; // has to be type 0 configuration cycle + + // Write and read progresses are used for determining next state + wire write_progress = ( (norm_access_to_config_in) || + (read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) || + (~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ; + wire read_progress = ( (~read_completed_in && norm_access_to_config_in) || + (read_completed_in && wbw_fifo_empty_in) ) ; + `endif +`else + // Wire tells when there is configuration (read or write) command with IDSEL signal active + wire config_access = (pci_idsel_reg_in && pci_cbe_reg_in[3]) && (~pci_cbe_reg_in[2] && pci_cbe_reg_in[1]) && // idsel asserted with correct bus command(101x) + (pci_ad_reg_in[1:0] == 2'b00) ; // has to be type 0 configuration cycle + + // Write and read progresses are used for determining next state + wire write_progress = ( (norm_access_to_config_in) || + (read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) || + (~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) ) ; + wire read_progress = ( (~read_completed_in && norm_access_to_config_in) || + (read_completed_in && wbw_fifo_empty_in) ) ; +`endif + +// Signal for loading data to medium register from pcir fifo when read completed from WB side! +wire prepare_rd_fifo_data = (read_completed_in && ~read_completed_reg) ; + +// Write allowed to PCIW_FIFO +wire write_to_fifo = ((read_completed_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in) || + (~read_processing_in && ~pciw_fifo_full_in && ~wbu_del_read_comp_pending_in)) ; +// Read allowed from PCIR_FIFO +wire read_from_fifo = (read_completed_in && wbw_fifo_empty_in) ; +`ifdef HOST + `ifdef NO_CNF_IMAGE + // Read request is allowed to be proceed regarding the WB side + wire read_request = (~read_completed_in && ~read_processing_in) ; + `else + // Read request is allowed to be proceed regarding the WB side + wire read_request = (~read_completed_in && ~read_processing_in && ~norm_access_to_config_in) ; + `endif +`else + // Read request is allowed to be proceed regarding the WB side + wire read_request = (~read_completed_in && ~read_processing_in && ~norm_access_to_config_in) ; +`endif + +// Critically calculated signals are latched in this clock period (address phase) to be used in the next clock period +reg rw_cbe0 ; +reg wr_progress ; +reg rd_progress ; +reg rd_from_fifo ; +reg rd_request ; +reg wr_to_fifo ; +reg same_read_reg ; + +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + rw_cbe0 <= #`FF_DELAY 1'b0 ; + wr_progress <= #`FF_DELAY 1'b0 ; + rd_progress <= #`FF_DELAY 1'b0 ; + rd_from_fifo <= #`FF_DELAY 1'b0 ; + rd_request <= #`FF_DELAY 1'b0 ; + wr_to_fifo <= #`FF_DELAY 1'b0 ; + same_read_reg <= #`FF_DELAY 1'b0 ; + end + else + begin + if (addr_phase) + begin + rw_cbe0 <= #`FF_DELAY pci_cbe_reg_in[0] ; + wr_progress <= #`FF_DELAY write_progress ; + rd_progress <= #`FF_DELAY read_progress ; + rd_from_fifo <= #`FF_DELAY read_from_fifo ; + rd_request <= #`FF_DELAY read_request ; + wr_to_fifo <= #`FF_DELAY write_to_fifo ; + same_read_reg <= #`FF_DELAY same_read_in ; + end + end +end + +`ifdef HOST + `ifdef NO_CNF_IMAGE + wire norm_access_to_conf_reg = 1'b0 ; + wire cnf_progress = 1'b0 ; + `else + reg norm_access_to_conf_reg ; + reg cnf_progress ; + always@(posedge clk_in or posedge reset_in) + begin + if (reset_in) + begin + norm_access_to_conf_reg <= #`FF_DELAY 1'b0 ; + cnf_progress <= #`FF_DELAY 1'b0 ; + end + else + begin + if (addr_phase) + begin + norm_access_to_conf_reg <= #`FF_DELAY norm_access_to_config_in ; + cnf_progress <= #`FF_DELAY config_access ; + end + end + end + `endif +`else + reg norm_access_to_conf_reg ; + reg cnf_progress ; + always@(posedge clk_in or posedge reset_in) + begin + if (reset_in) + begin + norm_access_to_conf_reg <= #`FF_DELAY 1'b0 ; + cnf_progress <= #`FF_DELAY 1'b0 ; + end + else + begin + if (addr_phase) + begin + norm_access_to_conf_reg <= #`FF_DELAY norm_access_to_config_in ; + cnf_progress <= #`FF_DELAY config_access ; + end + end + end +`endif + +// Signal used in S_WAIT state to determin next state +wire s_wait_progress = ( + (~cnf_progress && rw_cbe0 && wr_progress && ~target_abort_in) || + (~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && ~target_abort_in && ~pcir_fifo_data_err_in) || + (~cnf_progress && ~rw_cbe0 && ~same_read_reg && norm_access_to_conf_reg && ~target_abort_in) || + (cnf_progress && ~target_abort_in) + ) ; + +// Signal used in S_TRANSFERE state to determin next state +wire s_tran_progress = ( + (rw_cbe0 && !disconect_wo_data) || + (~rw_cbe0 && !disconect_wo_data && !target_abort_in && !pcir_fifo_data_err_in) + ) ; + +// Clock enable for PCI state machine driven directly from critical inputs - FRAME and IRDY +wire pcit_sm_clk_en ; +// FSM states signals indicating the current state +reg state_idle ; +reg state_wait ; +reg sm_transfere ; +reg backoff ; +reg state_default ; +wire state_backoff = sm_transfere && backoff ; +wire state_transfere = sm_transfere && !backoff ; + +always@(posedge clk_in or posedge reset_in) +begin + if ( reset_in ) + backoff <= #`FF_DELAY 1'b0 ; + else if ( state_idle ) + backoff <= #`FF_DELAY 1'b0 ; + else + backoff <= #`FF_DELAY (state_wait && !s_wait_progress) || + (sm_transfere && !s_tran_progress && !pci_frame_in && !pci_irdy_in) || + backoff ; +end +assign config_disconnect = sm_transfere && (norm_access_to_conf_reg || cnf_progress) ; + +// Clock enable module used for preserving the architecture because of minimum delay for critical inputs +pci_target32_clk_en pci_target_clock_en +( + .addr_phase (addr_phase), + .config_access (config_access), + .addr_claim_in (addr_claim_in), + .pci_frame_in (pci_frame_in), + .state_wait (state_wait), + .state_transfere (sm_transfere), + .state_default (state_default), + .clk_enable (pcit_sm_clk_en) +); + +reg [2:0] c_state ; //current state register +reg [2:0] n_state ; //next state input to current state register + +// state machine register control +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) // reset state machine to S_IDLE state + c_state <= #`FF_DELAY S_IDLE ; + else + if (pcit_sm_clk_en) // if conditions are true, then FSM goes to next state! + c_state <= #`FF_DELAY n_state ; +end + +// state machine logic +always@(c_state) +begin + case (c_state) + S_IDLE : + begin + state_idle <= 1'b1 ; + state_wait <= 1'b0 ; + sm_transfere <= 1'b0 ; + state_default <= 1'b0 ; + n_state <= S_WAIT ; + end + S_WAIT : + begin + state_idle <= 1'b0 ; + state_wait <= 1'b1 ; + sm_transfere <= 1'b0 ; + state_default <= 1'b0 ; + n_state <= S_TRANSFERE ; + end + S_TRANSFERE : + begin + state_idle <= 1'b0 ; + state_wait <= 1'b0 ; + sm_transfere <= 1'b1 ; + state_default <= 1'b0 ; + n_state <= S_IDLE ; + end + default : + begin + state_idle <= 1'b0 ; + state_wait <= 1'b0 ; + sm_transfere <= 1'b0 ; + state_default <= 1'b1 ; + n_state <= S_IDLE ; + end + endcase +end + + // if not retry and not target abort + // NO CRITICAL SIGNALS +wire trdy_w = ( + (state_wait && ~cnf_progress && rw_cbe0 && wr_progress && ~target_abort_in) || + (state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && ~target_abort_in && !pcir_fifo_data_err_in) || + (state_wait && ~cnf_progress && ~rw_cbe0 && ~same_read_reg && norm_access_to_conf_reg && ~target_abort_in) || + (state_wait && cnf_progress && ~target_abort_in) + ) ; + // if not disconnect without data and not target abort (only during reads) + // MUST BE ANDED WITH CRITICAL ~FRAME +wire trdy_w_frm = ( + (state_transfere && !cnf_progress && !norm_access_to_conf_reg && rw_cbe0 && !disconect_wo_data) || + (state_transfere && !cnf_progress && !norm_access_to_conf_reg && ~rw_cbe0 && !disconect_wo_data && ~pcir_fifo_data_err_in) || + (state_transfere && !cnf_progress && !norm_access_to_conf_reg && disconect_w_data && pci_irdy_reg_in && + ((~rw_cbe0 && ~pcir_fifo_data_err_in) || rw_cbe0)) + ) ; + // if not disconnect without data and not target abort (only during reads) + // MUST BE ANDED WITH CRITICAL ~FRAME AND IRDY +wire trdy_w_frm_irdy = ( ~bckp_trdy_in ) ; +// TRDY critical module used for preserving the architecture because of minimum delay for critical inputs +pci_target32_trdy_crit pci_target_trdy_critical +( + .trdy_w (trdy_w), + .trdy_w_frm (trdy_w_frm), + .trdy_w_frm_irdy (trdy_w_frm_irdy), + .pci_frame_in (pci_frame_in), + .pci_irdy_in (pci_irdy_in), + .pci_trdy_out (pci_trdy_out) +); + + // if target abort or retry + // NO CRITICAL SIGNALS +wire stop_w = ( + (state_wait && target_abort_in) || + (state_wait && ~cnf_progress && rw_cbe0 && ~wr_progress) || + (state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && ~rd_progress) || + (state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && pcir_fifo_data_err_in) || + (state_wait && ~cnf_progress && ~rw_cbe0 && ~same_read_reg && ~norm_access_to_conf_reg) + ) ; + // if asserted, wait for deactivating the frame + // MUST BE ANDED WITH CRITICAL ~FRAME +wire stop_w_frm = ( + (state_backoff && ~bckp_stop_in) + ) ; + // if target abort or if disconnect without data (after data transfere) + // MUST BE ANDED WITH CRITICAL ~FRAME AND ~IRDY +wire stop_w_frm_irdy = ( + (state_transfere && (disconect_wo_data)) || + (state_transfere && ~rw_cbe0 && pcir_fifo_data_err_in) + ) ; +// STOP critical module used for preserving the architecture because of minimum delay for critical inputs +pci_target32_stop_crit pci_target_stop_critical +( + .stop_w (stop_w), + .stop_w_frm (stop_w_frm), + .stop_w_frm_irdy (stop_w_frm_irdy), + .pci_frame_in (pci_frame_in), + .pci_irdy_in (pci_irdy_in), + .pci_stop_out (pci_stop_out) +); + + // if OK to respond and not target abort + // NO CRITICAL SIGNALS +wire devs_w = ( + (addr_phase && config_access) || + (addr_phase && ~config_access && addr_claim_in) || + (state_wait && ~target_abort_in && !(~cnf_progress && ~rw_cbe0 && same_read_reg && rd_progress && pcir_fifo_data_err_in) ) + ) ; + + // if not target abort (only during reads) or if asserted, wait for deactivating the frame + // MUST BE ANDED WITH CRITICAL ~FRAME +wire devs_w_frm = ( + (state_transfere && rw_cbe0) || + (state_transfere && ~rw_cbe0 && ~pcir_fifo_data_err_in) || + (state_backoff && ~bckp_devsel_in) + ) ; + // if not target abort (only during reads) + // MUST BE ANDED WITH CRITICAL ~FRAME AND IRDY +wire devs_w_frm_irdy = ( + (state_transfere && ~rw_cbe0 && pcir_fifo_data_err_in) + ) ; +// DEVSEL critical module used for preserving the architecture because of minimum delay for critical inputs +pci_target32_devs_crit pci_target_devsel_critical +( + .devs_w (devs_w), + .devs_w_frm (devs_w_frm), + .devs_w_frm_irdy (devs_w_frm_irdy), + .pci_frame_in (pci_frame_in), + .pci_irdy_in (pci_irdy_in), + .pci_devsel_out (pci_devsel_out) +); + +// signal used in AD enable module with preserving the hierarchy because of minimum delay for critical inputs +assign pci_ad_en_out = ( + (addr_phase && config_access && ~pci_cbe_reg_in[0]) || + (addr_phase && ~config_access && addr_claim_in && ~pci_cbe_reg_in[0]) || + (state_wait && ~rw_cbe0) || + (state_transfere && ~rw_cbe0) || + (state_backoff && ~rw_cbe0 && ~pci_frame_reg_in) + ) ; + +wire fast_back_to_back = (addr_phase && ~pci_irdy_reg_in) ; + + // if cycle will progress or will not be stopped + // NO CRITICAL SIGNALS +wire ctrl_en = + /*(~wbu_frame_en_in && fast_back_to_back) ||*/ + (addr_phase && config_access) || + (addr_phase && ~config_access && addr_claim_in) || + (state_wait) || + (state_transfere && ~(pci_frame_reg_in && ~pci_irdy_reg_in && (~pci_stop_reg_in || ~pci_trdy_reg_in))) || + (state_backoff && ~(pci_frame_reg_in && ~pci_irdy_reg_in && (~pci_stop_reg_in || ~pci_trdy_reg_in))) ; + +assign pci_trdy_en_out = ctrl_en ; +assign pci_stop_en_out = ctrl_en ; +assign pci_devsel_en_out = ctrl_en ; + +// target ready output signal delayed for one clock used in conjunction with irdy_reg to select which +// data are registered in io mux module - from fifo or medoum register +reg bckp_trdy_reg ; +// delayed indicators for states transfere and backoff +reg state_transfere_reg ; +reg state_backoff_reg ; +always@(posedge clk_in or posedge reset_in) +begin + if (reset_in) + begin + bckp_trdy_reg <= #`FF_DELAY 1'b1 ; + state_transfere_reg <= #`FF_DELAY 1'b0 ; + state_backoff_reg <= #`FF_DELAY 1'b0 ; + end + else + begin + bckp_trdy_reg <= #`FF_DELAY bckp_trdy_in ; + state_transfere_reg <= #`FF_DELAY state_transfere ; + state_backoff_reg <= #`FF_DELAY state_backoff ; + end +end + +// Read control signals assignments +assign + fetch_pcir_fifo_out = ( + (prepare_rd_fifo_data) || + (state_wait && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_from_fifo && ~target_abort_in) || + (bckp_trdy_en_in && ~pci_trdy_reg_in && ~cnf_progress && ~rw_cbe0 && same_read_reg && rd_from_fifo && ~pci_irdy_reg_in) + ) ; + +assign ad_load_out = (state_wait) ; + +assign ad_load_on_transfer_out = (bckp_trdy_en_in && ~rw_cbe0) ; + +assign load_medium_reg_out = ( + (prepare_rd_fifo_data) || + (state_wait && ~rw_cbe0 && ~cnf_progress && same_read_reg && rd_from_fifo && ~target_abort_in) || + (~pci_irdy_reg_in && ~rw_cbe0 && ~cnf_progress && same_read_reg && rd_from_fifo && ~pci_trdy_reg_in && bckp_trdy_en_in) + ) ; + +assign sel_fifo_mreg_out = (~pci_irdy_reg_in && ~bckp_trdy_reg) ; + +`ifdef HOST + `ifdef NO_CNF_IMAGE + assign sel_conf_fifo_out = 1'b0 ; + `else + assign sel_conf_fifo_out = (cnf_progress || norm_access_to_conf_reg) ; + `endif +`else + assign sel_conf_fifo_out = (cnf_progress || norm_access_to_conf_reg) ; +`endif + +// Write control signals assignments +assign + load_to_pciw_fifo_out = ( + (state_wait && (~cnf_progress && ~norm_access_to_conf_reg) && rw_cbe0 && wr_to_fifo && ~target_abort_in) || + (state_transfere_reg && ~state_backoff && rw_cbe0 && wr_to_fifo /*&& ~disconect_wo_data_reg*/ && ~pci_irdy_reg_in && ~bckp_trdy_reg && (~cnf_progress && ~norm_access_to_conf_reg)) || + ((state_backoff || state_backoff_reg) && rw_cbe0 && wr_to_fifo && ~pci_irdy_reg_in && ~bckp_trdy_reg && (~cnf_progress && ~norm_access_to_conf_reg)) + ) ; + +`ifdef HOST + `ifdef NO_CNF_IMAGE + assign load_to_conf_out = 1'b0 ; + `else + assign load_to_conf_out = ( + (state_transfere_reg && cnf_progress && rw_cbe0 && ~pci_irdy_reg_in && ~bckp_trdy_reg) || + (state_transfere_reg && norm_access_to_conf_reg && rw_cbe0 && ~pci_irdy_reg_in && ~bckp_trdy_reg) + ) ; + `endif +`else + assign load_to_conf_out = ( + (state_transfere_reg && cnf_progress && rw_cbe0 && ~pci_irdy_reg_in && ~bckp_trdy_reg) || + (state_transfere_reg && norm_access_to_conf_reg && rw_cbe0 && ~pci_irdy_reg_in && ~bckp_trdy_reg) + ) ; +`endif + +// General control sigal assignments +assign addr_phase_out = addr_phase ; +assign last_reg_out = (pci_frame_reg_in && ~pci_irdy_reg_in) ; +assign frame_reg_out = pci_frame_reg_in ; +assign bckp_devsel_out = bckp_devsel_in ; +assign bckp_trdy_out = bckp_trdy_in ; +assign bckp_stop_out = bckp_stop_in ; +assign target_abort_set_out = (bckp_devsel_in && bckp_trdy_in && ~bckp_stop_in && bckp_trdy_en_in) ; +// request signal for delayed sinc. module +reg master_will_request_read ; +always@(posedge clk_in or posedge reset_in) +begin + if ( reset_in ) + master_will_request_read <= #`FF_DELAY 1'b0 ; + else + master_will_request_read <= #`FF_DELAY ((state_wait && ~target_abort_in) || (state_backoff && ~target_abort_set_out)) && ~cnf_progress && ~norm_access_to_conf_reg && ~rw_cbe0 && rd_request ; +end +// MORE OPTIMIZED READS, but not easy to control in a testbench! +//assign req_out = master_will_request_read ; +assign req_out = master_will_request_read && !pci_irdy_reg_in && !read_processing_in ; + +// ready tells when address or data are written into fifo - RDY ? DATA : ADDRESS +assign rdy_out = ~bckp_trdy_reg ; + +// data and address outputs assignments! +assign pci_ad_out = data_in ; + +assign data_out = pci_ad_reg_in ; +assign be_out = pci_cbe_reg_in ; +assign next_be_out = pci_cbe_in ; +assign address_out = pci_ad_reg_in ; +assign bc_out = pci_cbe_reg_in ; +assign bc0_out = rw_cbe0 ; + + +endmodule diff --git a/ethernet/source/pci/pci_target32_stop_crit.v b/ethernet/source/pci/pci_target32_stop_crit.v new file mode 100644 index 0000000..8564a6e --- /dev/null +++ b/ethernet/source/pci/pci_target32_stop_crit.v @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_target32_stop_crit.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_target32_stop_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_target32_stop_crit +( + stop_w, + stop_w_frm, + stop_w_frm_irdy, + pci_frame_in, + pci_irdy_in, + pci_stop_out +); + +input stop_w ; // stop signal (composed without critical signals) that do not need critical inputs +input stop_w_frm ; // stop signal (composed without critical signals) that needs AND with critical FRAME input +input stop_w_frm_irdy ; // stop signal (composed without critical signals) that needs AND with critical FRAME and + // IRDY inputs +input pci_frame_in ; // critical constrained input signal +input pci_irdy_in ; // critical constrained input signal + +output pci_stop_out ; // PCI stop output + +// PCI stop output with preserved hierarchy for minimum delay! +assign pci_stop_out = ~(stop_w || (stop_w_frm && ~pci_frame_in) || (stop_w_frm_irdy && ~pci_frame_in && ~pci_irdy_in)) ; + + +endmodule diff --git a/ethernet/source/pci/pci_target32_trdy_crit.v b/ethernet/source/pci/pci_target32_trdy_crit.v new file mode 100644 index 0000000..9306ad0 --- /dev/null +++ b/ethernet/source/pci/pci_target32_trdy_crit.v @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_target32_trdy_crit.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_target32_trdy_crit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:13 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +// module is used to separate logic which uses criticaly constrained inputs from slower logic. +// It is used to synthesize critical timing logic separately with faster cells or without optimization + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_target32_trdy_crit +( + trdy_w, + trdy_w_frm, + trdy_w_frm_irdy, + pci_frame_in, + pci_irdy_in, + pci_trdy_out +); + +input trdy_w ; // trdy signal (composed without critical signals) that do not need critical inputs +input trdy_w_frm ; // trdy signal (composed without critical signals) that needs AND with critical FRAME input +input trdy_w_frm_irdy ; // trdy signal (composed without critical signals) that needs AND with critical FRAME and + // IRDY inputs +input pci_frame_in ; // critical constrained input signal +input pci_irdy_in ; // critical constrained input signal + +output pci_trdy_out ; // PCI trdy output + +// PCI trdy output with preserved hierarchy for minimum delay! +assign pci_trdy_out = ~(trdy_w || (trdy_w_frm && ~pci_frame_in) || (trdy_w_frm_irdy && ~pci_frame_in && pci_irdy_in)) ; + + +endmodule diff --git a/ethernet/source/pci/pci_target_unit.v b/ethernet/source/pci/pci_target_unit.v new file mode 100644 index 0000000..5dbf07e --- /dev/null +++ b/ethernet/source/pci/pci_target_unit.v @@ -0,0 +1,949 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: pci_target_unit.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_target_unit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.16 2004/08/19 15:27:34 mihad +// Changed minimum pci image size to 256 bytes because +// of some PC system problems with size of IO images. +// +// Revision 1.15 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.14 2003/10/17 09:11:52 markom +// mbist signals updated according to newest convention +// +// Revision 1.13 2003/08/21 20:55:14 tadejm +// Corrected bug when writing to FIFO (now it is registered). +// +// Revision 1.12 2003/08/08 16:36:33 tadejm +// Added 'three_left_out' to pci_pciw_fifo signaling three locations before full. Added comparison between current registered cbe and next unregistered cbe to signal wb_master whether it is allowed to performe burst or not. Due to this, I needed 'three_left_out' so that writing to pci_pciw_fifo can be registered, otherwise timing problems would occure. +// +// Revision 1.11 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.10 2002/10/18 03:36:37 tadejm +// Changed wrong signal name mbist_sen into mbist_ctrl_i. +// +// Revision 1.9 2002/10/17 22:51:08 tadejm +// Changed BIST signals for RAMs. +// +// Revision 1.8 2002/10/11 10:09:01 mihad +// Added additional testcase and changed rst name in BIST to trst +// +// Revision 1.7 2002/10/08 17:17:05 mihad +// Added BIST signals for RAMs. +// +// Revision 1.6 2002/09/25 15:53:52 mihad +// Removed all logic from asynchronous reset network +// +// Revision 1.5 2002/03/05 11:53:47 mihad +// Added some testcases, removed un-needed fifo signals +// +// Revision 1.4 2002/02/19 16:32:37 mihad +// Modified testbench and fixed some bugs +// +// Revision 1.3 2002/02/01 15:25:13 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +// Module instantiates and connects other modules lower in hierarcy +// PCI target unit consists of modules that together form datapath +// between external WISHBONE slaves and external PCI initiators +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_target_unit +( + reset_in, + wb_clock_in, + pci_clock_in, + + pciu_wbm_adr_o, + pciu_wbm_dat_o, + pciu_wbm_dat_i, + pciu_wbm_cyc_o, + pciu_wbm_stb_o, + pciu_wbm_we_o, + pciu_wbm_cti_o, + pciu_wbm_bte_o, + pciu_wbm_sel_o, + pciu_wbm_ack_i, + pciu_wbm_rty_i, + pciu_wbm_err_i, + pciu_mem_enable_in, + pciu_io_enable_in, + pciu_map_in, + pciu_pref_en_in, + pciu_conf_data_in, + pciu_wbw_fifo_empty_in, + pciu_wbu_del_read_comp_pending_in, + pciu_wbu_frame_en_in, + pciu_bar0_in, + pciu_bar1_in, + pciu_bar2_in, + pciu_bar3_in, + pciu_bar4_in, + pciu_bar5_in, + pciu_am0_in, + pciu_am1_in, + pciu_am2_in, + pciu_am3_in, + pciu_am4_in, + pciu_am5_in, + pciu_ta0_in, + pciu_ta1_in, + pciu_ta2_in, + pciu_ta3_in, + pciu_ta4_in, + pciu_ta5_in, + pciu_at_en_in, + pciu_cache_line_size_in, + pciu_cache_lsize_not_zero_in, + pciu_pciif_frame_in, + pciu_pciif_irdy_in, + pciu_pciif_idsel_in, + pciu_pciif_frame_reg_in, + pciu_pciif_irdy_reg_in, + pciu_pciif_idsel_reg_in, + pciu_pciif_ad_reg_in, + pciu_pciif_cbe_reg_in, + pciu_pciif_cbe_in, + pciu_pciif_bckp_trdy_en_in, + pciu_pciif_bckp_devsel_in, + pciu_pciif_bckp_trdy_in, + pciu_pciif_bckp_stop_in, + pciu_pciif_trdy_reg_in, + pciu_pciif_stop_reg_in, + pciu_pciif_trdy_out, + pciu_pciif_stop_out, + pciu_pciif_devsel_out, + pciu_pciif_trdy_en_out, + pciu_pciif_stop_en_out, + pciu_pciif_devsel_en_out, + pciu_ad_load_out, + pciu_ad_load_on_transfer_out, + pciu_pciif_ad_out, + pciu_pciif_ad_en_out, + pciu_pciif_tabort_set_out, + pciu_err_addr_out, + pciu_err_bc_out, + pciu_err_data_out, + pciu_err_be_out, + pciu_err_signal_out, + pciu_err_source_out, + pciu_err_rty_exp_out, + pciu_conf_offset_out, + pciu_conf_renable_out, + pciu_conf_wenable_out, + pciu_conf_be_out, + pciu_conf_data_out, + pciu_pci_drcomp_pending_out, + pciu_pciw_fifo_empty_out + +`ifdef PCI_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif +); + +`ifdef HOST + `ifdef NO_CNF_IMAGE + parameter pci_ba0_width = `PCI_NUM_OF_DEC_ADDR_LINES ; + `else + parameter pci_ba0_width = 20 ; + `endif +`endif + +`ifdef GUEST + parameter pci_ba0_width = 20 ; +`endif + +parameter pci_ba1_5_width = `PCI_NUM_OF_DEC_ADDR_LINES ; + +input reset_in, + wb_clock_in, + pci_clock_in ; + +output [31:0] pciu_wbm_adr_o ; +output [31:0] pciu_wbm_dat_o ; +input [31:0] pciu_wbm_dat_i ; +output pciu_wbm_cyc_o ; +output pciu_wbm_stb_o ; +output pciu_wbm_we_o ; +output [2:0] pciu_wbm_cti_o ; +output [1:0] pciu_wbm_bte_o ; +output [3:0] pciu_wbm_sel_o ; +input pciu_wbm_ack_i ; +input pciu_wbm_rty_i ; +input pciu_wbm_err_i ; + +input pciu_wbw_fifo_empty_in ; +input pciu_wbu_del_read_comp_pending_in ; +input pciu_wbu_frame_en_in ; + +input pciu_mem_enable_in ; +input pciu_io_enable_in ; +input [5:0] pciu_map_in ; +input [5:0] pciu_pref_en_in ; +input [31:0] pciu_conf_data_in ; + +input [pci_ba0_width - 1:0] pciu_bar0_in ; +input [pci_ba1_5_width - 1:0] pciu_bar1_in ; +input [pci_ba1_5_width - 1:0] pciu_bar2_in ; +input [pci_ba1_5_width - 1:0] pciu_bar3_in ; +input [pci_ba1_5_width - 1:0] pciu_bar4_in ; +input [pci_ba1_5_width - 1:0] pciu_bar5_in ; +input [pci_ba1_5_width - 1:0] pciu_am0_in ; +input [pci_ba1_5_width - 1:0] pciu_am1_in ; +input [pci_ba1_5_width - 1:0] pciu_am2_in ; +input [pci_ba1_5_width - 1:0] pciu_am3_in ; +input [pci_ba1_5_width - 1:0] pciu_am4_in ; +input [pci_ba1_5_width - 1:0] pciu_am5_in ; +input [pci_ba1_5_width - 1:0] pciu_ta0_in ; +input [pci_ba1_5_width - 1:0] pciu_ta1_in ; +input [pci_ba1_5_width - 1:0] pciu_ta2_in ; +input [pci_ba1_5_width - 1:0] pciu_ta3_in ; +input [pci_ba1_5_width - 1:0] pciu_ta4_in ; +input [pci_ba1_5_width - 1:0] pciu_ta5_in ; +input [5:0] pciu_at_en_in ; + +input [7:0] pciu_cache_line_size_in ; +input pciu_cache_lsize_not_zero_in ; + +input pciu_pciif_frame_in ; +input pciu_pciif_irdy_in ; +input pciu_pciif_idsel_in ; +input pciu_pciif_frame_reg_in ; +input pciu_pciif_irdy_reg_in ; +input pciu_pciif_idsel_reg_in ; +input [31:0] pciu_pciif_ad_reg_in ; +input [3:0] pciu_pciif_cbe_reg_in ; +input [3:0] pciu_pciif_cbe_in; +input pciu_pciif_bckp_trdy_en_in ; +input pciu_pciif_bckp_devsel_in ; +input pciu_pciif_bckp_trdy_in ; +input pciu_pciif_bckp_stop_in ; +input pciu_pciif_trdy_reg_in ; +input pciu_pciif_stop_reg_in ; + + +output pciu_pciif_trdy_out ; +output pciu_pciif_stop_out ; +output pciu_pciif_devsel_out ; +output pciu_pciif_trdy_en_out ; +output pciu_pciif_stop_en_out ; +output pciu_pciif_devsel_en_out ; +output pciu_ad_load_out ; +output pciu_ad_load_on_transfer_out ; +output [31:0] pciu_pciif_ad_out ; +output pciu_pciif_ad_en_out ; +output pciu_pciif_tabort_set_out ; + +output [31:0] pciu_err_addr_out ; +output [3:0] pciu_err_bc_out ; +output [31:0] pciu_err_data_out ; +output [3:0] pciu_err_be_out ; +output pciu_err_signal_out ; +output pciu_err_source_out ; +output pciu_err_rty_exp_out ; + +output [11:0] pciu_conf_offset_out ; +output pciu_conf_renable_out ; +output pciu_conf_wenable_out ; +output [3:0] pciu_conf_be_out ; +output [31:0] pciu_conf_data_out ; + +output pciu_pci_drcomp_pending_out ; +output pciu_pciw_fifo_empty_out ; + +`ifdef PCI_BIST +/*----------------------------------------------------- +BIST debug chain port signals +-----------------------------------------------------*/ +input mbist_si_i; // bist scan serial in +output mbist_so_o; // bist scan serial out +input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + + +// pci target state machine and interface outputs +wire pcit_sm_trdy_out ; +wire pcit_sm_stop_out ; +wire pcit_sm_devsel_out ; +wire pcit_sm_trdy_en_out ; +wire pcit_sm_stop_en_out ; +wire pcit_sm_devsel_en_out ; +wire pcit_sm_ad_load_out ; +wire pcit_sm_ad_load_on_transfer_out ; +wire [31:0] pcit_sm_ad_out ; +wire pcit_sm_ad_en_out ; +wire [31:0] pcit_sm_address_out ; +wire [3:0] pcit_sm_bc_out ; +wire pcit_sm_bc0_out ; +wire [31:0] pcit_sm_data_out ; +wire [3:0] pcit_sm_be_out ; +wire [3:0] pcit_sm_next_be_out ; +wire pcit_sm_req_out ; +wire pcit_sm_rdy_out ; +wire pcit_sm_addr_phase_out ; +wire pcit_sm_bckp_devsel_out ; +wire pcit_sm_bckp_trdy_out ; +wire pcit_sm_bckp_stop_out ; +wire pcit_sm_last_reg_out ; +wire pcit_sm_frame_reg_out ; +wire pcit_sm_fetch_pcir_fifo_out ; +wire pcit_sm_load_medium_reg_out ; +wire pcit_sm_sel_fifo_mreg_out ; +wire pcit_sm_sel_conf_fifo_out ; +wire pcit_sm_load_to_pciw_fifo_out ; +wire pcit_sm_load_to_conf_out ; + +wire pcit_sm_target_abort_set_out ; // to conf space + +assign pciu_pciif_trdy_out = pcit_sm_trdy_out ; +assign pciu_pciif_stop_out = pcit_sm_stop_out ; +assign pciu_pciif_devsel_out = pcit_sm_devsel_out ; +assign pciu_pciif_trdy_en_out = pcit_sm_trdy_en_out ; +assign pciu_pciif_stop_en_out = pcit_sm_stop_en_out ; +assign pciu_pciif_devsel_en_out = pcit_sm_devsel_en_out ; +assign pciu_ad_load_out = pcit_sm_ad_load_out ; +assign pciu_ad_load_on_transfer_out = pcit_sm_ad_load_on_transfer_out ; +assign pciu_pciif_ad_out = pcit_sm_ad_out ; +assign pciu_pciif_ad_en_out = pcit_sm_ad_en_out ; +assign pciu_pciif_tabort_set_out = pcit_sm_target_abort_set_out ; + +wire pcit_if_addr_claim_out ; +wire [31:0] pcit_if_data_out ; +wire pcit_if_same_read_out ; +wire pcit_if_norm_access_to_config_out ; +wire pcit_if_read_completed_out ; +wire pcit_if_read_processing_out ; +wire pcit_if_target_abort_out ; +wire pcit_if_disconect_wo_data_out ; +wire pcit_if_disconect_w_data_out ; +wire pcit_if_pciw_fifo_full_out ; +wire pcit_if_pcir_fifo_data_err_out ; +wire pcit_if_wbw_fifo_empty_out ; +wire pcit_if_wbu_del_read_comp_pending_out ; +wire pcit_if_req_out ; +wire pcit_if_done_out ; +wire pcit_if_in_progress_out ; +wire [31:0] pcit_if_addr_out ; +wire [3:0] pcit_if_be_out ; +wire pcit_if_we_out ; +wire [3:0] pcit_if_bc_out ; +wire pcit_if_burst_ok_out ; +wire pcit_if_pcir_fifo_renable_out ; +wire pcit_if_pcir_fifo_flush_out ; +wire pcit_if_pciw_fifo_wenable_out ; +wire [31:0] pcit_if_pciw_fifo_addr_data_out ; +wire [3:0] pcit_if_pciw_fifo_cbe_out ; +wire [3:0] pcit_if_pciw_fifo_control_out ; +wire [11:0] pcit_if_conf_addr_out ; +wire [31:0] pcit_if_conf_data_out ; +wire [3:0] pcit_if_conf_be_out ; +wire pcit_if_conf_we_out ; +wire pcit_if_conf_re_out ; + +// pci target state machine outputs +// pci interface signals +assign pciu_conf_offset_out = pcit_if_conf_addr_out ; +assign pciu_conf_renable_out = pcit_if_conf_re_out ; +assign pciu_conf_wenable_out = pcit_if_conf_we_out ; +assign pciu_conf_be_out = pcit_if_conf_be_out ; +assign pciu_conf_data_out = pcit_if_conf_data_out ; + +// wishbone master state machine outputs +wire wbm_sm_wb_read_done ; +wire wbm_sm_write_attempt ; +wire wbm_sm_pcir_fifo_wenable_out ; +wire [31:0] wbm_sm_pcir_fifo_data_out ; +wire [3:0] wbm_sm_pcir_fifo_be_out ; +wire [3:0] wbm_sm_pcir_fifo_control_out ; +wire wbm_sm_pciw_fifo_renable_out ; +wire wbm_sm_pci_error_sig_out ; +wire [3:0] wbm_sm_pci_error_bc ; +wire wbm_sm_write_rty_cnt_exp_out ; +wire wbm_sm_error_source_out ; +wire wbm_sm_read_rty_cnt_exp_out ; +wire wbm_sm_cyc_out ; +wire wbm_sm_stb_out ; +wire wbm_sm_we_out ; +wire [2:0] wbm_sm_cti_out ; +wire [1:0] wbm_sm_bte_out ; +wire [3:0] wbm_sm_sel_out ; +wire [31:0] wbm_sm_adr_out ; +wire [31:0] wbm_sm_mdata_out ; + +assign pciu_err_addr_out = wbm_sm_adr_out ; +assign pciu_err_bc_out = wbm_sm_pci_error_bc ; +assign pciu_err_data_out = wbm_sm_mdata_out ; +assign pciu_err_be_out = ~wbm_sm_sel_out ; +assign pciu_err_signal_out = wbm_sm_pci_error_sig_out ; +assign pciu_err_source_out = wbm_sm_error_source_out ; +assign pciu_err_rty_exp_out = wbm_sm_write_rty_cnt_exp_out ; + +assign pciu_wbm_adr_o = wbm_sm_adr_out ; +assign pciu_wbm_dat_o = wbm_sm_mdata_out ; +assign pciu_wbm_cyc_o = wbm_sm_cyc_out ; +assign pciu_wbm_stb_o = wbm_sm_stb_out ; +assign pciu_wbm_we_o = wbm_sm_we_out ; +assign pciu_wbm_cti_o = wbm_sm_cti_out ; +assign pciu_wbm_bte_o = wbm_sm_bte_out ; +assign pciu_wbm_sel_o = wbm_sm_sel_out ; + +// pciw_pcir fifo outputs + +// pciw_fifo_outputs: +wire [31:0] fifos_pciw_addr_data_out ; +wire [3:0] fifos_pciw_cbe_out ; +wire [3:0] fifos_pciw_control_out ; +wire fifos_pciw_three_left_out ; +wire fifos_pciw_two_left_out ; +wire fifos_pciw_almost_full_out ; +wire fifos_pciw_full_out ; +wire fifos_pciw_almost_empty_out ; +wire fifos_pciw_empty_out ; +wire fifos_pciw_transaction_ready_out ; + +assign pciu_pciw_fifo_empty_out = !wbm_sm_write_attempt; + +// pcir_fifo_outputs +wire [31:0] fifos_pcir_data_out ; +wire [3:0] fifos_pcir_be_out ; +wire [3:0] fifos_pcir_control_out ; +wire fifos_pcir_almost_empty_out ; +wire fifos_pcir_empty_out ; + +// delayed transaction logic outputs +wire [31:0] del_sync_addr_out ; +wire [3:0] del_sync_be_out ; +wire del_sync_we_out ; +wire del_sync_comp_req_pending_out ; +wire del_sync_comp_comp_pending_out ; +wire del_sync_req_req_pending_out ; +wire del_sync_req_comp_pending_out ; +wire [3:0] del_sync_bc_out ; +wire del_sync_status_out ; +wire del_sync_comp_flush_out ; +wire del_sync_burst_out ; + +assign pciu_pci_drcomp_pending_out = del_sync_comp_comp_pending_out ; + +// WISHBONE master interface inputs +wire wbm_sm_pci_tar_read_request = del_sync_comp_req_pending_out ; +wire [31:0] wbm_sm_pci_tar_address = del_sync_addr_out ; +wire [3:0] wbm_sm_pci_tar_cmd = del_sync_bc_out ; +wire [3:0] wbm_sm_pci_tar_be = del_sync_be_out ; +wire wbm_sm_pci_tar_burst_ok = del_sync_burst_out ; +wire [7:0] wbm_sm_pci_cache_line_size = pciu_cache_line_size_in ; +wire wbm_sm_cache_lsize_not_zero_in = pciu_cache_lsize_not_zero_in ; +wire [31:0] wbm_sm_pciw_fifo_addr_data_in = fifos_pciw_addr_data_out ; +wire [3:0] wbm_sm_pciw_fifo_cbe_in = fifos_pciw_cbe_out ; +wire [3:0] wbm_sm_pciw_fifo_control_in = fifos_pciw_control_out ; +wire wbm_sm_pciw_fifo_almost_empty_in = fifos_pciw_almost_empty_out ; +wire wbm_sm_pciw_fifo_empty_in = fifos_pciw_empty_out ; +wire wbm_sm_pciw_fifo_transaction_ready_in = fifos_pciw_transaction_ready_out ; +wire [31:0] wbm_sm_mdata_in = pciu_wbm_dat_i ; +wire wbm_sm_ack_in = pciu_wbm_ack_i ; +wire wbm_sm_rty_in = pciu_wbm_rty_i ; +wire wbm_sm_err_in = pciu_wbm_err_i ; + +// WISHBONE master interface instantiation +pci_wb_master wishbone_master +( + .wb_clock_in (wb_clock_in), + .reset_in (reset_in), + .pci_tar_read_request (wbm_sm_pci_tar_read_request), //in + .pci_tar_address (wbm_sm_pci_tar_address), //in + .pci_tar_cmd (wbm_sm_pci_tar_cmd), //in + .pci_tar_be (wbm_sm_pci_tar_be), //in + .pci_tar_burst_ok (wbm_sm_pci_tar_burst_ok), //in + .pci_cache_line_size (wbm_sm_pci_cache_line_size), //in + .cache_lsize_not_zero (wbm_sm_cache_lsize_not_zero_in), + .wb_read_done_out (wbm_sm_wb_read_done), //out + .w_attempt (wbm_sm_write_attempt), //out + .pcir_fifo_wenable_out (wbm_sm_pcir_fifo_wenable_out), + .pcir_fifo_data_out (wbm_sm_pcir_fifo_data_out), + .pcir_fifo_be_out (wbm_sm_pcir_fifo_be_out), + .pcir_fifo_control_out (wbm_sm_pcir_fifo_control_out), + .pciw_fifo_renable_out (wbm_sm_pciw_fifo_renable_out), + .pciw_fifo_addr_data_in (wbm_sm_pciw_fifo_addr_data_in), + .pciw_fifo_cbe_in (wbm_sm_pciw_fifo_cbe_in), + .pciw_fifo_control_in (wbm_sm_pciw_fifo_control_in), + .pciw_fifo_almost_empty_in (wbm_sm_pciw_fifo_almost_empty_in), + .pciw_fifo_empty_in (wbm_sm_pciw_fifo_empty_in), + .pciw_fifo_transaction_ready_in (wbm_sm_pciw_fifo_transaction_ready_in), + .pci_error_sig_out (wbm_sm_pci_error_sig_out), + .pci_error_bc (wbm_sm_pci_error_bc), + .write_rty_cnt_exp_out (wbm_sm_write_rty_cnt_exp_out), + .error_source_out (wbm_sm_error_source_out), + .read_rty_cnt_exp_out (wbm_sm_read_rty_cnt_exp_out), + .wb_cyc_o (wbm_sm_cyc_out), + .wb_stb_o (wbm_sm_stb_out), + .wb_we_o (wbm_sm_we_out), + .wb_cti_o (wbm_sm_cti_out), + .wb_bte_o (wbm_sm_bte_out), + .wb_sel_o (wbm_sm_sel_out), + .wb_adr_o (wbm_sm_adr_out), + .wb_dat_i (wbm_sm_mdata_in), + .wb_dat_o (wbm_sm_mdata_out), + .wb_ack_i (wbm_sm_ack_in), + .wb_rty_i (wbm_sm_rty_in), + .wb_err_i (wbm_sm_err_in) +); + +// pciw_pcir_fifos inputs +// PCIW_FIFO inputs +wire fifos_pciw_wenable_in = pcit_if_pciw_fifo_wenable_out ; +wire [31:0] fifos_pciw_addr_data_in = pcit_if_pciw_fifo_addr_data_out ; +wire [3:0] fifos_pciw_cbe_in = pcit_if_pciw_fifo_cbe_out ; +wire [3:0] fifos_pciw_control_in = pcit_if_pciw_fifo_control_out ; +wire fifos_pciw_renable_in = wbm_sm_pciw_fifo_renable_out ; +//wire fifos_pciw_flush_in = 1'b0 ; // flush not used for write fifo + +// PCIR_FIFO inputs +wire fifos_pcir_wenable_in = wbm_sm_pcir_fifo_wenable_out ; +wire [31:0] fifos_pcir_data_in = wbm_sm_pcir_fifo_data_out ; +wire [3:0] fifos_pcir_be_in = wbm_sm_pcir_fifo_be_out ; +wire [3:0] fifos_pcir_control_in = wbm_sm_pcir_fifo_control_out ; +wire fifos_pcir_renable_in = pcit_if_pcir_fifo_renable_out ; +wire fifos_pcir_flush_in = pcit_if_pcir_fifo_flush_out ; + +// PCIW_FIFO and PCIR_FIFO instantiation +pci_pciw_pcir_fifos fifos +( + .wb_clock_in (wb_clock_in), + .pci_clock_in (pci_clock_in), + .reset_in (reset_in), + .pciw_wenable_in (fifos_pciw_wenable_in), //for PCI Target !!! + .pciw_addr_data_in (fifos_pciw_addr_data_in), //for PCI Target !!! + .pciw_cbe_in (fifos_pciw_cbe_in), //for PCI Target !!! + .pciw_control_in (fifos_pciw_control_in), //for PCI Target !!! + .pciw_renable_in (fifos_pciw_renable_in), + .pciw_addr_data_out (fifos_pciw_addr_data_out), + .pciw_cbe_out (fifos_pciw_cbe_out), + .pciw_control_out (fifos_pciw_control_out), +// .pciw_flush_in (fifos_pciw_flush_in), // flush not used for write fifo + .pciw_three_left_out (fifos_pciw_three_left_out), //for PCI Target !!! + .pciw_two_left_out (fifos_pciw_two_left_out), //for PCI Target !!! + .pciw_almost_full_out (fifos_pciw_almost_full_out), //for PCI Target !!! + .pciw_full_out (fifos_pciw_full_out), //for PCI Target !!! + .pciw_almost_empty_out (fifos_pciw_almost_empty_out), + .pciw_empty_out (fifos_pciw_empty_out), + .pciw_transaction_ready_out (fifos_pciw_transaction_ready_out), + .pcir_wenable_in (fifos_pcir_wenable_in), + .pcir_data_in (fifos_pcir_data_in), + .pcir_be_in (fifos_pcir_be_in), + .pcir_control_in (fifos_pcir_control_in), + .pcir_renable_in (fifos_pcir_renable_in), //for PCI Target !!! + .pcir_data_out (fifos_pcir_data_out), //for PCI Target !!! + .pcir_be_out (fifos_pcir_be_out), //for PCI Target !!! + .pcir_control_out (fifos_pcir_control_out), //for PCI Target !!! + .pcir_flush_in (fifos_pcir_flush_in), //for PCI Target !!! + .pcir_full_out (), + .pcir_almost_empty_out (fifos_pcir_almost_empty_out), //for PCI Target !!! + .pcir_empty_out (fifos_pcir_empty_out), //for PCI Target !!! + .pcir_transaction_ready_out () + +`ifdef PCI_BIST + , + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) +`endif +) ; + +// delayed transaction logic inputs +wire del_sync_req_in = pcit_if_req_out ; +wire del_sync_comp_in = wbm_sm_wb_read_done ; +wire del_sync_done_in = pcit_if_done_out ; +wire del_sync_in_progress_in = pcit_if_in_progress_out ; +wire [31:0] del_sync_addr_in = pcit_if_addr_out ; +wire [3:0] del_sync_be_in = pcit_if_be_out ; +wire del_sync_we_in = pcit_if_we_out ; +wire [3:0] del_sync_bc_in = pcit_if_bc_out ; +wire del_sync_status_in = 1'b0 ; +wire del_sync_burst_in = pcit_if_burst_ok_out ; +wire del_sync_retry_expired_in = wbm_sm_read_rty_cnt_exp_out ; + +// delayed transaction logic instantiation +pci_delayed_sync del_sync +( + .reset_in (reset_in), + .req_clk_in (pci_clock_in), + .comp_clk_in (wb_clock_in), + .req_in (del_sync_req_in), + .comp_in (del_sync_comp_in), + .done_in (del_sync_done_in), + .in_progress_in (del_sync_in_progress_in), + .comp_req_pending_out (del_sync_comp_req_pending_out), + .comp_comp_pending_out (del_sync_comp_comp_pending_out), + .req_req_pending_out (del_sync_req_req_pending_out), + .req_comp_pending_out (del_sync_req_comp_pending_out), + .addr_in (del_sync_addr_in), + .be_in (del_sync_be_in), + .addr_out (del_sync_addr_out), + .be_out (del_sync_be_out), + .we_in (del_sync_we_in), + .we_out (del_sync_we_out), + .bc_in (del_sync_bc_in), + .bc_out (del_sync_bc_out), + .status_in (del_sync_status_in), + .status_out (del_sync_status_out), + .comp_flush_out (del_sync_comp_flush_out), + .burst_in (del_sync_burst_in), + .burst_out (del_sync_burst_out), + .retry_expired_in (del_sync_retry_expired_in) +); + +// pci target interface inputs +wire [31:0] pcit_if_address_in = pcit_sm_address_out ; +wire [3:0] pcit_if_bc_in = pcit_sm_bc_out ; +wire pcit_if_bc0_in = pcit_sm_bc0_out ; +wire [31:0] pcit_if_data_in = pcit_sm_data_out ; +wire [3:0] pcit_if_be_in = pcit_sm_be_out ; +wire [3:0] pcit_if_next_be_in = pcit_sm_next_be_out ; +wire pcit_if_req_in = pcit_sm_req_out ; +wire pcit_if_rdy_in = pcit_sm_rdy_out ; +wire pcit_if_addr_phase_in = pcit_sm_addr_phase_out ; +wire pcit_if_bckp_devsel_in = pcit_sm_bckp_devsel_out ; +wire pcit_if_bckp_trdy_in = pcit_sm_bckp_trdy_out ; +wire pcit_if_bckp_stop_in = pcit_sm_bckp_stop_out ; +wire pcit_if_last_reg_in = pcit_sm_last_reg_out ; +wire pcit_if_frame_reg_in = pcit_sm_frame_reg_out ; +wire pcit_if_fetch_pcir_fifo_in = pcit_sm_fetch_pcir_fifo_out ; +wire pcit_if_load_medium_reg_in = pcit_sm_load_medium_reg_out ; +wire pcit_if_sel_fifo_mreg_in = pcit_sm_sel_fifo_mreg_out ; +wire pcit_if_sel_conf_fifo_in = pcit_sm_sel_conf_fifo_out ; +wire pcit_if_load_to_pciw_fifo_in = pcit_sm_load_to_pciw_fifo_out ; +wire pcit_if_load_to_conf_in = pcit_sm_load_to_conf_out ; +wire pcit_if_req_req_pending_in = del_sync_req_req_pending_out ; +wire pcit_if_req_comp_pending_in = del_sync_req_comp_pending_out ; +wire pcit_if_status_in = del_sync_status_out ; +wire [31:0] pcit_if_strd_addr_in = del_sync_addr_out ; +wire [3:0] pcit_if_strd_bc_in = del_sync_bc_out ; +wire pcit_if_comp_flush_in = del_sync_comp_flush_out ; +wire [31:0] pcit_if_pcir_fifo_data_in = fifos_pcir_data_out ; +wire [3:0] pcit_if_pcir_fifo_be_in = fifos_pcir_be_out ; +wire [3:0] pcit_if_pcir_fifo_control_in = fifos_pcir_control_out ; +wire pcit_if_pcir_fifo_almost_empty_in = fifos_pcir_almost_empty_out ; +wire pcit_if_pcir_fifo_empty_in = fifos_pcir_empty_out ; +wire pcit_if_pciw_fifo_three_left_in = fifos_pciw_three_left_out ; +wire pcit_if_pciw_fifo_two_left_in = fifos_pciw_two_left_out ; +wire pcit_if_pciw_fifo_almost_full_in = fifos_pciw_almost_full_out ; +wire pcit_if_pciw_fifo_full_in = fifos_pciw_full_out ; +wire pcit_if_wbw_fifo_empty_in = pciu_wbw_fifo_empty_in ; +wire pcit_if_wbu_del_read_comp_pending_in = pciu_wbu_del_read_comp_pending_in ; +wire [31:0] pcit_if_conf_data_in = pciu_conf_data_in ; +wire pcit_if_mem_enable_in = pciu_mem_enable_in ; +wire pcit_if_io_enable_in = pciu_io_enable_in ; +wire pcit_if_mem_io_addr_space0_in = pciu_map_in[0] ; +wire pcit_if_mem_io_addr_space1_in = pciu_map_in[1] ; +wire pcit_if_mem_io_addr_space2_in = pciu_map_in[2] ; +wire pcit_if_mem_io_addr_space3_in = pciu_map_in[3] ; +wire pcit_if_mem_io_addr_space4_in = pciu_map_in[4] ; +wire pcit_if_mem_io_addr_space5_in = pciu_map_in[5] ; +wire pcit_if_pre_fetch_en0_in = pciu_pref_en_in[0] ; +wire pcit_if_pre_fetch_en1_in = pciu_pref_en_in[1] ; +wire pcit_if_pre_fetch_en2_in = pciu_pref_en_in[2] ; +wire pcit_if_pre_fetch_en3_in = pciu_pref_en_in[3] ; +wire pcit_if_pre_fetch_en4_in = pciu_pref_en_in[4] ; +wire pcit_if_pre_fetch_en5_in = pciu_pref_en_in[5] ; +wire [(pci_ba0_width - 1):0] pcit_if_pci_base_addr0_in = pciu_bar0_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_base_addr1_in = pciu_bar1_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_base_addr2_in = pciu_bar2_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_base_addr3_in = pciu_bar3_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_base_addr4_in = pciu_bar4_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_base_addr5_in = pciu_bar5_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_addr_mask0_in = pciu_am0_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_addr_mask1_in = pciu_am1_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_addr_mask2_in = pciu_am2_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_addr_mask3_in = pciu_am3_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_addr_mask4_in = pciu_am4_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_addr_mask5_in = pciu_am5_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_tran_addr0_in = pciu_ta0_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_tran_addr1_in = pciu_ta1_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_tran_addr2_in = pciu_ta2_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_tran_addr3_in = pciu_ta3_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_tran_addr4_in = pciu_ta4_in ; +wire [(pci_ba1_5_width - 1):0] pcit_if_pci_tran_addr5_in = pciu_ta5_in ; +wire pcit_if_addr_tran_en0_in = pciu_at_en_in[0] ; +wire pcit_if_addr_tran_en1_in = pciu_at_en_in[1] ; +wire pcit_if_addr_tran_en2_in = pciu_at_en_in[2] ; +wire pcit_if_addr_tran_en3_in = pciu_at_en_in[3] ; +wire pcit_if_addr_tran_en4_in = pciu_at_en_in[4] ; +wire pcit_if_addr_tran_en5_in = pciu_at_en_in[5] ; + +pci_target32_interface pci_target_if +( + .clk_in (pci_clock_in), + .reset_in (reset_in), + .address_in (pcit_if_address_in), + .addr_claim_out (pcit_if_addr_claim_out), + .bc_in (pcit_if_bc_in), + .bc0_in (pcit_if_bc0_in), + .data_in (pcit_if_data_in), + .data_out (pcit_if_data_out), + .be_in (pcit_if_be_in), + .next_be_in (pcit_if_next_be_in), + .req_in (pcit_if_req_in), + .rdy_in (pcit_if_rdy_in), + .addr_phase_in (pcit_if_addr_phase_in), + .bckp_devsel_in (pcit_if_bckp_devsel_in), + .bckp_trdy_in (pcit_if_bckp_trdy_in), + .bckp_stop_in (pcit_if_bckp_stop_in), + .last_reg_in (pcit_if_last_reg_in), + .frame_reg_in (pcit_if_frame_reg_in), + .fetch_pcir_fifo_in (pcit_if_fetch_pcir_fifo_in), + .load_medium_reg_in (pcit_if_load_medium_reg_in), + .sel_fifo_mreg_in (pcit_if_sel_fifo_mreg_in), + .sel_conf_fifo_in (pcit_if_sel_conf_fifo_in), + .load_to_pciw_fifo_in (pcit_if_load_to_pciw_fifo_in), + .load_to_conf_in (pcit_if_load_to_conf_in), + .same_read_out (pcit_if_same_read_out), + .norm_access_to_config_out (pcit_if_norm_access_to_config_out), + .read_completed_out (pcit_if_read_completed_out), + .read_processing_out (pcit_if_read_processing_out), + .target_abort_out (pcit_if_target_abort_out), + .disconect_wo_data_out (pcit_if_disconect_wo_data_out), + .disconect_w_data_out (pcit_if_disconect_w_data_out), + .pciw_fifo_full_out (pcit_if_pciw_fifo_full_out), + .pcir_fifo_data_err_out (pcit_if_pcir_fifo_data_err_out), + .wbw_fifo_empty_out (pcit_if_wbw_fifo_empty_out), + .wbu_del_read_comp_pending_out (pcit_if_wbu_del_read_comp_pending_out), + .req_out (pcit_if_req_out), + .done_out (pcit_if_done_out), + .in_progress_out (pcit_if_in_progress_out), + .req_req_pending_in (pcit_if_req_req_pending_in), + .req_comp_pending_in (pcit_if_req_comp_pending_in), + .addr_out (pcit_if_addr_out), + .be_out (pcit_if_be_out), + .we_out (pcit_if_we_out), + .bc_out (pcit_if_bc_out), + .burst_ok_out (pcit_if_burst_ok_out), + .strd_addr_in (pcit_if_strd_addr_in), + .strd_bc_in (pcit_if_strd_bc_in), + .status_in (pcit_if_status_in), + .comp_flush_in (pcit_if_comp_flush_in), + .pcir_fifo_renable_out (pcit_if_pcir_fifo_renable_out), + .pcir_fifo_data_in (pcit_if_pcir_fifo_data_in), + .pcir_fifo_be_in (pcit_if_pcir_fifo_be_in), + .pcir_fifo_control_in (pcit_if_pcir_fifo_control_in), + .pcir_fifo_flush_out (pcit_if_pcir_fifo_flush_out), + .pcir_fifo_almost_empty_in (pcit_if_pcir_fifo_almost_empty_in), + .pcir_fifo_empty_in (pcit_if_pcir_fifo_empty_in), + .pciw_fifo_wenable_out (pcit_if_pciw_fifo_wenable_out), + .pciw_fifo_addr_data_out (pcit_if_pciw_fifo_addr_data_out), + .pciw_fifo_cbe_out (pcit_if_pciw_fifo_cbe_out), + .pciw_fifo_control_out (pcit_if_pciw_fifo_control_out), + .pciw_fifo_three_left_in (pcit_if_pciw_fifo_three_left_in), + .pciw_fifo_two_left_in (pcit_if_pciw_fifo_two_left_in), + .pciw_fifo_almost_full_in (pcit_if_pciw_fifo_almost_full_in), + .pciw_fifo_full_in (pcit_if_pciw_fifo_full_in), + .wbw_fifo_empty_in (pcit_if_wbw_fifo_empty_in), + .wbu_del_read_comp_pending_in (pcit_if_wbu_del_read_comp_pending_in), + .conf_addr_out (pcit_if_conf_addr_out), + .conf_data_out (pcit_if_conf_data_out), + .conf_data_in (pcit_if_conf_data_in), + .conf_be_out (pcit_if_conf_be_out), + .conf_we_out (pcit_if_conf_we_out), + .conf_re_out (pcit_if_conf_re_out), + .mem_enable_in (pcit_if_mem_enable_in), + .io_enable_in (pcit_if_io_enable_in), + .mem_io_addr_space0_in (pcit_if_mem_io_addr_space0_in), + .mem_io_addr_space1_in (pcit_if_mem_io_addr_space1_in), + .mem_io_addr_space2_in (pcit_if_mem_io_addr_space2_in), + .mem_io_addr_space3_in (pcit_if_mem_io_addr_space3_in), + .mem_io_addr_space4_in (pcit_if_mem_io_addr_space4_in), + .mem_io_addr_space5_in (pcit_if_mem_io_addr_space5_in), + .pre_fetch_en0_in (pcit_if_pre_fetch_en0_in), + .pre_fetch_en1_in (pcit_if_pre_fetch_en1_in), + .pre_fetch_en2_in (pcit_if_pre_fetch_en2_in), + .pre_fetch_en3_in (pcit_if_pre_fetch_en3_in), + .pre_fetch_en4_in (pcit_if_pre_fetch_en4_in), + .pre_fetch_en5_in (pcit_if_pre_fetch_en5_in), + .pci_base_addr0_in (pcit_if_pci_base_addr0_in), + .pci_base_addr1_in (pcit_if_pci_base_addr1_in), + .pci_base_addr2_in (pcit_if_pci_base_addr2_in), + .pci_base_addr3_in (pcit_if_pci_base_addr3_in), + .pci_base_addr4_in (pcit_if_pci_base_addr4_in), + .pci_base_addr5_in (pcit_if_pci_base_addr5_in), + .pci_addr_mask0_in (pcit_if_pci_addr_mask0_in), + .pci_addr_mask1_in (pcit_if_pci_addr_mask1_in), + .pci_addr_mask2_in (pcit_if_pci_addr_mask2_in), + .pci_addr_mask3_in (pcit_if_pci_addr_mask3_in), + .pci_addr_mask4_in (pcit_if_pci_addr_mask4_in), + .pci_addr_mask5_in (pcit_if_pci_addr_mask5_in), + .pci_tran_addr0_in (pcit_if_pci_tran_addr0_in), + .pci_tran_addr1_in (pcit_if_pci_tran_addr1_in), + .pci_tran_addr2_in (pcit_if_pci_tran_addr2_in), + .pci_tran_addr3_in (pcit_if_pci_tran_addr3_in), + .pci_tran_addr4_in (pcit_if_pci_tran_addr4_in), + .pci_tran_addr5_in (pcit_if_pci_tran_addr5_in), + .addr_tran_en0_in (pcit_if_addr_tran_en0_in), + .addr_tran_en1_in (pcit_if_addr_tran_en1_in), + .addr_tran_en2_in (pcit_if_addr_tran_en2_in), + .addr_tran_en3_in (pcit_if_addr_tran_en3_in), + .addr_tran_en4_in (pcit_if_addr_tran_en4_in), + .addr_tran_en5_in (pcit_if_addr_tran_en5_in) +) ; + +// pci target state machine inputs +wire pcit_sm_frame_in = pciu_pciif_frame_in ; +wire pcit_sm_irdy_in = pciu_pciif_irdy_in ; +wire pcit_sm_idsel_in = pciu_pciif_idsel_in ; +wire pcit_sm_frame_reg_in = pciu_pciif_frame_reg_in ; +wire pcit_sm_irdy_reg_in = pciu_pciif_irdy_reg_in ; +wire pcit_sm_idsel_reg_in = pciu_pciif_idsel_reg_in ; +wire [31:0] pcit_sm_ad_reg_in = pciu_pciif_ad_reg_in ; +wire [3:0] pcit_sm_cbe_reg_in = pciu_pciif_cbe_reg_in ; +wire [3:0] pcit_sm_cbe_in = pciu_pciif_cbe_in ; +wire pcit_sm_bckp_trdy_en_in = pciu_pciif_bckp_trdy_en_in ; +wire pcit_sm_bckp_devsel_in = pciu_pciif_bckp_devsel_in ; +wire pcit_sm_bckp_trdy_in = pciu_pciif_bckp_trdy_in ; +wire pcit_sm_bckp_stop_in = pciu_pciif_bckp_stop_in ; +wire pcit_sm_addr_claim_in = pcit_if_addr_claim_out ; +wire [31:0] pcit_sm_data_in = pcit_if_data_out ; +wire pcit_sm_same_read_in = pcit_if_same_read_out ; +wire pcit_sm_norm_access_to_config_in = pcit_if_norm_access_to_config_out ; +wire pcit_sm_read_completed_in = pcit_if_read_completed_out ; +wire pcit_sm_read_processing_in = pcit_if_read_processing_out ; +wire pcit_sm_target_abort_in = pcit_if_target_abort_out ; +wire pcit_sm_disconect_wo_data_in = pcit_if_disconect_wo_data_out ; +wire pcit_sm_disconect_w_data_in = pcit_if_disconect_w_data_out ; +wire pcit_sm_pciw_fifo_full_in = pcit_if_pciw_fifo_full_out ; +wire pcit_sm_pcir_fifo_data_err_in = pcit_if_pcir_fifo_data_err_out ; +wire pcit_sm_wbw_fifo_empty_in = pcit_if_wbw_fifo_empty_out ; +wire pcit_sm_wbu_del_read_comp_pending_in = pcit_if_wbu_del_read_comp_pending_out ; +wire pcit_sm_wbu_frame_en_in = pciu_wbu_frame_en_in ; +wire pcit_sm_trdy_reg_in = pciu_pciif_trdy_reg_in ; +wire pcit_sm_stop_reg_in = pciu_pciif_stop_reg_in ; + + +pci_target32_sm pci_target_sm +( + .clk_in (pci_clock_in), + .reset_in (reset_in), + .pci_frame_in (pcit_sm_frame_in), + .pci_irdy_in (pcit_sm_irdy_in), + .pci_idsel_in (pcit_sm_idsel_in), + .pci_frame_reg_in (pcit_sm_frame_reg_in), + .pci_irdy_reg_in (pcit_sm_irdy_reg_in), + .pci_idsel_reg_in (pcit_sm_idsel_reg_in), + .pci_trdy_out (pcit_sm_trdy_out), + .pci_stop_out (pcit_sm_stop_out), + .pci_devsel_out (pcit_sm_devsel_out), + .pci_trdy_en_out (pcit_sm_trdy_en_out), + .pci_stop_en_out (pcit_sm_stop_en_out), + .pci_devsel_en_out (pcit_sm_devsel_en_out), + .ad_load_out (pcit_sm_ad_load_out), + .ad_load_on_transfer_out (pcit_sm_ad_load_on_transfer_out), + .pci_ad_reg_in (pcit_sm_ad_reg_in), + .pci_ad_out (pcit_sm_ad_out), + .pci_ad_en_out (pcit_sm_ad_en_out), + .pci_cbe_reg_in (pcit_sm_cbe_reg_in), + .pci_cbe_in (pcit_sm_cbe_in), + .bckp_trdy_en_in (pcit_sm_bckp_trdy_en_in), + .bckp_devsel_in (pcit_sm_bckp_devsel_in), + .bckp_trdy_in (pcit_sm_bckp_trdy_in), + .bckp_stop_in (pcit_sm_bckp_stop_in), + .pci_trdy_reg_in (pcit_sm_trdy_reg_in), + .pci_stop_reg_in (pcit_sm_stop_reg_in), + .address_out (pcit_sm_address_out), + .addr_claim_in (pcit_sm_addr_claim_in), + .bc_out (pcit_sm_bc_out), + .bc0_out (pcit_sm_bc0_out), + .data_out (pcit_sm_data_out), + .data_in (pcit_sm_data_in), + .be_out (pcit_sm_be_out), + .next_be_out (pcit_sm_next_be_out), + .req_out (pcit_sm_req_out), + .rdy_out (pcit_sm_rdy_out), + .addr_phase_out (pcit_sm_addr_phase_out), + .bckp_devsel_out (pcit_sm_bckp_devsel_out), + .bckp_trdy_out (pcit_sm_bckp_trdy_out), + .bckp_stop_out (pcit_sm_bckp_stop_out), + .last_reg_out (pcit_sm_last_reg_out), + .frame_reg_out (pcit_sm_frame_reg_out), + .fetch_pcir_fifo_out (pcit_sm_fetch_pcir_fifo_out), + .load_medium_reg_out (pcit_sm_load_medium_reg_out), + .sel_fifo_mreg_out (pcit_sm_sel_fifo_mreg_out), + .sel_conf_fifo_out (pcit_sm_sel_conf_fifo_out), + .load_to_pciw_fifo_out (pcit_sm_load_to_pciw_fifo_out), + .load_to_conf_out (pcit_sm_load_to_conf_out), + .same_read_in (pcit_sm_same_read_in), + .norm_access_to_config_in (pcit_sm_norm_access_to_config_in), + .read_completed_in (pcit_sm_read_completed_in), + .read_processing_in (pcit_sm_read_processing_in), + .target_abort_in (pcit_sm_target_abort_in), + .disconect_wo_data_in (pcit_sm_disconect_wo_data_in), + .disconect_w_data_in (pcit_sm_disconect_w_data_in), + .target_abort_set_out (pcit_sm_target_abort_set_out), + .pciw_fifo_full_in (pcit_sm_pciw_fifo_full_in), + .pcir_fifo_data_err_in (pcit_sm_pcir_fifo_data_err_in), + .wbw_fifo_empty_in (pcit_sm_wbw_fifo_empty_in), + .wbu_del_read_comp_pending_in (pcit_sm_wbu_del_read_comp_pending_in), + .wbu_frame_en_in (pcit_sm_wbu_frame_en_in) +) ; + +endmodule diff --git a/ethernet/source/pci/pci_user_constants.v b/ethernet/source/pci/pci_user_constants.v new file mode 100644 index 0000000..22ef572 --- /dev/null +++ b/ethernet/source/pci/pci_user_constants.v @@ -0,0 +1,333 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_user_constants.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// - Tadej Markovic (tadej@opencores.org) //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_user_constants.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.15 2004/08/19 15:27:34 mihad +// Changed minimum pci image size to 256 bytes because +// of some PC system problems with size of IO images. +// +// Revision 1.14 2004/07/07 12:45:01 mihad +// Added SubsystemVendorID, SubsystemID, MAXLatency, MinGnt defines. +// Enabled value loading from serial EEPROM for all of the above + VendorID and DeviceID registers. +// +// Revision 1.13 2004/01/24 11:54:18 mihad +// Update! SPOCI Implemented! +// +// Revision 1.12 2003/12/28 09:54:48 fr2201 +// def_wb_imagex_addr_map defined correctly +// +// Revision 1.11 2003/12/28 09:20:00 fr2201 +// Reset values for PCI, WB defined (PCI_TAx,WB_BAx,WB_TAx,WB_AMx,WB_BAx_MEM_IO) +// +// Revision 1.10 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.9 2003/08/03 18:05:06 mihad +// Added limited WISHBONE B3 support for WISHBONE Slave Unit. +// Doesn't support full speed bursts yet. +// +// Revision 1.8 2003/03/14 15:31:57 mihad +// Entered the option to disable no response counter in wb master. +// +// Revision 1.7 2003/01/27 17:05:50 mihad +// Updated. +// +// Revision 1.6 2003/01/27 16:51:19 mihad +// Old files with wrong names removed. +// +// Revision 1.5 2003/01/21 16:06:56 mihad +// Bug fixes, testcases added. +// +// Revision 1.4 2002/09/30 17:22:45 mihad +// Added support for Virtual Silicon two port RAM. Didn't run regression on it yet! +// +// Revision 1.3 2002/08/13 11:03:53 mihad +// Added a few testcases. Repaired wrong reset value for PCI_AM5 register. Repaired Parity Error Detected bit setting. Changed PCI_AM0 to always enabled(regardles of PCI_AM0 define), if image 0 is used as configuration image +// +// Revision 1.2 2002/03/05 11:53:47 mihad +// Added some testcases, removed un-needed fifo signals +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// +// + +// Fifo implementation defines: +// If FPGA and XILINX are defined, Xilinx's BlockSelectRAM+ is instantiated for Fifo storage. +// 16 bit width is used, so 8 bits of address ( 256 ) locations are available. If RAM_DONT_SHARE is not defined (commented out), +// then one block RAM is shared between two FIFOs. That means each Fifo can have a maximum address length of 7 - depth of 128 and only 6 block rams are used +// If RAM_DONT_SHARE is defined ( not commented out ), then 12 block RAMs are used and each Fifo can have a maximum address length of 8 ( 256 locations ) +// If FPGA is not defined, then ASIC RAMs are used. Currently there is only one version of ARTISAN RAM supported. User should generate synchronous RAM with +// width of 40 and instantiate it in pci_tpram.v. If RAM_DONT_SHARE is defined, then these can be dual port rams ( write port +// in one clock domain, read in other ), otherwise it must be two port RAM ( read and write ports in both clock domains ). +// If RAM_DONT_SHARE is defined, then all RAM address lengths must be specified accordingly, otherwise there are two relevant lengths - PCI_FIFO_RAM_ADDR_LENGTH and +// WB_FIFO_RAM_ADDR_LENGTH. + +`define WBW_ADDR_LENGTH 4 +`define WBR_ADDR_LENGTH 4 +`define PCIW_ADDR_LENGTH 3 +`define PCIR_ADDR_LENGTH 3 + +//`define FPGA +//`define XILINX + +`define WB_RAM_DONT_SHARE +`define PCI_RAM_DONT_SHARE + +`ifdef FPGA + `ifdef XILINX + `define PCI_FIFO_RAM_ADDR_LENGTH 8 // PCI target unit fifo storage definition + `define WB_FIFO_RAM_ADDR_LENGTH 8 // WB slave unit fifo storage definition + `define PCI_XILINX_RAMB4 + `define WB_XILINX_RAMB4 + //`define PCI_XILINX_DIST_RAM + //`define WB_XILINX_DIST_RAM + `endif +`else + `define PCI_FIFO_RAM_ADDR_LENGTH 3 // PCI target unit fifo storage definition when RAM sharing is used ( both pcir and pciw fifo use same instance of RAM ) + `define WB_FIFO_RAM_ADDR_LENGTH 4 // WB slave unit fifo storage definition when RAM sharing is used ( both wbr and wbw fifo use same instance of RAM ) +// `define WB_ARTISAN_SDP +// `define PCI_ARTISAN_SDP +// `define PCI_VS_STP +// `define WB_VS_STP +`endif + +// these two defines allow user to select active high or low output enables on PCI bus signals, depending on +// output buffers instantiated. Xilinx FPGAs use active low output enables. +`define ACTIVE_LOW_OE +//`define ACTIVE_HIGH_OE + +// HOST/GUEST implementation selection - see design document and specification for description of each implementation +// only one can be defined at same time +//`define HOST +`define GUEST + +// if NO_CNF_IMAGE is commented out, then READ-ONLY access to configuration space is ENABLED: +// - ENABLED Read-Only access from WISHBONE for GUEST bridges +// - ENABLED Read-Only access from PCI for HOST bridges +// with defining NO_CNF_IMAGE, one decoder and one multiplexer are saved +`define NO_CNF_IMAGE + +// number defined here specifies how many MS bits in PCI address are compared with base address, to decode +// accesses. Maximum number allows for minimum image size ( number = 20, image size = 4KB ), minimum number +// allows for maximum image size ( number = 1, image size = 2GB ). If you intend on using different sizes of PCI images, +// you have to define a number of minimum sized image and enlarge others by specifying different address mask. +// smaller the number here, faster the decoder operation +`define PCI_NUM_OF_DEC_ADDR_LINES 24 + +// no. of PCI Target IMAGES +// - PCI provides 6 base address registers for image implementation. +// PCI_IMAGE1 definition is not required and has no effect, since PCI image 1 is always implemented +// If GUEST is defined, PCI Image 0 is also always implemented and is used for configuration space +// access. +// If HOST is defined and NO_CNF_IMAGE is not, then PCI Image 0 is used for Read Only access to configuration +// space. If HOST is defined and NO_CNF_IMAGE is defined, then user can define PCI_IMAGE0 as normal image, and there +// is no access to Configuration space possible from PCI bus. +// Implementation of all other PCI images is selected by defining PCI_IMAGE2 through PCI_IMAGE5 regardles of HOST +// or GUEST implementation. +`ifdef HOST + `ifdef NO_CNF_IMAGE + //`define PCI_IMAGE0 + `endif +`endif + +//`define PCI_IMAGE2 +//`define PCI_IMAGE3 +//`define PCI_IMAGE4 +//`define PCI_IMAGE5 + +// initial value for PCI image address masks. Address masks can be defined in enabled state, +// to allow device independent software to detect size of image and map base addresses to +// memory space. If initial mask for an image is defined as 0, then device independent software +// won't detect base address implemented and device dependent software will have to configure +// address masks as well as base addresses! +// Don't define PCI_AMx to 24'hffff_ff for memory images! Use that just for I/O images. +`define PCI_AM0 24'hffff_f0 +`define PCI_AM1 24'hffff_ff +`define PCI_AM2 24'hffff_f0 +`define PCI_AM3 24'hffff_f0 +`define PCI_AM4 24'hffff_f0 +`define PCI_AM5 24'hffff_f0 + +// initial value for PCI image maping to MEMORY or IO spaces. If initial define is set to 0, +// then IMAGE with that base address points to MEMORY space, othervise it points ti IO space. D +// Device independent software sets the base addresses acording to MEMORY or IO maping! +`define PCI_BA0_MEM_IO 1'b0 // considered only when PCI_IMAGE0 is used as general PCI-WB image! +`define PCI_BA1_MEM_IO 1'b1 +`define PCI_BA2_MEM_IO 1'b0 +`define PCI_BA3_MEM_IO 1'b0 +`define PCI_BA4_MEM_IO 1'b0 +`define PCI_BA5_MEM_IO 1'b0 + +// initial value for PCI translation addresses. The initial values +// are set after reset. When ADDR_TRAN_IMPL is defined then then Images +// are transleted to this adresses whithout access to pci_ta registers. +`define PCI_TA0 24'h0000_0 +`define PCI_TA1 24'h0000_0 +`define PCI_TA2 24'h0000_0 +`define PCI_TA3 24'h0000_0 +`define PCI_TA4 24'h0000_0 +`define PCI_TA5 24'h0000_0 + +`define PCI_AT_EN0 1'b0 +`define PCI_AT_EN1 1'b0 +`define PCI_AT_EN2 1'b0 +`define PCI_AT_EN3 1'b0 +`define PCI_AT_EN4 1'b0 +`define PCI_AT_EN5 1'b0 + +// number defined here specifies how many MS bits in WB address are compared with base address, to decode +// accesses. Maximum number allows for minimum image size ( number = 20, image size = 4KB ), minimum number +// allows for maximum image size ( number = 1, image size = 2GB ). If you intend on using different sizes of WB images, +// you have to define a number of minimum sized image and enlarge others by specifying different address mask. +// smaller the number here, faster the decoder operation +`define WB_NUM_OF_DEC_ADDR_LINES 1 + +// no. of WISHBONE Slave IMAGES +// WB image 0 is always used for access to configuration space. In case configuration space access is not implemented, +// ( both GUEST and NO_CNF_IMAGE defined ), then WB image 0 is not implemented. User doesn't need to define image 0. +// WB Image 1 is always implemented and user doesnt need to specify its definition +// WB images' 2 through 5 implementation by defining each one. +`define WB_IMAGE2 +//`define WB_IMAGE3 +//`define WB_IMAGE4 +//`define WB_IMAGE5 + +//Address bar register defines the base address for each image. +//To asccess bus without Software configuration. +`define WB_BA1 20'h0000_0 +`define WB_BA2 20'h8000_0 +`define WB_BA3 20'h0000_0 +`define WB_BA4 20'h0000_0 +`define WB_BA5 20'h0000_0 + +// initial value for WB image maping to MEMORY or IO spaces. If initial define is set to 0, +// then IMAGE with that base address points to MEMORY space, othervise it points ti IO space. +`define WB_BA1_MEM_IO 1'b0 +`define WB_BA2_MEM_IO 1'b0 +`define WB_BA3_MEM_IO 1'b0 +`define WB_BA4_MEM_IO 1'b0 +`define WB_BA5_MEM_IO 1'b0 + +// initial value for WB image address masks. +`define WB_AM1 20'h8000_0 +`define WB_AM2 20'h8000_0 +`define WB_AM3 20'h0000_0 +`define WB_AM4 20'h0000_0 +`define WB_AM5 20'h0000_0 + +// initial value for WB translation addresses. The initial values +// are set after reset. When ADDR_TRAN_IMPL is defined then then Images +// are transleted to this adresses whithout access to pci_ta registers. +`define WB_TA1 20'h0000_0 +`define WB_TA2 20'h0000_0 +`define WB_TA3 20'h0000_0 +`define WB_TA4 20'h0000_0 +`define WB_TA5 20'h0000_0 + +`define WB_AT_EN1 1'b0 +`define WB_AT_EN2 1'b0 +`define WB_AT_EN3 1'b0 +`define WB_AT_EN4 1'b0 +`define WB_AT_EN5 1'b0 + +// If this define is commented out, then address translation will not be implemented. +// addresses will pass through bridge unchanged, regardles of address translation enable bits. +// Address translation also slows down the decoding +//When ADDR_TRAN_IMPL this define is present then adress translation is enabled after reset. +//`define ADDR_TRAN_IMPL + +// decode speed for WISHBONE definition - initial cycle on WISHBONE bus will take 1 WS for FAST, 2 WSs for MEDIUM and 3 WSs for slow. +// slower decode speed can be used, to provide enough time for address to be decoded. +`define WB_DECODE_FAST +//`define WB_DECODE_MEDIUM +//`define WB_DECODE_SLOW + +// Base address for Configuration space access from WB bus. This value cannot be changed during runtime +`define WB_CONFIGURATION_BASE 20'h0000_0 + +// Turn registered WISHBONE slave outputs on or off +// all outputs from WB Slave state machine are registered, if this is defined - WB bus outputs as well as +// outputs to internals of the core. +//`define REGISTER_WBS_OUTPUTS + +/*----------------------------------------------------------------------------------------------------------- +Core speed definition - used for simulation and 66MHz Capable bit value in status register indicating 66MHz +capable device +-----------------------------------------------------------------------------------------------------------*/ +`define PCI33 +//`define PCI66 + +/*----------------------------------------------------------------------------------------------------------- +[000h-00Ch] First 4 DWORDs (32-bit) of PCI configuration header - the same regardless of the HEADER type ! + Vendor_ID is an ID for a specific vendor defined by PCI_SIG - 2321h does not belong to anyone (e.g. + Xilinx's Vendor_ID is 10EEh and Altera's Vendor_ID is 1172h). Device_ID and Revision_ID should be used + together by application. +-----------------------------------------------------------------------------------------------------------*/ +`define HEADER_VENDOR_ID 16'h1895 +`define HEADER_DEVICE_ID 16'h0001 +`define HEADER_REVISION_ID 8'h01 +`define HEADER_SUBSYS_VENDOR_ID 16'h1895 +`define HEADER_SUBSYS_ID 16'h0001 +`define HEADER_MAX_LAT 8'h1a +`define HEADER_MIN_GNT 8'h08 + +// MAX Retry counter value for WISHBONE Master state-machine +// This value is 8-bit because of 8-bit retry counter !!! +`define WB_RTY_CNT_MAX 8'hff + +// define the macro below to disable internal retry generation in the wishbone master interface +// used when wb master accesses extremly slow devices. +`define PCI_WBM_NO_RESPONSE_CNT_DISABLE + +`define PCI_WB_REV_B3 +//`define PCI_WBS_B3_RTY_DISABLE + +`ifdef GUEST +// `define PCI_CPCI_HS_IMPLEMENT +// `define PCI_SPOCI +`endif + diff --git a/ethernet/source/pci/pci_wb_addr_mux.v b/ethernet/source/pci/pci_wb_addr_mux.v new file mode 100644 index 0000000..fcf22d9 --- /dev/null +++ b/ethernet/source/pci/pci_wb_addr_mux.v @@ -0,0 +1,282 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "wb_addr_mux.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_wb_addr_mux.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.4 2002/08/19 16:54:25 mihad +// Got rid of undef directives +// +// Revision 1.3 2002/02/01 15:25:13 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +// module provides instantiation of address decoders and address multiplexer for various number of implemented wishbone images +`include "pci_constants.v" +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_wb_addr_mux +( + `ifdef REGISTER_WBS_OUTPUTS + clk_in, + reset_in, + sample_address_in, + `endif + address_in, + bar0_in, + bar1_in, + bar2_in, + bar3_in, + bar4_in, + bar5_in, + am0_in, + am1_in, + am2_in, + am3_in, + am4_in, + am5_in, + ta0_in, + ta1_in, + ta2_in, + ta3_in, + ta4_in, + ta5_in, + at_en_in, + hit_out, + address_out +); + +input [31:0] address_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar0_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar1_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar2_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar3_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar4_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] bar5_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am0_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am1_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am2_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am3_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am4_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] am5_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta0_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta1_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta2_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta3_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta4_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] ta5_in ; +input [5:0] at_en_in ; +output [5:0] hit_out ; +output [31:0] address_out ; +reg [31:0] address_out ; + +wire [31:0] addr0 ; +wire [31:0] addr1 ; +wire [31:0] addr2 ; +wire [31:0] addr3 ; +wire [31:0] addr4 ; +wire [31:0] addr5 ; + +wire [5:0] hit ; +assign hit_out = hit ; + +`ifdef REGISTER_WBS_OUTPUTS + input clk_in, reset_in, sample_address_in ; + + reg [31:0] address ; + always@(posedge clk_in or posedge reset_in) + begin + if ( reset_in ) + address <= #`FF_DELAY 0 ; + else + if ( sample_address_in ) + address <= #`FF_DELAY address_in ; + end +`else + wire [31:0] address = address_in ; +`endif + +`ifdef GUEST + `ifdef NO_CNF_IMAGE + `else + `define PCI_WB_ADDR_MUX_DEC0_INCLUDE + `endif +`else +`ifdef HOST + `define PCI_WB_ADDR_MUX_DEC0_INCLUDE +`endif +`endif + +`ifdef PCI_WB_ADDR_MUX_DEC0_INCLUDE + pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec0 + ( + .hit (hit[0]), + .addr_out (addr0), + .addr_in (address), + .base_addr (bar0_in), + .mask_addr (am0_in), + .tran_addr (ta0_in), + .at_en (1'b0) + ) ; +`else + // configuration image not implemented + assign hit[0] = 1'b0 ; + assign addr0 = 32'h0000_0000 ; +`endif + +// one image is always implemented +pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec1 +( + .hit (hit[1]), + .addr_out (addr1), + .addr_in (address), + .base_addr (bar1_in), + .mask_addr (am1_in), + .tran_addr (ta1_in), + .at_en (at_en_in[1]) +) ; + +`ifdef WB_IMAGE2 + pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec2 + ( + .hit (hit[2]), + .addr_out (addr2), + .addr_in (address), + .base_addr (bar2_in), + .mask_addr (am2_in), + .tran_addr (ta2_in), + .at_en (at_en_in[2]) + ) ; + +`else + assign hit[2] = 1'b0 ; + assign addr2 = 0 ; +`endif + +`ifdef WB_IMAGE3 + pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec3 + ( + .hit (hit[3]), + .addr_out (addr3), + .addr_in (address), + .base_addr (bar3_in), + .mask_addr (am3_in), + .tran_addr (ta3_in), + .at_en (at_en_in[3]) + ) ; +`else + assign hit[3] = 1'b0 ; + assign addr3 = 0 ; +`endif + +`ifdef WB_IMAGE4 + pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec4 + ( + .hit (hit[4]), + .addr_out (addr4), + .addr_in (address), + .base_addr (bar4_in), + .mask_addr (am4_in), + .tran_addr (ta4_in), + .at_en (at_en_in[4]) + ) ; +`else + assign hit[4] = 1'b0 ; + assign addr4 = 0 ; +`endif + +`ifdef WB_IMAGE5 + pci_wb_decoder #(`WB_NUM_OF_DEC_ADDR_LINES) dec5 + ( + .hit (hit[5]), + .addr_out (addr5), + .addr_in (address), + .base_addr (bar5_in), + .mask_addr (am5_in), + .tran_addr (ta5_in), + .at_en (at_en_in[5]) + ) ; +`else + assign hit[5] = 1'b0 ; + assign addr5 = 0 ; +`endif + +// address multiplexer +always@ +( + hit or + addr0 or + addr1 or + addr2 or + addr3 or + addr4 or + addr5 +) +begin + case ( {hit[5:2], hit[0]} ) + 5'b0_0_0_0_1: address_out = addr0 ; + 5'b0_0_0_1_0: address_out = addr2 ; + 5'b0_0_1_0_0: address_out = addr3 ; + 5'b0_1_0_0_0: address_out = addr4 ; + 5'b1_0_0_0_0: address_out = addr5 ; + + // default address is address from decoder 1 - it is always implemented - in case of stripped down core to only one image + // this multiplexer can be completely removed during synthesys + default: address_out = addr1 ; + endcase +end + +endmodule diff --git a/ethernet/source/pci/pci_wb_decoder.v b/ethernet/source/pci/pci_wb_decoder.v new file mode 100644 index 0000000..76b7670 --- /dev/null +++ b/ethernet/source/pci/pci_wb_decoder.v @@ -0,0 +1,173 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: decoder.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// - Tilen Novak, tilen@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// Tilen Novak, tilen@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_wb_decoder.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:28 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_wb_decoder (hit, addr_out, addr_in, base_addr, mask_addr, tran_addr, at_en) ; + +// Decoding address size parameter - for FPGAs 1MegByte is recommended +// MAXIMUM is 20 (4KBytes), length 12 is 1 MByte !!! +parameter decode_len = 12 ; + +//########################################################################################################### +// ALL COMMENTS are written as there were decode_len 20. This number and 12 (32 - 20) are assigning the +// numbers of decoded and compared bits, etc. +//########################################################################################################### + +/*----------------------------------------------------------------------------------------------------------- +DECODER interface decodes input address (ADDR_IN); what means that it validates (HIT), if input address +falls within the defined image space boundaries. Image space boundarie is defined with image base address +register (BASE_ADDR) and address mask register (MASK_ADDR). +Beside that, it also translates (maps) the input address to the output address (ADDR_OUT), regarding the +translation address register (TRAN_ADDR) and the address mask register. +-----------------------------------------------------------------------------------------------------------*/ + +// output control +output hit ; +// output address +output [31:0] addr_out ; +// input address +input [31:0] addr_in ; + +// input registers - 12 LSbits are not valid since the smallest possible size is 4KB ! +input [31:(32-decode_len)] base_addr ; +input [31:(32-decode_len)] mask_addr ; +input [31:(32-decode_len)] tran_addr ; + +// input bit[2] of the Image Control register used to enable the address translation ! +input at_en ; +/*----------------------------------------------------------------------------------------------------------- +Internal signals ! +-----------------------------------------------------------------------------------------------------------*/ + +// bit[31] if address mask register is IMAGE ENABLE bit (img_en) +wire img_en ; + +// addr_in_compare are masked input address bits that are compared with masked base_addr +wire [31:(32-decode_len)] addr_in_compare ; +// base_addr_compare are masked base address bits that are compared with masked addr_in +wire [31:(32-decode_len)] base_addr_compare ; + +/*----------------------------------------------------------------------------------------------------------- +Decoding the input address! +This logic produces the loghest path in this module! + +20 MSbits of input addres are as well as base address (20 bits) masked with corrected address mask. Only +masked bits of each vector are actually logically compared. +Bit[31] of address mask register is used to enable the image space ! +-----------------------------------------------------------------------------------------------------------*/ + +assign addr_in_compare = (addr_in[31:(32-decode_len)] & mask_addr) ; + +assign base_addr_compare = (base_addr & mask_addr) ; + +assign img_en = mask_addr[31] ; + +assign hit = { 1'b1, addr_in_compare } == { img_en, base_addr_compare } ; + +/*----------------------------------------------------------------------------------------------------------- +Translating the input address! + +Translation of input address is not implemented if ADDR_TRAN_IMPL is not defined + +20 MSbits of input address are masked with negated value of the corrected address mask in order to get +address bits of the input address which won't be replaced with translation address bits. +Translation address bits (20 bits) are masked with corrected address mask. Only masked bits of vector are +actually valid, all others are zero. +Boath vectors are bit-wise ORed in order to get the valid translation address with an offset of an input +address. +12 LSbits of an input address are assigned to 12 LSbits of an output addres. +-----------------------------------------------------------------------------------------------------------*/ + +`ifdef ADDR_TRAN_IMPL + // if Address Translation Enable bit is set, then translation address is used othervise input address is used! + // addr_in_combine input address bits are not replaced with translation address! + wire [31:(32-decode_len)] addr_in_combine ; + // tran_addr_combine are masked and combined with addr_in_combine! + reg [31:(32-decode_len)] tran_addr_combine ; + + assign addr_in_combine = (addr_in[31:(32-decode_len)] & ~mask_addr) ; + always@(at_en or tran_addr or mask_addr or addr_in) + begin + if (at_en) + begin + tran_addr_combine <= (tran_addr & mask_addr) ; + end + else + begin + tran_addr_combine <= (addr_in[31:(32-decode_len)] & mask_addr) ; + end + end + + assign addr_out[31:(32-decode_len)] = addr_in_combine | tran_addr_combine ; + assign addr_out[(31-decode_len):0] = addr_in [(31-decode_len):0] ; +`else + assign addr_out = addr_in ; +`endif + +endmodule + diff --git a/ethernet/source/pci/pci_wb_master.v b/ethernet/source/pci/pci_wb_master.v new file mode 100644 index 0000000..aa7cd5e --- /dev/null +++ b/ethernet/source/pci/pci_wb_master.v @@ -0,0 +1,1176 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name: wb_master.v //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Tadej Markovic, tadej@opencores.org //// +//// //// +//// All additional information is avaliable in the README.txt //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Tadej Markovic, tadej@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_wb_master.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2004/01/24 11:54:18 mihad +// Update! SPOCI Implemented! +// +// Revision 1.5 2003/10/24 09:35:40 tadejm +// Added missing signals to 2 sensitivity lists. Everything works the same as before. +// +// Revision 1.4 2003/08/21 20:56:40 tadejm +// WB Master is now WISHBONE B3 compatible. +// +// Revision 1.3 2003/03/14 15:31:57 mihad +// Entered the option to disable no response counter in wb master. +// +// Revision 1.2 2003/01/30 22:01:09 mihad +// Updated synchronization in top level fifo modules. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.7 2002/12/05 12:19:23 mihad +// *** empty log message *** +// +// Revision 1.6 2002/10/11 14:15:29 mihad +// Cleaned up non-blocking assignments in combinatinal logic statements +// +// Revision 1.5 2002/03/05 11:53:47 mihad +// Added some testcases, removed un-needed fifo signals +// +// Revision 1.4 2002/02/19 16:32:37 mihad +// Modified testbench and fixed some bugs +// +// Revision 1.3 2002/02/01 15:25:13 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +`define WB_FSM_BITS 3 // number of bits needed for FSM states + + +`include "bus_commands.v" +`include "pci_constants.v" +//synopsys translate_off +`include "timescale.v" +//synopsys translate_on + +module pci_wb_master + ( wb_clock_in, // CLK_I + reset_in, // RST_I + + pci_tar_read_request, + pci_tar_address, + pci_tar_cmd, + pci_tar_be, + pci_tar_burst_ok, + pci_cache_line_size, + cache_lsize_not_zero, + wb_read_done_out, + w_attempt, + + pcir_fifo_wenable_out, + pcir_fifo_data_out, + pcir_fifo_be_out, + pcir_fifo_control_out, + //pcir_fifo_renable_out, for PCI Target !!! + //pcir_fifo_data_in, for PCI Target !!! + //pcir_fifo_be_in, for PCI Target !!! + //pcir_fifo_control_in, for PCI Target !!! + //pcir_fifo_flush_out, for PCI Target !!! + //pcir_fifo_almost_empty_in, for PCI Target !!! + //pcir_fifo_empty_in, NOT used + //pcir_fifo_transaction_ready_in, NOT used + //pciw_fifo_wenable_out, for PCI Target !!! + //pciw_fifo_addr_data_out, for PCI Target !!! + //pciw_fifo_cbe_out, for PCI Target !!! + //pciw_fifo_control_out, for PCI Target !!! + pciw_fifo_renable_out, + pciw_fifo_addr_data_in, + pciw_fifo_cbe_in, + pciw_fifo_control_in, + //pciw_fifo_flush_out, NOT used + //pciw_fifo_almost_full_in, for PCI Target !!! + //pciw_fifo_full_in, for PCI Target !!! + pciw_fifo_almost_empty_in, + pciw_fifo_empty_in, + pciw_fifo_transaction_ready_in, + + pci_error_sig_out, + pci_error_bc, + write_rty_cnt_exp_out, + error_source_out, + read_rty_cnt_exp_out, + + wb_cyc_o, + wb_stb_o, + wb_we_o, + wb_cti_o, + wb_bte_o, + wb_sel_o, + wb_adr_o, + wb_dat_i, + wb_dat_o, + wb_ack_i, + wb_rty_i, + wb_err_i +// CYC_O, +// STB_O, +// WE_O, +// SEL_O, +// ADR_O, +// MDATA_I, +// MDATA_O, +// ACK_I, +// RTY_I, +// ERR_I, + ); + +/*---------------------------------------------------------------------------------------------------------------------- +Various parameters needed for state machine and other stuff +----------------------------------------------------------------------------------------------------------------------*/ +parameter S_IDLE = `WB_FSM_BITS'h0 ; +parameter S_WRITE = `WB_FSM_BITS'h1 ; +parameter S_WRITE_ERR_RTY = `WB_FSM_BITS'h2 ; +parameter S_READ = `WB_FSM_BITS'h3 ; +parameter S_READ_RTY = `WB_FSM_BITS'h4 ; +parameter S_TURN_ARROUND = `WB_FSM_BITS'h5 ; + +/*---------------------------------------------------------------------------------------------------------------------- +System signals inputs +wb_clock_in - WISHBONE bus clock input +reset_in - system reset input controlled by bridge's reset logic +----------------------------------------------------------------------------------------------------------------------*/ +input wb_clock_in ; +input reset_in ; + +/*---------------------------------------------------------------------------------------------------------------------- +Control signals from PCI Target for READS to PCIR_FIFO +---------------------------------------------------------------------------------------------------------------------*/ +input pci_tar_read_request ; // read request from PCI Target +input [31:0] pci_tar_address ; // address for requested read from PCI Target +input [3:0] pci_tar_cmd ; // command for requested read from PCI Target +input [3:0] pci_tar_be ; // byte enables for requested read from PCI Target +input pci_tar_burst_ok ; +input [7:0] pci_cache_line_size ; // CACHE line size register value for burst length +input cache_lsize_not_zero ; +output wb_read_done_out ; // read done and PCIR_FIFO has data ready +output w_attempt ; + +reg wb_read_done_out ; +reg wb_read_done ; + +/*---------------------------------------------------------------------------------------------------------------------- +PCIR_FIFO control signals used for sinking data into PCIR_FIFO and status monitoring +---------------------------------------------------------------------------------------------------------------------*/ +output pcir_fifo_wenable_out ; // PCIR_FIFO write enable output +output [31:0] pcir_fifo_data_out ; // data output to PCIR_FIFO +output [3:0] pcir_fifo_be_out ; // byte enable output to PCIR_FIFO +output [3:0] pcir_fifo_control_out ; // control bus output to PCIR_FIFO + +reg [31:0] pcir_fifo_data_out ; +reg pcir_fifo_wenable_out ; +reg pcir_fifo_wenable ; +reg [3:0] pcir_fifo_control_out ; +reg [3:0] pcir_fifo_control ; + +/*---------------------------------------------------------------------------------------------------------------------- +PCIW_FIFO control signals used for fetching data from PCIW_FIFO and status monitoring +---------------------------------------------------------------------------------------------------------------------*/ +output pciw_fifo_renable_out ; // read enable for PCIW_FIFO output +input [31:0] pciw_fifo_addr_data_in ; // address and data input from PCIW_FIFO +input [3:0] pciw_fifo_cbe_in ; // command and byte_enables from PCIW_FIFO +input [3:0] pciw_fifo_control_in ; // control bus input from PCIW_FIFO +input pciw_fifo_almost_empty_in ; // almost empty status indicator from PCIW_FIFO +input pciw_fifo_empty_in ; // empty status indicator from PCIW_FIFO +input pciw_fifo_transaction_ready_in ; // write transaction is ready in PCIW_FIFO + +reg pciw_fifo_renable_out ; +reg pciw_fifo_renable ; + +/*---------------------------------------------------------------------------------------------------------------------- +Control INPUT / OUTPUT signals for configuration space reporting registers !!! +---------------------------------------------------------------------------------------------------------------------*/ +output pci_error_sig_out ; // When error occures (on WB bus, retry counter, etc.) +output [3:0] pci_error_bc ; // bus command at which error occured ! +output write_rty_cnt_exp_out ; // Signaling that RETRY counter has expired during write transaction! +output read_rty_cnt_exp_out ; // Signaling that RETRY counter has expired during read transaction! + // if error_source is '0' other side didn't respond + // if error_source is '1' other side RETRIED for max retry counter value +output error_source_out ; // Signaling error source - '0' other WB side signaled error OR didn't respond + // if '1' wridge counted max value in retry counter because of RTY responds +reg pci_error_sig_out ; +reg write_rty_cnt_exp_out ; +reg read_rty_cnt_exp_out ; +reg error_source_out ; + +/*---------------------------------------------------------------------------------------------------------------------- +WISHBONE bus interface signals - can be connected directly to WISHBONE bus +---------------------------------------------------------------------------------------------------------------------*/ +output wb_cyc_o; // cycle indicator output +output wb_stb_o; // strobe output - data is valid when strobe and cycle indicator are high +output wb_we_o; // write enable output - 1 - write operation, 0 - read operation +output [2:0] wb_cti_o; // WB B3 - cycle type identifier +output [1:0] wb_bte_o; // WB B3 - burst type +output [3:0] wb_sel_o; // Byte select outputs +output [31:0] wb_adr_o; // WISHBONE address output +input [31:0] wb_dat_i; // WISHBONE interface input data bus +output [31:0] wb_dat_o; // WISHBONE interface output data bus +input wb_ack_i; // Acknowledge input - qualifies valid data on data output bus or received data on data input bus +input wb_rty_i; // retry input - signals from WISHBONE slave that cycle should be terminated and retried later +input wb_err_i; // Signals from WISHBONE slave that access resulted in an error + +reg wb_cyc_o; +reg wb_stb_o; +reg wb_we_o; +reg [2:0] wb_cti_o; +reg [1:0] wb_bte_o; +reg [3:0] wb_sel_o; +reg [31:0] wb_dat_o; + + + +/*########################################################################################################### +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + LOGIC, COUNTERS, STATE MACHINE and some control register bits + ============================================================= +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +###########################################################################################################*/ + +reg last_data_transferred ; // signal is set by STATE MACHINE after each complete transfere ! + +// wire for write attempt - 1 when PCI Target attempt to write and PCIW_FIFO has a write transaction ready +reg w_attempt; +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) + w_attempt <= #`FF_DELAY 1'b0; + else + begin + if (pciw_fifo_transaction_ready_in && ~pciw_fifo_empty_in) + w_attempt <= #`FF_DELAY 1'b1; + else + if (last_data_transferred) + w_attempt <= #`FF_DELAY 1'b0; + end +end + +// wire for read attempt - 1 when PCI Target is attempting a read and PCIR_FIFO is not full ! +// because of transaction ordering, PCI Master must not start read untill all writes are done -> at that +// moment PCIW_FIFO is empty !!! (when read is pending PCI Target will block new reads and writes) +wire r_attempt = ( pci_tar_read_request && !w_attempt && pciw_fifo_empty_in ) ; + +// Signal is used for reads on WB, when there is retry! +reg first_wb_data_access ; + +reg last_data_from_pciw_fifo ; // signal tells when there is last data in pciw_fifo +reg last_data_from_pciw_fifo_reg ; +reg last_data_to_pcir_fifo ; // signal tells when there will be last data for pcir_fifo + +// Logic used in State Machine logic implemented out of State Machine because of less delay! +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) + last_data_from_pciw_fifo <= #`FF_DELAY 1'b0 ; + else + begin + if ((pciw_fifo_renable_out) && + (pciw_fifo_control_in[`LAST_CTRL_BIT] || pciw_fifo_almost_empty_in)) // if last data is going to be transfered + last_data_from_pciw_fifo <= #`FF_DELAY 1'b1 ; // signal for last data from PCIW_FIFO + else + last_data_from_pciw_fifo <= #`FF_DELAY 1'b0 ; + end +end + + reg read_count_load; + reg read_count_enable; + + reg [(`PCIR_ADDR_LENGTH - 1):0] max_read_count ; + always@(pci_cache_line_size or cache_lsize_not_zero or pci_tar_cmd) + begin + if (cache_lsize_not_zero) + if ( (pci_cache_line_size >= `PCIR_DEPTH) || (~pci_tar_cmd[1] && ~pci_tar_cmd[0]) ) + // If cache line size is larger than FIFO or BC_MEM_READ_MUL command is performed! + max_read_count = `PCIR_DEPTH - 1'b1; + else + max_read_count = pci_cache_line_size ; + else + max_read_count = 1'b1; + end + + reg [(`PCIR_ADDR_LENGTH - 1):0] read_count ; + + // cache line bound indicator - it signals when data for one complete cacheline was read + wire read_bound_comb = ~|( { read_count[(`PCIR_ADDR_LENGTH - 1):2], read_count[0] } ) ; + + reg read_bound ; + always@(posedge wb_clock_in or posedge reset_in) + begin + if ( reset_in ) + read_bound <= #`FF_DELAY 1'b0 ; + else if (read_count_load) + read_bound <= #`FF_DELAY 1'b0 ; + else if ( read_count_enable ) + read_bound <= #`FF_DELAY read_bound_comb ; + end + + // down counter with load + always@(posedge reset_in or posedge wb_clock_in) + begin + if (reset_in) + read_count <= #`FF_DELAY 0 ; + else + if (read_count_load) + read_count <= #`FF_DELAY max_read_count ; + else + if (read_count_enable) + read_count <= #`FF_DELAY read_count - 1'b1 ; + end + +// Logic used in State Machine logic implemented out of State Machine because of less delay! +// definition of signal telling, when there is last data written into FIFO +always@(pci_tar_cmd or pci_tar_burst_ok or read_bound) +begin + // burst is OK for reads when there is ((MEM_READ_LN or MEM_READ_MUL) and AD[1:0]==2'b00) OR + // (MEM_READ and Prefetchable_IMAGE and AD[1:0]==2'b00) -> pci_tar_burst_ok + case ({pci_tar_cmd, pci_tar_burst_ok}) + {`BC_MEM_READ, 1'b1}, + {`BC_MEM_READ_LN, 1'b1} : + begin // when burst cycle + if (read_bound) + last_data_to_pcir_fifo = 1'b1 ; + else + last_data_to_pcir_fifo = 1'b0 ; + end + {`BC_MEM_READ_MUL, 1'b1} : + begin // when burst cycle + if (read_bound) + last_data_to_pcir_fifo = 1'b1 ; + else + last_data_to_pcir_fifo = 1'b0 ; + end + default : + // {`BC_IO_READ, 1'b0}, + // {`BC_IO_READ, 1'b1}, + // {`BC_MEM_READ, 1'b0}, + // {`BC_MEM_READ_LN, 1'b0}, + // {`BC_MEM_READ_MUL, 1'b0}: + begin // when single cycle + last_data_to_pcir_fifo = 1'b1 ; + end + endcase +end + +reg wait_for_wb_response ; + +`ifdef PCI_WBM_NO_RESPONSE_CNT_DISABLE +wire set_retry = 1'b0 ; + +`else +reg [3:0] wb_no_response_cnt ; +reg [3:0] wb_response_value ; +reg set_retry ; // + +// internal WB no response retry generator counter! +always@(posedge reset_in or posedge wb_clock_in) +begin + if (reset_in) + wb_no_response_cnt <= #`FF_DELAY 4'h0 ; + else + wb_no_response_cnt <= #`FF_DELAY wb_response_value ; +end +// internal WB no response retry generator logic +always@(wait_for_wb_response or wb_no_response_cnt) +begin + if (wb_no_response_cnt == 4'h8) // when there isn't response for 8 clocks, set internal retry + begin + wb_response_value = 4'h0 ; + set_retry = 1'b1 ; + end + else + begin + if (wait_for_wb_response) + wb_response_value = wb_no_response_cnt + 1'h1 ; // count clocks when no response + else + wb_response_value = 4'h0 ; + set_retry = 1'b0 ; + end +end +`endif + +wire retry = wb_rty_i || set_retry ; // retry signal - logic OR function between wb_rty_i and internal WB no response retry! +reg [7:0] rty_counter ; // output from retry counter +reg [7:0] rty_counter_in ; // input value - output value + 1 OR output value +reg rty_counter_almost_max_value ; // signal tells when retry counter riches maximum value - 1! +reg reset_rty_cnt ; // signal for asynchronous reset of retry counter after each complete transfere + +// sinchronous signal after each transfere and asynchronous signal 'reset_rty_cnt' after reset +// for reseting the retry counter +always@(posedge reset_in or posedge wb_clock_in) +begin + if (reset_in) + reset_rty_cnt <= #`FF_DELAY 1'b1 ; // asynchronous set when reset signal is active + else + reset_rty_cnt <= #`FF_DELAY wb_ack_i || wb_err_i || last_data_transferred ; // synchronous set after completed transfere +end + +// Retry counter register control +always@(posedge reset_in or posedge wb_clock_in) +begin + if (reset_in) + rty_counter <= #`FF_DELAY 8'h00 ; + else + begin + if (reset_rty_cnt) + rty_counter <= #`FF_DELAY 8'h00 ; + else if (retry) + rty_counter <= #`FF_DELAY rty_counter_in ; + end +end +// Retry counter logic +always@(rty_counter) +begin + if(rty_counter == `WB_RTY_CNT_MAX - 1'b1) // stop counting + begin + rty_counter_in = rty_counter ; + rty_counter_almost_max_value = 1'b1 ; + end + else + begin + rty_counter_in = rty_counter + 1'b1 ; // count up + rty_counter_almost_max_value = 1'b0 ; + end +end + +reg [31:0] addr_cnt_out ; // output value from address counter to WB ADDRESS output +reg [31:0] addr_cnt_in ; // input address value to address counter +reg addr_into_cnt ; // control signal for loading starting address into counter +reg addr_into_cnt_reg ; +reg addr_count ; // control signal for count enable +reg [3:0] bc_register ; // used when error occures during writes! + +// wb address counter register control +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) // reset counter + begin + addr_cnt_out <= #`FF_DELAY 32'h0000_0000 ; + bc_register <= #`FF_DELAY 4'h0 ; + addr_into_cnt_reg <= #`FF_DELAY 1'b0; + end + else + begin + addr_cnt_out <= #`FF_DELAY addr_cnt_in ; // count up or hold value depending on cache line counter logic + addr_into_cnt_reg <= #`FF_DELAY addr_into_cnt; + if (addr_into_cnt) + bc_register <= #`FF_DELAY pciw_fifo_cbe_in ; + end +end + +// when '1', the bus command is IO command - not supported commands are checked in pci_decoder modules +wire io_memory_bus_command = !pci_tar_cmd[3] && !pci_tar_cmd[2] ; + +// wb address counter logic +always@(addr_into_cnt or r_attempt or addr_count or pciw_fifo_addr_data_in or pci_tar_address or addr_cnt_out or + io_memory_bus_command) +begin + if (addr_into_cnt) // load starting address into counter + begin + if (r_attempt) + begin // if read request, then load read addresss from PCI Target + addr_cnt_in = {pci_tar_address[31:2], pci_tar_address[1] && io_memory_bus_command, + pci_tar_address[0] && io_memory_bus_command} ; + end + else + begin // if not read request, then load write address from PCIW_FIFO + addr_cnt_in = pciw_fifo_addr_data_in[31:0] ; + end + end + else + if (addr_count) + begin + addr_cnt_in = addr_cnt_out + 3'h4 ; // count up for 32-bit alligned address + end + else + begin + addr_cnt_in = addr_cnt_out ; + end +end + +reg retried ; // Signal is output value from FF and is set for one clock period after retried_d is set +reg retried_d ; // Signal is set whenever cycle is retried and is input to FF for delaying -> used in S_IDLE state +reg retried_write; +reg rty_i_delayed; // Dignal used for determinig the source of retry! + +reg first_data_is_burst ; // Signal is set in S_WRITE or S_READ states, when data transfere is burst! +reg first_data_is_burst_reg ; +wire burst_transfer ; // This signal is set when data transfere is burst and is reset with RESET or last data transfered +reg burst_chopped; // This signal is set when WB_SEL_O is changed during burst write transaction +reg burst_chopped_delayed; + +// FFs output signals tell, when there is first data out from FIFO (for BURST checking) +// and for delaying retried signal +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) // reset signals + begin + retried <= #`FF_DELAY 1'b0 ; + retried_write <= #`FF_DELAY 1'b0 ; + rty_i_delayed <= #`FF_DELAY 1'B0 ; + end + else + begin + retried <= #`FF_DELAY retried_d ; // delaying retried signal + retried_write <= #`FF_DELAY retried ; + rty_i_delayed <= #`FF_DELAY wb_rty_i ; + end +end + +// Determinig if first data is a part of BURST or just a single transfere! +always@(addr_into_cnt or r_attempt or pci_tar_burst_ok or max_read_count or + pciw_fifo_control_in or pciw_fifo_empty_in) +begin + if (addr_into_cnt) + begin + if (r_attempt) + begin + // burst is OK for reads when there is ((MEM_READ_LN or MEM_READ_MUL) and AD[1:0]==2'b00) OR + // (MEM_READ and Prefetchable_IMAGE and AD[1:0]==2'b00) -> pci_tar_burst_ok + if (pci_tar_burst_ok && (max_read_count != 8'h1)) + first_data_is_burst = 1'b1 ; + else + first_data_is_burst = 1'b0 ; + end + else + begin + first_data_is_burst = 1'b0 ; + end + end + else + first_data_is_burst = pciw_fifo_control_in[`BURST_BIT] && ~pciw_fifo_empty_in && + ~pciw_fifo_control_in[`LAST_CTRL_BIT] /*&& ~pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT]*/; +end + +// FF for seting and reseting burst_transfer signal +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) + begin + burst_chopped <= #`FF_DELAY 1'b0; + burst_chopped_delayed <= #`FF_DELAY 1'b0; + first_data_is_burst_reg <= #`FF_DELAY 1'b0 ; + end + else + begin + if (pciw_fifo_transaction_ready_in) + begin + if (pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT]) + burst_chopped <= #`FF_DELAY 1'b1; + else if (wb_ack_i || wb_err_i || wb_rty_i) + burst_chopped <= #`FF_DELAY 1'b0; + end + else + burst_chopped <= #`FF_DELAY 1'b0; + burst_chopped_delayed <= #`FF_DELAY burst_chopped; + if (last_data_transferred || first_data_is_burst) + first_data_is_burst_reg <= #`FF_DELAY ~last_data_transferred ; + end +end +assign burst_transfer = first_data_is_burst || first_data_is_burst_reg ; + +reg [(`WB_FSM_BITS - 1):0] c_state ; //current state register +reg [(`WB_FSM_BITS - 1):0] n_state ; //next state input to current state register + +//################################## +// WISHBONE B3 master state machine +//################################## + +// state machine register control and registered outputs (without wb_adr_o counter) +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) // reset state machine to S_IDLE state + begin + c_state <= #`FF_DELAY S_IDLE; + wb_cyc_o <= #`FF_DELAY 1'b0; + wb_stb_o <= #`FF_DELAY 1'b0; + wb_we_o <= #`FF_DELAY 1'b0; + wb_cti_o <= #`FF_DELAY 3'h2; + wb_bte_o <= #`FF_DELAY 2'h0; + wb_sel_o <= #`FF_DELAY 4'h0; + wb_dat_o <= #`FF_DELAY 32'h0; + pcir_fifo_data_out <= #`FF_DELAY 32'h0; + pcir_fifo_control_out <= #`FF_DELAY 4'h0; + pcir_fifo_wenable_out <= #`FF_DELAY 1'b0; + end + else + begin + c_state <= #`FF_DELAY n_state; + wb_bte_o <= #`FF_DELAY 2'h0; + case (n_state) // synthesis parallel_case full_case + S_WRITE: + begin + wb_cyc_o <= #`FF_DELAY ~addr_into_cnt; + wb_stb_o <= #`FF_DELAY ~addr_into_cnt; + wb_we_o <= #`FF_DELAY ~addr_into_cnt; + // if '1' then next burst BE is not equat to current one => burst is chopped into singles + // OR if last data is going to be transfered + if ((wb_stb_o && wb_ack_i) || addr_into_cnt_reg || (~wb_cyc_o && (retried || burst_chopped_delayed))) + begin + if (burst_transfer && ~pciw_fifo_control_in[`DATA_ERROR_CTRL_BIT] && + ~(pciw_fifo_renable_out && (pciw_fifo_control_in[`LAST_CTRL_BIT] || pciw_fifo_almost_empty_in))) + wb_cti_o <= #`FF_DELAY 3'h2; + else + wb_cti_o <= #`FF_DELAY 3'h7; + end + if ((pciw_fifo_renable_out && ~addr_into_cnt) || addr_into_cnt_reg) + begin + wb_sel_o <= #`FF_DELAY ~pciw_fifo_cbe_in; + wb_dat_o <= #`FF_DELAY pciw_fifo_addr_data_in; + end + end + S_WRITE_ERR_RTY: + begin + wb_cyc_o <= #`FF_DELAY 1'b0; + wb_stb_o <= #`FF_DELAY 1'b0; + wb_we_o <= #`FF_DELAY 1'b0; + wb_cti_o <= #`FF_DELAY 3'h2; + // stay the same as previous + //wb_sel_o <= #`FF_DELAY 4'h0; + //wb_dat_o <= #`FF_DELAY 32'h0; + end + S_READ: + begin + wb_cyc_o <= #`FF_DELAY ~addr_into_cnt; + wb_stb_o <= #`FF_DELAY ~addr_into_cnt; + wb_we_o <= #`FF_DELAY 1'b0; + if ((wb_stb_o && wb_ack_i) || addr_into_cnt_reg || (~wb_cyc_o && retried)) + begin + if (burst_transfer && ~read_bound_comb) + wb_cti_o <= #`FF_DELAY 3'h2; + else + wb_cti_o <= #`FF_DELAY 3'h7; + end + if (burst_transfer) + wb_sel_o <= #`FF_DELAY 4'hF; + else + wb_sel_o <= #`FF_DELAY ~pci_tar_be; + // no need to change att all + //wb_dat_o <= #`FF_DELAY 32'h0; + end + S_READ_RTY: + begin + wb_cyc_o <= #`FF_DELAY 1'b0; + wb_stb_o <= #`FF_DELAY 1'b0; + wb_we_o <= #`FF_DELAY 1'b0; + wb_cti_o <= #`FF_DELAY 3'h2; + // no need to change att all + //wb_sel_o <= #`FF_DELAY 4'h0; + //wb_dat_o <= #`FF_DELAY 32'h0; + end + S_TURN_ARROUND: + begin + wb_cyc_o <= #`FF_DELAY 1'b0; + wb_stb_o <= #`FF_DELAY 1'b0; + wb_we_o <= #`FF_DELAY 1'b0; + wb_cti_o <= #`FF_DELAY 3'h2; + // no need to change att all + //wb_sel_o <= #`FF_DELAY 4'h0; + //wb_dat_o <= #`FF_DELAY 32'h0; + end + default: // S_IDLE: + begin + wb_cyc_o <= #`FF_DELAY 1'b0; + wb_stb_o <= #`FF_DELAY 1'b0; + wb_we_o <= #`FF_DELAY 1'b0; + wb_cti_o <= #`FF_DELAY 3'h2; + // no need to change att all + //wb_sel_o <= #`FF_DELAY 4'h0; + //wb_dat_o <= #`FF_DELAY 32'h0; + end + endcase + pcir_fifo_data_out <= #`FF_DELAY wb_dat_i; + pcir_fifo_control_out <= #`FF_DELAY pcir_fifo_control ; + pcir_fifo_wenable_out <= #`FF_DELAY pcir_fifo_wenable ; + end +end + +assign wb_adr_o = addr_cnt_out ; + +// state machine logic +always@(c_state or + wb_ack_i or + wb_rty_i or + wb_err_i or + w_attempt or + r_attempt or + retried or + burst_chopped or + burst_chopped_delayed or + rty_i_delayed or + pci_tar_read_request or + rty_counter_almost_max_value or + set_retry or + last_data_to_pcir_fifo or + first_wb_data_access or + pciw_fifo_control_in or + pciw_fifo_empty_in or + burst_transfer or + last_data_from_pciw_fifo_reg + ) +begin + case (c_state) + S_IDLE: + begin + // Default values for signals not used in this state + pcir_fifo_wenable = 1'b0 ; + pcir_fifo_control = 4'h0 ; + addr_count = 1'b0 ; + read_count_enable = 1'b0 ; + pci_error_sig_out = 1'b0 ; + error_source_out = 1'b0 ; + retried_d = 1'b0 ; + last_data_transferred = 1'b0 ; + wb_read_done = 1'b0 ; + wait_for_wb_response = 1'b0 ; + write_rty_cnt_exp_out = 1'b0 ; + pci_error_sig_out = 1'b0 ; + read_rty_cnt_exp_out = 1'b0 ; + case ({w_attempt, r_attempt, retried}) + 3'b101 : // Write request for PCIW_FIFO to WB bus transaction + begin // If there was retry, the same transaction must be initiated + pciw_fifo_renable = 1'b0 ; // the same data + addr_into_cnt = 1'b0 ; // the same address + read_count_load = 1'b0 ; // no need for cache line when there is write + n_state = S_WRITE ; + end + 3'b100 : // Write request for PCIW_FIFO to WB bus transaction + begin // If there is new transaction + if (burst_chopped_delayed) + begin + addr_into_cnt = 1'b0 ; // address must not be latched into address counter + pciw_fifo_renable = 1'b1 ; // first location is address (in FIFO), next will be data + end + else + begin + if (pciw_fifo_control_in[`ADDR_CTRL_BIT]) + addr_into_cnt = 1'b1 ; // address must be latched into address counter + else + addr_into_cnt = 1'b0 ; + pciw_fifo_renable = 1'b1 ; // first location is address (in FIFO), next will be data + end + read_count_load = 1'b0 ; // no need for cache line when there is write + n_state = S_WRITE ; + end + 3'b011 : // Read request from PCI Target for WB bus to PCIR_FIFO transaction + begin // If there was retry, the same transaction must be initiated + addr_into_cnt = 1'b0 ; // the same address + read_count_load = 1'b0 ; // cache line counter must not be changed for retried read + pciw_fifo_renable = 1'b0 ; // don't read from FIFO, when read transaction from WB to FIFO + n_state = S_READ ; + end + 3'b010 : // Read request from PCI Target for WB bus to PCIR_FIFO transaction + begin // If there is new transaction + addr_into_cnt = 1'b1 ; // address must be latched into counter from separate request bus + read_count_load = 1'b1 ; // cache line size must be latched into its counter + pciw_fifo_renable = 1'b0 ; // don't read from FIFO, when read transaction from WB to FIFO + n_state = S_READ ; + end + default : // stay in IDLE state + begin + pciw_fifo_renable = 1'b0 ; + addr_into_cnt = 1'b0 ; + read_count_load = 1'b0 ; + n_state = S_IDLE ; + end + endcase + end + S_WRITE: // WRITE from PCIW_FIFO to WB bus + begin + // Default values for signals not used in this state + pcir_fifo_wenable = 1'b0 ; + pcir_fifo_control = 4'h0 ; + addr_into_cnt = 1'b0 ; + read_count_load = 1'b0 ; + read_count_enable = 1'b0 ; + wb_read_done = 1'b0 ; + read_rty_cnt_exp_out = 1'b0 ; + case ({wb_ack_i, wb_err_i, wb_rty_i}) + 3'b100 : // If writting of one data is acknowledged + begin + addr_count = 1'b1 ; // prepare next address if there will be burst + retried_d = 1'b0 ; // there was no retry + pci_error_sig_out = 1'b0 ; // there was no error + error_source_out = 1'b0 ; + write_rty_cnt_exp_out = 1'b0 ; // there was no retry + wait_for_wb_response = 1'b0 ; + // if last data was transfered ! + if (last_data_from_pciw_fifo_reg) + begin + n_state = S_TURN_ARROUND; + if (~pciw_fifo_empty_in) + pciw_fifo_renable = 1'b0 ; // prepare next value (address when new trans., data when burst tran.) + else + pciw_fifo_renable = 1'b0 ; + last_data_transferred = 1'b1 ; // signal for last data transfered + end + // next burst data has different byte enables ! + else if (burst_transfer && burst_chopped) + begin + n_state = S_IDLE ; + pciw_fifo_renable = 1'b0 ; // next value (address when new trans., data when burst tran.) + last_data_transferred = 1'b0 ; + end + else + begin + n_state = S_WRITE ; + pciw_fifo_renable = 1'b1 ; // prepare next value (address when new trans., data when burst tran.) + last_data_transferred = 1'b0 ; + end + end + 3'b010 : // If writting of one data is terminated with ERROR + begin + if (~pciw_fifo_empty_in) + pciw_fifo_renable = 1'b1 ; // prepare next value (address when new trans., data when cleaning FIFO) + else + pciw_fifo_renable = 1'b0 ; + addr_count = 1'b0 ; // no need for new address + retried_d = 1'b0 ; // there was no retry + last_data_transferred = 1'b1 ; // signal for last data transfered + pci_error_sig_out = 1'b1 ; // segnal for error reporting + error_source_out = 1'b0 ; // error source from other side of WB bus + write_rty_cnt_exp_out = 1'b0 ; // there was no retry + wait_for_wb_response = 1'b0 ; + if (last_data_from_pciw_fifo_reg) // if last data was transfered + n_state = S_TURN_ARROUND ; // go to S_TURN_ARROUND for new transfere + else // if there wasn't last data of transfere + n_state = S_WRITE_ERR_RTY ; // go here to clean this write transaction from PCIW_FIFO + end + 3'b001 : // If writting of one data is retried + begin + addr_count = 1'b0 ; + last_data_transferred = 1'b0 ; + retried_d = 1'b1 ; // there was a retry + wait_for_wb_response = 1'b0 ; + if(rty_counter_almost_max_value) // If retry counter reached maximum allowed value + begin + if (last_data_from_pciw_fifo_reg) // if last data was transfered + pciw_fifo_renable = 1'b0 ; + else // if there wasn't last data of transfere + pciw_fifo_renable = 1'b1 ; + n_state = S_WRITE_ERR_RTY ; // go here to clean this write transaction from PCIW_FIFO + write_rty_cnt_exp_out = 1'b1 ; // signal for reporting write counter expired + pci_error_sig_out = 1'b1 ; + error_source_out = 1'b1 ; // error ocuerd because of retry counter + end + else + begin + pciw_fifo_renable = 1'b0 ; + n_state = S_IDLE ; // go to S_IDLE state for retrying the transaction + write_rty_cnt_exp_out = 1'b0 ; // retry counter hasn't expired yet + pci_error_sig_out = 1'b0 ; + error_source_out = 1'b0 ; + end + end + default : + begin + addr_count = 1'b0 ; + last_data_transferred = 1'b0 ; + wait_for_wb_response = 1'b1 ; // wait for WB device to response (after 8 clocks RTY CNT is incremented) + error_source_out = 1'b0 ; // if error ocures, error source is from other WB bus side + if((rty_counter_almost_max_value)&&(set_retry)) // when no WB response and RTY CNT reached maximum allowed value + begin + retried_d = 1'b1 ; + if (last_data_from_pciw_fifo_reg) // if last data was transfered + pciw_fifo_renable = 1'b0 ; + else // if there wasn't last data of transfere + pciw_fifo_renable = 1'b1 ; + n_state = S_WRITE_ERR_RTY ; // go here to clean this write transaction from PCIW_FIFO + write_rty_cnt_exp_out = 1'b1 ; // signal for reporting write counter expired + pci_error_sig_out = 1'b1 ; // signal for error reporting + end + else + begin + pciw_fifo_renable = 1'b0 ; + retried_d = 1'b0 ; + n_state = S_WRITE ; // stay in S_WRITE state to wait WB to response + write_rty_cnt_exp_out = 1'b0 ; // retry counter hasn't expired yet + pci_error_sig_out = 1'b0 ; + end + end + endcase + end + S_WRITE_ERR_RTY: // Clean current write transaction from PCIW_FIFO if ERROR or Retry counter expired occures + begin + pciw_fifo_renable = !last_data_from_pciw_fifo_reg ; // put out next data (untill last data or FIFO empty) + last_data_transferred = 1'b1 ; // after exiting this state, negedge of this signal is used + // Default values for signals not used in this state + pcir_fifo_wenable = 1'b0 ; + pcir_fifo_control = 4'h0 ; + addr_into_cnt = 1'b0 ; + read_count_load = 1'b0 ; + read_count_enable = 1'b0 ; + addr_count = 1'b0 ; + pci_error_sig_out = 1'b0 ; + error_source_out = 1'b0 ; + retried_d = 1'b0 ; + wb_read_done = 1'b0 ; + write_rty_cnt_exp_out = 1'b0 ; + read_rty_cnt_exp_out = 1'b0 ; + wait_for_wb_response = 1'b0 ; + // If last data is cleaned out from PCIW_FIFO + if (last_data_from_pciw_fifo_reg) + n_state = S_IDLE ; + else + n_state = S_WRITE_ERR_RTY ; // Clean until last data is cleaned out from FIFO + end + S_READ: // READ from WB bus to PCIR_FIFO + begin + // Default values for signals not used in this state + pciw_fifo_renable = 1'b0 ; + addr_into_cnt = 1'b0 ; + read_count_load = 1'b0 ; + pci_error_sig_out = 1'b0 ; + error_source_out = 1'b0 ; + write_rty_cnt_exp_out = 1'b0 ; + case ({wb_ack_i, wb_err_i, wb_rty_i}) + 3'b100 : // If reading of one data is acknowledged + begin + pcir_fifo_wenable = 1'b1 ; // enable writting data into PCIR_FIFO + addr_count = 1'b1 ; // prepare next address if there will be burst + read_count_enable = 1'b1 ; // decrease counter value for cache line size + retried_d = 1'b0 ; // there was no retry + read_rty_cnt_exp_out = 1'b0 ; // there was no retry + wait_for_wb_response = 1'b0 ; + // if last data was transfered + if (last_data_to_pcir_fifo) + begin + pcir_fifo_control[`LAST_CTRL_BIT] = 1'b1 ; // FIFO must indicate LAST data transfered + pcir_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b0 ; + pcir_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ; + pcir_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; + last_data_transferred = 1'b1 ; // signal for last data transfered + wb_read_done = 1'b1 ; // signal last data of read transaction for PCI Target + n_state = S_TURN_ARROUND ; + end + else // if not last data transfered + begin + pcir_fifo_control = 4'h0 ; // ZERO for control code + last_data_transferred = 1'b0 ; // not last data transfered + wb_read_done = 1'b0 ; // read is not done yet + n_state = S_READ ; + end + end + 3'b010 : // If reading of one data is terminated with ERROR + begin + pcir_fifo_wenable = 1'b1 ; // enable for writting to FIFO data with ERROR + addr_count = 1'b0 ; // no need for new address + pcir_fifo_control[`LAST_CTRL_BIT] = 1'b0 ; + pcir_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b1 ; // FIFO must indicate the DATA with ERROR + pcir_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ; + pcir_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; + last_data_transferred = 1'b1 ; // signal for last data transfered + wb_read_done = 1'b1 ; // signal last data of read transaction for PCI Target + read_count_enable = 1'b0 ; // no need for cache line, when error occures + n_state = S_TURN_ARROUND ; + retried_d = 1'b0 ; // there was no retry + wait_for_wb_response = 1'b0 ; + read_rty_cnt_exp_out = 1'b0 ; // there was no retry + end + 3'b001 : // If reading of one data is retried + begin + pcir_fifo_wenable = 1'b0 ; + pcir_fifo_control = 4'h0 ; + addr_count = 1'b0 ; + read_count_enable = 1'b0 ; + wait_for_wb_response = 1'b0 ; + case ({first_wb_data_access, rty_counter_almost_max_value}) + 2'b10 : + begin // if first data of the cycle (CYC_O) is retried - after each retry CYC_O goes inactive + n_state = S_IDLE ; // go to S_IDLE state for retrying the transaction + read_rty_cnt_exp_out = 1'b0 ; // retry counter hasn't expired yet + last_data_transferred = 1'b0 ; + wb_read_done = 1'b0 ; + retried_d = 1'b1 ; // there was a retry + end + 2'b11 : + begin // if retry counter reached maximum value + n_state = S_READ_RTY ; // go here to wait for PCI Target to remove read request + read_rty_cnt_exp_out = 1'b1 ; // signal for reporting read counter expired + last_data_transferred = 1'b0 ; + wb_read_done = 1'b0 ; + retried_d = 1'b1 ; // there was a retry + end + default : // if retry occures after at least 1 data was transferred without breaking cycle (CYC_O inactive) + begin // then PCI device will retry access! + n_state = S_TURN_ARROUND ; // go to S_TURN_ARROUND state + read_rty_cnt_exp_out = 1'b0 ; // retry counter hasn't expired + last_data_transferred = 1'b1 ; + wb_read_done = 1'b1 ; + retried_d = 1'b0 ; // retry must not be retried, since there is not a first data + end + endcase + end + default : + begin + addr_count = 1'b0 ; + read_count_enable = 1'b0 ; + read_rty_cnt_exp_out = 1'b0 ; + wait_for_wb_response = 1'b1 ; // wait for WB device to response (after 8 clocks RTY CNT is incremented) + if((rty_counter_almost_max_value)&&(set_retry)) // when no WB response and RTY CNT reached maximum allowed value + begin + retried_d = 1'b1 ; + n_state = S_TURN_ARROUND ; // go here to stop read request + pcir_fifo_wenable = 1'b1 ; + pcir_fifo_control[`LAST_CTRL_BIT] = 1'b0 ; + pcir_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b1 ; // FIFO must indicate the DATA with ERROR + pcir_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ; + pcir_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; + last_data_transferred = 1'b1 ; + wb_read_done = 1'b1 ; + end + else + begin + retried_d = 1'b0 ; + n_state = S_READ ; // stay in S_READ state to wait WB to response + pcir_fifo_wenable = 1'b0 ; + pcir_fifo_control = 4'h0 ; + last_data_transferred = 1'b0 ; + wb_read_done = 1'b0 ; + end + end + endcase + end + S_READ_RTY: // Wait for PCI Target to remove read request, when retry counter reaches maximum value! + begin + // Default values for signals not used in this state + pciw_fifo_renable = 1'b0 ; + pcir_fifo_wenable = 1'b0 ; + pcir_fifo_control = 4'h0 ; + addr_into_cnt = 1'b0 ; + read_count_load = 1'b0 ; + read_count_enable = 1'b0 ; + addr_count = 1'b0 ; + pci_error_sig_out = 1'b0 ; + error_source_out = 1'b0 ; + retried_d = 1'b0 ; + wb_read_done = 1'b0 ; + write_rty_cnt_exp_out = 1'b0 ; + read_rty_cnt_exp_out = 1'b0 ; + wait_for_wb_response = 1'b0 ; + // wait for PCI Target to remove read request + if (pci_tar_read_request) + begin + n_state = S_READ_RTY ; // stay in this state until read request is removed + last_data_transferred = 1'b0 ; + end + else // when read request is removed + begin + n_state = S_IDLE ; + last_data_transferred = 1'b1 ; // when read request is removed, there is "last" data + end + end + // Turn arround cycle after writting to PCIR_FIFO (for correct data when reading from PCIW_FIFO) + default: // S_TURN_ARROUND: + begin + // Default values for signals not used in this state + pciw_fifo_renable = 1'b0 ; + pcir_fifo_wenable = 1'b0 ; + pcir_fifo_control = 4'h0 ; + addr_into_cnt = 1'b0 ; + read_count_load = 1'b0 ; + read_count_enable = 1'b0 ; + addr_count = 1'b0 ; + pci_error_sig_out = 1'b0 ; + error_source_out = 1'b0 ; + retried_d = 1'b0 ; + last_data_transferred = 1'b1 ; + wb_read_done = 1'b0 ; + write_rty_cnt_exp_out = 1'b0 ; + read_rty_cnt_exp_out = 1'b0 ; + wait_for_wb_response = 1'b0 ; + n_state = S_IDLE ; + end + endcase +end + +// Signal for retry monitor in state machine when there is read and first (or single) data access +wire ack_rty_response = wb_ack_i || wb_rty_i ; + +// Signal first_wb_data_access is set when no WB cycle present till end of first data access of WB cycle on WB bus +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) + first_wb_data_access = 1'b1 ; + else + begin + if (~wb_cyc_o) + first_wb_data_access = 1'b1 ; + else if (ack_rty_response) + first_wb_data_access = 1'b0 ; + end +end + +// Signals to FIFO +assign pcir_fifo_be_out = 4'hf ; // pci_tar_be ; + +// Signals to Conf. space +assign pci_error_bc = bc_register ; + + +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) + wb_read_done_out <= #`FF_DELAY 1'b0 ; + else + wb_read_done_out <= #`FF_DELAY wb_read_done ; +end + +always@(pciw_fifo_renable or addr_into_cnt_reg or pciw_fifo_control_in or pciw_fifo_empty_in) +begin + pciw_fifo_renable_out = pciw_fifo_renable || addr_into_cnt_reg ; + last_data_from_pciw_fifo_reg = pciw_fifo_control_in[`ADDR_CTRL_BIT] || pciw_fifo_empty_in ; +end + + +endmodule + diff --git a/ethernet/source/pci/pci_wb_slave.v b/ethernet/source/pci/pci_wb_slave.v new file mode 100644 index 0000000..dfe91bc --- /dev/null +++ b/ethernet/source/pci/pci_wb_slave.v @@ -0,0 +1,1164 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "wb_slave.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_wb_slave.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.6 2006/07/04 13:16:19 mihad +// Write burst performance patch applied. +// Not tested. Everything should be backwards +// compatible, since functional code is ifdefed. +// +// Revision 1.5 2004/01/24 11:54:18 mihad +// Update! SPOCI Implemented! +// +// Revision 1.4 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.3 2003/08/14 18:01:53 simons +// ifdefs moved to thier own lines, this confuses some of the tools. +// +// Revision 1.2 2003/08/03 18:05:06 mihad +// Added limited WISHBONE B3 support for WISHBONE Slave Unit. +// Doesn't support full speed bursts yet. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.4 2002/08/19 16:54:25 mihad +// Got rid of undef directives +// +// Revision 1.3 2002/02/01 15:25:13 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +`include "bus_commands.v" +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + + + +module pci_wb_slave + ( wb_clock_in, + reset_in, + wb_hit_in, + wb_conf_hit_in, + wb_map_in, + wb_pref_en_in, + wb_mrl_en_in, + wb_addr_in, + del_bc_in, + wb_del_req_pending_in, + wb_del_comp_pending_in, + pci_drcomp_pending_in, + del_bc_out, + del_req_out, + del_done_out, + del_burst_out, + del_write_out, + del_write_in, + del_error_in, + del_in_progress_out, + ccyc_addr_in, + wb_del_addr_in, + wb_del_be_in, + wb_conf_offset_out, + wb_conf_renable_out, + wb_conf_wenable_out, + wb_conf_be_out, + wb_conf_data_in, + wb_conf_data_out, + wb_data_out, + wb_cbe_out, + wbw_fifo_wenable_out, + wbw_fifo_control_out, + wbw_fifo_almost_full_in, + wbw_fifo_full_in, + wbw_fifo_half_full_in, //Robert, burst issue + wbr_fifo_renable_out, + wbr_fifo_be_in, + wbr_fifo_data_in, + wbr_fifo_control_in, + wbr_fifo_flush_out, + wbr_fifo_empty_in, + pciw_fifo_empty_in, + wbs_lock_in, + init_complete_in, + cache_line_size_not_zero, + sample_address_out, + CYC_I, + STB_I, + WE_I, + SEL_I, + SDATA_I, + SDATA_O, + ACK_O, + RTY_O, + ERR_O, + CAB_I + ); + +/*---------------------------------------------------------------------------------------------------------------------- +Various parameters needed for state machine and other stuff +----------------------------------------------------------------------------------------------------------------------*/ +parameter WBR_SEL = 1'b0 ; +parameter CONF_SEL = 1'b1 ; + +`define FSM_BITS 3 +parameter S_IDLE = `FSM_BITS'h0 ; +parameter S_DEC1 = `FSM_BITS'h1 ; +parameter S_DEC2 = `FSM_BITS'h2 ; +parameter S_START = `FSM_BITS'h3 ; +parameter S_W_ADDR_DATA = `FSM_BITS'h4 ; +parameter S_READ = `FSM_BITS'h5 ; +parameter S_CONF_WRITE = `FSM_BITS'h6 ; +parameter S_CONF_READ = `FSM_BITS'h7 ; + +/*---------------------------------------------------------------------------------------------------------------------- +System signals inputs +wb_clock_in - WISHBONE bus clock input +reset_in - system reset input controlled by bridge's reset logic +----------------------------------------------------------------------------------------------------------------------*/ +input wb_clock_in, reset_in ; + +/*---------------------------------------------------------------------------------------------------------------------- +Inputs from address decoding logic +wb_hit_in - Decoder logic indicates if address is in a range of one of images +wb_conf_hit_in - Decoder logic indicates that address is in configuration space range +wb_map_in - Decoder logic provides information about image mapping - memory mapped image - wb_map_in = 0 + IO space mapped image - wb_map_in = 1 +wb_pref_en_in - Prefetch enable signal from currently selected image - used for PCI bus command usage +wb_addr_in - Address already transalted from WB bus to PCI bus input +wb_mrl_en_in - Memory read line enable input for each image +----------------------------------------------------------------------------------------------------------------------*/ +input [4:0] wb_hit_in ; // hit indicators +input wb_conf_hit_in ; // configuration hit indicator +input [4:0] wb_pref_en_in ; // prefetch enable from all images +input [4:0] wb_mrl_en_in ; // Memory Read line command enable from images +input [4:0] wb_map_in ; // address space mapping indicators - 1 memory space mapping, 0-IO space mapping +input [31:0] wb_addr_in ; // Translated address input + +/*---------------------------------------------------------------------------------------------------------------------- +Delayed transaction control inputs and outputs: +Used for locking particular accesses when delayed transactions are in progress: +wb_del_addr_in - delayed transaction address input - when completion is ready it's used for transaction decoding +wb_del_be_in - delayed transaction byte enable input - when completion is ready it's used for transaction decoding +----------------------------------------------------------------------------------------------------------------------*/ +input [31:0] wb_del_addr_in ; +input [3:0] wb_del_be_in ; + +input [3:0] del_bc_in ; // delayed request bus command used +input wb_del_req_pending_in ; // delayed request pending indicator +input wb_del_comp_pending_in ; // delayed completion pending indicator +input pci_drcomp_pending_in ; // PCI initiated delayed read completion pending + +output [3:0] del_bc_out ; // delayed transaction bus command output + +output del_req_out ; // output for issuing delayed transaction requests + +output del_done_out ; // output indicating current delayed completion finished on WISHBONE bus + +output del_burst_out ; // delayed burst transaction indicator + +output del_in_progress_out ; // delayed in progress indicator - since delayed transaction can be a burst transaction, progress indicator must be used for proper operation + +output del_write_out ; // write enable for delayed transaction - used for indicating that transaction is a write + +input del_write_in ; // indicates that current delayed completion is from a write request +input del_error_in ; // indicate that delayed request terminated with an error - used for write requests + +input [31:0] ccyc_addr_in ; // configuration cycle address input - it's separate from other addresses, since it is stored separately and decoded for type 0 configuration access + +/*---------------------------------------------------------------------------------------------------------------------- +Configuration space access control and data signals +wb_conf_offset_out - lower 12 bits of address input provided for register offset +wb_conf_renable - read enable signal for configuration space accesses +wb_conf_wenable - write enable signal for configuration space accesses +wb_conf_be_out - byte enable signals for configuration space accesses +wb_conf_data_in - data from configuration space +wb_conf_data_in - data provided for configuration space +----------------------------------------------------------------------------------------------------------------------*/ +output [11:0] wb_conf_offset_out ; // register offset output +output wb_conf_renable_out, // configuration read and write enable outputs + wb_conf_wenable_out ; +output [3:0] wb_conf_be_out ; // byte enable outputs for configuration space +input [31:0] wb_conf_data_in ; // configuration data input from configuration space +output [31:0] wb_conf_data_out ; // configuration data output for configuration space + +/*---------------------------------------------------------------------------------------------------------------------- +Data from WISHBONE bus output to interiror of the core: +Data output is used for normal and configuration accesses. +---------------------------------------------------------------------------------------------------------------------*/ +output [31:0] wb_data_out ; + +/*---------------------------------------------------------------------------------------------------------------------- +Bus command - byte enable output - during address phase of image access this bus holds information about PCI +bus command that should be used, during dataphases ( configuration or image access ) this bus contains inverted +SEL_I signals +---------------------------------------------------------------------------------------------------------------------*/ +output [3:0] wb_cbe_out ; + +/*---------------------------------------------------------------------------------------------------------------------- +WBW_FIFO control signals used for sinking data into WBW_FIFO and status monitoring +---------------------------------------------------------------------------------------------------------------------*/ +output wbw_fifo_wenable_out ; // write enable for WBW_FIFO output +output [3:0] wbw_fifo_control_out ; // control bus output for WBW_FIFO +input wbw_fifo_almost_full_in ; // almost full status indicator from WBW_FIFO +input wbw_fifo_full_in ; // full status indicator from WBW_FIFO +input wbw_fifo_half_full_in; //Robert, burst issue + +/*---------------------------------------------------------------------------------------------------------------------- +WBR_FIFO control signals used for fetching data from WBR_FIFO and status monitoring +---------------------------------------------------------------------------------------------------------------------*/ +output wbr_fifo_renable_out ; // WBR_FIFO read enable output +input [3:0] wbr_fifo_be_in ; // byte enable input from WBR_FIFO +input [31:0] wbr_fifo_data_in ; // data input from WBR_FIFO +input [3:0] wbr_fifo_control_in ; // control bus input from WBR_FIFO +output wbr_fifo_flush_out ; // flush signal for WBR_FIFO +input wbr_fifo_empty_in ; // empty status indicator from WBR_FIFO + +// used for transaction ordering requirements - WISHBONE read cannot complete until writes from PCI are completed +input pciw_fifo_empty_in ; // empty status indicator from PCIW_FIFO + +/*---------------------------------------------------------------------------------------------------------------------- +wbs_lock_in: internal signal that locks out all accesses, except delayed completions or configuration accesses. +( when master operation is disabled via master enable bit in configuration spacei ) +init_complete_in: while initialization sequence is in progress, the state machine +remains in the idle state - it does not respond to accesses. +---------------------------------------------------------------------------------------------------------------------*/ +input wbs_lock_in ; +input init_complete_in ; + +// cache line size register must hold appropriate value to enable read bursts and special commands on PCI bus! +input cache_line_size_not_zero ; + +// state machine signals to wb_addr_mux when to sample wb address input +output sample_address_out ; +reg sample_address_out ; + +/*---------------------------------------------------------------------------------------------------------------------- +WISHBONE bus interface signals - can be connected directly to WISHBONE bus +---------------------------------------------------------------------------------------------------------------------*/ +input CYC_I ; // cycle indicator +input STB_I ; // strobe input - input data is valid when strobe and cycle indicator are high +input WE_I ; // write enable input - 1 - write operation, 0 - read operation +input [3:0] SEL_I ; // Byte select inputs +input [31:0] SDATA_I ; // WISHBONE slave interface input data bus +output [31:0] SDATA_O ; // WISHBONE slave interface output data bus +output ACK_O ; // Acknowledge output - qualifies valid data on data output bus or received data on data input bus +output RTY_O ; // retry output - signals to WISHBONE master that cycle should be terminated and retried later +output ERR_O ; // Signals to WISHBONE master that access resulted in an error +input CAB_I ; // consecutive address burst input - indicates that master will do a serial address transfer in current cycle + +`ifdef REGISTER_WBS_OUTPUTS +reg [31:0] SDATA_O ; +reg ACK_O ; +reg RTY_O ; +reg ERR_O ; + +reg [3:0] del_bc_out ; // delayed transaction bus command output +reg del_req_out ; // output for issuing delayed transaction requests +reg del_done_out ; // output indicating current delayed completion finished on WISHBONE bus +reg del_burst_out ; // delayed burst transaction indicator +reg del_in_progress_out ; // delayed in progress indicator - since delayed transaction can be a burst transaction, progress indicator must be used for proper operation +reg del_write_out ; // write enable for delayed transaction - used for indicating that transaction is a write + +`ifdef HOST +reg wb_conf_wenable_out ; +reg [31:0] wb_conf_data_out ; // configuration data output for configuration space +`endif + +reg [3:0] wb_conf_be_out ; // byte enable outputs for configuration space +reg [31:0] wb_data_out ; + +reg [3:0] wb_cbe_out ; + +reg wbw_fifo_wenable_out ; // write enable for WBW_FIFO output +reg [3:0] wbw_fifo_control_out ; // control bus output for WBW_FIFO + +reg wbr_fifo_renable_out ; // WBR_FIFO read enable output +`endif + +reg [(`FSM_BITS - 1):0] c_state ; //current state register + +reg [(`FSM_BITS - 1):0] n_state ; //next state input to current state register + +// state machine register control +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) + c_state <= #`FF_DELAY S_IDLE ; + else + c_state <= #`FF_DELAY n_state ; +end + + +// variable for bus command multiplexer logic output for delayed requests +reg [3:0] del_bc ; + +//register for intermediate data and select storage +reg [35:0] d_incoming ; + +// enable for incoming data register +reg d_incoming_ena ; + +// incoming data register control logic +always@(posedge wb_clock_in or posedge reset_in) +begin + if (reset_in) + d_incoming <= #`FF_DELAY {35{1'b0}} ; + else if (d_incoming_ena) + d_incoming <= #`FF_DELAY {SEL_I, SDATA_I} ; +end + +/*=================================================================================================================================================================================== +Write allow for image accesses. Writes through images are allowed when all of following are true: +- WBW_FIFO musn't be almost full nor full for image writes to be allowed - Every transaction takes at least two locations in the FIFO +- delayed read from from WISHBONE to PCI request musn't be present +- delayed read from PCI to WISHBONE completion musn't be present +- lock input musn't be set - it can be set because of error reporting or because PCI master state machine is disabled +===================================================================================================================================================================================*/ +//Robert, burst issue +//`ifdef BURST_ISSUE +wire wimg_wallow = ~|{ wbw_fifo_half_full_in, wb_del_req_pending_in, pci_drcomp_pending_in, wbs_lock_in } ; +//`else +//wire wimg_wallow = ~|{ wbw_fifo_almost_full_in , wbw_fifo_full_in, wb_del_req_pending_in, pci_drcomp_pending_in, wbs_lock_in } ; +//`endif + +reg img_wallow ; +/*=================================================================================================================================================================================== +WISHBONE slave can request an image read accesses when all of following are true: +- delayed completion is not present +- delayed request is not present +- operation is not locked because of error reporting mechanism or because PCI master is disabled +===================================================================================================================================================================================*/ +wire wdo_del_request = ~|{ wb_del_req_pending_in, wb_del_comp_pending_in, wbs_lock_in } ; +reg do_del_request ; +/*=================================================================================================================================================================================== +WISHBONE slave can complete an image read accesses when all of following are true: +- delayed read completion is present +- delayed read completion is the same as current read access ( dread_completion_hit is 1 ) +- PCI Write FIFO is empty - no posted write is waiting to be finished in PCIW_FIFO +- WBR_FIFO empty status is not active +===================================================================================================================================================================================*/ +wire wdel_addr_hit = ( wb_del_addr_in == wb_addr_in ) && ( SEL_I == wb_del_be_in ) ; +reg del_addr_hit ; +wire wdel_completion_allow = wb_del_comp_pending_in && ((~del_write_in && ~WE_I && pciw_fifo_empty_in && ~wbr_fifo_empty_in) || (del_write_in && WE_I)) ; +reg del_completion_allow ; + +/*---------------------------------------------------------------------------------------------------------------------- +img_hit - state of wb_hit_in bus when when state machine signals decode is over +---------------------------------------------------------------------------------------------------------------------*/ +reg [4:0] img_hit ; +wire wb_hit = |( img_hit ) ; + +/*---------------------------------------------------------------------------------------------------------------------- +Control logic for image control signals +pref_en - prefetch enable of currently selected image +mrl_en - Memory read line enable of currently selected image +map - Address space mapping for currently selected image +---------------------------------------------------------------------------------------------------------------------*/ +reg pref_en, mrl_en, map ; +wire wpref_en = |(wb_pref_en_in & wb_hit_in) ; +wire wmrl_en = |(wb_mrl_en_in & wb_hit_in) ; +wire wmap = |(wb_map_in & wb_hit_in) ; + +// state machine controls when results from decoders, comparison etc. are sampled into registers to decode an access +reg decode_en ; + +reg wb_conf_hit ; +always@(posedge reset_in or posedge wb_clock_in) +begin + if (reset_in) + begin + img_wallow <= #`FF_DELAY 1'b0 ; + wb_conf_hit <= #`FF_DELAY 1'b0 ; + do_del_request <= #`FF_DELAY 1'b0 ; + del_addr_hit <= #`FF_DELAY 1'b0 ; + del_completion_allow <= #`FF_DELAY 1'b0 ; + img_hit <= #`FF_DELAY 5'h00 ; + pref_en <= #`FF_DELAY 1'b0 ; + mrl_en <= #`FF_DELAY 1'b0 ; + map <= #`FF_DELAY 1'b0 ; + end + else + if (decode_en) + begin + img_wallow <= #`FF_DELAY wimg_wallow ; + wb_conf_hit <= #`FF_DELAY wb_conf_hit_in ; + do_del_request <= #`FF_DELAY wdo_del_request ; + del_addr_hit <= #`FF_DELAY wdel_addr_hit ; + del_completion_allow <= #`FF_DELAY wdel_completion_allow ; + img_hit <= #`FF_DELAY wb_hit_in ; + pref_en <= #`FF_DELAY wpref_en && cache_line_size_not_zero ; + mrl_en <= #`FF_DELAY wmrl_en && cache_line_size_not_zero ; + map <= #`FF_DELAY wmap ; + end +end + +wire del_burst = CAB_I && (pref_en || mrl_en) && ~WE_I && cache_line_size_not_zero ; // delayed burst indicator - only when WB master attempts CAB transfer and cache line size register is set appropriately and + // either prefetch enable or memory read line enable of corresponding image are set - + // applies for reads only - delayed write cannot be a burst +wire do_dread_completion = del_completion_allow && del_addr_hit ; + +`ifdef GUEST + + // wires indicating allowance for configuration cycle generation requests + wire do_ccyc_req = 1'b0 ; + wire do_ccyc_comp = 1'b0 ; + + // wires indicating allowance for interrupt acknowledge cycle generation requests + wire do_iack_req = 1'b0 ; + wire do_iack_comp = 1'b0 ; + + // variables for configuration access control signals + reg conf_wenable ; + assign wb_conf_wenable_out = 1'b0 ; + + // configuration cycle data register hit + wire ccyc_hit = 1'b0 ; + wire iack_hit = 1'b0 ; + + wire wccyc_hit = 1'b0 ; + wire wiack_hit = 1'b0 ; + +`else +`ifdef HOST + // only host implementation has access for generating interrupt acknowledge and configuration cycles + // configuration cycle data register hit + reg current_delayed_is_ccyc ; + reg current_delayed_is_iack ; + + wire wccyc_hit = (wb_addr_in[8:2] == {1'b1, `CNF_DATA_ADDR}) ; + + wire wiack_hit = (wb_addr_in[8:2] == {1'b1, `INT_ACK_ADDR}) ; + + reg iack_hit ; + reg ccyc_hit ; + always@(posedge reset_in or posedge wb_clock_in) + begin + if (reset_in) + begin + ccyc_hit <= #`FF_DELAY 1'b0 ; + iack_hit <= #`FF_DELAY 1'b0 ; + end + else + if (decode_en) + begin + ccyc_hit <= #`FF_DELAY wccyc_hit ; + iack_hit <= #`FF_DELAY wiack_hit ; + end + end + + // wires indicating allowance for configuration cycle generation requests + wire do_ccyc_req = do_del_request && ccyc_hit; + wire do_ccyc_comp = del_completion_allow && ccyc_hit && current_delayed_is_ccyc ; // && del_bc_hit + + // wires indicating allowance for interrupt acknowledge cycle generation requests + wire do_iack_req = do_del_request && iack_hit ; + wire do_iack_comp = del_completion_allow && iack_hit && current_delayed_is_iack ; // && del_bc_hit + + // variables for configuration access control signals + reg conf_wenable ; + + // following flip-flops remember whether current delayed transaction is interrupt acknowledge or configuration cycle transaction + always@(posedge wb_clock_in or posedge reset_in) + begin + if ( reset_in ) + begin + current_delayed_is_ccyc <= #`FF_DELAY 1'b0 ; + current_delayed_is_iack <= #`FF_DELAY 1'b0 ; + end + else + if ( del_done_out ) + begin + current_delayed_is_ccyc <= #`FF_DELAY 1'b0 ; + current_delayed_is_iack <= #`FF_DELAY 1'b0 ; + end + else + if ( del_req_out && wb_conf_hit ) + begin + current_delayed_is_ccyc <= #`FF_DELAY do_ccyc_req ; + current_delayed_is_iack <= #`FF_DELAY do_iack_req ; + end + end + +`endif +`endif + +// configuration read enable - supplied for host and guest bridges +reg conf_renable ; +assign wb_conf_renable_out = conf_renable ; + +// burst access indicator +wire burst_transfer = CYC_I && CAB_I ; + +// WBW_FIFO control output +reg [3:0] wbw_fifo_control ; + +// WBW_FIFO wenable output assignment +reg wbw_fifo_wenable ; + +// WBR_FIFO control outputs +reg wbr_fifo_flush, wbr_fifo_renable ; // flush and read enable outputs + +// flush signal for WBR_FIFO must be registered, since it asinchronously resets some status registers +wire wbr_fifo_flush_reg ; +pci_async_reset_flop async_reset_as_wbr_flush +( + .data_in (wbr_fifo_flush), + .clk_in (wb_clock_in), + .async_reset_data_out (wbr_fifo_flush_reg), + .reset_in (reset_in) +) ; +assign wbr_fifo_flush_out = wbr_fifo_flush_reg ; + +// delayed transaction request control signals +reg del_req, del_done ; + +// WISHBONE handshaking control outputs +reg ack, rty, err ; + +`ifdef REGISTER_WBS_OUTPUTS +// wire for write attempt - 1 when external WB master is attempting a write +// wire for read attempt - 1 when external master is attempting a read +wire wattempt = ( CYC_I && STB_I && WE_I ) && (!ACK_O && !ERR_O && !RTY_O) ; +wire rattempt = ( CYC_I && STB_I && ~WE_I ) && (!ACK_O && !ERR_O && !RTY_O) ; + +`else +// wire for write attempt - 1 when external WB master is attempting a write +// wire for read attempt - 1 when external master is attempting a read +wire wattempt = ( CYC_I && STB_I && WE_I ) ; // write is qualified when cycle, strobe and write enable inputs are all high +wire rattempt = ( CYC_I && STB_I && ~WE_I ) ; // read is qualified when cycle and strobe are high and write enable is low + +`endif +/*---------------------------------------------------------------------------------------------------------------------- +Delayed transaction bus command generation +Bus command for delayed reads depends on image's address space mapping and control bits and +whether or not these are interrupt acknowledge requests or configuration cycle requests +---------------------------------------------------------------------------------------------------------------------*/ + +always@(map or mrl_en or ccyc_hit or WE_I or wb_conf_hit or CAB_I or pref_en) +begin +`ifdef HOST +// only host implementation supports configuration and interrupt acknowledge commands + if (wb_conf_hit) + begin + case( {ccyc_hit, WE_I} ) + 2'b11: del_bc = `BC_CONF_WRITE ; + 2'b10: del_bc = `BC_CONF_READ ; + 2'b01: del_bc = `BC_RESERVED0 ; // invalid combination - interrupt acknowledge cycle must be a read + 2'b00: del_bc = `BC_IACK ; + endcase + end + else +`endif + begin + if ( map ) + begin + del_bc = `BC_IO_READ ; + end + else + begin + case ({(CAB_I && mrl_en), pref_en}) + 2'b00: del_bc = `BC_MEM_READ ; // if this is not burst transfer or memory read line command is disabled - use memory read + 2'b01: del_bc = `BC_MEM_READ ; // same as previous case + 2'b10: del_bc = `BC_MEM_READ_LN ; // burst transfer, memory read line command enabled, prefetch disabled - use memory read line command + 2'b11: del_bc = `BC_MEM_READ_MUL ; // same as previous case, except prefetch is enabled - use memory read multiple command + endcase + end + end +end + +reg del_in_progress ; // state machine indicates whether current read completion is in progress on WISHBONE bus + +wire image_access_error = (map && burst_transfer) ; // IO write is a burst + +`ifdef HOST + reg [1:0] wbw_data_out_sel ; + parameter SEL_ADDR_IN = 2'b10 ; + parameter SEL_CCYC_ADDR = 2'b11 ; + parameter SEL_DATA_IN = 2'b00 ; +`else +`ifdef GUEST + reg wbw_data_out_sel ; + parameter SEL_ADDR_IN = 1'b1 ; + parameter SEL_DATA_IN = 1'b0 ; +`endif +`endif + +`ifdef WB_DECODE_FAST + `ifdef REGISTER_WBS_OUTPUTS + `define PCI_WB_SLAVE_S_DEC1 + `endif +`endif + +`ifdef WB_DECODE_MEDIUM + `define PCI_WB_SLAVE_S_DEC1 +`endif + +`ifdef WB_DECODE_SLOW + `define PCI_WB_SLAVE_S_DEC1 + `define PCI_WB_SLAVE_S_DEC2 +`endif +// state machine logic +always@( + c_state or + wattempt or + img_wallow or + burst_transfer or + wb_hit or + map or + rattempt or + do_dread_completion or + wbr_fifo_control_in or + wb_conf_hit or + do_ccyc_req or + do_ccyc_comp or + ccyc_hit or + del_error_in or + do_iack_req or + do_iack_comp or + iack_hit or + image_access_error or + wbw_fifo_almost_full_in or + wbw_fifo_full_in or + do_del_request or + wbr_fifo_empty_in or + init_complete_in + ) +begin + // default signal values + // response signals inactive + ack = 1'b0 ; + rty = 1'b0 ; + err = 1'b0 ; + + //write signals inactive + wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b1 ; + wbw_fifo_control[`DATA_ERROR_CTRL_BIT] = 1'b0 ; + wbw_fifo_control[`LAST_CTRL_BIT] = 1'b0 ; + wbw_fifo_control[`UNUSED_CTRL_BIT] = 1'b0 ; + + wbw_fifo_wenable = 1'b0 ; + d_incoming_ena = 1'b0 ; + + // read signals inactive + wbr_fifo_flush = 1'b0 ; + wbr_fifo_renable = 1'b0 ; + del_req = 1'b0 ; + del_done = 1'b0 ; + + // configuration space control signals inactive + conf_wenable = 1'b0 ; + conf_renable = 1'b0 ; + + // read is not in progress + del_in_progress = 1'b0 ; + + decode_en = 1'b0 ; + + wbw_data_out_sel = SEL_ADDR_IN ; + + sample_address_out = 1'b0 ; + + case (c_state) + S_IDLE: begin + if ( (wattempt || rattempt) & init_complete_in ) + begin + + `ifdef PCI_WB_SLAVE_S_DEC1 + n_state = S_DEC1 ; + `else + decode_en = 1'b1 ; + n_state = S_START ; + `endif + + sample_address_out = 1'b1 ; + end + else + n_state = S_IDLE ; + end +`ifdef PCI_WB_SLAVE_S_DEC1 + S_DEC1: begin + if ( wattempt || rattempt ) + begin + + `ifdef PCI_WB_SLAVE_S_DEC2 + n_state = S_DEC2 ; + `else + decode_en = 1'b1 ; + n_state = S_START ; + `endif + + end + else + n_state = S_IDLE ; + end +`endif +`ifdef PCI_WB_SLAVE_S_DEC2 + S_DEC2: begin + + if ( wattempt || rattempt ) + begin + decode_en = 1'b1 ; + n_state = S_START ; + end + else + n_state = S_IDLE ; + end +`endif + S_START:begin + if (wb_conf_hit) // configuration space hit + begin + `ifdef HOST + wbw_data_out_sel = SEL_CCYC_ADDR ; + `endif + + if ( wattempt ) + n_state = S_CONF_WRITE ; // go to conf. write state + else + if ( rattempt ) + begin + n_state = S_CONF_READ ; // go to conf. read state + end + else + n_state = S_IDLE ; // master terminated - go back to idle state + + end // wb_conf_hit + else + if( wb_hit && (wattempt || rattempt) ) + begin + wbw_data_out_sel = SEL_DATA_IN ; + + // check error conditions for image writes or reads + if ( image_access_error ) + begin + n_state = S_IDLE ; // go back to idle state because of an error condition + err = 1'b1 ; + end // error conditions + else + // check for retry conditions for image writes or reads + if ( (wattempt && ~img_wallow) || + (rattempt && ~do_dread_completion) // write to image not allowed, no read ready yet - retry + ) + begin + n_state = S_IDLE ; // go back to IDLE + + rty = 1'b1 ; + + del_req = do_del_request && rattempt ; + + end //retry + else // everything OK - proceed + if ( wattempt ) + begin + n_state = S_W_ADDR_DATA ; // goto write transfer state + + // respond with acknowledge + ack = 1'b1 ; + + wbw_fifo_wenable = 1'b1 ; + + // data is latched to data incoming intermidiate stage - it will be put in FIFO later + d_incoming_ena = 1'b1 ; + end + else + begin + err = wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] ; + ack = ~wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] ; + wbr_fifo_renable = 1'b1 ; + del_in_progress = 1'b1 ; + + if ( wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] || wbr_fifo_control_in[`LAST_CTRL_BIT] ) + begin + + n_state = S_IDLE ; // go back to idle state + // respond that read is finished + del_done = 1'b1 ; + + end // end read + else + n_state = S_READ ; // go to read state + end + end + else + n_state = S_IDLE ; + + end + + S_W_ADDR_DATA: begin + wbw_data_out_sel = SEL_DATA_IN ; + err = 1'b0 ; + rty = burst_transfer && wattempt && (wbw_fifo_almost_full_in || wbw_fifo_full_in) ; + if ( ~burst_transfer || wattempt && ( wbw_fifo_almost_full_in || wbw_fifo_full_in ) ) + begin + n_state = S_IDLE ; + + // write last data to FIFO and don't latch new data + wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; + wbw_fifo_control[`LAST_CTRL_BIT] = 1'b1 ; + wbw_fifo_wenable = 1'b1 ; + end + else + begin + n_state = S_W_ADDR_DATA ; + wbw_fifo_control[`ADDR_CTRL_BIT] = 1'b0 ; + wbw_fifo_control[`LAST_CTRL_BIT] = 1'b0 ; + ack = wattempt ; + wbw_fifo_wenable = wattempt ; + d_incoming_ena = wattempt ; + end + end // S_W_ADDR_DATA + + S_READ:begin + // this state is for reads only - in this state read is in progress all the time + del_in_progress = 1'b1 ; + + ack = burst_transfer && rattempt && ~wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] && ~wbr_fifo_empty_in ; + err = burst_transfer && rattempt && wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] && ~wbr_fifo_empty_in ; + + // if acknowledge is beeing signalled then enable read from wbr fifo + wbr_fifo_renable = burst_transfer && rattempt && ~wbr_fifo_empty_in ; + + if ( ~burst_transfer || rattempt && (wbr_fifo_empty_in || wbr_fifo_control_in[`DATA_ERROR_CTRL_BIT] || wbr_fifo_control_in[`LAST_CTRL_BIT]) ) + begin + n_state = S_IDLE ; + del_done = 1'b1 ; + wbr_fifo_flush = ~wbr_fifo_empty_in ; + end + else + begin + n_state = S_READ ; + end + end // S_READ + + S_CONF_WRITE: begin + `ifdef HOST + wbw_data_out_sel = SEL_CCYC_ADDR ; + del_req = do_ccyc_req && ~burst_transfer ; + del_done = do_ccyc_comp && ~burst_transfer ; + del_in_progress = do_ccyc_comp && ~burst_transfer ; + `endif + + n_state = S_IDLE ; // next state after configuration access is always idle + + if ( burst_transfer ) + begin + err = 1'b1 ; + end + else + begin + `ifdef HOST + if ( do_ccyc_req || (ccyc_hit && ~do_ccyc_comp)) + begin + rty = 1'b1 ; + end + else + if ( do_ccyc_comp ) + begin + err = del_error_in ; + ack = ~del_error_in ; + end + else + begin + ack = ~ccyc_hit ; + conf_wenable = ~ccyc_hit ; + end + `else + ack = 1'b1 ; + conf_wenable = 1'b1 ; + `endif + end + end // S_CONF_WRITE + + S_CONF_READ: begin + `ifdef HOST + wbw_data_out_sel = SEL_CCYC_ADDR ; + del_req = ~burst_transfer && ( do_ccyc_req || do_iack_req ) ; + del_done = ~burst_transfer && ( do_ccyc_comp || do_iack_comp ) ; + del_in_progress = ~burst_transfer && ( do_ccyc_comp || do_iack_comp ) ; + wbr_fifo_renable = ~burst_transfer && ( do_ccyc_comp || do_iack_comp ) ; + `endif + + n_state = S_IDLE ; // next state after configuration access is always idle + + if ( burst_transfer ) + begin + err = 1'b1 ; + end + else + begin + `ifdef HOST + if ( do_ccyc_req || ( ccyc_hit && ~do_ccyc_comp )) + begin + rty = 1'b1 ; + end + else + if ( do_iack_req || ( iack_hit && ~do_iack_comp )) + begin + rty = 1'b1 ; + end + else + if ( do_iack_comp || do_ccyc_comp ) + begin + err = del_error_in ; + ack = ~del_error_in ; + end + else + begin + ack = ~( ccyc_hit || iack_hit ) ; + conf_renable = ~( ccyc_hit || iack_hit ) ; + end + `else + ack = 1'b1 ; + conf_renable = 1'b1 ; + `endif + end + end //S_CONF_READ + default:begin + n_state = S_IDLE ; // return to idle state + end //default + endcase +end + +// configuration space offset output assignment +assign wb_conf_offset_out = {wb_addr_in[11:2], 2'b00} ; // upper 10 bits of address input and two zeros + +// data output assignment - for image writes, first data is address, subsequent data comes from intermediate register +reg [31:0] wb_data ; +`ifdef HOST +reg [1:0] wbw_data_out_sel_reg ; +always@(posedge wb_clock_in or posedge reset_in) +begin + if ( reset_in ) + wbw_data_out_sel_reg <= #`FF_DELAY SEL_ADDR_IN ; + else + wbw_data_out_sel_reg <= #`FF_DELAY wbw_data_out_sel ; +end + +always@(wbw_data_out_sel_reg or wb_addr_in or ccyc_addr_in or d_incoming) +begin + case ( wbw_data_out_sel_reg ) + SEL_CCYC_ADDR: wb_data = ccyc_addr_in ; + SEL_DATA_IN: wb_data = d_incoming ; + default: wb_data = wb_addr_in ; + endcase +end +`else +`ifdef GUEST +reg wbw_data_out_sel_reg ; +always@(posedge wb_clock_in or posedge reset_in) +begin + if ( reset_in ) + wbw_data_out_sel_reg <= #`FF_DELAY SEL_ADDR_IN ; + else + wbw_data_out_sel_reg <= #`FF_DELAY wbw_data_out_sel ; +end + +always@(wbw_data_out_sel_reg or wb_addr_in or d_incoming) +begin + if ( wbw_data_out_sel_reg ) + wb_data = wb_addr_in ; + else + wb_data = d_incoming ; +end +`endif +`endif + +// command / byte enable assignment - with address, bus command is provided, with data - byte enables are provided +reg [3:0] wb_cbe ; + +always@(wbw_data_out_sel_reg or d_incoming or map) +begin + if (wbw_data_out_sel_reg && map) + wb_cbe = `BC_IO_WRITE ; + else + if (wbw_data_out_sel_reg) + wb_cbe = `BC_MEM_WRITE ; + else + wb_cbe = ~(d_incoming[35:32]) ; +end + +// for configuration writes, data output is always data from WISHBONE - in guest implementation data is all 0. +`ifdef GUEST + assign wb_conf_data_out = 32'h00000000 ; +`endif + +`ifdef GUEST + `ifdef NO_CNF_IMAGE + `else + `define PCI_WB_SLAVE_DO_OUT_MUX + `endif +`else +`ifdef HOST + `define PCI_WB_SLAVE_DO_OUT_MUX ; +`endif +`endif + +`ifdef PCI_WB_SLAVE_DO_OUT_MUX + reg [31:0] sdata_source ; + + // WISHBONE data output select lines for output multiplexor + wire sdata_o_sel_new = ( wb_conf_hit_in && ~wiack_hit && ~wccyc_hit ) ? CONF_SEL : WBR_SEL ; + reg sdata_o_sel ; + + always@(posedge wb_clock_in or posedge reset_in) + begin + if ( reset_in ) + sdata_o_sel <= #`FF_DELAY WBR_SEL ; + else + if ( decode_en ) + sdata_o_sel <= #`FF_DELAY sdata_o_sel_new ; + end + + always@(sdata_o_sel or wbr_fifo_data_in or wb_conf_data_in) + begin + case (sdata_o_sel) + WBR_SEL :sdata_source = wbr_fifo_data_in ; + CONF_SEL:sdata_source = wb_conf_data_in ; + endcase + end +`else + wire [31:0] sdata_source = wbr_fifo_data_in ; +`endif + +`ifdef REGISTER_WBS_OUTPUTS + +always@(posedge wb_clock_in or posedge reset_in) +begin + if ( reset_in ) + begin + ACK_O <= #`FF_DELAY 1'b0 ; + RTY_O <= #`FF_DELAY 1'b0 ; + ERR_O <= #`FF_DELAY 1'b0 ; + SDATA_O <= #`FF_DELAY 0 ; + del_write_out <= #`FF_DELAY 1'b0 ; + + `ifdef HOST + wb_conf_wenable_out <= #`FF_DELAY 1'b0 ; + wb_conf_data_out <= #`FF_DELAY 0 ; + `endif + + del_bc_out <= #`FF_DELAY `BC_RESERVED0 ; + del_req_out <= #`FF_DELAY 1'b0 ; + del_done_out <= #`FF_DELAY 1'b0 ; + del_burst_out <= #`FF_DELAY 1'b0 ; + del_in_progress_out <= #`FF_DELAY 1'b0 ; + wb_conf_be_out <= #`FF_DELAY 0 ; + wb_data_out <= #`FF_DELAY 0 ; + wb_cbe_out <= #`FF_DELAY 0 ; + wbw_fifo_wenable_out <= #`FF_DELAY 0 ; + wbw_fifo_control_out <= #`FF_DELAY 0 ; + wbr_fifo_renable_out <= #`FF_DELAY 0 ; + end + else + begin + ACK_O <= #`FF_DELAY ack && !ACK_O ; + RTY_O <= #`FF_DELAY rty && !RTY_O ; + ERR_O <= #`FF_DELAY err && !ERR_O ; + SDATA_O <= #`FF_DELAY sdata_source ; + del_write_out <= #`FF_DELAY WE_I ; + + `ifdef HOST + wb_conf_wenable_out <= #`FF_DELAY conf_wenable ; + wb_conf_data_out <= #`FF_DELAY SDATA_I ; + `endif + + del_bc_out <= #`FF_DELAY del_bc ; + del_req_out <= #`FF_DELAY del_req ; + del_done_out <= #`FF_DELAY del_done ; + del_burst_out <= #`FF_DELAY del_burst ; + del_in_progress_out <= #`FF_DELAY del_in_progress ; + wb_conf_be_out <= #`FF_DELAY SEL_I ; + wb_data_out <= #`FF_DELAY wb_data ; + wb_cbe_out <= #`FF_DELAY wb_cbe ; + wbw_fifo_wenable_out <= #`FF_DELAY wbw_fifo_wenable ; + wbw_fifo_control_out <= #`FF_DELAY wbw_fifo_control ; + wbr_fifo_renable_out <= #`FF_DELAY wbr_fifo_renable ; + end +end + +`else + +assign SDATA_O = sdata_source ; + +assign ACK_O = ack ; +assign RTY_O = rty ; +assign ERR_O = err ; + +// write operation indicator for delayed transaction requests +assign del_write_out = WE_I ; +assign del_bc_out = del_bc ; +assign del_req_out = del_req ; // read request +assign del_done_out = del_done ; // read done +assign del_burst_out = del_burst ; +assign del_in_progress_out = del_in_progress ; +`ifdef HOST +assign wb_conf_data_out = SDATA_I ; +assign wb_conf_wenable_out = conf_wenable ; +`endif +// Configuration space byte enables output +assign wb_conf_be_out = SEL_I ; // just route select lines from WISHBONE to conf space +assign wb_data_out = wb_data ; +assign wb_cbe_out = wb_cbe ; +assign wbw_fifo_wenable_out = wbw_fifo_wenable ; //write enable for WBW_FIFO +assign wbw_fifo_control_out = wbw_fifo_control ; //control bus output for WBW_FIFO +assign wbr_fifo_renable_out = wbr_fifo_renable ; //read enable for wbr_fifo +`endif + +endmodule //WB_SLAVE diff --git a/ethernet/source/pci/pci_wb_slave_unit.v b/ethernet/source/pci/pci_wb_slave_unit.v new file mode 100644 index 0000000..23ea1fa --- /dev/null +++ b/ethernet/source/pci/pci_wb_slave_unit.v @@ -0,0 +1,888 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "wb_slave_unit.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_wb_slave_unit.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2006/07/04 13:16:19 mihad +// Write burst performance patch applied. +// Not tested. Everything should be backwards +// compatible, since functional code is ifdefed. +// +// Revision 1.3 2004/01/24 11:54:18 mihad +// Update! SPOCI Implemented! +// +// Revision 1.2 2003/10/17 09:11:52 markom +// mbist signals updated according to newest convention +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.8 2002/10/18 03:36:37 tadejm +// Changed wrong signal name mbist_sen into mbist_ctrl_i. +// +// Revision 1.7 2002/10/17 22:49:22 tadejm +// Changed BIST signals for RAMs. +// +// Revision 1.6 2002/10/11 10:09:01 mihad +// Added additional testcase and changed rst name in BIST to trst +// +// Revision 1.5 2002/10/08 17:17:06 mihad +// Added BIST signals for RAMs. +// +// Revision 1.4 2002/09/25 15:53:52 mihad +// Removed all logic from asynchronous reset network +// +// Revision 1.3 2002/02/01 15:25:13 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:30 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +// Module instantiates and connects other modules lower in hierarcy +// Wishbone slave unit consists of modules that together form datapath +// between external WISHBONE masters and external PCI targets +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module pci_wb_slave_unit +( + reset_in, + wb_clock_in, + pci_clock_in, + ADDR_I, + SDATA_I, + SDATA_O, + CYC_I, + STB_I, + WE_I, + SEL_I, + ACK_O, + RTY_O, + ERR_O, + CAB_I, + wbu_map_in, + wbu_pref_en_in, + wbu_mrl_en_in, + wbu_pci_drcomp_pending_in, + wbu_conf_data_in, + wbu_pciw_empty_in, + wbu_bar0_in, + wbu_bar1_in, + wbu_bar2_in, + wbu_bar3_in, + wbu_bar4_in, + wbu_bar5_in, + wbu_am0_in, + wbu_am1_in, + wbu_am2_in, + wbu_am3_in, + wbu_am4_in, + wbu_am5_in, + wbu_ta0_in, + wbu_ta1_in, + wbu_ta2_in, + wbu_ta3_in, + wbu_ta4_in, + wbu_ta5_in, + wbu_at_en_in, + wbu_ccyc_addr_in , + wbu_master_enable_in, + wb_init_complete_in, + wbu_cache_line_size_not_zero, + wbu_cache_line_size_in, + wbu_pciif_gnt_in, + wbu_pciif_frame_in, + wbu_pciif_irdy_in, + wbu_pciif_trdy_in, + wbu_pciif_trdy_reg_in, + wbu_pciif_stop_in, + wbu_pciif_stop_reg_in, + wbu_pciif_devsel_in, + wbu_pciif_devsel_reg_in, + wbu_pciif_ad_reg_in, + wbu_pciif_req_out, + wbu_pciif_frame_out, + wbu_pciif_frame_en_out, + wbu_pciif_frame_en_in, + wbu_pciif_frame_out_in, + wbu_pciif_frame_load_out, + wbu_pciif_irdy_out, + wbu_pciif_irdy_en_out, + wbu_pciif_ad_out, + wbu_pciif_ad_en_out, + wbu_pciif_cbe_out, + wbu_pciif_cbe_en_out, + wbu_err_addr_out, + wbu_err_bc_out, + wbu_err_signal_out, + wbu_err_source_out, + wbu_err_rty_exp_out, + wbu_tabort_rec_out, + wbu_mabort_rec_out, + wbu_conf_offset_out, + wbu_conf_renable_out, + wbu_conf_wenable_out, + wbu_conf_be_out, + wbu_conf_data_out, + wbu_del_read_comp_pending_out, + wbu_wbw_fifo_empty_out, + wbu_latency_tim_val_in, + wbu_ad_load_out, + wbu_ad_load_on_transfer_out + +`ifdef PCI_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif +); + +input reset_in, + wb_clock_in, + pci_clock_in ; + +input [31:0] ADDR_I ; +input [31:0] SDATA_I ; +output [31:0] SDATA_O ; +input CYC_I ; +input STB_I ; +input WE_I ; +input [3:0] SEL_I ; +output ACK_O ; +output RTY_O ; +output ERR_O ; +input CAB_I ; + +input [5:0] wbu_map_in ; +input [5:0] wbu_pref_en_in ; +input [5:0] wbu_mrl_en_in ; + +input wbu_pci_drcomp_pending_in ; + +input [31:0] wbu_conf_data_in ; + +input wbu_pciw_empty_in ; + +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar0_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar1_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar2_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar3_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar4_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_bar5_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am0_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am1_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am2_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am3_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am4_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_am5_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta0_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta1_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta2_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta3_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta4_in ; +input [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] wbu_ta5_in ; +input [5:0] wbu_at_en_in ; + +input [23:0] wbu_ccyc_addr_in ; + +input wbu_master_enable_in ; +input wb_init_complete_in ; + +input wbu_cache_line_size_not_zero ; +input [7:0] wbu_cache_line_size_in ; + +input wbu_pciif_gnt_in ; +input wbu_pciif_frame_in ; +input wbu_pciif_frame_en_in ; +input wbu_pciif_irdy_in ; +input wbu_pciif_trdy_in; +input wbu_pciif_trdy_reg_in; +input wbu_pciif_stop_in ; +input wbu_pciif_stop_reg_in ; +input wbu_pciif_devsel_in ; +input wbu_pciif_devsel_reg_in ; +input [31:0] wbu_pciif_ad_reg_in ; + +output wbu_pciif_req_out ; +output wbu_pciif_frame_out ; +output wbu_pciif_frame_en_out ; +input wbu_pciif_frame_out_in ; +output wbu_pciif_frame_load_out ; +output wbu_pciif_irdy_out ; +output wbu_pciif_irdy_en_out ; +output [31:0] wbu_pciif_ad_out ; +output wbu_pciif_ad_en_out ; +output [3:0] wbu_pciif_cbe_out ; +output wbu_pciif_cbe_en_out ; + +output [31:0] wbu_err_addr_out ; +output [3:0] wbu_err_bc_out ; +output wbu_err_signal_out ; +output wbu_err_source_out ; +output wbu_err_rty_exp_out ; +output wbu_tabort_rec_out ; +output wbu_mabort_rec_out ; + +output [11:0] wbu_conf_offset_out ; +output wbu_conf_renable_out ; +output wbu_conf_wenable_out ; +output [3:0] wbu_conf_be_out ; +output [31:0] wbu_conf_data_out ; + +output wbu_del_read_comp_pending_out ; +output wbu_wbw_fifo_empty_out ; + +input [7:0] wbu_latency_tim_val_in ; + +output wbu_ad_load_out ; +output wbu_ad_load_on_transfer_out ; + +`ifdef PCI_BIST +/*----------------------------------------------------- +BIST debug chain port signals +-----------------------------------------------------*/ +input mbist_si_i; // bist scan serial in +output mbist_so_o; // bist scan serial out +input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + +// pci master interface outputs +wire [31:0] pcim_if_address_out ; +wire [3:0] pcim_if_bc_out ; +wire [31:0] pcim_if_data_out ; +wire [3:0] pcim_if_be_out ; +wire pcim_if_req_out ; +wire pcim_if_rdy_out ; +wire pcim_if_last_out ; +wire pcim_if_wbw_renable_out ; +wire pcim_if_wbr_wenable_out ; +wire [31:0] pcim_if_wbr_data_out ; +wire [3:0] pcim_if_wbr_be_out ; +wire [3:0] pcim_if_wbr_control_out ; +wire pcim_if_del_complete_out ; +wire pcim_if_del_error_out ; +wire pcim_if_del_rty_exp_out ; +wire [31:0] pcim_if_err_addr_out ; +wire [3:0] pcim_if_err_bc_out ; +wire pcim_if_err_signal_out ; +wire pcim_if_err_source_out ; +wire pcim_if_err_rty_exp_out ; +wire pcim_if_tabort_out ; +wire pcim_if_mabort_out ; +wire [31:0] pcim_if_next_data_out ; +wire [3:0] pcim_if_next_be_out ; +wire pcim_if_next_last_out ; +wire pcim_if_posted_write_not_present_out ; + + + +wire pcim_sm_req_out ; +wire pcim_sm_frame_out ; +wire pcim_sm_frame_en_out ; +wire pcim_sm_irdy_out ; +wire pcim_sm_irdy_en_out ; +wire [31:0] pcim_sm_ad_out ; +wire pcim_sm_ad_en_out ; +wire [3:0] pcim_sm_cbe_out ; +wire pcim_sm_cbe_en_out ; +wire pcim_sm_ad_load_out ; +wire pcim_sm_ad_load_on_transfer_out ; + +wire pcim_sm_wait_out ; +wire pcim_sm_wtransfer_out ; +wire pcim_sm_rtransfer_out ; +wire pcim_sm_retry_out ; +wire pcim_sm_rerror_out ; +wire pcim_sm_first_out ; +wire pcim_sm_mabort_out ; +wire pcim_sm_frame_load_out ; + +assign wbu_pciif_frame_load_out = pcim_sm_frame_load_out ; + +assign wbu_err_addr_out = pcim_if_err_addr_out ; +assign wbu_err_bc_out = pcim_if_err_bc_out ; +assign wbu_err_signal_out = pcim_if_err_signal_out ; +assign wbu_err_source_out = pcim_if_err_source_out ; +assign wbu_err_rty_exp_out = pcim_if_err_rty_exp_out ; +assign wbu_tabort_rec_out = pcim_if_tabort_out ; +assign wbu_mabort_rec_out = pcim_if_mabort_out ; + +assign wbu_wbw_fifo_empty_out = pcim_if_posted_write_not_present_out ; + +// pci master state machine outputs +// pci interface signals +assign wbu_pciif_req_out = pcim_sm_req_out ; +assign wbu_pciif_frame_out = pcim_sm_frame_out ; +assign wbu_pciif_frame_en_out = pcim_sm_frame_en_out ; +assign wbu_pciif_irdy_out = pcim_sm_irdy_out ; +assign wbu_pciif_irdy_en_out = pcim_sm_irdy_en_out ; +assign wbu_pciif_ad_out = pcim_sm_ad_out ; +assign wbu_pciif_ad_en_out = pcim_sm_ad_en_out ; +assign wbu_pciif_cbe_out = pcim_sm_cbe_out ; +assign wbu_pciif_cbe_en_out = pcim_sm_cbe_en_out ; +assign wbu_ad_load_out = pcim_sm_ad_load_out ; +assign wbu_ad_load_on_transfer_out = pcim_sm_ad_load_on_transfer_out ; + +// signals to internal of the core +wire [31:0] pcim_sm_data_out ; + +// wishbone slave state machine outputs +wire [3:0] wbs_sm_del_bc_out ; +wire wbs_sm_del_req_out ; +wire wbs_sm_del_done_out ; +wire wbs_sm_del_burst_out ; +wire wbs_sm_del_write_out ; +wire [11:0] wbs_sm_conf_offset_out ; +wire wbs_sm_conf_renable_out ; +wire wbs_sm_conf_wenable_out ; +wire [3:0] wbs_sm_conf_be_out ; +wire [31:0] wbs_sm_conf_data_out ; +wire [31:0] wbs_sm_data_out ; +wire [3:0] wbs_sm_cbe_out ; +wire wbs_sm_wbw_wenable_out ; +wire [3:0] wbs_sm_wbw_control_out ; +wire wbs_sm_wbr_renable_out ; +wire wbs_sm_wbr_flush_out ; +wire wbs_sm_del_in_progress_out ; +wire [31:0] wbs_sm_sdata_out ; +wire wbs_sm_ack_out ; +wire wbs_sm_rty_out ; +wire wbs_sm_err_out ; +wire wbs_sm_sample_address_out ; + +assign wbu_conf_offset_out = wbs_sm_conf_offset_out ; +assign wbu_conf_renable_out = wbs_sm_conf_renable_out ; +assign wbu_conf_wenable_out = wbs_sm_conf_wenable_out ; +assign wbu_conf_be_out = ~wbs_sm_conf_be_out ; +assign wbu_conf_data_out = wbs_sm_conf_data_out ; + +assign SDATA_O = wbs_sm_sdata_out ; +assign ACK_O = wbs_sm_ack_out ; +assign RTY_O = wbs_sm_rty_out ; +assign ERR_O = wbs_sm_err_out ; + + +// wbw_wbr fifo outputs + +// wbw_fifo_outputs: +wire [31:0] fifos_wbw_addr_data_out ; +wire [3:0] fifos_wbw_cbe_out ; +wire [3:0] fifos_wbw_control_out ; +wire fifos_wbw_almost_full_out ; +wire fifos_wbw_full_out ; +wire fifos_wbw_half_full_out; //Robert, burst issue +wire fifos_wbw_empty_out ; +wire fifos_wbw_transaction_ready_out ; + +// wbr_fifo_outputs +wire [31:0] fifos_wbr_data_out ; +wire [3:0] fifos_wbr_be_out ; +wire [3:0] fifos_wbr_control_out ; +wire fifos_wbr_empty_out ; + +// address multiplexer outputs +wire [5:0] amux_hit_out ; +wire [31:0] amux_address_out ; + +// delayed transaction logic outputs +wire [31:0] del_sync_addr_out ; +wire [3:0] del_sync_be_out ; +wire del_sync_we_out ; +wire del_sync_comp_req_pending_out ; +wire del_sync_comp_comp_pending_out ; +wire del_sync_req_req_pending_out ; +wire del_sync_req_comp_pending_out ; +wire [3:0] del_sync_bc_out ; +wire del_sync_status_out ; +wire del_sync_comp_flush_out ; +wire del_sync_burst_out ; + +assign wbu_del_read_comp_pending_out = del_sync_comp_comp_pending_out ; + +// delayed write storage output +wire [31:0] del_write_data_out ; + +// config. cycle address decoder output +wire [31:0] ccyc_addr_out ; + + +// WISHBONE slave interface inputs +wire [4:0] wbs_sm_hit_in = amux_hit_out[5:1] ; +wire wbs_sm_conf_hit_in = amux_hit_out[0] ; +wire [4:0] wbs_sm_map_in = wbu_map_in[5:1] ; +wire [4:0] wbs_sm_pref_en_in = wbu_pref_en_in[5:1] ; +wire [4:0] wbs_sm_mrl_en_in = wbu_mrl_en_in[5:1] ; +wire [31:0] wbs_sm_addr_in = amux_address_out ; +wire [3:0] wbs_sm_del_bc_in = del_sync_bc_out ; +wire wbs_sm_del_req_pending_in = del_sync_req_req_pending_out ; +wire wbs_sm_wb_del_comp_pending_in = del_sync_req_comp_pending_out ; +wire wbs_sm_pci_drcomp_pending_in = wbu_pci_drcomp_pending_in ; +wire wbs_sm_del_write_in = del_sync_we_out ; +wire wbs_sm_del_error_in = del_sync_status_out ; +wire [31:0] wbs_sm_del_addr_in = del_sync_addr_out ; +wire [3:0] wbs_sm_del_be_in = del_sync_be_out ; +wire [31:0] wbs_sm_conf_data_in = wbu_conf_data_in ; +wire wbs_sm_wbw_almost_full_in = fifos_wbw_almost_full_out ; +wire wbs_sm_wbw_full_in = fifos_wbw_full_out ; +wire wbs_sm_wbw_half_full_in = fifos_wbw_half_full_out; ////Robert, burst issue +wire [3:0] wbs_sm_wbr_be_in = fifos_wbr_be_out ; +wire [31:0] wbs_sm_wbr_data_in = fifos_wbr_data_out ; +wire [3:0] wbs_sm_wbr_control_in = fifos_wbr_control_out ; +wire wbs_sm_wbr_empty_in = fifos_wbr_empty_out ; +wire wbs_sm_pciw_empty_in = wbu_pciw_empty_in ; +wire wbs_sm_lock_in = ~wbu_master_enable_in ; +wire wbs_sm_cache_line_size_not_zero = wbu_cache_line_size_not_zero ; +wire wbs_sm_cyc_in = CYC_I ; +wire wbs_sm_stb_in = STB_I ; +wire wbs_sm_we_in = WE_I ; +wire [3:0] wbs_sm_sel_in = SEL_I ; +wire [31:0] wbs_sm_sdata_in = SDATA_I ; +wire wbs_sm_cab_in = CAB_I ; +wire [31:0] wbs_sm_ccyc_addr_in = ccyc_addr_out ; +wire wbs_sm_init_complete_in = wb_init_complete_in ; + +// WISHBONE slave interface instantiation +pci_wb_slave wishbone_slave( + .wb_clock_in (wb_clock_in) , + .reset_in (reset_in) , + .wb_hit_in (wbs_sm_hit_in) , + .wb_conf_hit_in (wbs_sm_conf_hit_in) , + .wb_map_in (wbs_sm_map_in) , + .wb_pref_en_in (wbs_sm_pref_en_in) , + .wb_mrl_en_in (wbs_sm_mrl_en_in) , + .wb_addr_in (wbs_sm_addr_in), + .del_bc_in (wbs_sm_del_bc_in), + .wb_del_req_pending_in (wbs_sm_del_req_pending_in), + .wb_del_comp_pending_in (wbs_sm_wb_del_comp_pending_in), + .pci_drcomp_pending_in (wbs_sm_pci_drcomp_pending_in), + .del_bc_out (wbs_sm_del_bc_out), + .del_req_out (wbs_sm_del_req_out), + .del_done_out (wbs_sm_del_done_out), + .del_burst_out (wbs_sm_del_burst_out), + .del_write_out (wbs_sm_del_write_out), + .del_write_in (wbs_sm_del_write_in), + .del_error_in (wbs_sm_del_error_in), + .wb_del_addr_in (wbs_sm_del_addr_in), + .wb_del_be_in (wbs_sm_del_be_in), + .wb_conf_offset_out (wbs_sm_conf_offset_out), + .wb_conf_renable_out (wbs_sm_conf_renable_out), + .wb_conf_wenable_out (wbs_sm_conf_wenable_out), + .wb_conf_be_out (wbs_sm_conf_be_out), + .wb_conf_data_in (wbs_sm_conf_data_in), + .wb_conf_data_out (wbs_sm_conf_data_out), + .wb_data_out (wbs_sm_data_out), + .wb_cbe_out (wbs_sm_cbe_out), + .wbw_fifo_wenable_out (wbs_sm_wbw_wenable_out), + .wbw_fifo_control_out (wbs_sm_wbw_control_out), + .wbw_fifo_almost_full_in (wbs_sm_wbw_almost_full_in), + .wbw_fifo_full_in (wbs_sm_wbw_full_in), + .wbw_fifo_half_full_in (wbs_sm_wbw_half_full_in), ////Robert, burst issue + .wbr_fifo_renable_out (wbs_sm_wbr_renable_out), + .wbr_fifo_be_in (wbs_sm_wbr_be_in), + .wbr_fifo_data_in (wbs_sm_wbr_data_in), + .wbr_fifo_control_in (wbs_sm_wbr_control_in), + .wbr_fifo_flush_out (wbs_sm_wbr_flush_out), + .wbr_fifo_empty_in (wbs_sm_wbr_empty_in), + .pciw_fifo_empty_in (wbs_sm_pciw_empty_in), + .wbs_lock_in (wbs_sm_lock_in), + .init_complete_in (wbs_sm_init_complete_in), + .cache_line_size_not_zero (wbs_sm_cache_line_size_not_zero), + .del_in_progress_out (wbs_sm_del_in_progress_out), + .ccyc_addr_in (wbs_sm_ccyc_addr_in), + .sample_address_out (wbs_sm_sample_address_out), + .CYC_I (wbs_sm_cyc_in), + .STB_I (wbs_sm_stb_in), + .WE_I (wbs_sm_we_in), + .SEL_I (wbs_sm_sel_in), + .SDATA_I (wbs_sm_sdata_in), + .SDATA_O (wbs_sm_sdata_out), + .ACK_O (wbs_sm_ack_out), + .RTY_O (wbs_sm_rty_out), + .ERR_O (wbs_sm_err_out), + .CAB_I (wbs_sm_cab_in) + ); + +// wbw_wbr_fifos inputs +// WBW_FIFO inputs +wire fifos_wbw_wenable_in = wbs_sm_wbw_wenable_out; +wire [31:0] fifos_wbw_addr_data_in = wbs_sm_data_out ; +wire [3:0] fifos_wbw_cbe_in = wbs_sm_cbe_out ; +wire [3:0] fifos_wbw_control_in = wbs_sm_wbw_control_out ; +wire fifos_wbw_renable_in = pcim_if_wbw_renable_out ; + +//wire fifos_wbw_flush_in = 1'b0 ; flush for write fifo not used + +// WBR_FIFO inputs +wire fifos_wbr_wenable_in = pcim_if_wbr_wenable_out ; +wire [31:0] fifos_wbr_data_in = pcim_if_wbr_data_out ; +wire [3:0] fifos_wbr_be_in = pcim_if_wbr_be_out ; +wire [3:0] fifos_wbr_control_in = pcim_if_wbr_control_out ; +wire fifos_wbr_renable_in = wbs_sm_wbr_renable_out ; +wire fifos_wbr_flush_in = wbs_sm_wbr_flush_out || del_sync_comp_flush_out ; + +// WBW_FIFO and WBR_FIFO instantiation +pci_wbw_wbr_fifos fifos +( + .wb_clock_in (wb_clock_in), + .pci_clock_in (pci_clock_in), + .reset_in (reset_in), + .wbw_wenable_in (fifos_wbw_wenable_in), + .wbw_addr_data_in (fifos_wbw_addr_data_in), + .wbw_cbe_in (fifos_wbw_cbe_in), + .wbw_control_in (fifos_wbw_control_in), + .wbw_renable_in (fifos_wbw_renable_in), + .wbw_addr_data_out (fifos_wbw_addr_data_out), + .wbw_cbe_out (fifos_wbw_cbe_out), + .wbw_control_out (fifos_wbw_control_out), +// .wbw_flush_in (fifos_wbw_flush_in), // flush for write fifo not used + .wbw_almost_full_out (fifos_wbw_almost_full_out), + .wbw_full_out (fifos_wbw_full_out), + .wbw_empty_out (fifos_wbw_empty_out), + .wbw_transaction_ready_out (fifos_wbw_transaction_ready_out), + .wbw_half_full_out (fifos_wbw_half_full_out),////Robert, burst issue + .wbr_wenable_in (fifos_wbr_wenable_in), + .wbr_data_in (fifos_wbr_data_in), + .wbr_be_in (fifos_wbr_be_in), + .wbr_control_in (fifos_wbr_control_in), + .wbr_renable_in (fifos_wbr_renable_in), + .wbr_data_out (fifos_wbr_data_out), + .wbr_be_out (fifos_wbr_be_out), + .wbr_control_out (fifos_wbr_control_out), + .wbr_flush_in (fifos_wbr_flush_in), + .wbr_empty_out (fifos_wbr_empty_out) + +`ifdef PCI_BIST + , + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) +`endif +) ; + +wire [31:0] amux_addr_in = ADDR_I ; +wire amux_sample_address_in = wbs_sm_sample_address_out ; + +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar0_in = wbu_bar0_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar1_in = wbu_bar1_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar2_in = wbu_bar2_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar3_in = wbu_bar3_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar4_in = wbu_bar4_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_bar5_in = wbu_bar5_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am0_in = wbu_am0_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am1_in = wbu_am1_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am2_in = wbu_am2_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am3_in = wbu_am3_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am4_in = wbu_am4_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_am5_in = wbu_am5_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta0_in = wbu_ta0_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta1_in = wbu_ta1_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta2_in = wbu_ta2_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta3_in = wbu_ta3_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta4_in = wbu_ta4_in ; +wire [(`WB_NUM_OF_DEC_ADDR_LINES - 1):0] amux_ta5_in = wbu_ta5_in ; +wire [5:0] amux_at_en_in = wbu_at_en_in ; + +pci_wb_addr_mux wb_addr_dec +( + `ifdef REGISTER_WBS_OUTPUTS + .clk_in (wb_clock_in), + .reset_in (reset_in), + .sample_address_in (amux_sample_address_in), + `endif + .address_in (amux_addr_in), + .bar0_in (amux_bar0_in), + .bar1_in (amux_bar1_in), + .bar2_in (amux_bar2_in), + .bar3_in (amux_bar3_in), + .bar4_in (amux_bar4_in), + .bar5_in (amux_bar5_in), + .am0_in (amux_am0_in), + .am1_in (amux_am1_in), + .am2_in (amux_am2_in), + .am3_in (amux_am3_in), + .am4_in (amux_am4_in), + .am5_in (amux_am5_in), + .ta0_in (amux_ta0_in), + .ta1_in (amux_ta1_in), + .ta2_in (amux_ta2_in), + .ta3_in (amux_ta3_in), + .ta4_in (amux_ta4_in), + .ta5_in (amux_ta5_in), + .at_en_in (amux_at_en_in), + .hit_out (amux_hit_out), + .address_out (amux_address_out) +); + +// delayed transaction logic inputs +wire del_sync_req_in = wbs_sm_del_req_out ; +wire del_sync_comp_in = pcim_if_del_complete_out ; +wire del_sync_done_in = wbs_sm_del_done_out ; +wire del_sync_in_progress_in = wbs_sm_del_in_progress_out ; +wire [31:0] del_sync_addr_in = wbs_sm_data_out ; +wire [3:0] del_sync_be_in = wbs_sm_conf_be_out ; +wire del_sync_we_in = wbs_sm_del_write_out ; +wire [3:0] del_sync_bc_in = wbs_sm_del_bc_out ; +wire del_sync_status_in = pcim_if_del_error_out ; +wire del_sync_burst_in = wbs_sm_del_burst_out ; +wire del_sync_retry_expired_in = pcim_if_del_rty_exp_out ; + +// delayed transaction logic instantiation +pci_delayed_sync del_sync ( + .reset_in (reset_in), + .req_clk_in (wb_clock_in), + .comp_clk_in (pci_clock_in), + .req_in (del_sync_req_in), + .comp_in (del_sync_comp_in), + .done_in (del_sync_done_in), + .in_progress_in (del_sync_in_progress_in), + .comp_req_pending_out (del_sync_comp_req_pending_out), + .comp_comp_pending_out(del_sync_comp_comp_pending_out), + .req_req_pending_out (del_sync_req_req_pending_out), + .req_comp_pending_out (del_sync_req_comp_pending_out), + .addr_in (del_sync_addr_in), + .be_in (del_sync_be_in), + .addr_out (del_sync_addr_out), + .be_out (del_sync_be_out), + .we_in (del_sync_we_in), + .we_out (del_sync_we_out), + .bc_in (del_sync_bc_in), + .bc_out (del_sync_bc_out), + .status_in (del_sync_status_in), + .status_out (del_sync_status_out), + .comp_flush_out (del_sync_comp_flush_out), + .burst_in (del_sync_burst_in), + .burst_out (del_sync_burst_out), + .retry_expired_in (del_sync_retry_expired_in) + ); + +// delayed write storage inputs +wire del_write_we_in = wbs_sm_del_req_out && wbs_sm_del_write_out ; +wire [31:0] del_write_data_in = wbs_sm_conf_data_out ; + +pci_delayed_write_reg delayed_write_data +( + .reset_in (reset_in), + .req_clk_in (wb_clock_in), + .comp_wdata_out (del_write_data_out), + .req_we_in (del_write_we_in), + .req_wdata_in (del_write_data_in) +); + +`ifdef HOST + // configuration cycle address decoder input + wire [31:0] ccyc_addr_in = {8'h00, wbu_ccyc_addr_in} ; + + pci_conf_cyc_addr_dec ccyc_addr_dec + ( + .ccyc_addr_in (ccyc_addr_in), + .ccyc_addr_out (ccyc_addr_out) + ) ; +`else +`ifdef GUEST + assign ccyc_addr_out = 32'h0000_0000 ; +`endif +`endif + +// pci master interface inputs +wire [31:0] pcim_if_wbw_addr_data_in = fifos_wbw_addr_data_out ; +wire [3:0] pcim_if_wbw_cbe_in = fifos_wbw_cbe_out ; +wire [3:0] pcim_if_wbw_control_in = fifos_wbw_control_out ; +wire pcim_if_wbw_empty_in = fifos_wbw_empty_out ; +wire pcim_if_wbw_transaction_ready_in = fifos_wbw_transaction_ready_out ; +wire [31:0] pcim_if_data_in = pcim_sm_data_out ; +wire [31:0] pcim_if_del_wdata_in = del_write_data_out ; +wire pcim_if_del_req_in = del_sync_comp_req_pending_out ; +wire [31:0] pcim_if_del_addr_in = del_sync_addr_out ; +wire [3:0] pcim_if_del_bc_in = del_sync_bc_out ; +wire [3:0] pcim_if_del_be_in = del_sync_be_out ; +wire pcim_if_del_burst_in = del_sync_burst_out ; +wire pcim_if_del_we_in = del_sync_we_out ; +wire [7:0] pcim_if_cache_line_size_in = wbu_cache_line_size_in ; +wire pcim_if_wait_in = pcim_sm_wait_out ; +wire pcim_if_wtransfer_in = pcim_sm_wtransfer_out ; +wire pcim_if_rtransfer_in = pcim_sm_rtransfer_out ; +wire pcim_if_retry_in = pcim_sm_retry_out ; +wire pcim_if_rerror_in = pcim_sm_rerror_out ; +wire pcim_if_first_in = pcim_sm_first_out ; +wire pcim_if_mabort_in = pcim_sm_mabort_out ; + +pci_master32_sm_if pci_initiator_if +( + .clk_in (pci_clock_in), + .reset_in (reset_in), + .address_out (pcim_if_address_out), + .bc_out (pcim_if_bc_out), + .data_out (pcim_if_data_out), + .data_in (pcim_if_data_in), + .be_out (pcim_if_be_out), + .req_out (pcim_if_req_out), + .rdy_out (pcim_if_rdy_out), + .last_out (pcim_if_last_out), + .wbw_renable_out (pcim_if_wbw_renable_out), + .wbw_fifo_addr_data_in (pcim_if_wbw_addr_data_in), + .wbw_fifo_cbe_in (pcim_if_wbw_cbe_in), + .wbw_fifo_control_in (pcim_if_wbw_control_in), + .wbw_fifo_empty_in (pcim_if_wbw_empty_in), + .wbw_fifo_transaction_ready_in (pcim_if_wbw_transaction_ready_in), + .wbr_fifo_wenable_out (pcim_if_wbr_wenable_out), + .wbr_fifo_data_out (pcim_if_wbr_data_out), + .wbr_fifo_be_out (pcim_if_wbr_be_out), + .wbr_fifo_control_out (pcim_if_wbr_control_out), + .del_wdata_in (pcim_if_del_wdata_in), + .del_complete_out (pcim_if_del_complete_out), + .del_req_in (pcim_if_del_req_in), + .del_addr_in (pcim_if_del_addr_in), + .del_bc_in (pcim_if_del_bc_in), + .del_be_in (pcim_if_del_be_in), + .del_burst_in (pcim_if_del_burst_in), + .del_error_out (pcim_if_del_error_out), + .del_rty_exp_out (pcim_if_del_rty_exp_out), + .del_we_in (pcim_if_del_we_in), + .err_addr_out (pcim_if_err_addr_out), + .err_bc_out (pcim_if_err_bc_out), + .err_signal_out (pcim_if_err_signal_out), + .err_source_out (pcim_if_err_source_out), + .err_rty_exp_out (pcim_if_err_rty_exp_out), + .cache_line_size_in (pcim_if_cache_line_size_in), + .mabort_received_out (pcim_if_mabort_out), + .tabort_received_out (pcim_if_tabort_out), + .next_data_out (pcim_if_next_data_out), + .next_be_out (pcim_if_next_be_out), + .next_last_out (pcim_if_next_last_out), + .wait_in (pcim_if_wait_in), + .wtransfer_in (pcim_if_wtransfer_in), + .rtransfer_in (pcim_if_rtransfer_in), + .retry_in (pcim_if_retry_in), + .rerror_in (pcim_if_rerror_in), + .first_in (pcim_if_first_in), + .mabort_in (pcim_if_mabort_in), + .posted_write_not_present_out (pcim_if_posted_write_not_present_out) +); + +// pci master state machine inputs +wire pcim_sm_gnt_in = wbu_pciif_gnt_in ; +wire pcim_sm_frame_in = wbu_pciif_frame_in ; +wire pcim_sm_irdy_in = wbu_pciif_irdy_in ; +wire pcim_sm_trdy_in = wbu_pciif_trdy_in; +wire pcim_sm_stop_in = wbu_pciif_stop_in ; +wire pcim_sm_devsel_in = wbu_pciif_devsel_in ; +wire [31:0] pcim_sm_ad_reg_in = wbu_pciif_ad_reg_in ; +wire [31:0] pcim_sm_address_in = pcim_if_address_out ; +wire [3:0] pcim_sm_bc_in = pcim_if_bc_out ; +wire [31:0] pcim_sm_data_in = pcim_if_data_out ; +wire [3:0] pcim_sm_be_in = pcim_if_be_out ; +wire pcim_sm_req_in = pcim_if_req_out ; +wire pcim_sm_rdy_in = pcim_if_rdy_out ; +wire pcim_sm_last_in = pcim_if_last_out ; +wire [7:0] pcim_sm_latency_tim_val_in = wbu_latency_tim_val_in ; +wire [31:0] pcim_sm_next_data_in = pcim_if_next_data_out ; +wire [3:0] pcim_sm_next_be_in = pcim_if_next_be_out ; +wire pcim_sm_next_last_in = pcim_if_next_last_out ; +wire pcim_sm_trdy_reg_in = wbu_pciif_trdy_reg_in ; +wire pcim_sm_stop_reg_in = wbu_pciif_stop_reg_in ; +wire pcim_sm_devsel_reg_in = wbu_pciif_devsel_reg_in ; +wire pcim_sm_frame_en_in = wbu_pciif_frame_en_in ; +wire pcim_sm_frame_out_in = wbu_pciif_frame_out_in ; + +pci_master32_sm pci_initiator_sm +( + .clk_in (pci_clock_in), + .reset_in (reset_in), + .pci_req_out (pcim_sm_req_out), + .pci_gnt_in (pcim_sm_gnt_in), + .pci_frame_in (pcim_sm_frame_in), + .pci_frame_out (pcim_sm_frame_out), + .pci_frame_en_out (pcim_sm_frame_en_out), + .pci_frame_out_in (pcim_sm_frame_out_in), + .pci_frame_load_out (pcim_sm_frame_load_out), + .pci_frame_en_in (pcim_sm_frame_en_in), + .pci_irdy_in (pcim_sm_irdy_in), + .pci_irdy_out (pcim_sm_irdy_out), + .pci_irdy_en_out (pcim_sm_irdy_en_out), + .pci_trdy_in (pcim_sm_trdy_in), + .pci_trdy_reg_in (pcim_sm_trdy_reg_in), + .pci_stop_in (pcim_sm_stop_in), + .pci_stop_reg_in (pcim_sm_stop_reg_in), + .pci_devsel_in (pcim_sm_devsel_in), + .pci_devsel_reg_in (pcim_sm_devsel_reg_in), + .pci_ad_reg_in (pcim_sm_ad_reg_in), + .pci_ad_out (pcim_sm_ad_out), + .pci_ad_en_out (pcim_sm_ad_en_out), + .pci_cbe_out (pcim_sm_cbe_out), + .pci_cbe_en_out (pcim_sm_cbe_en_out), + .address_in (pcim_sm_address_in), + .bc_in (pcim_sm_bc_in), + .data_in (pcim_sm_data_in), + .data_out (pcim_sm_data_out), + .be_in (pcim_sm_be_in), + .req_in (pcim_sm_req_in), + .rdy_in (pcim_sm_rdy_in), + .last_in (pcim_sm_last_in), + .latency_tim_val_in (pcim_sm_latency_tim_val_in), + .next_data_in (pcim_sm_next_data_in), + .next_be_in (pcim_sm_next_be_in), + .next_last_in (pcim_sm_next_last_in), + .ad_load_out (pcim_sm_ad_load_out), + .ad_load_on_transfer_out (pcim_sm_ad_load_on_transfer_out), + .wait_out (pcim_sm_wait_out), + .wtransfer_out (pcim_sm_wtransfer_out), + .rtransfer_out (pcim_sm_rtransfer_out), + .retry_out (pcim_sm_retry_out), + .rerror_out (pcim_sm_rerror_out), + .first_out (pcim_sm_first_out), + .mabort_out (pcim_sm_mabort_out) +) ; + +endmodule diff --git a/ethernet/source/pci/pci_wb_tpram.v b/ethernet/source/pci/pci_wb_tpram.v new file mode 100644 index 0000000..196c6e1 --- /dev/null +++ b/ethernet/source/pci/pci_wb_tpram.v @@ -0,0 +1,468 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// Generic Two-Port Synchronous RAM //// +//// //// +//// This file is part of pci bridge project //// +//// http://www.opencores.org/cvsweb.shtml/pci/ //// +//// //// +//// Description //// +//// This block is a wrapper with common two-port //// +//// synchronous memory interface for different //// +//// types of ASIC and FPGA RAMs. Beside universal memory //// +//// interface it also provides behavioral model of generic //// +//// two-port synchronous RAM. //// +//// It should be used in all OPENCORES designs that want to be //// +//// portable accross different target technologies and //// +//// independent of target memory. //// +//// //// +//// Supported ASIC RAMs are: //// +//// - Artisan Double-Port Sync RAM //// +//// - Avant! Two-Port Sync RAM (*) //// +//// - Virage 2-port Sync RAM //// +//// //// +//// Supported FPGA RAMs are: //// +//// - Xilinx Virtex RAMB4_S16_S16 //// +//// //// +//// To Do: //// +//// - fix Avant! //// +//// - xilinx rams need external tri-state logic //// +//// - add additional RAMs (Altera, VS etc) //// +//// //// +//// Author(s): //// +//// - Damjan Lampret, lampret@opencores.org //// +//// - Miha Dolenc, mihad@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_wb_tpram.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.4 2004/08/19 15:27:34 mihad +// Changed minimum pci image size to 256 bytes because +// of some PC system problems with size of IO images. +// +// Revision 1.3 2003/10/17 09:11:52 markom +// mbist signals updated according to newest convention +// +// Revision 1.2 2003/08/14 13:06:03 simons +// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.7 2002/10/18 03:36:37 tadejm +// Changed wrong signal name mbist_sen into mbist_ctrl_i. +// +// Revision 1.6 2002/10/17 22:49:22 tadejm +// Changed BIST signals for RAMs. +// +// Revision 1.5 2002/10/11 10:09:01 mihad +// Added additional testcase and changed rst name in BIST to trst +// +// Revision 1.4 2002/10/08 17:17:06 mihad +// Added BIST signals for RAMs. +// +// Revision 1.3 2002/09/30 17:22:27 mihad +// Added support for Virtual Silicon two port RAM. Didn't run regression on it yet! +// +// Revision 1.2 2002/08/19 16:51:36 mihad +// Extracted distributed RAM module from wb/pci_tpram.v to its own file, got rid of undef directives +// +// Revision 1.1 2002/02/01 14:43:31 mihad +// *** empty log message *** +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on +`include "pci_constants.v" + +module pci_wb_tpram +( + // Generic synchronous two-port RAM interface + clk_a, + rst_a, + ce_a, + we_a, + oe_a, + addr_a, + di_a, + do_a, + clk_b, + rst_b, + ce_b, + we_b, + oe_b, + addr_b, + di_b, + do_b +`ifdef PCI_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif +); + +// +// Default address and data buses width +// +parameter aw = 8; +parameter dw = 40; + +// +// Generic synchronous two-port RAM interface +// +input clk_a; // Clock +input rst_a; // Reset +input ce_a; // Chip enable input +input we_a; // Write enable input +input oe_a; // Output enable input +input [aw-1:0] addr_a; // address bus inputs +input [dw-1:0] di_a; // input data bus +output [dw-1:0] do_a; // output data bus +input clk_b; // Clock +input rst_b; // Reset +input ce_b; // Chip enable input +input we_b; // Write enable input +input oe_b; // Output enable input +input [aw-1:0] addr_b; // address bus inputs +input [dw-1:0] di_b; // input data bus +output [dw-1:0] do_b; // output data bus + +`ifdef PCI_BIST +// debug chain signals +input mbist_si_i; // bist scan serial in +output mbist_so_o; // bist scan serial out +input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + +// +// Internal wires and registers +// + +`ifdef WB_VS_STP + `define PCI_WB_RAM_SELECTED + `ifdef PCI_BIST + vs_hdtp_64x40_bist i_vs_hdtp_64x40_bist + `else + vs_hdtp_64x40 i_vs_hdtp_64x40 + `endif + ( + .RCK (clk_b), + .WCK (clk_a), + .RADR (addr_b), + .WADR (addr_a), + .DI (di_a), + .DOUT (do_b), + .REN (1'b0), + .WEN (!we_a) + `ifdef PCI_BIST + , + // debug chain signals + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) + `endif + ); + + assign do_a = 0 ; +`endif + +`ifdef WB_ARTISAN_SDP + `define PCI_WB_RAM_SELECTED + // + // Instantiation of ASIC memory: + // + // Artisan Synchronous Double-Port RAM (ra2sh) + // + `ifdef PCI_BIST + art_hsdp_64x40_bist /*#(dw, 1< raddr) ? ({1'b0, waddr} - {1'b0, raddr}) : ({1'b1, waddr} - {1'b0, raddr}); +assign half_full_out = fifo_fullness[(ADDR_LENGTH - 1)] ; +//Robert, burst issue + + +// address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out +// done for zero wait state burst +assign raddr_out = rallow_out ? raddr_plus_one : raddr ; + +always@(posedge rclock_in or posedge clear) +begin + if (clear) + begin + raddr_plus_one <= #`FF_DELAY 4 ; + raddr <= #`FF_DELAY 3 ; + end + else if (rallow_out) + begin + raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ; + raddr <= #`FF_DELAY raddr_plus_one ; + end +end + +/*----------------------------------------------------------------------------------------------- +Read address control consists of Read address counter and Grey Address pipeline +There are 3 Grey addresses: + - rgrey_minus1 is Grey Code of address one before current address + - rgrey_addr is Grey Code of current read address + - rgrey_next is Grey Code of next read address +--------------------------------------------------------------------------------------------------*/ +// grey coded address pipeline for status generation in read clock domain +always@(posedge rclock_in or posedge clear) +begin + if (clear) + begin + // initial value is 0 + rgrey_minus1 <= #1 0 ; + rgrey_addr <= #1 1 ; + rgrey_next <= #`FF_DELAY 3 ; + end + else + if (rallow_out) + begin + rgrey_minus1 <= #1 rgrey_addr ; + rgrey_addr <= #1 rgrey_next ; + rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ; + end +end + +/*-------------------------------------------------------------------------------------------- +Write address control consists of write address counter and Grey Code Register +----------------------------------------------------------------------------------------------*/ +// grey coded address pipeline for status generation in write clock domain +always@(posedge wclock_in or posedge clear) +begin + if (clear) + begin + wgrey_addr <= #`FF_DELAY 1 ; + wgrey_next <= #1 3 ; + end + else + if (wallow_out) + begin + wgrey_addr <= #`FF_DELAY wgrey_next ; + wgrey_next <= #1 {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ; + end +end + +// write address counter - nothing special - initial value is important though +always@(posedge wclock_in or posedge clear) +begin + if (clear) + // initial value 4 + waddr <= #`FF_DELAY 3 ; + else + if (wallow_out) + waddr <= #`FF_DELAY waddr + 1'b1 ; +end + +/*------------------------------------------------------------------------------------------------------------------------------ +Gray coded address of read address decremented by 1 is synchronized to write clock domain and compared to: + +- Gray coded write address. If they are equal, fifo is full. + +- Gray coded next write address. If they are equal, fifo is almost full. +--------------------------------------------------------------------------------------------------------------------------------*/ +wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ; +reg [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ; + +pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus1 +( + .data_in (rgrey_minus1), + .clk_out (wclock_in), + .sync_data_out (wclk_sync_rgrey_minus1), + .async_reset (clear) +) ; + +always@(posedge wclock_in or posedge clear) +begin + if (clear) + begin + wclk_rgrey_minus1 <= #`FF_DELAY 0 ; + end + else + begin + wclk_rgrey_minus1 <= #`FF_DELAY wclk_sync_rgrey_minus1 ; + end +end + +assign full_out = (wgrey_addr == wclk_rgrey_minus1) ; +assign almost_full_out = (wgrey_next == wclk_rgrey_minus1) ; + +/*------------------------------------------------------------------------------------------------------------------------------ +Empty control: +Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address. +If they are equal, fifo is empty. +--------------------------------------------------------------------------------------------------------------------------------*/ +wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_next ; +reg [(ADDR_LENGTH - 1):0] rclk_wgrey_next ; +pci_synchronizer_flop #(ADDR_LENGTH, 3) i_synchronizer_reg_wgrey_next +( + .data_in (wgrey_next), + .clk_out (rclock_in), + .sync_data_out (rclk_sync_wgrey_next), + .async_reset (clear) +) ; + +always@(posedge rclock_in or posedge clear) +begin + if (clear) + rclk_wgrey_next <= #`FF_DELAY 3 ; + else + rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ; +end + +assign empty_out = (rgrey_next == rclk_wgrey_next) ; + +endmodule diff --git a/ethernet/source/pci/pci_wbw_wbr_fifos.v b/ethernet/source/pci/pci_wbw_wbr_fifos.v new file mode 100644 index 0000000..86aa9f9 --- /dev/null +++ b/ethernet/source/pci/pci_wbw_wbr_fifos.v @@ -0,0 +1,615 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "wbw_wbr_fifos.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute 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 source 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 source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_wbw_wbr_fifos.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.7 2006/07/04 13:16:19 mihad +// Write burst performance patch applied. +// Not tested. Everything should be backwards +// compatible, since functional code is ifdefed. +// +// Revision 1.6 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.5 2003/10/17 09:11:52 markom +// mbist signals updated according to newest convention +// +// Revision 1.4 2003/08/14 13:06:03 simons +// synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. +// +// Revision 1.3 2003/03/26 13:16:18 mihad +// Added the reset value parameter to the synchronizer flop module. +// Added resets to all synchronizer flop instances. +// Repaired initial sync value in fifos. +// +// Revision 1.2 2003/01/30 22:01:09 mihad +// Updated synchronization in top level fifo modules. +// +// Revision 1.1 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.9 2002/10/18 03:36:37 tadejm +// Changed wrong signal name mbist_sen into mbist_ctrl_i. +// +// Revision 1.8 2002/10/17 22:49:22 tadejm +// Changed BIST signals for RAMs. +// +// Revision 1.7 2002/10/11 10:09:01 mihad +// Added additional testcase and changed rst name in BIST to trst +// +// Revision 1.6 2002/10/08 17:17:06 mihad +// Added BIST signals for RAMs. +// +// Revision 1.5 2002/09/30 16:03:04 mihad +// Added meta flop module for easier meta stable FF identification during synthesis +// +// Revision 1.4 2002/09/25 15:53:52 mihad +// Removed all logic from asynchronous reset network +// +// Revision 1.3 2002/02/01 15:25:14 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:20:12 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:47 mihad +// New project directory structure +// +// + +`include "pci_constants.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + + + +module pci_wbw_wbr_fifos +( + wb_clock_in, + pci_clock_in, + reset_in, + wbw_wenable_in, + wbw_addr_data_in, + wbw_cbe_in, + wbw_control_in, + wbw_renable_in, + wbw_addr_data_out, + wbw_cbe_out, + wbw_control_out, +// wbw_flush_in, write fifo flush not used + wbw_almost_full_out, + wbw_full_out, + wbw_empty_out, + wbw_transaction_ready_out, + wbw_half_full_out, ////Robert, burst issue + wbr_wenable_in, + wbr_data_in, + wbr_be_in, + wbr_control_in, + wbr_renable_in, + wbr_data_out, + wbr_be_out, + wbr_control_out, + wbr_flush_in, + wbr_empty_out + + +`ifdef PCI_BIST + , + // debug chain signals + mbist_si_i, // bist scan serial in + mbist_so_o, // bist scan serial out + mbist_ctrl_i // bist chain shift control +`endif +) ; + +/*----------------------------------------------------------------------------------------------------------- +System inputs: +wb_clock_in - WISHBONE bus clock +pci_clock_in - PCI bus clock +reset_in - reset from control logic +-------------------------------------------------------------------------------------------------------------*/ +input wb_clock_in, pci_clock_in, reset_in ; + +/*----------------------------------------------------------------------------------------------------------- +WISHBONE WRITE FIFO interface signals prefixed with wbw_ - FIFO is used for posted writes initiated by +WISHBONE master, traveling through FIFO and are completed on PCI by PCI master interface + +write enable signal: +wbw_wenable_in = write enable input for WBW_FIFO - driven by WISHBONE slave interface + +data input signals: +wbw_addr_data_in = data input - data from WISHBONE bus - first entry of transaction is address others are data entries +wbw_cbe_in = bus command/byte enable(~SEL[3:0]) input - first entry of transaction is bus command, other are byte enables +wbw_control_in = control input - encoded control bus input + +read enable signal: +wbw_renable_in = read enable input driven by PCI master interface + +data output signals: +wbw_addr_data_out = data output - data from WISHBONE bus - first entry of transaction is address, others are data entries +wbw_cbe_out = bus command/byte enable output - first entry of transaction is bus command, others are byte enables +wbw_control_out = control input - encoded control bus input + +status signals - monitored by various resources in the core +wbw_flush_in = flush signal input for WBW_FIFO - when asserted, fifo is flushed(emptied) +wbw_almost_full_out = almost full output from WBW_FIFO +wbw_full_out = full output from WBW_FIFO +wbw_empty_out = empty output from WBW_FIFO +wbw_transaction_ready_out = output indicating that one complete transaction is waiting in WBW_FIFO +-----------------------------------------------------------------------------------------------------------*/ +// input control and data +input wbw_wenable_in ; +input [31:0] wbw_addr_data_in ; +input [3:0] wbw_cbe_in ; +input [3:0] wbw_control_in ; + +// output control and data +input wbw_renable_in ; +output [31:0] wbw_addr_data_out ; +output [3:0] wbw_cbe_out ; +output [3:0] wbw_control_out ; + +// flush input +// input wbw_flush_in ; // not used + +// status outputs +output wbw_almost_full_out ; +output wbw_full_out ; +output wbw_empty_out ; +output wbw_transaction_ready_out ; +output wbw_half_full_out; ////Robert, burst issue + +/*----------------------------------------------------------------------------------------------------------- +WISHBONE READ FIFO interface signals prefixed with wbr_ - FIFO is used for holding delayed read completions +initiated by master on WISHBONE bus and completed on PCI bus, + +write enable signal: +wbr_wenable_in = write enable input for WBR_FIFO - driven by PCI master interface + +data input signals: +wbr_data_in = data input - data from PCI bus - there is no address entry here, since address is stored in separate register +wbr_be_in = byte enable(~BE#[3:0]) input - byte enables - same through one transaction +wbr_control_in = control input - encoded control bus input + +read enable signal: +wbr_renable_in = read enable input driven by WISHBONE slave interface + +data output signals: +wbr_data_out = data output - data from PCI bus +wbr_be_out = byte enable output(~#BE) +wbr_control_out = control output - encoded control bus output + +status signals - monitored by various resources in the core +wbr_flush_in = flush signal input for WBR_FIFO - when asserted, fifo is flushed(emptied) +wbr full_out = full output from WBR_FIFO +wbr_empty_out = empty output from WBR_FIFO +-----------------------------------------------------------------------------------------------------------*/ +// input control and data +input wbr_wenable_in ; +input [31:0] wbr_data_in ; +input [3:0] wbr_be_in ; +input [3:0] wbr_control_in ; + +// output control and data +input wbr_renable_in ; +output [31:0] wbr_data_out ; +output [3:0] wbr_be_out ; +output [3:0] wbr_control_out ; + +// flush input +input wbr_flush_in ; + +output wbr_empty_out ; + +`ifdef PCI_BIST +/*----------------------------------------------------- +BIST debug chain port signals +-----------------------------------------------------*/ +input mbist_si_i; // bist scan serial in +output mbist_so_o; // bist scan serial out +input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control +`endif + +/*----------------------------------------------------------------------------------------------------------- +FIFO depth parameters: +WBW_DEPTH = defines WBW_FIFO depth +WBR_DEPTH = defines WBR_FIFO depth +WBW_ADDR_LENGTH = defines WBW_FIFO's location address length = log2(WBW_DEPTH) +WBR_ADDR_LENGTH = defines WBR_FIFO's location address length = log2(WBR_DEPTH) +-----------------------------------------------------------------------------------------------------------*/ +parameter WBW_DEPTH = `WBW_DEPTH ; +parameter WBW_ADDR_LENGTH = `WBW_ADDR_LENGTH ; +parameter WBR_DEPTH = `WBR_DEPTH ; +parameter WBR_ADDR_LENGTH = `WBR_ADDR_LENGTH ; + +/*----------------------------------------------------------------------------------------------------------- +wbw_wallow = WBW_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1 +wbw_rallow = WBW_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1 +-----------------------------------------------------------------------------------------------------------*/ +wire wbw_wallow ; +wire wbw_rallow ; + +/*----------------------------------------------------------------------------------------------------------- +wbr_wallow = WBR_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1 +wbr_rallow = WBR_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1 +-----------------------------------------------------------------------------------------------------------*/ +wire wbr_wallow ; +wire wbr_rallow ; + +/*----------------------------------------------------------------------------------------------------------- +wires for address port conections from WBW_FIFO control logic to RAM blocks used for WBW_FIFO +-----------------------------------------------------------------------------------------------------------*/ +wire [(WBW_ADDR_LENGTH - 1):0] wbw_raddr ; +wire [(WBW_ADDR_LENGTH - 1):0] wbw_waddr ; + +/*----------------------------------------------------------------------------------------------------------- +wires for address port conections from WBR_FIFO control logic to RAM blocks used for WBR_FIFO +-----------------------------------------------------------------------------------------------------------*/ +wire [(WBR_ADDR_LENGTH - 1):0] wbr_raddr ; +wire [(WBR_ADDR_LENGTH - 1):0] wbr_waddr ; + +/*----------------------------------------------------------------------------------------------------------- +WBW_FIFO transaction counters: used to count incoming transactions and outgoing transactions. When number of +input transactions is equal to number of output transactions, it means that there isn't any complete transaction +currently present in the FIFO. +-----------------------------------------------------------------------------------------------------------*/ +reg [(WBW_ADDR_LENGTH - 2):0] wbw_inTransactionCount ; +reg [(WBW_ADDR_LENGTH - 2):0] wbw_outTransactionCount ; + +/*----------------------------------------------------------------------------------------------------------- +wires monitoring control bus. When control bus on a write transaction has a value of `LAST, it means that +complete transaction is in the FIFO. When control bus on a read transaction has a value of `LAST, +it means that there was one complete transaction taken out of FIFO. +-----------------------------------------------------------------------------------------------------------*/ +wire wbw_last_in = wbw_control_in[`LAST_CTRL_BIT] ; +wire wbw_last_out = wbw_control_out[`LAST_CTRL_BIT] ; + +wire wbw_empty ; +wire wbr_empty ; + +assign wbw_empty_out = wbw_empty ; +assign wbr_empty_out = wbr_empty ; + +// clear wires for fifos +wire wbw_clear = reset_in /*|| wbw_flush_in*/ ; // WBW_FIFO clear flush not used +wire wbr_clear = reset_in /*|| wbr_flush_in*/ ; // WBR_FIFO clear - flush changed from asynchronous to synchronous + +/*----------------------------------------------------------------------------------------------------------- +Definitions of wires for connecting RAM instances +-----------------------------------------------------------------------------------------------------------*/ +wire [39:0] dpram_portA_output ; +wire [39:0] dpram_portB_output ; + +wire [39:0] dpram_portA_input = {wbw_control_in, wbw_cbe_in, wbw_addr_data_in} ; +wire [39:0] dpram_portB_input = {wbr_control_in, wbr_be_in, wbr_data_in} ; + +/*----------------------------------------------------------------------------------------------------------- +Fifo output assignments - each ram port provides data for different fifo +-----------------------------------------------------------------------------------------------------------*/ +assign wbw_control_out = dpram_portB_output[39:36] ; +assign wbr_control_out = dpram_portA_output[39:36] ; + +assign wbw_cbe_out = dpram_portB_output[35:32] ; +assign wbr_be_out = dpram_portA_output[35:32] ; + +assign wbw_addr_data_out = dpram_portB_output[31:0] ; +assign wbr_data_out = dpram_portA_output[31:0] ; + +`ifdef WB_RAM_DONT_SHARE + + /*----------------------------------------------------------------------------------------------------------- + Piece of code in this ifdef section is used in applications which can provide enough RAM instances to + accomodate four fifos - each occupying its own instance of ram. Ports are connected in such a way, + that instances of RAMs can be changed from two port to dual port ( async read/write port ). In that case, + write port is always port a and read port is port b. + -----------------------------------------------------------------------------------------------------------*/ + + /*----------------------------------------------------------------------------------------------------------- + Pad redundant address lines with zeros. This may seem stupid, but it comes in perfect for FPGA impl. + -----------------------------------------------------------------------------------------------------------*/ + /* + wire [(`WBW_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH - 1):0] wbw_addr_prefix = {( `WBW_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH){1'b0}} ; + wire [(`WBR_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH - 1):0] wbr_addr_prefix = {( `WBR_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH){1'b0}} ; + */ + + // compose complete port addresses + wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbw_whole_waddr = wbw_waddr ; + wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbw_whole_raddr = wbw_raddr ; + + wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbr_whole_waddr = wbr_waddr ; + wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbr_whole_raddr = wbr_raddr ; + + wire wbw_read_enable = 1'b1 ; + wire wbr_read_enable = 1'b1 ; + + `ifdef PCI_BIST + wire mbist_so_o_internal ; // wires for connection of debug ports on two rams + wire mbist_si_i_internal = mbist_so_o_internal ; + `endif + + // instantiate and connect two generic rams - one for wishbone write fifo and one for wishbone read fifo + pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbw_fifo_storage + ( + /////////////////Generic synchronous two-port RAM interface + .clk_a(wb_clock_in), + .rst_a(reset_in), + .ce_a(1'b1), + .we_a(wbw_wallow), + .oe_a(1'b1), + .addr_a(wbw_whole_waddr), + .di_a(dpram_portA_input), + .do_a(), + + .clk_b(pci_clock_in), + .rst_b(reset_in), + .ce_b(wbw_read_enable), + .we_b(1'b0), + .oe_b(1'b1), + .addr_b(wbw_whole_raddr), + .di_b(40'h00_0000_0000), + .do_b(dpram_portB_output) + + `ifdef PCI_BIST + , + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o_internal), + .mbist_ctrl_i (mbist_ctrl_i) + `endif + ); + + pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbr_fifo_storage + ( + // Generic synchronous two-port RAM interface + .clk_a(pci_clock_in), + .rst_a(reset_in), + .ce_a(1'b1), + .we_a(wbr_wallow), + .oe_a(1'b1), + .addr_a(wbr_whole_waddr), + .di_a(dpram_portB_input), + .do_a(), + + .clk_b(wb_clock_in), + .rst_b(reset_in), + .ce_b(wbr_read_enable), + .we_b(1'b0), + .oe_b(1'b1), + .addr_b(wbr_whole_raddr), + .di_b(40'h00_0000_0000), + .do_b(dpram_portA_output) + + `ifdef PCI_BIST + , + .mbist_si_i (mbist_si_i_internal), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) + `endif + ); + + +`else // RAM blocks sharing between two fifos + + /*----------------------------------------------------------------------------------------------------------- + Code section under this ifdef is used for implementation where RAM instances are too expensive. In this + case one RAM instance is used for both - WISHBONE read and WISHBONE write fifo. + -----------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------------------- + Address prefix definition - since both FIFOs reside in same RAM instance, storage is separated by MSB + addresses. WISHBONE write fifo addresses are padded with zeros on the MSB side ( at least one address line + must be used for this ), WISHBONE read fifo addresses are padded with ones on the right ( at least one ). + -----------------------------------------------------------------------------------------------------------*/ + wire [(`WB_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH - 1):0] wbw_addr_prefix = {( `WB_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH){1'b0}} ; + wire [(`WB_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH - 1):0] wbr_addr_prefix = {( `WB_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH){1'b1}} ; + + /*----------------------------------------------------------------------------------------------------------- + Port A address generation for RAM instance. RAM instance must be full two port RAM - read and write capability + on both sides. + Port A is clocked by WISHBONE clock, DIA is input for wbw_fifo, DOA is output for wbr_fifo. + Address is multiplexed so operation can be switched between fifos. Default is a read on port. + -----------------------------------------------------------------------------------------------------------*/ + wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] portA_addr = wbw_wallow ? {wbw_addr_prefix, wbw_waddr} : {wbr_addr_prefix, wbr_raddr} ; + + /*----------------------------------------------------------------------------------------------------------- + Port B is clocked by PCI clock, DIB is input for wbr_fifo, DOB is output for wbw_fifo. + Address is multiplexed so operation can be switched between fifos. Default is a read on port. + -----------------------------------------------------------------------------------------------------------*/ + wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] portB_addr = wbr_wallow ? {wbr_addr_prefix, wbr_waddr} : {wbw_addr_prefix, wbw_raddr} ; + + wire portA_enable = 1'b1 ; + + wire portB_enable = 1'b1 ; + + // instantiate RAM for these two fifos + pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbu_fifo_storage + ( + // Generic synchronous two-port RAM interface + .clk_a(wb_clock_in), + .rst_a(reset_in), + .ce_a(portA_enable), + .we_a(wbw_wallow), + .oe_a(1'b1), + .addr_a(portA_addr), + .di_a(dpram_portA_input), + .do_a(dpram_portA_output), + .clk_b(pci_clock_in), + .rst_b(reset_in), + .ce_b(portB_enable), + .we_b(wbr_wallow), + .oe_b(1'b1), + .addr_b(portB_addr), + .di_b(dpram_portB_input), + .do_b(dpram_portB_output) + + `ifdef PCI_BIST + , + .mbist_si_i (mbist_si_i), + .mbist_so_o (mbist_so_o), + .mbist_ctrl_i (mbist_ctrl_i) + `endif + ); + +`endif + + +/*----------------------------------------------------------------------------------------------------------- +Instantiation of two control logic modules - one for WBW_FIFO and one for WBR_FIFO +-----------------------------------------------------------------------------------------------------------*/ +pci_wbw_fifo_control #(WBW_ADDR_LENGTH) wbw_fifo_ctrl +( + .rclock_in(pci_clock_in), + .wclock_in(wb_clock_in), + .renable_in(wbw_renable_in), + .wenable_in(wbw_wenable_in), + .reset_in(reset_in), +////////////////////////////// .flush_in(wbw_flush_in), + .almost_full_out(wbw_almost_full_out), + .full_out(wbw_full_out), + .empty_out(wbw_empty), + .waddr_out(wbw_waddr), + .raddr_out(wbw_raddr), + .rallow_out(wbw_rallow), + .wallow_out(wbw_wallow), + .half_full_out(wbw_half_full_out) ////Robert, burst issue +); + +pci_wbr_fifo_control #(WBR_ADDR_LENGTH) wbr_fifo_ctrl +( .rclock_in(wb_clock_in), + .wclock_in(pci_clock_in), + .renable_in(wbr_renable_in), + .wenable_in(wbr_wenable_in), + .reset_in(reset_in), + .flush_in(wbr_flush_in), + .empty_out(wbr_empty), + .waddr_out(wbr_waddr), + .raddr_out(wbr_raddr), + .rallow_out(wbr_rallow), + .wallow_out(wbr_wallow) +); + + +// in and out transaction counters and grey codes +reg [(WBW_ADDR_LENGTH-2):0] inGreyCount ; +reg [(WBW_ADDR_LENGTH-2):0] outGreyCount ; +wire [(WBW_ADDR_LENGTH-2):0] inNextGreyCount = {wbw_inTransactionCount[(WBW_ADDR_LENGTH-2)], wbw_inTransactionCount[(WBW_ADDR_LENGTH-2):1] ^ wbw_inTransactionCount[(WBW_ADDR_LENGTH-3):0]} ; +wire [(WBW_ADDR_LENGTH-2):0] outNextGreyCount = {wbw_outTransactionCount[(WBW_ADDR_LENGTH-2)], wbw_outTransactionCount[(WBW_ADDR_LENGTH-2):1] ^ wbw_outTransactionCount[(WBW_ADDR_LENGTH-3):0]} ; + +// input transaction counter increment - when last data of transaction is written to fifo +wire in_count_en = wbw_wallow && wbw_last_in ; + +// output transaction counter increment - when last data is on top of fifo and read from it +wire out_count_en = wbw_renable_in && wbw_last_out ; + +// register holding grey coded count of incoming transactions +always@(posedge wb_clock_in or posedge wbw_clear) +begin + if (wbw_clear) + begin + inGreyCount <= #3 0 ; + end + else + if (in_count_en) + inGreyCount <= #3 inNextGreyCount ; +end + +wire [(WBW_ADDR_LENGTH-2):0] pci_clk_sync_inGreyCount ; +reg [(WBW_ADDR_LENGTH-2):0] pci_clk_inGreyCount ; +pci_synchronizer_flop #((WBW_ADDR_LENGTH - 1), 0) i_synchronizer_reg_inGreyCount +( + .data_in (inGreyCount), + .clk_out (pci_clock_in), + .sync_data_out (pci_clk_sync_inGreyCount), + .async_reset (wbw_clear) +) ; + +always@(posedge pci_clock_in or posedge wbw_clear) +begin + if (wbw_clear) + pci_clk_inGreyCount <= #`FF_DELAY 0 ; + else + pci_clk_inGreyCount <= # `FF_DELAY pci_clk_sync_inGreyCount ; +end + +// register holding grey coded count of outgoing transactions +always@(posedge pci_clock_in or posedge wbw_clear) +begin + if (wbw_clear) + begin + outGreyCount <= #`FF_DELAY 0 ; + end + else + if (out_count_en) + outGreyCount <= #`FF_DELAY outNextGreyCount ; +end + +// incoming transactions counter +always@(posedge wb_clock_in or posedge wbw_clear) +begin + if (wbw_clear) + wbw_inTransactionCount <= #`FF_DELAY 1 ; + else + if (in_count_en) + wbw_inTransactionCount <= #`FF_DELAY wbw_inTransactionCount + 1'b1 ; +end + +// outgoing transactions counter +always@(posedge pci_clock_in or posedge wbw_clear) +begin + if (wbw_clear) + wbw_outTransactionCount <= 1 ; + else + if (out_count_en) + wbw_outTransactionCount <= #`FF_DELAY wbw_outTransactionCount + 1'b1 ; +end + +assign wbw_transaction_ready_out = pci_clk_inGreyCount != outGreyCount ; + +endmodule + diff --git a/ethernet/source/pci/timescale.v b/ethernet/source/pci/timescale.v new file mode 100644 index 0000000..f7885e3 --- /dev/null +++ b/ethernet/source/pci/timescale.v @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "timescale.v" //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: timescale.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.2 2002/02/01 15:25:13 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.1 2001/10/05 08:11:22 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// + +// timescale directive is included in all core's modules for simulation purposes +`timescale 1ns/1ps \ No newline at end of file diff --git a/ethernet/source/top.vhd b/ethernet/source/top.vhd new file mode 100644 index 0000000..af81bdd --- /dev/null +++ b/ethernet/source/top.vhd @@ -0,0 +1,303 @@ +entity top is +PORT( + PCI_AD : INOUT std_logic_vector(31 downto 0); + PCI_CLOCK : IN std_logic; + PCI_IDSEL : IN std_logic; + PCI_CBEn : INOUT std_logic_vector (3 downto 0); + PCI_FRAMEn : INOUT std_logic; + PCI_IRDYn : INOUT std_logic; + PCI_RSTn : INOUT std_logic; + PCI_DEVSELn : INOUT std_logic; + PCI_INTAn : INOUT std_logic; + PCI_PERRn : INOUT std_logic; + PCI_SERRn : INOUT std_logic; + PCI_STOPn : INOUT std_logic; + PCI_TRDYn : INOUT std_logic; + PCI_PAR : INOUT std_logic; + PCI_REQn : OUT std_logic; + PCI_GNTn : IN std_logic; + + MTX_CLK_PAD_I : IN std_logic; + MTXD_PAD_O : OUT std_logic_vector (3 downto 0); + MTXEN_PAD_O : OUT std_logic; + MRX_CLK_PAD_I : IN std_logic; + MRXD_PAD_I : IN std_logic_vector (3 downto 0); + MRXDV_PAD_I : IN std_logic; + MRXERR_PAD_I : IN std_logic; + MCOLL_PAD_I : IN std_logic; + MCRS_PAD_I : IN std_logic; + MD_PAD_IO : INOUT std_logic; + MDC_PAD_O : OUT std_logic; +); +end top; + +architecture bla of top is + +COMPONENT eth_top +PORT( + wb_clk_i : IN std_logic; + wb_rst_i : IN std_logic; + wb_dat_i : IN std_logic_vector(31 downto 0); + wb_adr_i : IN std_logic_vector(11 downto 2); + wb_sel_i : IN std_logic_vector(3 downto 0); + wb_we_i : IN std_logic; + wb_cyc_i : IN std_logic; + wb_stb_i : IN std_logic; + m_wb_dat_i : IN std_logic_vector(31 downto 0); + m_wb_ack_i : IN std_logic; + m_wb_err_i : IN std_logic; + mtx_clk_pad_i : IN std_logic; + mrx_clk_pad_i : IN std_logic; + mrxd_pad_i : IN std_logic_vector(3 downto 0); + mrxdv_pad_i : IN std_logic; + mrxerr_pad_i : IN std_logic; + mcoll_pad_i : IN std_logic; + mcrs_pad_i : IN std_logic; + md_pad_i : IN std_logic; + wb_dat_o : OUT std_logic_vector(31 downto 0); + wb_ack_o : OUT std_logic; + wb_err_o : OUT std_logic; + m_wb_adr_o : OUT std_logic_vector(31 downto 0); + m_wb_sel_o : OUT std_logic_vector(3 downto 0); + m_wb_we_o : OUT std_logic; + m_wb_dat_o : OUT std_logic_vector(31 downto 0); + m_wb_cyc_o : OUT std_logic; + m_wb_stb_o : OUT std_logic; + mtxd_pad_o : OUT std_logic_vector(3 downto 0); + mtxen_pad_o : OUT std_logic; + mtxerr_pad_o : OUT std_logic; + mdc_pad_o : OUT std_logic; + md_pad_o : OUT std_logic; + md_padoe_o : OUT std_logic; + int_o : OUT std_logic + ); +END COMPONENT; + +COMPONENT pci_bridge32 +PORT( + wb_clk_i : IN std_logic; + wb_rst_i : IN std_logic; + wb_int_i : IN std_logic; + wbs_adr_i : IN std_logic_vector(31 downto 0); + wbs_dat_i : IN std_logic_vector(31 downto 0); + wbs_sel_i : IN std_logic_vector(3 downto 0); + wbs_cyc_i : IN std_logic; + wbs_stb_i : IN std_logic; + wbs_we_i : IN std_logic; + wbs_cti_i : IN std_logic_vector(2 downto 0); + wbs_bte_i : IN std_logic_vector(1 downto 0); + wbm_dat_i : IN std_logic_vector(31 downto 0); + wbm_ack_i : IN std_logic; + wbm_rty_i : IN std_logic; + wbm_err_i : IN std_logic; + pci_clk_i : IN std_logic; + pci_rst_i : IN std_logic; + pci_inta_i : IN std_logic; + pci_gnt_i : IN std_logic; + pci_frame_i : IN std_logic; + pci_irdy_i : IN std_logic; + pci_idsel_i : IN std_logic; + pci_devsel_i : IN std_logic; + pci_trdy_i : IN std_logic; + pci_stop_i : IN std_logic; + pci_ad_i : IN std_logic_vector(31 downto 0); + pci_cbe_i : IN std_logic_vector(3 downto 0); + pci_par_i : IN std_logic; + pci_perr_i : IN std_logic; + wb_rst_o : OUT std_logic; + wb_int_o : OUT std_logic; + wbs_dat_o : OUT std_logic_vector(31 downto 0); + wbs_ack_o : OUT std_logic; + wbs_rty_o : OUT std_logic; + wbs_err_o : OUT std_logic; + wbm_adr_o : OUT std_logic_vector(31 downto 0); + wbm_dat_o : OUT std_logic_vector(31 downto 0); + wbm_sel_o : OUT std_logic_vector(3 downto 0); + wbm_cyc_o : OUT std_logic; + wbm_stb_o : OUT std_logic; + wbm_we_o : OUT std_logic; + wbm_cti_o : OUT std_logic_vector(2 downto 0); + wbm_bte_o : OUT std_logic_vector(1 downto 0); + pci_rst_o : OUT std_logic; + pci_inta_o : OUT std_logic; + pci_rst_oe_o : OUT std_logic; + pci_inta_oe_o : OUT std_logic; + pci_req_o : OUT std_logic; + pci_req_oe_o : OUT std_logic; + pci_frame_o : OUT std_logic; + pci_frame_oe_o : OUT std_logic; + pci_irdy_oe_o : OUT std_logic; + pci_devsel_oe_o : OUT std_logic; + pci_trdy_oe_o : OUT std_logic; + pci_stop_oe_o : OUT std_logic; + pci_ad_oe_o : OUT std_logic_vector(31 downto 0); + pci_cbe_oe_o : OUT std_logic_vector(3 downto 0); + pci_irdy_o : OUT std_logic; + pci_devsel_o : OUT std_logic; + pci_trdy_o : OUT std_logic; + pci_stop_o : OUT std_logic; + pci_ad_o : OUT std_logic_vector(31 downto 0); + pci_cbe_o : OUT std_logic_vector(3 downto 0); + pci_par_o : OUT std_logic; + pci_par_oe_o : OUT std_logic; + pci_perr_o : OUT std_logic; + pci_perr_oe_o : OUT std_logic; + pci_serr_o : OUT std_logic; + pci_serr_oe_o : OUT std_logic + ); +END COMPONENT; + +signal pci_rst_o : std_logic; +signal pci_rst_oe_o : std_logic; +signal pci_inta_o : std_logic; +signal pci_inta_oe_o : std_logic; +signal pci_req_o : std_logic; +signal pci_req_oe_o : std_logic; +signal pci_frame_o : std_logic; +signal pci_frame_oe_o : std_logic; +signal pci_irdy_o : std_logic; +signal pci_irdy_oe_o : std_logic; +signal pci_devsel_o : std_logic; +signal pci_devsel_oe_o : std_logic; +signal pci_trdy_o : std_logic; +signal pci_trdy_oe_o : std_logic; +signal pci_stop_o : std_logic; +signal pci_stop_oe_o : std_logic; +signal pci_par_o : std_logic; +signal pci_par_oe_o : std_logic; +signal pci_perr_o : std_logic; +signal pci_perr_oe_o : std_logic; +signal pci_serr_o : std_logic; +signal pci_serr_oe_o : std_logic; +signal pci_ad_oe_o : std_logic; +signal pci_cbe_oe_o : std_logic; +signal pci_ad_o : std_logic_vector (31 downto 0); +signal pci_cbe_o : std_logic_vector (3 downto 0); + +BEGIN + +PCI_RSTn <= if (pci_rst_oe_o = '1') then pci_rst_o else 'Z'; +PCI_INTAn <= if (pci_inta_oe_o = '1') then pci_inta_o else 'Z'; +PCI_REQn <= if (pci_req_oe_o = '1') then pci_req_o else 'Z'; +PCI_FRAMEn <= if (pci_frame_oe_o '1') then pci_frame_o else 'Z'; +PCI_IRDYn <= if (pci_irdy_oe_o = '1') then pci_irdy_o else 'Z'; +PCI_DEVSELn <= if (pci_devsel_oe_o = '1') then pci_devsel_o else 'Z'; +PCI_TRDYn <= if (pci_trdy_oe_o = '1') then pci_trdy_o else 'Z'; +PCI_STOPn <= if (pci_stop_oe_o = '1') then pci_stop_o else 'Z'; +PCI_AD <= if (pci_ad_oe_o = '1') then pci_ad_o else (others => 'Z'); +PCI_CBEn <= if (pci_cbe_oe_o = '1') then pci_cbe_o else (others => 'Z'); +PCI_PAR <= if (pci_par_oe_o = '1') then pci_par_o else 'Z'; +PCI_PERRn <= if (pci_perr_oe_o = '1') then pci_perr_o else 'Z'; +PCI_SERRn <= if (pci_serr_oe_o = '1') then pci_serr_o else 'Z'; + +Inst_pci_bridge32: pci_bridge32 PORT MAP( + wb_clk_i => , + wb_rst_i => , + wb_rst_o => , + wb_int_i => , + wb_int_o => , + wbs_adr_i => , + wbs_dat_i => , + wbs_dat_o => , + wbs_sel_i => , + wbs_cyc_i => , + wbs_stb_i => , + wbs_we_i => , + wbs_cti_i => , + wbs_bte_i => , + wbs_ack_o => , + wbs_rty_o => , + wbs_err_o => , + wbm_adr_o => , + wbm_dat_i => , + wbm_dat_o => , + wbm_sel_o => , + wbm_cyc_o => , + wbm_stb_o => , + wbm_we_o => , + wbm_cti_o => , + wbm_bte_o => , + wbm_ack_i => , + wbm_rty_i => , + wbm_err_i => , + pci_clk_i => PCI_CLOCK, + pci_rst_i => PCI_RSTn, + pci_rst_o => pci_rst_o , + pci_rst_oe_o => pci_rst_oe_o, + pci_inta_i => PCI_INTAn, + pci_inta_o => pci_inta_o, + pci_inta_oe_o => pci_inta_oe_o, + pci_req_o => pci_req_o, + pci_req_oe_o => pci_req_oe_o, + pci_gnt_i => PCI_GNTn, + pci_frame_i => PCI_FRAMEn, + pci_frame_o => pci_frame_o, + pci_frame_oe_o => pci_frame_oe_o, + pci_irdy_oe_o => pci_irdy_oe_o, + pci_devsel_oe_o => pci_devsel_oe_o, + pci_trdy_oe_o => pci_trdy_oe_o, + pci_stop_oe_o => pci_stop_oe_o, + pci_ad_oe_o => pci_ad_oe_o, + pci_cbe_oe_o => pci_cbe_oe_o, + pci_irdy_i => PCI_IRDYn, + pci_irdy_o => pci_irdy_o, + pci_idsel_i => PCI_IDSEL, + pci_devsel_i => PCI_DEVSELn, + pci_devsel_o => pci_devsel_o, + pci_trdy_i => PCI_TRDYn, + pci_trdy_o => pci_trdy_o, + pci_stop_i => PCI_STOPn, + pci_stop_o => pci_stop_o, + pci_ad_i => PCI_AD, + pci_ad_o => pci_ad_o, + pci_cbe_i => PCI_CBEn, + pci_cbe_o => pci_cbe_o, + pci_par_i => PCI_PAR, + pci_par_o => pci_par_o, + pci_par_oe_o => pci_par_oe_o, + pci_perr_i => PCI_PERRn, + pci_perr_o => pci_perr_o, + pci_perr_oe_o => pci_perr_oe_o, + pci_serr_o => pci_serr_o, + pci_serr_oe_o => pci_serr_oe_o +); + +Inst_eth_top: eth_top PORT MAP( + wb_clk_i => , + wb_rst_i => , + wb_dat_i => , + wb_dat_o => , + wb_adr_i => , + wb_sel_i => , + wb_we_i => , + wb_cyc_i => , + wb_stb_i => , + wb_ack_o => , + wb_err_o => , + m_wb_adr_o => , + m_wb_sel_o => , + m_wb_we_o => , + m_wb_dat_o => , + m_wb_dat_i => , + m_wb_cyc_o => , + m_wb_stb_o => , + m_wb_ack_i => , + m_wb_err_i => , + mtx_clk_pad_i => , + mtxd_pad_o => , + mtxen_pad_o => , + mtxerr_pad_o => , + mrx_clk_pad_i => , + mrxd_pad_i => , + mrxdv_pad_i => , + mrxerr_pad_i => , + mcoll_pad_i => , + mcrs_pad_i => , + mdc_pad_o => , + md_pad_i => , + md_pad_o => , + md_padoe_o => , + int_o => +); + +end architecture bla;