// SPDX-License-Identifier: AGPL-3.0-Only /* * Copyright (C) 2022 Sean Anderson */ `include "common.vh" `include "io.vh" module mii_io_tx ( input clk, input isolate, /* On-chip */ output reg ce, output reg enable, output reg err, output reg [3:0] data, /* Off-chip */ output reg tx_clk, input tx_en, input tx_er, input [3:0] txd ); reg ce_next, raw_enable; reg tx_clk_p_next, tx_clk_n, tx_clk_n_next; reg [2:0] counter, counter_next; initial counter = 4; always @(*) begin tx_clk_p_next = 0; tx_clk_n_next = 0; ce_next = 0; counter_next = counter - 1; case (counter) 4, 3: begin tx_clk_p_next = 1; tx_clk_n_next = 1; end 2: tx_clk_p_next = 1; 1: ; 0: begin ce_next = 1; counter_next = 4; end endcase enable = raw_enable && !isolate; end always @(posedge clk) begin counter <= counter_next; tx_clk_n <= tx_clk_n_next; ce <= ce_next; end `ifdef SYNTHESIS SB_IO #( .PIN_TYPE(`PIN_OUTPUT_ENABLE | `PIN_OUTPUT_DDR) ) tx_clk_pin ( .PACKAGE_PIN(tx_clk), .OUTPUT_CLK(clk), .OUTPUT_ENABLE(!isolate), .D_OUT_0(tx_clk_p_next), .D_OUT_1(tx_clk_n) ); SB_IO #( .PIN_TYPE(`PIN_INPUT_REGISTERED) ) tx_en_pin ( .PACKAGE_PIN(tx_en), .CLOCK_ENABLE(ce_next), .INPUT_CLK(clk), .D_IN_0(raw_enable) ); SB_IO #( .PIN_TYPE(`PIN_INPUT_REGISTERED) ) tx_er_pin ( .PACKAGE_PIN(tx_er), .CLOCK_ENABLE(ce_next), .INPUT_CLK(clk), .D_IN_0(err) ); genvar i; generate for (i = 0; i < 4; i = i + 1) begin SB_IO #( .PIN_TYPE(`PIN_INPUT_REGISTERED) ) txd_pin ( .PACKAGE_PIN(txd[i]), .CLOCK_ENABLE(ce_next), .INPUT_CLK(clk), .D_IN_0(data[i]) ); end endgenerate `else always @(posedge clk) begin if (ce_next) begin raw_enable <= tx_en; err <= tx_er; data <= txd; end end always @(posedge clk, negedge clk) begin if (isolate) tx_clk <= 1'bz; else tx_clk <= clk ? tx_clk_p_next : tx_clk_n; end `endif endmodule