JitMeas-verilog/src/rmii/rmii_transmit_controller.v
2024-11-29 23:57:14 +01:00

129 lines
2.2 KiB
Verilog

`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