`timescale 1ns / 1ps `include "src/fifo.v" `include "src/rmii/rmii_serializer.v" module rmii_transmit_controller #( parameter FIFO_DEPTH = 16, parameter STORAGE_WIDTH = 8, // AUTOCALCULATED parameter STORAGE_MSB = STORAGE_WIDTH - 1, parameter SHIFT_COUNT = FIFO_DEPTH )( input clk, rst, clear, // general signals /* FIFO signals */ input [STORAGE_MSB:0] data_in, // input data input wrt, // store the data output not_full, // the internal buffer is not full /* RMII signals */ output reg TXEN, // transmit enable output [1:0] TXD, // transmit data output reg busy // there's an ongoing transmission ); wire rstclr = rst | clear; /* TX FIFO and its signals */ wire tx_fifo_empty; wire tx_fifo_out_valid; wire tx_fifo_full; wire [STORAGE_WIDTH-1:0]tx_fifo_out; //wire start = wrt && !busy; wire tx_fifo_pop = (busy && oser_empty) || oser_single; fifo #( .DEPTH(FIFO_DEPTH), .WIDTH(STORAGE_WIDTH) ) tx_fifo ( .clk(clk), .rst(rst), .clear(clear), .empty(tx_fifo_empty), .out_valid(tx_fifo_out_valid), .full(tx_fifo_full), .in(data_in), .push(wrt), .out(tx_fifo_out), .pop(tx_fifo_pop) ); assign not_full = !tx_fifo_full; /* output serializer */ wire oser_load = tx_fifo_out_valid; wire oser_empty; //wire oser_exhausted; wire oser_single; wire [1:0] oser_out; rmii_serializer #( .STORE_SIZE(STORAGE_WIDTH), .DIR(1) // RIGHT ) out_serializer ( .clk(clk), .rst(rst), .clear(clear), .par_in(tx_fifo_out), .ser_out(oser_out), .load(oser_load), .shift(1'b1), .single(oser_single), .empty(oser_empty), .exhausted(/*oser_exhausted*/) ); /* TXEN control */ always @(posedge clk) begin if (rstclr) begin TXEN <= 0; end else begin if (oser_load) // assert the same time the shift register loading occurs begin TXEN <= 1; end else if (oser_empty && tx_fifo_empty) // deassert only when all buffers has depleted begin TXEN <= 0; end end end /* busy control */ always @(posedge clk) begin if (rstclr) begin busy <= 0; end else begin if (!busy && wrt) begin busy <= 1; end if (busy && !wrt && !TXEN) begin busy <= 0; end end end // combinatorial output assign TXD = TXEN ? oser_out : 2'b0; endmodule