From caf2865968fedfe4ba4aff072e4a67904638e256 Mon Sep 17 00:00:00 2001 From: hadeshyp Date: Tue, 8 May 2012 11:58:13 +0000 Subject: [PATCH] *** empty log message *** --- .../ipcores_ecp3/sgmii33/rate_resolution.v | 66 ++ .../sgmii33/register_interface_hb.v | 918 ++++++++++++++++++ .../sgmii33/reset_controller_cdr.v | 219 +++++ .../sgmii33/reset_controller_pcs.v | 226 +++++ .../ipcores_ecp3/sgmii33/sgmii_channel_smi.v | 237 +++++ 5 files changed, 1666 insertions(+) create mode 100755 gbe2_ecp3/ipcores_ecp3/sgmii33/rate_resolution.v create mode 100755 gbe2_ecp3/ipcores_ecp3/sgmii33/register_interface_hb.v create mode 100755 gbe2_ecp3/ipcores_ecp3/sgmii33/reset_controller_cdr.v create mode 100755 gbe2_ecp3/ipcores_ecp3/sgmii33/reset_controller_pcs.v create mode 100644 gbe2_ecp3/ipcores_ecp3/sgmii33/sgmii_channel_smi.v diff --git a/gbe2_ecp3/ipcores_ecp3/sgmii33/rate_resolution.v b/gbe2_ecp3/ipcores_ecp3/sgmii33/rate_resolution.v new file mode 100755 index 0000000..b9edbef --- /dev/null +++ b/gbe2_ecp3/ipcores_ecp3/sgmii33/rate_resolution.v @@ -0,0 +1,66 @@ +//************************************************************************** +// ************************************************************************* +// * LATTICE SEMICONDUCTOR CONFIDENTIAL * +// * PROPRIETARY NOTE * +// * * +// * This software contains information confidential and proprietary * +// * to Lattice Semiconductor Corporation. It shall not be reproduced * +// * in whole or in part, or transferred to other documents, or disclosed * +// * to third parties, or used for any purpose other than that for which * +// * it was obtained, without the prior written consent of Lattice * +// * Semiconductor Corporation. All rights reserved. * +// * * +// ************************************************************************* +//************************************************************************** + +`timescale 1ns/100ps + +module rate_resolution ( + gbe_mode, + sgmii_mode, + an_enable, + advertised_rate, + link_partner_rate, + non_an_rate, + + operational_rate +); + +input gbe_mode; +input sgmii_mode; +input an_enable; +input [1:0] advertised_rate; // 00=10Mbps 01=100Mbps 10=1Gbps +input [1:0] link_partner_rate; +input [1:0] non_an_rate; + +output [1:0] operational_rate; +reg [1:0] operational_rate; + + + +always @(gbe_mode or sgmii_mode or an_enable or advertised_rate or link_partner_rate or non_an_rate) begin + if (gbe_mode) begin + operational_rate <= 2'b10; // 1Gbps + end + else begin + if (an_enable) begin + if (sgmii_mode) begin + // PHY Mode + operational_rate <= advertised_rate; + end + else begin + // MAC Mode + operational_rate <= link_partner_rate; + end + end + else begin + // If auto-negotiation disabled, then this becomes active rate + operational_rate <= non_an_rate; + end + end +end + + + +endmodule + diff --git a/gbe2_ecp3/ipcores_ecp3/sgmii33/register_interface_hb.v b/gbe2_ecp3/ipcores_ecp3/sgmii33/register_interface_hb.v new file mode 100755 index 0000000..73e0b86 --- /dev/null +++ b/gbe2_ecp3/ipcores_ecp3/sgmii33/register_interface_hb.v @@ -0,0 +1,918 @@ +//************************************************************************** +// ************************************************************************* +// * LATTICE SEMICONDUCTOR CONFIDENTIAL * +// * PROPRIETARY NOTE * +// * * +// * This software contains information confidential and proprietary * +// * to Lattice Semiconductor Corporation. It shall not be reproduced * +// * in whole or in part, or transferred to other documents, or disclosed * +// * to third parties, or used for any purpose other than that for which * +// * it was obtained, without the prior written consent of Lattice * +// * Semiconductor Corporation. All rights reserved. * +// * * +// ************************************************************************* +//************************************************************************** + +`timescale 1ns/100ps + +module register_interface_hb ( + + // Control Signals + rst_n, + hclk, + gbe_mode, + sgmii_mode, + + // Host Bus + hcs_n, + hwrite_n, + haddr, + hdatain, + + hdataout, + hready_n, + + // Register Inputs + mr_an_enable, + mr_restart_an, + mr_adv_ability, + + // Register Outputs + mr_main_reset, + mr_an_complete, + mr_page_rx, + mr_lp_adv_ability + ); + + +input rst_n ; +input hclk ; +input gbe_mode ; +input sgmii_mode ; + +input hcs_n; +input hwrite_n; +input [3:0] haddr; +input [7:0] hdatain; + +output [7:0] hdataout; +output hready_n; + +input mr_an_complete; +input mr_page_rx; +input [15:0] mr_lp_adv_ability; + +output mr_an_enable; +output mr_restart_an; +output [15:0] mr_adv_ability; +output mr_main_reset; + +regs_hb regs ( + .rst_n (rst_n), + .hclk (hclk), + + .gbe_mode (gbe_mode), + .sgmii_mode (sgmii_mode), + + .hcs_n (hcs_n), + .hwrite_n (hwrite_n), + .haddr (haddr), + .hdatain (hdatain), + + .hdataout (hdataout), + .hready_n (hready_n), + + .mr_an_complete (mr_an_complete), + .mr_page_rx (mr_page_rx), + .mr_lp_adv_ability (mr_lp_adv_ability), + + .mr_main_reset (mr_main_reset), + .mr_an_enable (mr_an_enable), + .mr_restart_an (mr_restart_an), + .mr_adv_ability (mr_adv_ability) +); +endmodule + + + + + + +module register_0_hb ( + rst_n, + clk, + cs_0, + cs_1, + write, + ready, + data_in, + + data_out, + mr_main_reset, + mr_an_enable, + mr_restart_an +); + +input rst_n; +input clk; +input cs_0; +input cs_1; +input write; +input ready; +input [15:0] data_in; + +output [15:0] data_out; +output mr_main_reset; // bit D15 // R/W // Self Clearing +output mr_an_enable; // bit D12 // R/W +output mr_restart_an; // bit D09 // R/W // Self Clearing + +reg [15:0] data_out; +reg mr_main_reset; +reg mr_an_enable; +reg mr_restart_an; +reg m_m_r; +reg m_r_a; + + +// Write Operations + + // Low Portion of Register[D7:D0] has no + // implemented bits. Therefore, no write + // operations here. + + // High Portion of Register[D15:D8] + always @(posedge clk or negedge rst_n) begin + if (rst_n == 1'b0) begin + mr_main_reset <= 0; // default value + mr_an_enable <= 1; // default value + mr_restart_an <= 0; // default value + m_m_r <= 0; + m_r_a <= 0; + end + else begin + + // Do the Writes + if (cs_1 && ready && write) begin + mr_main_reset <= data_in[15]; + mr_an_enable <= data_in[12]; + mr_restart_an <= data_in[9]; + end + + // Delay the Self Clearing Register Bits + m_m_r <= mr_main_reset; + m_r_a <= mr_restart_an; + + // Do the Self Clearing + if (m_m_r) + mr_main_reset <= 0; + + if (m_r_a) + mr_restart_an <= 0; + end + end + + + + + +// Read Operations + always @(*) begin + data_out[7:0] = 8'b00000000; + data_out[15] = mr_main_reset; + data_out[14] = 0; + data_out[13] = 0; + data_out[12] = mr_an_enable; + data_out[11] = 0; + data_out[10] = 0; + data_out[9] = mr_restart_an; + data_out[8] = 0; + end +endmodule + +module register_1_hb ( + rst_n, + cs_0, + cs_1, + mr_an_complete, + + data_out +); + +input rst_n; +input cs_0; +input cs_1; +input mr_an_complete; // bit D5 // Read-Only + +output [15:0] data_out; + +reg [15:0] data_out; + + +// Read Operations + + always @(*) begin + data_out[7] <= 0; + data_out[6] <= 0; + data_out[5] <= mr_an_complete; + data_out[4] <= 0; + data_out[3] <= 0; + data_out[2] <= 0; + data_out[1] <= 0; + data_out[0] <= 0; + data_out[15:8] <= 8'b00000000; + end +endmodule + +module register_4_hb ( + rst_n, + clk, + gbe_mode, + sgmii_mode, + cs_0, + cs_1, + write, + ready, + data_in, + + data_out, + mr_adv_ability +); + +parameter [15:0] initval_gbe = 16'h0020; +parameter [15:0] initval_phy = 16'hd801; +parameter [15:0] initval_mac = 16'h4001; + +input rst_n; +input clk; +input gbe_mode; +input sgmii_mode; +input cs_0; +input cs_1; +input write; +input ready; +input [15:0] data_in; + +output [15:0] data_out; +output [15:0] mr_adv_ability; // When sgmii_mode == 1 == PHY + // all bits D15-D0 are R/W, + /////////////////////////////////// + // D15 = Link Status (1=up, 0=down) + // D14 = Can be written but has no effect + // on autonegotiation. Instead + // the autonegotiation state machine + // controls the utilization of this bit. + // D12 = Duplex Mode (1=full, 0=half) + // D11:10 = Speed (11=reserved) + // (10=1000Mbps) + // (01=100 Mbps) + // (00=10 Mbps) + // D0 = 1 + // all other bits = 0 + /////////////////////////////////// + //When sgmii_mode == 0 = MAC + // all bits D15-D0 are R/W, + // D14 = Can be written but has no effect + // on autonegotiation. Instead + // the autonegotiation state machine + // controls the utilization of this bit. + // D0 = 1 + // all other bits = 0 + /////////////////////////////////// + + +reg [15:0] data_out; +reg [15:0] mr_adv_ability; +reg rst_d1; +reg rst_d2; +reg rst_d3; +reg rst_d4; +reg rst_d5; +reg rst_d6; +reg rst_d7; +reg rst_d8; +reg sync_reset; +reg sgmii_mode_d1; +reg sgmii_mode_d2; +reg sgmii_mode_d3; +reg sgmii_mode_d4; +reg sgmii_mode_change; +reg gbe_mode_d1; +reg gbe_mode_d2; +reg gbe_mode_d3; +reg gbe_mode_d4; +reg gbe_mode_change; + +// generate a synchronous reset signal +// note: this method is used so that +// an initval can be applied during +// device run-time, instead of at compile time +always @(posedge clk or negedge rst_n) begin + if (rst_n == 1'b0) begin + rst_d1 <= 0; + rst_d2 <= 0; + rst_d3 <= 0; + rst_d4 <= 0; + rst_d5 <= 0; + rst_d6 <= 0; + rst_d7 <= 0; + rst_d8 <= 0; + sync_reset <= 0; + end + else begin + rst_d1 <= 1; + rst_d2 <= rst_d1; + rst_d3 <= rst_d2; + rst_d4 <= rst_d3; + rst_d5 <= rst_d4; + rst_d6 <= rst_d5; + rst_d7 <= rst_d6; + rst_d8 <= rst_d7; + + // asserts on rising edge of rst_d8 + sync_reset <= !rst_d8 & rst_d7; + end +end + + +// Detect change in sgmii_mode +always @(posedge clk or negedge rst_n) begin + if (rst_n == 1'b0) begin + sgmii_mode_d1 <= 0; + sgmii_mode_d2 <= 0; + sgmii_mode_d3 <= 0; + sgmii_mode_d4 <= 0; + sgmii_mode_change <= 0; + end + else begin + + // deboggle + sgmii_mode_d1 <= sgmii_mode; + sgmii_mode_d2 <= sgmii_mode_d1; + + // delay + sgmii_mode_d3 <= sgmii_mode_d2; + sgmii_mode_d4 <= sgmii_mode_d3; + + // detect change + if (sgmii_mode_d3 != sgmii_mode_d4) + sgmii_mode_change <= 1; + else + sgmii_mode_change <= 0; + end +end + + +// Detect change in gbe_mode +always @(posedge clk or negedge rst_n) begin + if (rst_n == 1'b0) begin + gbe_mode_d1 <= 0; + gbe_mode_d2 <= 0; + gbe_mode_d3 <= 0; + gbe_mode_d4 <= 0; + gbe_mode_change <= 0; + end + else begin + + // deboggle + gbe_mode_d1 <= gbe_mode; + gbe_mode_d2 <= gbe_mode_d1; + + // delay + gbe_mode_d3 <= gbe_mode_d2; + gbe_mode_d4 <= gbe_mode_d3; + + // detect change + if (gbe_mode_d3 != gbe_mode_d4) + gbe_mode_change <= 1; + else + gbe_mode_change <= 0; + end +end + + +// Write Operations + // Low Portion of Register[D7:D0] + always @(posedge clk or negedge rst_n) begin + if (rst_n == 1'b0) begin + mr_adv_ability[7:0] <= 8'h01; + end + else if (sync_reset || sgmii_mode_change || gbe_mode_change) begin + if (gbe_mode_d4) + mr_adv_ability[7:0] <= initval_gbe[7:0]; + else if (sgmii_mode) + mr_adv_ability[7:0] <= initval_phy[7:0]; + else + mr_adv_ability[7:0] <= initval_mac[7:0]; + end + else begin + if (cs_0 && ready && write && (sgmii_mode || gbe_mode)) begin + mr_adv_ability[7:0] <= data_in[7:0]; + end + end + end + + + // High Portion of Register[D15:D8] + always @(posedge clk or negedge rst_n) begin + if (rst_n == 1'b0) begin + mr_adv_ability[15:8] <= 8'h40; // default + end + else if (sync_reset || sgmii_mode_change || gbe_mode_change) begin + if (gbe_mode_d4) + mr_adv_ability[15:8] <= initval_gbe[15:8]; + else if (sgmii_mode) + mr_adv_ability[15:8] <= initval_phy[15:8]; + else + mr_adv_ability[15:8] <= initval_mac[15:8]; + end + else begin + if (cs_1 && ready && write && (sgmii_mode || gbe_mode)) begin + mr_adv_ability[15:8] <= data_in[15:8]; + end + end + end + + + + + + + + + +// Read Operations + + always @(*) begin + data_out[7:0] <= mr_adv_ability[7:0]; + data_out[15:8] <= mr_adv_ability[15:8]; + end + +endmodule + + + + + + +module register_5_hb ( + rst_n, + mr_lp_adv_ability, + cs_0, + cs_1, + ready, + + data_out +); + +input rst_n; +input cs_0; +input cs_1; +input ready; +input [15:0] mr_lp_adv_ability; + // This entire register is read-only + /////////////////////////////////// + // When sgmii_mode == 0 == MAC + /////////////////////////////////// + // D15 = PHY Link Status (1=up, 0=down) + // D14 = PHY Autonegotiation Handshake + // D12 = PHY Duplex Mode (1=full, 0=half) + // D11:10 = PHY Speed (11=reserved) + // (10=1000Mbps) + // (01=100 Mbps) + // (00=10 Mbps) + // D0 = 1 + // all other bits = 0 + /////////////////////////////////// + //When sgmii_mode == 1 = PHY + // D14 = MAC Autonegotiation Handshake + // D0 = 1 + // all other bits = 0 + /////////////////////////////////// +output [15:0] data_out; + +reg [15:0] data_out; + +// Read Operations + + always @(*) begin + data_out[7:0] <= mr_lp_adv_ability[7:0]; + data_out[15:8] <= mr_lp_adv_ability[15:8]; + end +endmodule + +module register_6_hb ( + rst_n, + clk, + mr_page_rx, + cs_0, + cs_1, + write, + ready, + + data_out +); + +input rst_n; +input clk; +input cs_0; +input cs_1; +input write; +input ready; +input mr_page_rx; +output [15:0] data_out; + +reg [15:0] data_out; +reg mr_page_rx_latched; +reg clear_on_read; +reg read_detect; +reg rd_d1; +reg rd_d2; + +// generate clear-on-read signal + always @(posedge clk or negedge rst_n) begin + if (rst_n == 1'b0) begin + clear_on_read <= 0; + read_detect <= 0; + rd_d1 <= 0; + rd_d2 <= 0; + end + else begin + if (!write && ready && cs_0) + read_detect <= 1; + else + read_detect <= 0; + + rd_d1 <= read_detect; + rd_d2 <= rd_d1; + + // assert on falling edge of rd_d2 + clear_on_read <= !rd_d1 & rd_d2; + end + end + + +// Latch and Clear + always @(posedge clk or negedge rst_n) begin + if (rst_n == 1'b0) begin + mr_page_rx_latched <= 0; + end + else begin + if (clear_on_read) + mr_page_rx_latched <= 0; + else if (mr_page_rx) + mr_page_rx_latched <= 1; + end + end + + +// Read Operations + + always @(*) begin + data_out[15:2] <= 14'd0; + data_out[1] <= mr_page_rx_latched; + data_out[0] <= 0; + end +endmodule + + +module regs_hb ( + rst_n, + hclk, + gbe_mode, + sgmii_mode, + hcs_n, + hwrite_n, + haddr, + hdatain, + + hdataout, + hready_n, + + mr_an_complete, + mr_page_rx, + mr_lp_adv_ability, + + mr_main_reset, + mr_an_enable, + mr_restart_an, + mr_adv_ability +); + +input rst_n; +input hclk; +input gbe_mode; +input sgmii_mode; +input hcs_n; +input hwrite_n; +input [3:0] haddr; +input [7:0] hdatain; + +output [7:0] hdataout; +output hready_n; + +input mr_an_complete; +input mr_page_rx; +input [15:0] mr_lp_adv_ability; + +output mr_main_reset; +output mr_an_enable; +output mr_restart_an; +output [15:0] mr_adv_ability; + +/////////////////////////////////// + + + +reg [7:0] hdataout; +reg hr; +reg hready_n; + +reg hcs_n_delayed; + +wire reg0_cs_0; +wire reg0_cs_1; + +wire reg1_cs_0; +wire reg1_cs_1; + +wire reg4_cs_0; +wire reg4_cs_1; + +wire reg5_cs_0; +wire reg5_cs_1; + +wire reg6_cs_0; +wire reg6_cs_1; + +wire [15:0] data_out_reg_0; +wire [15:0] data_out_reg_1; +wire [15:0] data_out_reg_4; +wire [15:0] data_out_reg_5; +wire [15:0] data_out_reg_6; + + + +register_addr_decoder ad_dec ( + .rst_n(rst_n), + .addr(haddr), + .cs_in(~hcs_n), + + .reg0_cs_0 (reg0_cs_0), + .reg0_cs_1 (reg0_cs_1), + .reg1_cs_0 (reg1_cs_0), + .reg1_cs_1 (reg1_cs_1), + .reg4_cs_0 (reg4_cs_0), + .reg4_cs_1 (reg4_cs_1), + .reg5_cs_0 (reg5_cs_0), + .reg5_cs_1 (reg5_cs_1), + .reg6_cs_0 (reg6_cs_0), + .reg6_cs_1 (reg6_cs_1) +); + + +register_0_hb register_0 ( + .rst_n (rst_n), + .clk (hclk), + .cs_0 (reg0_cs_0), + .cs_1 (reg0_cs_1), + .write (~hwrite_n), + .ready (1'b1), + .data_in ({hdatain, hdatain}), + + .data_out (data_out_reg_0), + .mr_main_reset (mr_main_reset), + .mr_an_enable (mr_an_enable), + .mr_restart_an (mr_restart_an) +); + + +register_1_hb register_1 ( + .rst_n (rst_n), + .cs_0 (reg1_cs_0), + .cs_1 (reg1_cs_1), + .mr_an_complete (mr_an_complete), + + .data_out (data_out_reg_1) +); + + +register_4_hb register_4 ( + .rst_n (rst_n), + .clk (hclk), + .gbe_mode (gbe_mode), + .sgmii_mode (sgmii_mode), + .cs_0 (reg4_cs_0), + .cs_1 (reg4_cs_1), + .write (~hwrite_n), + .ready (1'b1), + .data_in ({hdatain, hdatain}), + + .data_out (data_out_reg_4), + .mr_adv_ability (mr_adv_ability) +); + + +register_5_hb register_5 ( + .rst_n (rst_n), + .mr_lp_adv_ability (mr_lp_adv_ability), + .cs_0 (reg5_cs_0), + .cs_1 (reg5_cs_1), + .ready (1'b1), + + .data_out (data_out_reg_5) +); + + +register_6_hb register_6 ( + .rst_n (rst_n), + .clk (hclk), + .mr_page_rx (mr_page_rx), + .cs_0 (reg6_cs_0), + .cs_1 (reg6_cs_1), + .write (~hwrite_n), + .ready (1'b1), + + .data_out (data_out_reg_6) +); + + + +// generate an ack +always @(posedge hclk or negedge rst_n) begin + if (rst_n == 1'b0) begin + hcs_n_delayed <= 1'b1; + hr <= 1'b1; + hready_n <= 1'b1; + end + else begin + hcs_n_delayed <= hcs_n; + + //assert on falling edge of delayed chip select + hr <= ~hcs_n & hcs_n_delayed; + hready_n <= ~hr; + end +end + + + +// Mux Register Read-Data Outputs +always @(posedge hclk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + hdataout <= 8'd0; + end + else begin + case (haddr[3:0]) + + 4'd0: + begin + hdataout <= data_out_reg_0[7:0]; + end + + + 4'd1: + begin + hdataout <= data_out_reg_0[15:8]; + end + + ///////////////////////////////////////////// + + 4'd2: + begin + hdataout <= data_out_reg_1[7:0]; + end + + + 4'd3: + begin + hdataout <= data_out_reg_1[15:8]; + end + + ///////////////////////////////////////////// + + 4'd8: + begin + hdataout <= data_out_reg_4[7:0]; + end + + + 4'd9: + begin + hdataout <= data_out_reg_4[15:8]; + end + + ///////////////////////////////////////////// + + 4'd10: + begin + hdataout <= data_out_reg_5[7:0]; + end + + + 4'd11: + begin + hdataout <= data_out_reg_5[15:8]; + end + + ///////////////////////////////////////////// + + 4'd12: + begin + hdataout <= data_out_reg_6[7:0]; + end + + + 4'd13: + begin + hdataout <= data_out_reg_6[15:8]; + end + + ///////////////////////////////////////////// + + default: + begin + hdataout <= 8'd0; + end + endcase + end +end + +endmodule + +module register_addr_decoder ( + rst_n, + addr, + cs_in, + + reg0_cs_0, + reg0_cs_1, + + reg1_cs_0, + reg1_cs_1, + + reg4_cs_0, + reg4_cs_1, + + reg5_cs_0, + reg5_cs_1, + + reg6_cs_0, + reg6_cs_1 +); + +input rst_n; +input cs_in; +input [3:0] addr; + +output reg0_cs_0; +output reg0_cs_1; + +output reg1_cs_0; +output reg1_cs_1; + +output reg4_cs_0; +output reg4_cs_1; + +output reg5_cs_0; +output reg5_cs_1; + +output reg6_cs_0; +output reg6_cs_1; + +////////////////////////// + +wire reg0_cs_0; +wire reg0_cs_1; + +wire reg1_cs_0; +wire reg1_cs_1; + +wire reg4_cs_0; +wire reg4_cs_1; + +wire reg5_cs_0; +wire reg5_cs_1; + +wire reg6_cs_0; +wire reg6_cs_1; + +////////////////////////// + +assign reg0_cs_0 = (addr == 4'h0) ? cs_in : 1'b0; +assign reg0_cs_1 = (addr == 4'h1) ? cs_in : 1'b0; + +assign reg1_cs_0 = (addr == 4'h2) ? cs_in : 1'b0; +assign reg1_cs_1 = (addr == 4'h3) ? cs_in : 1'b0; + +assign reg4_cs_0 = (addr == 4'h8) ? cs_in : 1'b0; +assign reg4_cs_1 = (addr == 4'h9) ? cs_in : 1'b0; + +assign reg5_cs_0 = (addr == 4'ha) ? cs_in : 1'b0; +assign reg5_cs_1 = (addr == 4'hb) ? cs_in : 1'b0; + +assign reg6_cs_0 = (addr == 4'hc) ? cs_in : 1'b0; +assign reg6_cs_1 = (addr == 4'hd) ? cs_in : 1'b0; + + +endmodule + diff --git a/gbe2_ecp3/ipcores_ecp3/sgmii33/reset_controller_cdr.v b/gbe2_ecp3/ipcores_ecp3/sgmii33/reset_controller_cdr.v new file mode 100755 index 0000000..fa0a645 --- /dev/null +++ b/gbe2_ecp3/ipcores_ecp3/sgmii33/reset_controller_cdr.v @@ -0,0 +1,219 @@ +//************************************************************************** +// ************************************************************************* +// * LATTICE SEMICONDUCTOR CONFIDENTIAL * +// * PROPRIETARY NOTE * +// * * +// * This software contains information confidential and proprietary * +// * to Lattice Semiconductor Corporation. It shall not be reproduced * +// * in whole or in part, or transferred to other documents, or disclosed * +// * to third parties, or used for any purpose other than that for which * +// * it was obtained, without the prior written consent of Lattice * +// * Semiconductor Corporation. All rights reserved. * +// * * +// ************************************************************************* +//************************************************************************** + +//////////////////////////////////////////////////////////////////////// +// This module forces a RESET to the SERDES CDR +// when the CDR either loses lock or loses signal +//////////////////////////////////////////////////////////////////////// + +`timescale 1ns/100ps + +module reset_controller_cdr ( + + rst_n, + clk, + + cdr_lol, + + cdr_rst_out + ); + +input rst_n; +input clk; // 125Mhz clock + +input cdr_lol; + +output cdr_rst_out; + + +/////////////////////////////////////// + +reg cdr_rst_out; + +reg cdr_lol_mstb_1; +reg cdr_lol_mstb_2; + + +reg sht_mx; +reg [5:0] sht_count; + +reg lng_mx; +reg [22:0] lng_count; + +reg cnt_rst; +parameter + ASSRT_RST = 3'd0, + WAIT_SHORT = 3'd1, + DSSRT_RST = 3'd2, + WAIT_LONG = 3'd3, + SEEK_CDR_ERR = 3'd4, + SEEK_SIGNAL_RESTORE = 3'd5; +reg[2:0] fsm; + +////////////////////////////////////// +// Mestastability Filter +////////////////////////////////////// +always @(posedge clk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + cdr_lol_mstb_1 <= 1'b1; + cdr_lol_mstb_2 <= 1'b1; + + + end + else begin + cdr_lol_mstb_1 <= cdr_lol; + cdr_lol_mstb_2 <= cdr_lol_mstb_1; + + end +end + + + +/////////////////////////////////////// +// Operate Short Timer (256 nsec) +/////////////////////////////////////// +always @(posedge clk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + sht_mx <= 1'b0; + sht_count <= 6'd0; + end + else begin + + // define max count + if (sht_count[5] && (!cnt_rst)) begin + sht_mx <= 1'b1; + end + else begin + sht_mx <= 1'b0; + end + + // operate counter + if (cnt_rst) begin + sht_count <= 6'd0; //clear + end + else if (sht_mx) begin + sht_count <= sht_count; //hold + end + else begin + sht_count <= sht_count + 1; //count + end + end +end + + +///////////////////////////////////// +// Operate Long Timer (33 msec) +///////////////////////////////////// +always @(posedge clk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + lng_mx <= 1'b0; + lng_count <= 23'd0; + end + else begin + + // define max count + if (lng_count[22] && (!cnt_rst)) begin + lng_mx <= 1'b1; + end + else begin + lng_mx <= 1'b0; + end + + // operate counter + if (cnt_rst) begin + lng_count <= 6'd0; //clear + end + else if (lng_mx) begin + lng_count <= lng_count; //hold + end + else begin + lng_count <= lng_count + 1; //count + end + end +end + + +///////////////////////////////////// +// State Machine +///////////////////////////////////// +always @(posedge clk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + cdr_rst_out <= 1'b1; + cnt_rst <= 1'b1; + fsm <= ASSRT_RST; + end + else begin + + // defaults + cnt_rst <= 1'b0; + + case (fsm) + ASSRT_RST: begin + cdr_rst_out <= 1'b1; // assert + cnt_rst <= 1'b1; + fsm <= WAIT_SHORT; + end + + WAIT_SHORT: begin + // wait for 256 nsec + if (sht_mx && (!cnt_rst)) begin + fsm <= DSSRT_RST; + end + end + + DSSRT_RST: begin + cdr_rst_out <= 1'b0; // de-assert + fsm <= WAIT_LONG; + end + + WAIT_LONG: begin + // wait for 33 msec + if (lng_mx && (!cnt_rst)) begin + fsm <= SEEK_CDR_ERR; + end + end + + SEEK_CDR_ERR: begin + + cnt_rst <= 1'b1; + + + // Wait for CDR to fail + if (cdr_lol_mstb_2) begin + fsm <= ASSRT_RST; + end + else begin + fsm <= SEEK_CDR_ERR; + end + end + + + + default: begin + fsm <= ASSRT_RST; + end + endcase + + end +end + + + +endmodule + diff --git a/gbe2_ecp3/ipcores_ecp3/sgmii33/reset_controller_pcs.v b/gbe2_ecp3/ipcores_ecp3/sgmii33/reset_controller_pcs.v new file mode 100755 index 0000000..9d2e584 --- /dev/null +++ b/gbe2_ecp3/ipcores_ecp3/sgmii33/reset_controller_pcs.v @@ -0,0 +1,226 @@ +//************************************************************************** +// ************************************************************************* +// * LATTICE SEMICONDUCTOR CONFIDENTIAL * +// * PROPRIETARY NOTE * +// * * +// * This software contains information confidential and proprietary * +// * to Lattice Semiconductor Corporation. It shall not be reproduced * +// * in whole or in part, or transferred to other documents, or disclosed * +// * to third parties, or used for any purpose other than that for which * +// * it was obtained, without the prior written consent of Lattice * +// * Semiconductor Corporation. All rights reserved. * +// * * +// ************************************************************************* +//************************************************************************** + +//////////////////////////////////////////////////////////////////////// +// This module implements the SERDES/PCS reset sequence as specified +// in Figure 47 of Lattice Technical Note TN1176 +//////////////////////////////////////////////////////////////////////// + +`timescale 1ns/100ps + +module reset_controller_pcs ( + + rst_n, + clk, + + tx_plol, + rx_cdr_lol, + + quad_rst_out, + tx_pcs_rst_out, + rx_pcs_rst_out + ); + +input rst_n; +input clk; // 125Mhz clock + +input tx_plol; +input rx_cdr_lol; + +output quad_rst_out; +output tx_pcs_rst_out; +output rx_pcs_rst_out; + + +/////////////////////////////////////// + +reg quad_rst_out; +reg tx_pcs_rst_out; +reg rx_pcs_rst_out; + +reg q_mx; +reg [3:0] q_count; + +reg rx_cdr_lol_mstb_1; +reg rx_cdr_lol_mstb_2; + +reg wd_mx; +reg wd_mx_d1; +reg wd_mx_re; +reg [22:0] wd_count; +reg watchdog_flag; + +//////////////////////////////////////////////////////// +// Assert Quad RST For 8 Clocks After Device Hard Reset +//////////////////////////////////////////////////////// +always @(posedge clk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + q_mx <= 1'b0; + q_count <= 4'd0; + quad_rst_out <= 1'b1; // assert + end + else begin + + // define max count + if (q_count[3]) begin + q_mx <= 1'b1; + end + else begin + q_mx <= 1'b0; + end + + // operate counter + if (q_mx) begin + q_count <= q_count; //hold + end + else begin + q_count <= q_count + 1; //count + end + + // operate quad reset + if (q_mx) begin + quad_rst_out <= 1'b0; //de-assert on max-count + end + else begin + quad_rst_out <= 1'b1; //assert otherwise + end + end +end + + +//////////////////////////////////////////////////////////////////// +// Watchdog Timer -- In Case PLLs Don't Acquire Lock Within 33msec +//////////////////////////////////////////////////////////////////// +always @(posedge clk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + wd_mx <= 1'b0; + wd_mx_d1 <= 1'b0; + wd_mx_re <= 1'b0; + wd_count <= 23'd0; + watchdog_flag <= 1'b0; + end + else begin + + // define max count + if (wd_count[22]) begin + wd_mx <= 1'b1; + end + else begin + wd_mx <= 1'b0; + end + + // operate counter + if (quad_rst_out) begin + wd_count <= 23'd0; //clear + end + else if (wd_mx) begin + wd_count <= wd_count; //hold + end + else begin + wd_count <= wd_count + 1; //count + end + + // detect rising edge of max_count flag + wd_mx_d1 <= wd_mx; + + wd_mx_re <= wd_mx & (!wd_mx_d1); + + // generate watchdog flag + watchdog_flag <= wd_mx_re; + end +end + + + + +//////////////////////////////////////////////// +// De-Assert TX PCS After TX PLL Acquires Lock +//////////////////////////////////////////////// +always @(posedge clk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + tx_pcs_rst_out <= 1'b1; // assert + end + else begin + + case (tx_pcs_rst_out) + 1'b1: begin + // if asserted, wait for PLL to acquire lock + if ((!quad_rst_out && (!tx_plol)) || watchdog_flag) begin + tx_pcs_rst_out <= 1'b0; // deassert + end + end + + 1'b0: begin + // if de-asserted, stay that way + tx_pcs_rst_out <= 1'b0; // deassert + end + + default: begin + tx_pcs_rst_out <= 1'b1; // assert + end + endcase + + end +end + + + + + +/////////////////////////////////////////////////////// +// De-Assert RX PCS-Chan-0 After RX CDR Acquires Lock +/////////////////////////////////////////////////////// +always @(posedge clk or negedge rst_n) +begin + if (rst_n == 1'b0) begin + rx_pcs_rst_out <= 1'b1; // assert + rx_cdr_lol_mstb_1 <= 1'b1; + rx_cdr_lol_mstb_2 <= 1'b1; + end + else begin + + // metastability - filter + rx_cdr_lol_mstb_1 <= rx_cdr_lol; + rx_cdr_lol_mstb_2 <= rx_cdr_lol_mstb_1; + + case (rx_pcs_rst_out) + 1'b1: begin + // if asserted, wait for CDR to acquire lock + if ((!quad_rst_out && (!rx_cdr_lol_mstb_2)) || watchdog_flag) begin + rx_pcs_rst_out <= 1'b0; // deassert + end + end + + 1'b0: begin + // if de-asserted, stay that way + rx_pcs_rst_out <= 1'b0; // deassert + end + + default: begin + rx_pcs_rst_out <= 1'b1; // assert + end + endcase + + end +end + + + + +endmodule + diff --git a/gbe2_ecp3/ipcores_ecp3/sgmii33/sgmii_channel_smi.v b/gbe2_ecp3/ipcores_ecp3/sgmii33/sgmii_channel_smi.v new file mode 100644 index 0000000..a97ca4f --- /dev/null +++ b/gbe2_ecp3/ipcores_ecp3/sgmii33/sgmii_channel_smi.v @@ -0,0 +1,237 @@ +//************************************************************************** +// ************************************************************************* +// * LATTICE SEMICONDUCTOR CONFIDENTIAL * +// * PROPRIETARY NOTE * +// * * +// * This software contains information confidential and proprietary * +// * to Lattice Semiconductor Corporation. It shall not be reproduced * +// * in whole or in part, or transferred to other documents, or disclosed * +// * to third parties, or used for any purpose other than that for which * +// * it was obtained, without the prior written consent of Lattice * +// * Semiconductor Corporation. All rights reserved. * +// * * +// ************************************************************************* +//************************************************************************** + +`timescale 1ns/100ps + +module sgmii_channel_smi ( + + // Control Interface + rst_n, + gbe_mode, + sgmii_mode, + signal_detect, + debug_link_timer_short, + rx_compensation_err, + non_an_rate, + + // G/MII Interface + in_clk_gmii, + in_clk_mii, + data_in_mii, + en_in_mii, + err_in_mii, + + out_clk_gmii, + out_clk_mii, + data_out_mii, + dv_out_mii, + err_out_mii, + col_out_mii, + crs_out_mii, + + // 8-bit Interface + data_out_8bi, + kcntl_out_8bi, + disparity_cntl_out_8bi, + + serdes_recovered_clk, + data_in_8bi, + kcntl_in_8bi, + even_in_8bi, + disp_err_in_8bi, + cv_err_in_8bi, + err_decode_mode_8bi, + + // MDIO Port + mdc, + mdio, + port_id + ); + + + +// I/O Declarations +input rst_n ; // System Reset, Active Low +input signal_detect ; +input gbe_mode ; // GBE Mode (0=SGMII 1=GBE) +input sgmii_mode ; // SGMII PCS Mode (0=MAC 1=PHY) +input debug_link_timer_short ; // (0=NORMAL 1=SHORT) +output rx_compensation_err; // Active high pulse indicating RX_CTC_FIFO either underflowed or overflowed +input [1:0] non_an_rate ; // MII Rate Used When Autonegotiation is Disabled (00=10Mbps; 01=100Mbps; 10=1Gbps) + +input in_clk_mii ; // G/MII Transmit clock 2.5Mhz/25Mhz/125Mhz +input [7:0] data_in_mii ; // G/MII Tx data +input en_in_mii ; // G/MII data valid +input err_in_mii ; // G/MII Tx error + +input out_clk_mii ; // G/MII Receice clock 2.5Mhz/25Mhz/125MHz +output [7:0] data_out_mii ; // G/MII Rx data +output dv_out_mii ; // G/MII Rx data valid +output err_out_mii ; // G/MII Rx error +output col_out_mii ; // G/MII collision detect +output crs_out_mii ; // G/MII carrier sense detect + +output [7:0] data_out_8bi ; // 8BI Tx Data +output kcntl_out_8bi ; // 8BI Tx Kcntl +output disparity_cntl_out_8bi ; // 8BI Tx Kcntl + +input serdes_recovered_clk ; +input [7:0] data_in_8bi ; // 8BI Rx Data +input kcntl_in_8bi ; // 8BI Rx Kcntl +input even_in_8bi ; // 8BI Rx Even +input disp_err_in_8bi ; // 8BI Rx Disparity Error +input cv_err_in_8bi ; // 8BI Rx Coding Violation Error +input err_decode_mode_8bi ; // 8BI Error Decode Mode (0=NORMAL, 1=DECODE_MODE) + +input in_clk_gmii ; // GMII Transmit clock 125Mhz +input out_clk_gmii ; // GMII Receive clock 125Mhz + +input mdc; +inout mdio; +input [4:0] port_id; + + +wire mdin; +wire mdout; +wire mdout_en; + +// Internal Signals + +wire mr_an_complete; +wire mr_page_rx; +wire [15:0] mr_lp_adv_ability; + +wire mr_main_reset; +wire mr_an_enable; +wire mr_restart_an; +wire [15:0] mr_adv_ability; + +wire [1:0] operational_rate; + + + + + + + + +// SGMII PCS +sgmii33 sgmii33_U ( + // Clock and Reset + .rst_n (rst_n ), + .signal_detect (signal_detect), + .gbe_mode (gbe_mode), + .sgmii_mode (sgmii_mode), + .debug_link_timer_short (debug_link_timer_short), + .operational_rate (operational_rate), + .rx_compensation_err (rx_compensation_err), + .tx_clk_125 (in_clk_gmii), + .serdes_recovered_clk (serdes_recovered_clk), + .rx_clk_125 (out_clk_gmii), + + // Control + + + // (G)MII TX Port + .tx_clk_mii (in_clk_mii), + .tx_d (data_in_mii), + .tx_en (err_in_mii), + .tx_er (en_in_mii), + + // (G)MII RX Port + .rx_clk_mii (out_clk_mii), + .rx_d (data_out_mii), + .rx_dv (dv_out_mii), + .rx_er (err_out_mii), + .col (col_out_mii), + .crs (crs_out_mii), + + // 8BI TX Port + .tx_data (data_out_8bi), + .tx_kcntl (kcntl_out_8bi), + .tx_disparity_cntl (disparity_cntl_out_8bi), + + // 8BI RX Port + .rx_data (data_in_8bi), + .rx_kcntl (kcntl_in_8bi), + .rx_even (even_in_8bi), + .rx_disp_err (disp_err_in_8bi), + .rx_cv_err (cv_err_in_8bi), + .rx_err_decode_mode (err_decode_mode_8bi), + + // Management Interface I/O + .mr_adv_ability (mr_adv_ability), + .mr_an_enable (mr_an_enable), + .mr_main_reset (mr_main_reset), + .mr_restart_an (mr_restart_an), + + .mr_an_complete (mr_an_complete), + .mr_lp_adv_ability (mr_lp_adv_ability), + .mr_page_rx (mr_page_rx) + ); + + + +// SMI Register Interface for SGMII IP Core +register_interface_smi ri ( + + // Control Signals + .rst_n (rst_n), + .gbe_mode (gbe_mode), + .sgmii_mode (sgmii_mode), + + // MDIO Port + .mdc (mdc), + .mdin (mdin), + .mdout (mdout), + .mdout_en (mdout_en), + .port_id (port_id), + + // Register Outputs + .mr_an_enable (mr_an_enable), + .mr_restart_an (mr_restart_an), + .mr_main_reset (mr_main_reset), + .mr_adv_ability (mr_adv_ability), + + // Register Inputs + .mr_an_complete (mr_an_complete), + .mr_page_rx (mr_page_rx), + .mr_lp_adv_ability (mr_lp_adv_ability) + ); + + + +// (G)MII Rate Resolution for SGMII IP Core +rate_resolution rate_resolution ( + .gbe_mode (gbe_mode), + .sgmii_mode (sgmii_mode), + .an_enable (mr_an_enable), + .advertised_rate (mr_adv_ability[11:10]), + .link_partner_rate (mr_lp_adv_ability[11:10]), + .non_an_rate (non_an_rate), + + .operational_rate (operational_rate) +); + + + + + +// Bidirectional Assignments +assign mdio = mdout_en ? mdout : 1'bz; // MDIO Output +assign mdin = mdio; // MDIO Input + +endmodule + -- 2.43.0