module Reg_int ( // Wishbone compliant core host interface input CLK_I, // Wishbone interface clock (nominally 50 MHz) input RST_I, // Active high (async) reset of the Wishbone interface input STB_I, // Active high module-select input CYC_I, // Active high cycle-enable input [6:0] ADR_I, // Module register address input WE_I, // Active high for writes, low for reads input [31:0] DAT_I, // Write data output reg [31:0] DAT_O, // Read data output reg ACK_O, // Acknowledge output – single high pulse // Tx host interface output [4:0] Tx_Hwmark, output [4:0] Tx_Lwmark, output MAC_tx_add_en, output FullDuplex, output [3:0] MaxRetry, output [5:0] IFGset, output [7:0] MAC_tx_add_prom_data, output [2:0] MAC_tx_add_prom_add, output MAC_tx_add_prom_wr, // Rx host interface output MAC_rx_add_chk_en, output [7:0] MAC_rx_add_prom_data, output [2:0] MAC_rx_add_prom_add, output MAC_rx_add_prom_wr, output broadcast_filter_en, output [15:0] broadcast_bucket_depth, output [15:0] broadcast_bucket_interval, output RX_APPEND_CRC, output [4:0] Rx_Hwmark, output [4:0] Rx_Lwmark, output CRC_chk_en, output [5:0] RX_IFG_SET, output [15:0] RX_MAX_LENGTH, // Default 1518 output [6:0] RX_MIN_LENGTH, // Default 64 // Flow control settings output pause_frame_send_en, output [15:0] pause_quanta_set, output tx_pause_en, output [15:0] fc_hwmark, output [15:0] fc_lwmark, // RMON host interface output [5:0] CPU_rd_addr, output CPU_rd_apply, input CPU_rd_grant, input [31:0] CPU_rd_dout, //Phy int host interface output Line_loop_en, output [2:0] Speed, //MII to CPU output [7:0] Divider, // Divider for the host clock output [15:0] CtrlData, // Control Data (to be written to the PHY reg.) output [4:0] Rgad, // Register Address (within the PHY) output [4:0] Fiad, // PHY Address output NoPre, // No Preamble (no 32-bit preamble) output WCtrlData, // Write Control Data operation output RStat, // Read Status operation output ScanStat, // Scan Status operation input Busy, // Busy Signal input LinkFail, // Link Integrity Signal input Nvalid, // Invalid Status (qualifier for the valid scan result) input [15:0] Prsd, // Read Status Data (data read from the PHY) input WCtrlDataStart, // This signals resets the WCTRLDATA bit in the MIIM Command register input RStatStart, // This signal resets the RSTAT BIT in the MIIM Command register input UpdateMIIRX_DATAReg // Updates MII RX_DATA register with read data ); // New registers for controlling the MII interface wire [8:0] MIIMODER; reg [2:0] MIICOMMAND; wire [12:0] MIIADDRESS; wire [15:0] MIITX_DATA; reg [15:0] MIIRX_DATA; wire [2:0] MIISTATUS; // New registers for controlling the MII interface // MIIMODER assign NoPre = MIIMODER[8]; assign Divider = MIIMODER[7:0]; // MIICOMMAND assign WCtrlData = MIICOMMAND[2]; assign RStat = MIICOMMAND[1]; assign ScanStat = MIICOMMAND[0]; // MIIADDRESS assign Rgad = MIIADDRESS[12:8]; assign Fiad = MIIADDRESS[4:0]; // MIITX_DATA assign CtrlData = MIITX_DATA[15:0]; // MIISTATUS assign MIISTATUS[2:0] = { 13'b0, Nvalid, Busy, LinkFail }; wire Wr; RegCPUData #( 5 ) U_0_000( Tx_Hwmark , 7'd000, 5'h09, RST_I, CLK_I, Wr, ADR_I, DAT_I[4:0] ); RegCPUData #( 5 ) U_0_001( Tx_Lwmark , 7'd001, 5'h08, RST_I, CLK_I, Wr, ADR_I, DAT_I[4:0] ); RegCPUData #( 1 ) U_0_002( pause_frame_send_en , 7'd002, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 16 ) U_0_003( pause_quanta_set , 7'd003, 16'h01af, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); RegCPUData #( 6 ) U_0_004( IFGset , 7'd004, 6'h0c, RST_I, CLK_I, Wr, ADR_I, DAT_I[5:0] ); RegCPUData #( 1 ) U_0_005( FullDuplex , 7'd005, 1'h1, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 4 ) U_0_006( MaxRetry , 7'd006, 4'h2, RST_I, CLK_I, Wr, ADR_I, DAT_I[3:0] ); RegCPUData #( 1 ) U_0_007( MAC_tx_add_en , 7'd007, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 8 ) U_0_008( MAC_tx_add_prom_data , 7'd008, 8'h00, RST_I, CLK_I, Wr, ADR_I, DAT_I[7:0] ); RegCPUData #( 3 ) U_0_009( MAC_tx_add_prom_add , 7'd009, 3'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[2:0] ); RegCPUData #( 1 ) U_0_010( MAC_tx_add_prom_wr , 7'd010, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 1 ) U_0_011( tx_pause_en , 7'd011, 1'h1, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 16 ) U_0_012( fc_hwmark , 7'd012, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); RegCPUData #( 16 ) U_0_013( fc_lwmark , 7'd013, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); RegCPUData #( 1 ) U_0_014( MAC_rx_add_chk_en , 7'd014, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 8 ) U_0_015( MAC_rx_add_prom_data , 7'd015, 8'h00, RST_I, CLK_I, Wr, ADR_I, DAT_I[7:0] ); RegCPUData #( 3 ) U_0_016( MAC_rx_add_prom_add , 7'd016, 3'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[2:0] ); RegCPUData #( 1 ) U_0_017( MAC_rx_add_prom_wr , 7'd017, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 1 ) U_0_018( broadcast_filter_en , 7'd018, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 16 ) U_0_019( broadcast_bucket_depth , 7'd019, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); RegCPUData #( 16 ) U_0_020( broadcast_bucket_interval , 7'd020, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); RegCPUData #( 1 ) U_0_021( RX_APPEND_CRC , 7'd021, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 5 ) U_0_022( Rx_Hwmark , 7'd022, 5'h1a, RST_I, CLK_I, Wr, ADR_I, DAT_I[4:0] ); RegCPUData #( 5 ) U_0_023( Rx_Lwmark , 7'd023, 5'h10, RST_I, CLK_I, Wr, ADR_I, DAT_I[4:0] ); RegCPUData #( 1 ) U_0_024( CRC_chk_en , 7'd024, 1'h1, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 6 ) U_0_025( RX_IFG_SET , 7'd025, 6'h0c, RST_I, CLK_I, Wr, ADR_I, DAT_I[5:0] ); RegCPUData #( 16 ) U_0_026( RX_MAX_LENGTH , 7'd026, 16'h2710, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); RegCPUData #( 7 ) U_0_027( RX_MIN_LENGTH , 7'd027, 7'h40, RST_I, CLK_I, Wr, ADR_I, DAT_I[6:0] ); RegCPUData #( 6 ) U_0_028( CPU_rd_addr , 7'd028, 6'h00, RST_I, CLK_I, Wr, ADR_I, DAT_I[5:0] ); RegCPUData #( 1 ) U_0_029( CPU_rd_apply , 7'd029, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); //RegCPUData #( 1 ) U_0_030( CPU_rd_grant , 7'd030, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); //RegCPUData #( 16 ) U_0_031( CPU_rd_dout_l , 7'd031, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); //RegCPUData #( 16 ) U_0_032( CPU_rd_dout_h , 7'd032, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); RegCPUData #( 1 ) U_0_033( Line_loop_en , 7'd033, 1'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[0:0] ); RegCPUData #( 3 ) U_0_034( Speed , 7'd034, 3'h0, RST_I, CLK_I, Wr, ADR_I, DAT_I[2:0] ); // New registers for controlling the MDIO interface RegCPUData #( 9 ) U_0_035( MIIMODER , 7'd035, 9'h064, RST_I, CLK_I, Wr, ADR_I, DAT_I[8:0] ); // Reg #36 is MIICOMMAND - implemented separately below RegCPUData #( 13 ) U_0_037( MIIADDRESS , 7'd037, 13'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[12:0] ); RegCPUData #( 16 ) U_0_038( MIITX_DATA , 7'd038, 16'h0000, RST_I, CLK_I, Wr, ADR_I, DAT_I[15:0] ); // Asserted in first clock of 2-cycle access, negated otherwise wire Access = ~ACK_O & STB_I & CYC_I; // Asserted in first clock of 2-cycle write access, negated otherwise assign Wr = Access & WE_I; // MIICOMMAND register - needs special treatment because of auto-resetting bits always @ ( posedge RST_I or posedge CLK_I ) if ( RST_I ) MIICOMMAND <= 0; else begin if ( Wr & ( ADR_I == 7'd036 ) ) // Write access MIICOMMAND <= DAT_I; else begin if ( WCtrlDataStart ) MIICOMMAND[2] <= 0; if ( RStatStart ) MIICOMMAND[1] <= 0; end end // MIIRX_DATA register always @ ( posedge RST_I or posedge CLK_I ) if ( RST_I ) MIIRX_DATA <= 0; else if ( UpdateMIIRX_DATAReg ) MIIRX_DATA <= Prsd; // ACK_O is asserted in second clock of 2-cycle access, negated otherwise always @ ( posedge RST_I or posedge CLK_I ) if ( RST_I ) ACK_O <= 0; else ACK_O <= Access; always @ ( posedge RST_I or posedge CLK_I ) if(RST_I) DAT_O <= 0; else begin DAT_O <=0; if ( Access & ~WE_I ) casez ( ADR_I ) 7'd00: DAT_O <= Tx_Hwmark; 7'd01: DAT_O <= Tx_Lwmark; 7'd02: DAT_O <= pause_frame_send_en; 7'd03: DAT_O <= pause_quanta_set; 7'd04: DAT_O <= IFGset; 7'd05: DAT_O <= FullDuplex; 7'd06: DAT_O <= MaxRetry; 7'd07: DAT_O <= MAC_tx_add_en; 7'd08: DAT_O <= MAC_tx_add_prom_data; 7'd09: DAT_O <= MAC_tx_add_prom_add; 7'd10: DAT_O <= MAC_tx_add_prom_wr; 7'd11: DAT_O <= tx_pause_en; 7'd12: DAT_O <= fc_hwmark; 7'd13: DAT_O <= fc_lwmark; 7'd14: DAT_O <= MAC_rx_add_chk_en; 7'd15: DAT_O <= MAC_rx_add_prom_data; 7'd16: DAT_O <= MAC_rx_add_prom_add; 7'd17: DAT_O <= MAC_rx_add_prom_wr; 7'd18: DAT_O <= broadcast_filter_en; 7'd19: DAT_O <= broadcast_bucket_depth; 7'd20: DAT_O <= broadcast_bucket_interval; 7'd21: DAT_O <= RX_APPEND_CRC; 7'd22: DAT_O <= Rx_Hwmark; 7'd23: DAT_O <= Rx_Lwmark; 7'd24: DAT_O <= CRC_chk_en; 7'd25: DAT_O <= RX_IFG_SET; 7'd26: DAT_O <= RX_MAX_LENGTH; 7'd27: DAT_O <= RX_MIN_LENGTH; 7'd28: DAT_O <= CPU_rd_addr; 7'd29: DAT_O <= CPU_rd_apply; 7'd30: DAT_O <= CPU_rd_grant; 7'd31: DAT_O <= CPU_rd_dout; //7'd32: DAT_O <= CPU_rd_dout[31:16]; 7'd33: DAT_O <= Line_loop_en; 7'd34: DAT_O <= Speed; // New registers for controlling MII interface 7'd35: DAT_O <= MIIMODER; 7'd36: DAT_O <= MIICOMMAND; 7'd37: DAT_O <= MIIADDRESS; 7'd38: DAT_O <= MIITX_DATA; 7'd39: DAT_O <= MIIRX_DATA; 7'd40: DAT_O <= MIISTATUS; endcase end endmodule module RegCPUData( RegOut, RegAddr, RegInit, Reset, Clk, Wr, Addr, WrData ); parameter WIDTH = 16; output reg [WIDTH-1:0] RegOut; input [6:0] RegAddr; input [WIDTH-1:0] RegInit; input Reset; input Clk; input Wr; input [6:0] Addr; input [WIDTH-1:0] WrData; always @( posedge Reset or posedge Clk ) if ( Reset ) RegOut <= RegInit; else if ( Wr && ( Addr == RegAddr ) ) RegOut <= WrData; endmodule