aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v')
-rw-r--r--fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v1031
1 files changed, 1031 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v b/fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v
new file mode 100644
index 000000000..b70bc7294
--- /dev/null
+++ b/fpga/usrp3/lib/xge/rtl/verilog/wishbone_if.v
@@ -0,0 +1,1031 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// File name "wishbone.v" ////
+//// ////
+//// This file is part of the "10GE MAC" project ////
+//// http://www.opencores.org/cores/xge_mac/ ////
+//// ////
+//// Author(s): ////
+//// - A. Tanguay (antanguay@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 AUTHORS. All rights reserved. ////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`include "defines.v"
+
+module wishbone_if(/*AUTOARG*/
+ // Outputs
+ wb_dat_o, wb_ack_o, wb_int_o, ctrl_tx_enable,
+ mdc, mdio_out, mdio_tri, xge_gpo,
+
+ // Inputs
+ wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i, wb_we_i, wb_stb_i, wb_cyc_i,
+ status_crc_error, status_fragment_error, status_txdfifo_ovflow,
+ status_txdfifo_udflow, status_rxdfifo_ovflow, status_rxdfifo_udflow,
+ status_pause_frame_rx, status_local_fault, status_remote_fault,
+ mdio_in, xge_gpi
+ );
+
+
+input wb_clk_i;
+input wb_rst_i;
+
+input [7:0] wb_adr_i;
+input [31:0] wb_dat_i;
+input wb_we_i;
+input wb_stb_i;
+input wb_cyc_i;
+
+output [31:0] wb_dat_o;
+output wb_ack_o;
+output wb_int_o;
+
+input status_crc_error;
+input status_fragment_error;
+
+input status_txdfifo_ovflow;
+
+input status_txdfifo_udflow;
+
+input status_rxdfifo_ovflow;
+
+input status_rxdfifo_udflow;
+
+input status_pause_frame_rx;
+
+input status_local_fault;
+input status_remote_fault;
+
+output ctrl_tx_enable;
+
+output reg mdc;
+output reg mdio_out;
+output reg mdio_tri; // Assert to tristate driver.
+input mdio_in;
+input [7:0] xge_gpi;
+output reg [7:0] xge_gpo;
+
+ //
+ // State Declarations
+ //
+ parameter IDLE = 0,
+ PREAMBLE1 = 1,
+ PREAMBLE2 = 2,
+ PREAMBLE3 = 3,
+ PREAMBLE4 = 4,
+ PREAMBLE5 = 5,
+ PREAMBLE6 = 6,
+ PREAMBLE7 = 7,
+ PREAMBLE8 = 8,
+ PREAMBLE9 = 9,
+ PREAMBLE10 = 10,
+ PREAMBLE11 = 11,
+ PREAMBLE12 = 12,
+ PREAMBLE13 = 13,
+ PREAMBLE14 = 14,
+ PREAMBLE15 = 15,
+ PREAMBLE16 = 16,
+ PREAMBLE17 = 17,
+ PREAMBLE18 = 18,
+ PREAMBLE19 = 19,
+ PREAMBLE20 = 20,
+ PREAMBLE21 = 21,
+ PREAMBLE22 = 22,
+ PREAMBLE23 = 23,
+ PREAMBLE24 = 24,
+ PREAMBLE25 = 25,
+ PREAMBLE26 = 26,
+ PREAMBLE27 = 27,
+ PREAMBLE28 = 28,
+ PREAMBLE29 = 29,
+ PREAMBLE30 = 30,
+ PREAMBLE31 = 31,
+ PREAMBLE32 = 32,
+ START1 = 33,
+ C22_START2 = 34,
+ C45_START2 = 35,
+ OP1 = 36,
+ OP2 = 37,
+ PRTAD1 = 38,
+ PRTAD2 = 39,
+ PRTAD3 = 40,
+ PRTAD4 = 41,
+ PRTAD5 = 42,
+ DEVAD1 = 43,
+ DEVAD2 = 44,
+ DEVAD3 = 45,
+ DEVAD4 = 46,
+ DEVAD5 = 47,
+ TA1 = 48,
+ TA2 = 49,
+ TA3 = 50,
+ READ1 = 51,
+ READ2 = 52,
+ READ3 = 53,
+ READ4 = 54,
+ READ5 = 55,
+ READ6 = 56,
+ READ7 = 57,
+ READ8 = 58,
+ READ9 = 59,
+ READ10 = 60,
+ READ11 = 61,
+ READ12 = 62,
+ READ13 = 63,
+ READ14 = 64,
+ READ15 = 65,
+ READ16 = 66,
+ WRITE1 = 67,
+ WRITE2 = 68,
+ WRITE3 = 69,
+ WRITE4 = 70,
+ WRITE5 = 71,
+ WRITE6 = 72,
+ WRITE7 = 73,
+ WRITE8 = 74,
+ WRITE9 = 75,
+ WRITE10 = 76,
+ WRITE11 = 77,
+ WRITE12 = 78,
+ WRITE13 = 79,
+ WRITE14 = 80,
+ WRITE15 = 81,
+ WRITE16 = 82,
+ C45_ADDR1 = 83,
+ C45_ADDR2 = 84,
+ C45_ADDR3 = 85,
+ C45_ADDR4 = 86,
+ C45_ADDR5 = 87,
+ C45_ADDR6 = 88,
+ C45_ADDR7 = 89,
+ C45_ADDR8 = 90,
+ C45_ADDR9 = 91,
+ C45_ADDR10 = 92,
+ C45_ADDR11 = 93,
+ C45_ADDR12 = 94,
+ C45_ADDR13 = 95,
+ C45_ADDR14 = 96,
+ C45_ADDR15 = 97,
+ C45_ADDR16 = 98,
+ PREIDLE = 99;
+
+
+
+
+/*AUTOREG*/
+// Beginning of automatic regs (for this module's undeclared outputs)
+reg [31:0] wb_dat_o;
+reg wb_int_o;
+// End of automatics
+
+reg [0:0] cpureg_config0;
+reg [8:0] cpureg_int_pending;
+reg [8:0] cpureg_int_mask;
+
+reg cpuack;
+
+reg status_remote_fault_d1;
+reg status_local_fault_d1;
+
+reg [15:0] mdio_read_data;
+reg [15:0] mdio_write_data;
+reg [15:0] mdio_address;
+reg [12:0] mdio_operation;
+reg mdio_control;
+reg [7:0] mdc_clk_count;
+reg mdc_falling_edge;
+reg mdio_running;
+reg mdio_done;
+reg [7:0] state;
+reg [7:0] xge_gpi_reg;
+reg [7:0] xge_gpo_reg;
+
+
+
+/*AUTOWIRE*/
+
+wire [8:0] int_sources;
+
+
+//---
+// Source of interrupts, some are edge sensitive, others
+// expect a pulse signal.
+
+assign int_sources = {
+ status_fragment_error,
+ status_crc_error,
+
+ status_pause_frame_rx,
+
+ status_remote_fault ^ status_remote_fault_d1,
+ status_local_fault ^ status_local_fault_d1,
+
+ status_rxdfifo_udflow,
+ status_rxdfifo_ovflow,
+ status_txdfifo_udflow,
+ status_txdfifo_ovflow
+ };
+
+//---
+// Config Register 0
+
+//TODO
+//assign ctrl_tx_enable = cpureg_config0[0];
+assign ctrl_tx_enable = 1'b1;
+
+
+
+//---
+// Wishbone signals
+
+assign wb_ack_o = cpuack && wb_stb_i;
+
+always @(posedge wb_clk_i or posedge wb_rst_i) begin
+
+ if (wb_rst_i == 1'b1) begin
+
+ cpureg_config0 <= 1'h1;
+ cpureg_int_pending <= 9'b0;
+ cpureg_int_mask <= 9'b0;
+
+ wb_dat_o <= 32'b0;
+ wb_int_o <= 1'b0;
+
+ cpuack <= 1'b0;
+
+ mdio_address <= 0;
+ mdio_operation <= 0;
+ mdio_write_data <= 0;
+
+ mdio_running <= 0;
+ xge_gpi_reg <= 0;
+ xge_gpo <= 0;
+ xge_gpo_reg <= 0;
+
+
+
+
+ // status_remote_fault_d1 <= status_remote_fault;
+ // status_local_fault_d1 <= status_local_fault;
+ // IJB. Original code was unsynthesizable and a little bizzare
+ // implying reset would latch data.
+ status_remote_fault_d1 <= 0;
+ status_local_fault_d1 <= 0;
+ end
+ else begin
+
+ wb_int_o <= |(cpureg_int_pending & cpureg_int_mask);
+
+ cpureg_int_pending <= cpureg_int_pending | int_sources;
+
+ cpuack <= wb_cyc_i && wb_stb_i;
+
+ status_remote_fault_d1 <= status_remote_fault;
+ status_local_fault_d1 <= status_local_fault;
+
+ // Handshake to MDIO state machine to reset running flag in status.
+ // Wait for falling MDC edge to prevent S/W race condition occuring
+ // where done flag still asserted but running flag now cleared (repeatedly).
+ if (mdio_done && mdc_falling_edge)
+ mdio_running <= 0;
+
+ // Register GPIO to allow regs placed in the I/O cells and provide some metastability prot
+ xge_gpi_reg <= xge_gpi;
+ xge_gpo <= xge_gpo_reg;
+
+
+ //---
+ // Read access
+
+ if (wb_cyc_i && wb_stb_i && !wb_we_i) begin
+
+ case ({wb_adr_i[7:2], 2'b0})
+
+ `CPUREG_CONFIG0: begin
+ wb_dat_o <= {31'b0, cpureg_config0};
+ end
+
+ `CPUREG_INT_PENDING: begin
+ wb_dat_o <= {23'b0, cpureg_int_pending};
+ cpureg_int_pending <= int_sources;
+ wb_int_o <= 1'b0;
+ end
+
+ `CPUREG_INT_STATUS: begin
+ wb_dat_o <= {23'b0, int_sources};
+ end
+
+ `CPUREG_INT_MASK: begin
+ wb_dat_o <= {23'b0, cpureg_int_mask};
+ end
+
+ `CPUREG_MDIO_DATA: begin
+ wb_dat_o <= {16'b0, mdio_read_data};
+ end
+
+ `CPUREG_MDIO_STATUS: begin
+ wb_dat_o <= {31'b0, mdio_running};
+ end
+
+ `CPUREG_GPIO: begin
+ wb_dat_o <= {24'b0, xge_gpi_reg};
+ end
+
+
+ default: begin
+ end
+
+ endcase
+
+ end
+
+ //---
+ // Write access
+
+ if (wb_cyc_i && wb_stb_i && wb_we_i) begin
+ $display("reg write @ addr %x",({wb_adr_i[7:2], 2'b0}));
+
+ case ({wb_adr_i[7:2], 2'b0})
+
+ `CPUREG_CONFIG0: begin
+ cpureg_config0 <= wb_dat_i[0:0];
+ end
+
+ `CPUREG_INT_PENDING: begin
+ cpureg_int_pending <= wb_dat_i[8:0] | cpureg_int_pending | int_sources;
+ end
+
+ `CPUREG_INT_MASK: begin
+ cpureg_int_mask <= wb_dat_i[8:0];
+ end
+
+ `CPUREG_MDIO_DATA: begin
+ mdio_write_data <= wb_dat_i[15:0];
+ end
+
+ `CPUREG_MDIO_ADDR: begin
+ mdio_address <= wb_dat_i[15:0];
+ end
+
+ `CPUREG_MDIO_OP: begin
+ mdio_operation <= wb_dat_i[12:0];
+ end
+
+ `CPUREG_MDIO_CONTROL: begin
+ // Trigger mdio operation here. Cleared by state machine at end of bus transaction.
+ if (wb_dat_i[0])
+ mdio_running <= 1;
+ end
+
+ `CPUREG_GPIO: begin
+ xge_gpo_reg <= wb_dat_i[7:0];
+ end
+
+
+ default: begin
+ end
+
+ endcase
+
+ end
+
+ end
+
+end // always @ (posedge wb_clk_i or posedge wb_rst_i)
+
+ //
+ // Produce mdc clock as a signal synchronously from Wishbone clock.
+ //
+ always @(posedge wb_clk_i or posedge wb_rst_i)
+ if (wb_rst_i)
+ begin
+ mdc_clk_count <= 1;
+ mdc <= 0;
+ mdc_falling_edge <= 0;
+ end
+ else if (mdc_clk_count == `MDC_HALF_PERIOD)
+ begin
+ mdc_clk_count <= 1;
+ mdc <= ~mdc;
+ mdc_falling_edge <= mdc;
+ end
+ else
+ begin
+ mdc_clk_count <= mdc_clk_count + 1;
+ mdc_falling_edge <= 0;
+ end
+
+ //
+ // MDIO state machine
+ //
+ always @(posedge wb_clk_i or posedge wb_rst_i)
+ if (wb_rst_i)
+ begin
+ mdio_tri <= 1;
+ mdio_out <= 0;
+ mdio_done <= 0;
+ mdio_read_data <= 0;
+ state <= IDLE;
+ end
+ else if (mdc_falling_edge)
+ //
+ // This is the MDIO bus controller. Use falling edge of MDC.
+ //
+ begin
+ // Defaults
+ mdio_tri <= 1;
+ mdio_out <= 0;
+ mdio_done <= 0;
+
+
+ case(state)
+ // IDLE.
+ // In Clause 22 & 45 the master of the MDIO bus is tristate during idle.
+ //
+ IDLE: begin
+ mdio_tri <= 1;
+ mdio_out <= 0;
+ if (mdio_running)
+ state <= PREAMBLE1;
+ end
+ // Preamble. All MDIO transactions begin witrh 32bits of 1 bits as a preamble.
+ PREAMBLE1: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE2;
+ end
+ PREAMBLE2: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE3;
+ end
+ PREAMBLE3: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE4;
+ end
+ PREAMBLE4: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE5;
+ end
+ PREAMBLE5: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE6;
+ end
+ PREAMBLE6: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE7;
+ end
+ PREAMBLE7: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE8;
+ end
+ PREAMBLE8: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE9;
+ end
+ PREAMBLE9: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE10;
+ end
+ PREAMBLE10: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE11;
+ end
+ PREAMBLE11: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE12;
+ end
+ PREAMBLE12: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE13;
+ end
+ PREAMBLE13: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE14;
+ end
+ PREAMBLE14: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE15;
+ end
+ PREAMBLE15: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE16;
+ end
+ PREAMBLE16: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE17;
+ end
+ PREAMBLE17: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE18;
+ end
+ PREAMBLE18: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE19;
+ end
+ PREAMBLE19: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE20;
+ end
+ PREAMBLE20: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE21;
+ end
+ PREAMBLE21: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE22;
+ end
+ PREAMBLE22: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE23;
+ end
+ PREAMBLE23: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE24;
+ end
+ PREAMBLE24: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE25;
+ end
+ PREAMBLE25: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE26;
+ end
+ PREAMBLE26: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE27;
+ end
+ PREAMBLE27: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE28;
+ end
+ PREAMBLE28: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE29;
+ end
+ PREAMBLE29: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE30;
+ end
+ PREAMBLE30: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE31;
+ end
+ PREAMBLE31: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= PREAMBLE32;
+ end
+ PREAMBLE32: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= START1;
+ end
+ //
+ // Start code for Clause 22 is 01 and Clause 45 is 00
+ //
+ START1: begin
+ mdio_tri <= 0;
+ mdio_out <= 0;
+ if (mdio_operation[12])
+ // Clause 45 bit set.
+ state <= C45_START2;
+ else
+ state <= C22_START2;
+ end
+ //
+ // 2nd Clause 22 start bit is a 1
+ //
+ C22_START2: begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= OP1;
+ end
+ //
+ // 2nd Clause 45 start bit is a 0
+ //
+ C45_START2: begin
+ mdio_tri <= 0;
+ mdio_out <= 0;
+ state <= OP1;
+ end
+ //
+ // Both Clause 22 & 45 use 2 bits for operation and are compatable.
+ // Note we don't screen here for illegal Clause 22 ops.
+ //
+ OP1: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[11];
+ state <= OP2;
+ end
+ OP2: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[10];
+ state <= PRTAD1;
+ end
+ //
+ // Both Clause 22 & 45 use 2 sucsessive 5 bit fields to form a hierarchical address
+ // though it's used slightly different between the 2 standards.
+ //
+ PRTAD1: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[9];
+ state <= PRTAD2;
+ end
+ PRTAD2: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[8];
+ state <= PRTAD3;
+ end
+ PRTAD3: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[7];
+ state <= PRTAD4;
+ end
+ PRTAD4: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[6];
+ state <= PRTAD5;
+ end
+ PRTAD5: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[5];
+ state <= DEVAD1;
+ end
+ DEVAD1: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[4];
+ state <= DEVAD2;
+ end
+ DEVAD2: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[3];
+ state <= DEVAD3;
+ end
+ DEVAD3: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[2];
+ state <= DEVAD4;
+ end
+ DEVAD4: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[1];
+ state <= DEVAD5;
+ end
+ DEVAD5: begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_operation[0];
+ state <= TA1;
+ end
+ //
+ // Both Clause 22 & Clause 45 use the same turn around on the bus.
+ // Reads have Z as the first bit and 0 driven by the slave for the 2nd bit.
+ // Note that slaves drive the bus on the rising edge of MDC.
+ // Writes and Address cycles have 10 driven by the master.
+ //
+ TA1: begin
+ if (mdio_operation[11] == 0) // Write/Address
+ begin
+ mdio_tri <= 0;
+ mdio_out <= 1;
+ state <= TA2;
+ end
+ else // Read
+ begin
+ mdio_tri <= 1;
+ state <= TA3;
+ end
+ end
+ TA2: begin
+ mdio_tri <= 0;
+ mdio_out <= 0;
+ if (!mdio_operation[12]) // Clause 22 Write
+ state <= WRITE1;
+ else if (mdio_operation[10]) // Clause 45 Write
+ state <= WRITE1;
+ else // Clause 45 ADDRESS
+ state <= C45_ADDR1;
+ end
+ TA3: begin
+ mdio_tri <= 1;
+ state <= READ1;
+ end
+ //
+ // Clause 22 Reads and both forms of clause 45 Reads have the same bus transaction from here out.
+ //
+ READ1: begin
+ mdio_tri <= 1;
+ mdio_read_data[15] <= mdio_in;
+ state <= READ2;
+ end
+ READ2: begin
+ mdio_tri <= 1;
+ mdio_read_data[14] <= mdio_in;
+ state <= READ3;
+ end
+ READ3: begin
+ mdio_tri <= 1;
+ mdio_read_data[13] <= mdio_in;
+ state <= READ4;
+ end
+ READ4: begin
+ mdio_tri <= 1;
+ mdio_read_data[12] <= mdio_in;
+ state <= READ5;
+ end
+ READ5: begin
+ mdio_tri <= 1;
+ mdio_read_data[11] <= mdio_in;
+ state <= READ6;
+ end
+ READ6: begin
+ mdio_tri <= 1;
+ mdio_read_data[10] <= mdio_in;
+ state <= READ7;
+ end
+ READ7: begin
+ mdio_tri <= 1;
+ mdio_read_data[9] <= mdio_in;
+ state <= READ8;
+ end
+ READ8: begin
+ mdio_tri <= 1;
+ mdio_read_data[8] <= mdio_in;
+ state <= READ9;
+ end
+ READ9: begin
+ mdio_tri <= 1;
+ mdio_read_data[7] <= mdio_in;
+ state <= READ10;
+ end
+ READ10: begin
+ mdio_tri <= 1;
+ mdio_read_data[6] <= mdio_in;
+ state <= READ11;
+ end
+ READ11: begin
+ mdio_tri <= 1;
+ mdio_read_data[5] <= mdio_in;
+ state <= READ12;
+ end
+ READ12: begin
+ mdio_tri <= 1;
+ mdio_read_data[4] <= mdio_in;
+ state <= READ13;
+ end
+ READ13: begin
+ mdio_tri <= 1;
+ mdio_read_data[3] <= mdio_in;
+ state <= READ14;
+ end
+ READ14: begin
+ mdio_tri <= 1;
+ mdio_read_data[2] <= mdio_in;
+ state <= READ15;
+ end
+ READ15: begin
+ mdio_tri <= 1;
+ mdio_read_data[1] <= mdio_in;
+ state <= READ16;
+ end
+ READ16: begin
+ mdio_tri <= 1;
+ mdio_read_data[0] <= mdio_in;
+ state <= PREIDLE;
+ mdio_done <= 1;
+ end
+ //
+ // Write 16bits of data for all types of Write.
+ //
+ WRITE1:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[15];
+ state <= WRITE2;
+ end
+ WRITE2:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[14];
+ state <= WRITE3;
+ end
+ WRITE3:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[13];
+ state <= WRITE4;
+ end
+ WRITE4:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[12];
+ state <= WRITE5;
+ end
+ WRITE5:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[11];
+ state <= WRITE6;
+ end
+ WRITE6:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[10];
+ state <= WRITE7;
+ end
+ WRITE7:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[9];
+ state <= WRITE8;
+ end
+ WRITE8:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[8];
+ state <= WRITE9;
+ end
+ WRITE9:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[7];
+ state <= WRITE10;
+ end
+ WRITE10:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[6];
+ state <= WRITE11;
+ end
+ WRITE11:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[5];
+ state <= WRITE12;
+ end
+ WRITE12:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[4];
+ state <= WRITE13;
+ end
+ WRITE13:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[3];
+ state <= WRITE14;
+ end
+ WRITE14:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[2];
+ state <= WRITE15;
+ end
+ WRITE15:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[1];
+ state <= WRITE16;
+ end
+ WRITE16:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_write_data[0];
+ state <= PREIDLE;
+ mdio_done <= 1;
+ end
+ //
+ // Write 16bits of address for a Clause 45 Address transaction
+ //
+ C45_ADDR1:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[15];
+ state <= C45_ADDR2;
+ end
+ C45_ADDR2:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[14];
+ state <= C45_ADDR3;
+ end
+ C45_ADDR3:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[13];
+ state <= C45_ADDR4;
+ end
+ C45_ADDR4:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[12];
+ state <= C45_ADDR5;
+ end
+ C45_ADDR5:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[11];
+ state <= C45_ADDR6;
+ end
+ C45_ADDR6:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[10];
+ state <= C45_ADDR7;
+ end
+ C45_ADDR7:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[9];
+ state <= C45_ADDR8;
+ end
+ C45_ADDR8:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[8];
+ state <= C45_ADDR9;
+ end
+ C45_ADDR9:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[7];
+ state <= C45_ADDR10;
+ end
+ C45_ADDR10:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[6];
+ state <= C45_ADDR11;
+ end
+ C45_ADDR11:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[5];
+ state <= C45_ADDR12;
+ end
+ C45_ADDR12:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[4];
+ state <= C45_ADDR13;
+ end
+ C45_ADDR13:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[3];
+ state <= C45_ADDR14;
+ end
+ C45_ADDR14:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[2];
+ state <= C45_ADDR15;
+ end
+ C45_ADDR15:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[1];
+ state <= C45_ADDR16;
+ end
+ C45_ADDR16:begin
+ mdio_tri <= 0;
+ mdio_out <= mdio_address[0];
+ state <= PREIDLE;
+ mdio_done <= 1;
+ end
+ //
+ // PREIDLE allows the mdio_running bit to reset.
+ //
+ PREIDLE: begin
+ state <= IDLE;
+ end
+ endcase // case(state)
+
+ end // if (mdc_falling_edge)
+
+
+
+
+endmodule
+