Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
`timescale 1ns / 1ps
module phy_tx_module(
input clk_in,
input MII_TX_EN,
input [3:0] MII_TXD,
output MII_TX_CLK,//2.5 mhz
output TX_p,
output TX_n
);
//clk_in - 80mhz
reg tx_clk = 1'd0;//10mhz
reg mii_tx_clk_reg = 'd0;//2.5mhz
assign MII_TX_CLK = mii_tx_clk_reg;
//this counters are only for clk generation
reg [3:0] clk_cnt = 'd0;//ethernet clk counter
reg [1:0] clk_cnt2 = 'd0;//MII_TX_CLK counter
reg [3:0] in_data_latch = 4'd0;
reg mii_tx_clk_edge = 1'd0;//2.5 mhz
reg serial_data = 1'd0;
reg tx_enable = 1'd0;//latched MII_TX_EN
wire manch_data = (serial_data^tx_clk) & tx_enable;//manchester data
// generate the NLP
//counter is 20 bit length
reg [19:0] link_pulse_count = 'd0;
always @(posedge clk_in) link_pulse_count <= tx_enable ? 20'd0 : link_pulse_count + 20'd1;
reg link_pulse = 'd0;
always @(posedge clk_in) link_pulse <= &link_pulse_count[19:3];
// generate the TP_IDL
reg [5:0] idlecount = 'd33; // enough bits to count 3 bit-times (8*3 = 24)
always @(posedge clk_in)
if (tx_enable) idlecount<=0; else if(~&idlecount) idlecount<=idlecount+5'd1;
wire idle_pulse = (~tx_enable) & (idlecount<24);//idle_pulse must not lock data, so it's disabled during tx time
wire tx_data2 = link_pulse | manch_data | idle_pulse;//include additional link data
wire tx_en2 = tx_enable | link_pulse | idle_pulse;//include additional link data
assign TX_p = tx_en2? tx_data2: 1'd0;
assign TX_n = tx_en2? ~tx_data2: 1'd0;
//80 div 8 = 10
//10 div 4 = 2.5
always@(posedge clk_in)
begin
if (clk_cnt > 'd6)
begin
clk_cnt = 'd0;
if (clk_cnt2 > 'd2) clk_cnt2 = 'd0;
else clk_cnt2 = clk_cnt2 + 2'd1;//2+1=3, and (3) will be hold for a tick
end
else clk_cnt = clk_cnt + 4'd1;//6+1=7, and (7) will be hold for a tick
if (clk_cnt < 'd3) tx_clk<= 'd1;//10 mhz
else tx_clk<= 'd0;
if (clk_cnt2 < 'd2) mii_tx_clk_reg<='d1;//2.5 mhz
else mii_tx_clk_reg<='d0;
mii_tx_clk_edge = ((clk_cnt2 == 'd0) && (clk_cnt == 'd0))? 1'd1: 1'd0;//2.5 mhz
if (mii_tx_clk_edge == 1'd1)
begin
in_data_latch = MII_TXD;//capture data from input
tx_enable <= MII_TX_EN;
serial_data <= MII_TXD[0];//first bit
end
else if (clk_cnt == 'd0)
begin
in_data_latch = {1'd0,in_data_latch[3:1]};
serial_data <= in_data_latch[0];
end
end
endmodule
d0f74983cThis file is pinned to the selected release. Download the original to open it in your design tool.