mirror of
https://github.com/corundum/corundum.git
synced 2025-01-30 08:32:52 +08:00
475 lines
12 KiB
Verilog
475 lines
12 KiB
Verilog
/*
|
|
|
|
Copyright (c) 2016-2018 Alex Forencich
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
// Language: Verilog 2001
|
|
|
|
`resetall
|
|
`timescale 1ns / 1ps
|
|
`default_nettype none
|
|
|
|
/*
|
|
* FPGA top-level module
|
|
*/
|
|
module fpga (
|
|
// CPU reset button
|
|
input wire CPU_RESET_n,
|
|
// buttons
|
|
input wire [3:0] BUTTON,
|
|
input wire [3:0] SW,
|
|
// LEDs
|
|
output wire [6:0] HEX0_D,
|
|
output wire HEX0_DP,
|
|
output wire [6:0] HEX1_D,
|
|
output wire HEX1_DP,
|
|
output wire [3:0] LED,
|
|
output wire [3:0] LED_BRACKET,
|
|
output wire LED_RJ45_L,
|
|
output wire LED_RJ45_R,
|
|
// Temperature control
|
|
//inout wire TEMP_CLK,
|
|
//inout wire TEMP_DATA,
|
|
//input wire TEMP_INT_n,
|
|
//input wire TEMP_OVERT_n,
|
|
output wire FAN_CTRL,
|
|
// 50 MHz clock inputs
|
|
input wire OSC_50_B3B,
|
|
input wire OSC_50_B3D,
|
|
input wire OSC_50_B4A,
|
|
input wire OSC_50_B4D,
|
|
input wire OSC_50_B7A,
|
|
input wire OSC_50_B7D,
|
|
input wire OSC_50_B8A,
|
|
input wire OSC_50_B8D,
|
|
// PCIe interface
|
|
//input wire PCIE_PERST_n,
|
|
//input wire PCIE_REFCLK_p,
|
|
//input wire [7:0] PCIE_RX_p,
|
|
//output wire [7:0] PCIE_TX_p,
|
|
//input wire PCIE_WAKE_n,
|
|
//inout wire PCIE_SMBCLK,
|
|
//inout wire PCIE_SMBDAT,
|
|
// Si570
|
|
inout wire CLOCK_SCL,
|
|
inout wire CLOCK_SDA,
|
|
// 10G Ethernet
|
|
input wire SFPA_LOS,
|
|
input wire SFPA_TXFAULT,
|
|
input wire SFPA_MOD0_PRESNT_n,
|
|
inout wire SFPA_MOD1_SCL,
|
|
inout wire SFPA_MOD2_SDA,
|
|
output wire SFPA_TXDISABLE,
|
|
output wire [1:0] SPFA_RATESEL,
|
|
input wire SFPA_RX_p,
|
|
output wire SFPA_TX_p,
|
|
input wire SFPB_LOS,
|
|
input wire SFPB_TXFAULT,
|
|
input wire SFPB_MOD0_PRESNT_n,
|
|
inout wire SFPB_MOD1_SCL,
|
|
inout wire SFPB_MOD2_SDA,
|
|
output wire SFPB_TXDISABLE,
|
|
output wire [1:0] SPFB_RATESEL,
|
|
input wire SFPB_RX_p,
|
|
output wire SFPB_TX_p,
|
|
input wire SFPC_LOS,
|
|
input wire SFPC_TXFAULT,
|
|
input wire SFPC_MOD0_PRESNT_n,
|
|
inout wire SFPC_MOD1_SCL,
|
|
inout wire SFPC_MOD2_SDA,
|
|
output wire SFPC_TXDISABLE,
|
|
output wire [1:0] SPFC_RATESEL,
|
|
input wire SFPC_RX_p,
|
|
output wire SFPC_TX_p,
|
|
input wire SFPD_LOS,
|
|
input wire SFPD_TXFAULT,
|
|
input wire SFPD_MOD0_PRESNT_n,
|
|
inout wire SFPD_MOD1_SCL,
|
|
inout wire SFPD_MOD2_SDA,
|
|
output wire SFPD_TXDISABLE,
|
|
output wire [1:0] SPFD_RATESEL,
|
|
input wire SFPD_RX_p,
|
|
output wire SFPD_TX_p,
|
|
input wire SFP_REFCLK_P
|
|
);
|
|
|
|
// Clock and reset
|
|
|
|
wire clk_50mhz = OSC_50_B3B;
|
|
wire rst_50mhz;
|
|
|
|
sync_reset #(
|
|
.N(4)
|
|
)
|
|
sync_reset_50mhz_inst (
|
|
.clk(clk_50mhz),
|
|
.rst(~CPU_RESET_n),
|
|
.out(rst_50mhz)
|
|
);
|
|
|
|
wire clk_156mhz;
|
|
wire rst_156mhz;
|
|
|
|
wire phy_pll_locked;
|
|
|
|
sync_reset #(
|
|
.N(4)
|
|
)
|
|
sync_reset_156mhz_inst (
|
|
.clk(clk_156mhz),
|
|
.rst(rst_50mhz | ~phy_pll_locked),
|
|
.out(rst_156mhz)
|
|
);
|
|
|
|
// GPIO
|
|
|
|
wire [3:0] btn_int;
|
|
wire [3:0] sw_int;
|
|
wire [3:0] led_int;
|
|
wire [3:0] led_bkt_int;
|
|
wire [6:0] led_hex0_d_int;
|
|
wire led_hex0_dp_int;
|
|
wire [6:0] led_hex1_d_int;
|
|
wire led_hex1_dp_int;
|
|
|
|
debounce_switch #(
|
|
.WIDTH(8),
|
|
.N(4),
|
|
.RATE(156250)
|
|
)
|
|
debounce_switch_inst (
|
|
.clk(clk_156mhz),
|
|
.rst(rst_156mhz),
|
|
.in({BUTTON,
|
|
SW}),
|
|
.out({btn_int,
|
|
sw_int})
|
|
);
|
|
|
|
assign LED = ~led_int;
|
|
assign LED_BRACKET = ~led_bkt_int;
|
|
assign HEX0_D = ~led_hex0_d_int;
|
|
assign HEX0_DP = ~led_hex0_dp_int;
|
|
assign HEX1_D = ~led_hex1_d_int;
|
|
assign HEX1_DP = ~led_hex1_dp_int;
|
|
|
|
assign FAN_CTRL = 1;
|
|
|
|
// Si570 oscillator I2C init
|
|
|
|
wire si570_scl_i;
|
|
wire si570_scl_o;
|
|
wire si570_scl_t;
|
|
wire si570_sda_i;
|
|
wire si570_sda_o;
|
|
wire si570_sda_t;
|
|
|
|
assign si570_sda_i = CLOCK_SDA;
|
|
assign CLOCK_SDA = si570_sda_t ? 1'bz : si570_sda_o;
|
|
assign si570_scl_i = CLOCK_SCL;
|
|
assign CLOCK_SCL = si570_scl_t ? 1'bz : si570_scl_o;
|
|
|
|
wire [6:0] si570_i2c_cmd_address;
|
|
wire si570_i2c_cmd_start;
|
|
wire si570_i2c_cmd_read;
|
|
wire si570_i2c_cmd_write;
|
|
wire si570_i2c_cmd_write_multiple;
|
|
wire si570_i2c_cmd_stop;
|
|
wire si570_i2c_cmd_valid;
|
|
wire si570_i2c_cmd_ready;
|
|
|
|
wire [7:0] si570_i2c_data;
|
|
wire si570_i2c_data_valid;
|
|
wire si570_i2c_data_ready;
|
|
wire si570_i2c_data_last;
|
|
|
|
si570_i2c_init
|
|
si570_i2c_init_inst (
|
|
.clk(clk_50mhz),
|
|
.rst(rst_50mhz),
|
|
.cmd_address(si570_i2c_cmd_address),
|
|
.cmd_start(si570_i2c_cmd_start),
|
|
.cmd_read(si570_i2c_cmd_read),
|
|
.cmd_write(si570_i2c_cmd_write),
|
|
.cmd_write_multiple(si570_i2c_cmd_write_multiple),
|
|
.cmd_stop(si570_i2c_cmd_stop),
|
|
.cmd_valid(si570_i2c_cmd_valid),
|
|
.cmd_ready(si570_i2c_cmd_ready),
|
|
.data_out(si570_i2c_data),
|
|
.data_out_valid(si570_i2c_data_valid),
|
|
.data_out_ready(si570_i2c_data_ready),
|
|
.data_out_last(si570_i2c_data_last),
|
|
.busy(),
|
|
.start(1)
|
|
);
|
|
|
|
i2c_master
|
|
si570_i2c_master_inst (
|
|
.clk(clk_50mhz),
|
|
.rst(rst_50mhz),
|
|
.cmd_address(si570_i2c_cmd_address),
|
|
.cmd_start(si570_i2c_cmd_start),
|
|
.cmd_read(si570_i2c_cmd_read),
|
|
.cmd_write(si570_i2c_cmd_write),
|
|
.cmd_write_multiple(si570_i2c_cmd_write_multiple),
|
|
.cmd_stop(si570_i2c_cmd_stop),
|
|
.cmd_valid(si570_i2c_cmd_valid),
|
|
.cmd_ready(si570_i2c_cmd_ready),
|
|
.data_in(si570_i2c_data),
|
|
.data_in_valid(si570_i2c_data_valid),
|
|
.data_in_ready(si570_i2c_data_ready),
|
|
.data_in_last(si570_i2c_data_last),
|
|
.data_out(),
|
|
.data_out_valid(),
|
|
.data_out_ready(1),
|
|
.data_out_last(),
|
|
.scl_i(si570_scl_i),
|
|
.scl_o(si570_scl_o),
|
|
.scl_t(si570_scl_t),
|
|
.sda_i(si570_sda_i),
|
|
.sda_o(si570_sda_o),
|
|
.sda_t(si570_sda_t),
|
|
.busy(),
|
|
.bus_control(),
|
|
.bus_active(),
|
|
.missed_ack(),
|
|
.prescale(312),
|
|
.stop_on_idle(1)
|
|
);
|
|
|
|
// 10G Ethernet PHY
|
|
|
|
wire [71:0] sfp_a_tx_dc;
|
|
wire [71:0] sfp_a_rx_dc;
|
|
wire [71:0] sfp_b_tx_dc;
|
|
wire [71:0] sfp_b_rx_dc;
|
|
wire [71:0] sfp_c_tx_dc;
|
|
wire [71:0] sfp_c_rx_dc;
|
|
wire [71:0] sfp_d_tx_dc;
|
|
wire [71:0] sfp_d_rx_dc;
|
|
|
|
wire [367:0] phy_reconfig_from_xcvr;
|
|
wire [559:0] phy_reconfig_to_xcvr;
|
|
|
|
assign SFPA_MOD1_SCL = 1'bz;
|
|
assign SFPA_MOD2_SDA = 1'bz;
|
|
assign SFPA_TXDISABLE = 1'b0;
|
|
assign SPFA_RATESEL = 2'b00;
|
|
|
|
assign SFPB_MOD1_SCL = 1'bz;
|
|
assign SFPB_MOD2_SDA = 1'bz;
|
|
assign SFPB_TXDISABLE = 1'b0;
|
|
assign SPFB_RATESEL = 2'b00;
|
|
|
|
assign SFPC_MOD1_SCL = 1'bz;
|
|
assign SFPC_MOD2_SDA = 1'bz;
|
|
assign SFPC_TXDISABLE = 1'b0;
|
|
assign SPFC_RATESEL = 2'b00;
|
|
|
|
assign SFPD_MOD1_SCL = 1'bz;
|
|
assign SFPD_MOD2_SDA = 1'bz;
|
|
assign SFPD_TXDISABLE = 1'b0;
|
|
assign SPFD_RATESEL = 2'b00;
|
|
|
|
phy
|
|
phy_inst (
|
|
.pll_ref_clk(SFP_REFCLK_P),
|
|
.pll_locked(phy_pll_locked),
|
|
|
|
.tx_serial_data_0(SFPA_TX_p),
|
|
.rx_serial_data_0(SFPA_RX_p),
|
|
.tx_serial_data_1(SFPB_TX_p),
|
|
.rx_serial_data_1(SFPB_RX_p),
|
|
.tx_serial_data_2(SFPC_TX_p),
|
|
.rx_serial_data_2(SFPC_RX_p),
|
|
.tx_serial_data_3(SFPD_TX_p),
|
|
.rx_serial_data_3(SFPD_RX_p),
|
|
|
|
.xgmii_tx_dc_0(sfp_a_tx_dc),
|
|
.xgmii_rx_dc_0(sfp_a_rx_dc),
|
|
.xgmii_tx_dc_1(sfp_b_tx_dc),
|
|
.xgmii_rx_dc_1(sfp_b_rx_dc),
|
|
.xgmii_tx_dc_2(sfp_c_tx_dc),
|
|
.xgmii_rx_dc_2(sfp_c_rx_dc),
|
|
.xgmii_tx_dc_3(sfp_d_tx_dc),
|
|
.xgmii_rx_dc_3(sfp_d_rx_dc),
|
|
|
|
.xgmii_rx_clk(clk_156mhz),
|
|
.xgmii_tx_clk(clk_156mhz),
|
|
|
|
.tx_ready(~rst_156mhz),
|
|
.rx_ready(),
|
|
|
|
.rx_data_ready(),
|
|
|
|
.phy_mgmt_clk(clk_50mhz),
|
|
.phy_mgmt_clk_reset(rst_50mhz),
|
|
.phy_mgmt_address(9'd0),
|
|
.phy_mgmt_read(1'b0),
|
|
.phy_mgmt_readdata(),
|
|
.phy_mgmt_waitrequest(),
|
|
.phy_mgmt_write(1'b0),
|
|
.phy_mgmt_writedata(32'd0),
|
|
|
|
.reconfig_from_xcvr(phy_reconfig_from_xcvr),
|
|
.reconfig_to_xcvr(phy_reconfig_to_xcvr)
|
|
);
|
|
|
|
phy_reconfig
|
|
phy_reconfig_inst (
|
|
.reconfig_busy(),
|
|
|
|
.mgmt_clk_clk(clk_50mhz),
|
|
.mgmt_rst_reset(rst_50mhz),
|
|
|
|
.reconfig_mgmt_address(7'd0),
|
|
.reconfig_mgmt_read(1'b0),
|
|
.reconfig_mgmt_readdata(),
|
|
.reconfig_mgmt_waitrequest(),
|
|
.reconfig_mgmt_write(1'b0),
|
|
.reconfig_mgmt_writedata(32'd0),
|
|
|
|
.reconfig_to_xcvr(phy_reconfig_to_xcvr),
|
|
.reconfig_from_xcvr(phy_reconfig_from_xcvr)
|
|
);
|
|
|
|
// Convert XGMII interfaces
|
|
|
|
wire [63:0] sfp_a_txd_int;
|
|
wire [7:0] sfp_a_txc_int;
|
|
wire [63:0] sfp_a_rxd_int;
|
|
wire [7:0] sfp_a_rxc_int;
|
|
wire [63:0] sfp_b_txd_int;
|
|
wire [7:0] sfp_b_txc_int;
|
|
wire [63:0] sfp_b_rxd_int;
|
|
wire [7:0] sfp_b_rxc_int;
|
|
wire [63:0] sfp_c_txd_int;
|
|
wire [7:0] sfp_c_txc_int;
|
|
wire [63:0] sfp_c_rxd_int;
|
|
wire [7:0] sfp_c_rxc_int;
|
|
wire [63:0] sfp_d_txd_int;
|
|
wire [7:0] sfp_d_txc_int;
|
|
wire [63:0] sfp_d_rxd_int;
|
|
wire [7:0] sfp_d_rxc_int;
|
|
|
|
xgmii_interleave
|
|
xgmii_interleave_inst_a (
|
|
.input_xgmii_d(sfp_a_txd_int),
|
|
.input_xgmii_c(sfp_a_txc_int),
|
|
.output_xgmii_dc(sfp_a_tx_dc)
|
|
);
|
|
|
|
xgmii_deinterleave
|
|
xgmii_deinterleave_inst_a (
|
|
.input_xgmii_dc(sfp_a_rx_dc),
|
|
.output_xgmii_d(sfp_a_rxd_int),
|
|
.output_xgmii_c(sfp_a_rxc_int)
|
|
);
|
|
|
|
xgmii_interleave
|
|
xgmii_interleave_inst_b (
|
|
.input_xgmii_d(sfp_b_txd_int),
|
|
.input_xgmii_c(sfp_b_txc_int),
|
|
.output_xgmii_dc(sfp_b_tx_dc)
|
|
);
|
|
|
|
xgmii_deinterleave
|
|
xgmii_deinterleave_inst_b (
|
|
.input_xgmii_dc(sfp_b_rx_dc),
|
|
.output_xgmii_d(sfp_b_rxd_int),
|
|
.output_xgmii_c(sfp_b_rxc_int)
|
|
);
|
|
|
|
xgmii_interleave
|
|
xgmii_interleave_inst_c (
|
|
.input_xgmii_d(sfp_c_txd_int),
|
|
.input_xgmii_c(sfp_c_txc_int),
|
|
.output_xgmii_dc(sfp_c_tx_dc)
|
|
);
|
|
|
|
xgmii_deinterleave
|
|
xgmii_deinterleave_inst_c (
|
|
.input_xgmii_dc(sfp_c_rx_dc),
|
|
.output_xgmii_d(sfp_c_rxd_int),
|
|
.output_xgmii_c(sfp_c_rxc_int)
|
|
);
|
|
|
|
xgmii_interleave
|
|
xgmii_interleave_inst_d (
|
|
.input_xgmii_d(sfp_d_txd_int),
|
|
.input_xgmii_c(sfp_d_txc_int),
|
|
.output_xgmii_dc(sfp_d_tx_dc)
|
|
);
|
|
|
|
xgmii_deinterleave
|
|
xgmii_deinterleave_inst_d (
|
|
.input_xgmii_dc(sfp_d_rx_dc),
|
|
.output_xgmii_d(sfp_d_rxd_int),
|
|
.output_xgmii_c(sfp_d_rxc_int)
|
|
);
|
|
|
|
// Core logic
|
|
|
|
fpga_core
|
|
core_inst (
|
|
/*
|
|
* Clock: 156.25MHz
|
|
* Synchronous reset
|
|
*/
|
|
.clk(clk_156mhz),
|
|
.rst(rst_156mhz),
|
|
/*
|
|
* GPIO
|
|
*/
|
|
.btn(btn_int),
|
|
.sw(sw_int),
|
|
.led(led_int),
|
|
.led_bkt(led_bkt_int),
|
|
.led_hex0_d(led_hex0_d_int),
|
|
.led_hex0_dp(led_hex0_dp_int),
|
|
.led_hex1_d(led_hex1_d_int),
|
|
.led_hex1_dp(led_hex1_dp_int),
|
|
/*
|
|
* 10G Ethernet
|
|
*/
|
|
.sfp_a_txd(sfp_a_txd_int),
|
|
.sfp_a_txc(sfp_a_txc_int),
|
|
.sfp_a_rxd(sfp_a_rxd_int),
|
|
.sfp_a_rxc(sfp_a_rxc_int),
|
|
.sfp_b_txd(sfp_b_txd_int),
|
|
.sfp_b_txc(sfp_b_txc_int),
|
|
.sfp_b_rxd(sfp_b_rxd_int),
|
|
.sfp_b_rxc(sfp_b_rxc_int),
|
|
.sfp_c_txd(sfp_c_txd_int),
|
|
.sfp_c_txc(sfp_c_txc_int),
|
|
.sfp_c_rxd(sfp_c_rxd_int),
|
|
.sfp_c_rxc(sfp_c_rxc_int),
|
|
.sfp_d_txd(sfp_d_txd_int),
|
|
.sfp_d_txc(sfp_d_txc_int),
|
|
.sfp_d_rxd(sfp_d_rxd_int),
|
|
.sfp_d_rxc(sfp_d_rxc_int)
|
|
);
|
|
|
|
endmodule
|
|
|
|
`resetall
|