Implement generic MAX2771 raw Ethernet recorder
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
`default_nettype none
|
||||
|
||||
// RTL8211FDI link qualification over IEEE 802.3 Clause-22 MDIO. The board
|
||||
// straps the PHY for auto-negotiation and address 2. Realtek PHYSR is on page
|
||||
// 0xa43, register 0x1a; it reports real-time link, resolved speed and duplex.
|
||||
// Page 0 is restored after every poll so no hidden PHY state leaks outward.
|
||||
module phy_init_rtl8211f #(
|
||||
parameter int unsigned CLK_HZ = 125_000_000,
|
||||
parameter int unsigned SETTLE_MS = 30,
|
||||
parameter int unsigned POLL_MS = 100,
|
||||
parameter logic [4:0] PHY_ADDRESS = 5'd2
|
||||
) (
|
||||
input wire logic clk,
|
||||
input wire logic rst,
|
||||
input wire logic phy_reset_complete,
|
||||
output logic mdio_start,
|
||||
output logic mdio_write,
|
||||
output logic [4:0] mdio_phy_address,
|
||||
output logic [4:0] mdio_register_address,
|
||||
output logic [15:0] mdio_write_data,
|
||||
input wire logic mdio_busy,
|
||||
input wire logic mdio_done,
|
||||
input wire logic [15:0] mdio_read_data,
|
||||
output logic initialization_complete,
|
||||
output logic link_ready,
|
||||
output logic [63:0] link_down_events
|
||||
);
|
||||
localparam longint unsigned SETTLE_CYCLES = (CLK_HZ / 1000) * SETTLE_MS;
|
||||
localparam longint unsigned POLL_CYCLES = (CLK_HZ / 1000) * POLL_MS;
|
||||
localparam longint unsigned MAX_CYCLES =
|
||||
(POLL_CYCLES > SETTLE_CYCLES) ? POLL_CYCLES : SETTLE_CYCLES;
|
||||
localparam int unsigned TIMER_W = (MAX_CYCLES < 2) ? 1 : $clog2(MAX_CYCLES + 1);
|
||||
|
||||
typedef enum logic [3:0] {
|
||||
S_WAIT_RESET, S_SETTLE,
|
||||
S_START_PAGE, S_WAIT_PAGE,
|
||||
S_START_PHYSR, S_WAIT_PHYSR,
|
||||
S_START_RESTORE, S_WAIT_RESTORE,
|
||||
S_POLL_WAIT
|
||||
} state_t;
|
||||
state_t state;
|
||||
logic [TIMER_W-1:0] timer;
|
||||
logic [15:0] physr;
|
||||
logic qualified_link;
|
||||
|
||||
always_comb begin
|
||||
mdio_write = (state == S_START_PAGE || state == S_WAIT_PAGE ||
|
||||
state == S_START_RESTORE || state == S_WAIT_RESTORE);
|
||||
mdio_phy_address = PHY_ADDRESS;
|
||||
mdio_register_address = (state == S_START_PHYSR || state == S_WAIT_PHYSR)
|
||||
? 5'h1a : 5'h1f;
|
||||
mdio_write_data = (state == S_START_PAGE || state == S_WAIT_PAGE)
|
||||
? 16'h0a43 : 16'h0000;
|
||||
|
||||
// PHYSR[5:4]=2'b10 is 1000 Mb/s, bit 3 full duplex, bit 2 link.
|
||||
qualified_link = (physr[5:4] == 2'b10) && physr[3] && physr[2];
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
state <= S_WAIT_RESET;
|
||||
timer <= '0;
|
||||
physr <= 16'd0;
|
||||
mdio_start <= 1'b0;
|
||||
initialization_complete <= 1'b0;
|
||||
link_ready <= 1'b0;
|
||||
link_down_events <= 64'd0;
|
||||
end else begin
|
||||
mdio_start <= 1'b0;
|
||||
case (state)
|
||||
S_WAIT_RESET: begin
|
||||
link_ready <= 1'b0;
|
||||
if (phy_reset_complete) begin
|
||||
timer <= '0;
|
||||
state <= S_SETTLE;
|
||||
end
|
||||
end
|
||||
|
||||
S_SETTLE: begin
|
||||
if (timer == SETTLE_CYCLES-1) begin
|
||||
timer <= '0;
|
||||
state <= S_START_PAGE;
|
||||
end else begin
|
||||
timer <= timer + {{(TIMER_W-1){1'b0}}, 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
S_START_PAGE: begin
|
||||
if (!mdio_busy) begin
|
||||
mdio_start <= 1'b1;
|
||||
state <= S_WAIT_PAGE;
|
||||
end
|
||||
end
|
||||
S_WAIT_PAGE: if (mdio_done) state <= S_START_PHYSR;
|
||||
|
||||
S_START_PHYSR: begin
|
||||
if (!mdio_busy) begin
|
||||
mdio_start <= 1'b1;
|
||||
state <= S_WAIT_PHYSR;
|
||||
end
|
||||
end
|
||||
S_WAIT_PHYSR: begin
|
||||
if (mdio_done) begin
|
||||
physr <= mdio_read_data;
|
||||
state <= S_START_RESTORE;
|
||||
end
|
||||
end
|
||||
|
||||
S_START_RESTORE: begin
|
||||
if (!mdio_busy) begin
|
||||
mdio_start <= 1'b1;
|
||||
state <= S_WAIT_RESTORE;
|
||||
end
|
||||
end
|
||||
S_WAIT_RESTORE: begin
|
||||
if (mdio_done) begin
|
||||
initialization_complete <= 1'b1;
|
||||
if (link_ready && !qualified_link)
|
||||
link_down_events <= link_down_events + 64'd1;
|
||||
link_ready <= qualified_link;
|
||||
timer <= '0;
|
||||
state <= S_POLL_WAIT;
|
||||
end
|
||||
end
|
||||
|
||||
S_POLL_WAIT: begin
|
||||
if (timer == POLL_CYCLES-1) begin
|
||||
timer <= '0;
|
||||
state <= S_START_PAGE;
|
||||
end else begin
|
||||
timer <= timer + {{(TIMER_W-1){1'b0}}, 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
default: state <= S_WAIT_RESET;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
if (CLK_HZ < 1000) $error("CLK_HZ must be at least 1000");
|
||||
if (SETTLE_MS == 0 || POLL_MS == 0)
|
||||
$error("SETTLE_MS and POLL_MS must be non-zero");
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
@@ -0,0 +1,31 @@
|
||||
`default_nettype none
|
||||
|
||||
// Core-side half-cycle values for Efinity Interface Designer DDIO outputs.
|
||||
// The physical GPIOs are configured as DDIO_RESYNC in interface/create_interface.py.
|
||||
// *_HI is launched on the rising edge and *_LO on the falling edge.
|
||||
module rgmii_tx_efinix (
|
||||
input wire logic [7:0] gmii_txd,
|
||||
input wire logic gmii_tx_en,
|
||||
input wire logic gmii_tx_er,
|
||||
output logic [3:0] eth_txd_HI,
|
||||
output logic [3:0] eth_txd_LO,
|
||||
output logic eth_txctl_HI,
|
||||
output logic eth_txctl_LO,
|
||||
output logic eth_txc_HI,
|
||||
output logic eth_txc_LO
|
||||
);
|
||||
always_comb begin
|
||||
// RGMII: GMII bits 3:0 on the rising edge, bits 7:4 on falling.
|
||||
eth_txd_HI = gmii_txd[3:0];
|
||||
eth_txd_LO = gmii_txd[7:4];
|
||||
eth_txctl_HI = gmii_tx_en;
|
||||
eth_txctl_LO = gmii_tx_en ^ gmii_tx_er;
|
||||
|
||||
// These constants are clocked by the 90-degree PLL output in the
|
||||
// periphery, producing the forwarded 125 MHz RGMII TX clock.
|
||||
eth_txc_HI = 1'b1;
|
||||
eth_txc_LO = 1'b0;
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
@@ -0,0 +1,142 @@
|
||||
`default_nettype none
|
||||
|
||||
// Hardware-only Ethernet diagnostic. This top intentionally bypasses the RF
|
||||
// capture/FIFO and supplies an endless, ordered 0..15 sample sequence to the
|
||||
// production packetizer, MAC, FCS, RGMII and PHY-management blocks.
|
||||
module ti375_ethernet_selftest_top (
|
||||
input wire logic pll_dummy_clk,
|
||||
input wire logic eth_clk,
|
||||
input wire logic eth_clk90,
|
||||
input wire logic pll_locked,
|
||||
output logic pll_resetn,
|
||||
input wire logic rf_clk_pmod,
|
||||
input wire logic [3:0] rf_data_pmod_HI,
|
||||
input wire logic [3:0] rf_data_pmod_LO,
|
||||
output logic eth_mdc,
|
||||
input wire logic eth_mdio_IN,
|
||||
output logic eth_mdio_OUT,
|
||||
output logic eth_mdio_OE,
|
||||
output logic eth_phyrst_n,
|
||||
output logic [3:0] eth_txd_HI,
|
||||
output logic [3:0] eth_txd_LO,
|
||||
output logic eth_txctl_HI,
|
||||
output logic eth_txctl_LO,
|
||||
output logic eth_txc_HI,
|
||||
output logic eth_txc_LO,
|
||||
output logic [4:0] user_led
|
||||
);
|
||||
localparam int unsigned FIFO_DEPTH = 16384;
|
||||
|
||||
logic eth_rst;
|
||||
logic phy_reset_complete;
|
||||
logic mdio_start, mdio_write, mdio_busy, mdio_done;
|
||||
logic [4:0] mdio_phy_address, mdio_register_address;
|
||||
logic [15:0] mdio_write_data, mdio_read_data;
|
||||
logic phy_init_complete, link_ready;
|
||||
logic [63:0] link_down_events;
|
||||
|
||||
logic fifo_rd_en, fifo_rd_valid;
|
||||
logic [68:0] fifo_rd_data;
|
||||
logic [63:0] generated_sample_index;
|
||||
logic mac_frame_start, mac_payload_valid, mac_payload_ready;
|
||||
logic mac_busy, mac_frame_done;
|
||||
logic [10:0] mac_payload_length;
|
||||
logic [7:0] mac_payload_data;
|
||||
logic [31:0] packet_sequence;
|
||||
logic frame_activity_pulse;
|
||||
logic [7:0] gmii_txd;
|
||||
logic gmii_tx_en, gmii_tx_er;
|
||||
logic [63:0] frames_transmitted, payload_bytes_transmitted;
|
||||
logic [22:0] heartbeat;
|
||||
logic activity_toggle;
|
||||
|
||||
assign pll_resetn = 1'b1;
|
||||
|
||||
reset_sync u_eth_reset (.clk(eth_clk), .arst(!pll_locked), .srst(eth_rst));
|
||||
|
||||
phy_reset_ctrl #(.CLK_HZ(125_000_000), .RESET_LOW_MS(10)) u_phy_reset (
|
||||
.clk(eth_clk), .rst(eth_rst), .phy_reset_n(eth_phyrst_n),
|
||||
.reset_complete(phy_reset_complete)
|
||||
);
|
||||
phy_init_rtl8211f u_phy_init (
|
||||
.clk(eth_clk), .rst(eth_rst), .phy_reset_complete(phy_reset_complete),
|
||||
.mdio_start(mdio_start), .mdio_write(mdio_write),
|
||||
.mdio_phy_address(mdio_phy_address),
|
||||
.mdio_register_address(mdio_register_address), .mdio_write_data(mdio_write_data),
|
||||
.mdio_busy(mdio_busy), .mdio_done(mdio_done), .mdio_read_data(mdio_read_data),
|
||||
.initialization_complete(phy_init_complete), .link_ready(link_ready),
|
||||
.link_down_events(link_down_events)
|
||||
);
|
||||
mdio_master #(.MDC_DIV(25)) u_mdio (
|
||||
.clk(eth_clk), .rst(eth_rst), .start(mdio_start),
|
||||
.command_write(mdio_write), .phy_address(mdio_phy_address),
|
||||
.register_address(mdio_register_address), .write_data(mdio_write_data),
|
||||
.busy(mdio_busy), .done(mdio_done), .read_data(mdio_read_data),
|
||||
.read_valid(), .mdc(eth_mdc), .mdio_i(eth_mdio_IN),
|
||||
.mdio_o(eth_mdio_OUT), .mdio_oe(eth_mdio_OE)
|
||||
);
|
||||
|
||||
// One-cycle read response that has the same entry format as max2771_capture:
|
||||
// {discontinuity, absolute sample index, literal four-bit sample}.
|
||||
always_ff @(posedge eth_clk) begin
|
||||
if (eth_rst) begin
|
||||
fifo_rd_valid <= 1'b0;
|
||||
fifo_rd_data <= 69'd0;
|
||||
generated_sample_index <= 64'd0;
|
||||
heartbeat <= 23'd0;
|
||||
activity_toggle <= 1'b0;
|
||||
end else begin
|
||||
fifo_rd_valid <= fifo_rd_en;
|
||||
if (fifo_rd_en) begin
|
||||
fifo_rd_data <= {1'b0, generated_sample_index,
|
||||
generated_sample_index[3:0]};
|
||||
generated_sample_index <= generated_sample_index + 64'd1;
|
||||
end
|
||||
heartbeat <= heartbeat + 23'd1;
|
||||
if (frame_activity_pulse)
|
||||
activity_toggle <= !activity_toggle;
|
||||
end
|
||||
end
|
||||
|
||||
ethernet_packetizer #(
|
||||
.FIFO_DEPTH(FIFO_DEPTH), .FULL_SAMPLES(2936),
|
||||
.EARLIER_SAMPLE_HIGH_NIBBLE(1'b1)
|
||||
) u_packetizer (
|
||||
.clk(eth_clk), .rst(eth_rst), .link_ready(link_ready),
|
||||
.dropped_samples_low(32'd0), .fifo_empty(1'b0),
|
||||
.fifo_level(15'd16384), .fifo_rd_en(fifo_rd_en),
|
||||
.fifo_rd_data(fifo_rd_data), .fifo_rd_valid(fifo_rd_valid),
|
||||
.mac_frame_start(mac_frame_start), .mac_payload_length(mac_payload_length),
|
||||
.mac_payload_data(mac_payload_data), .mac_payload_valid(mac_payload_valid),
|
||||
.mac_payload_ready(mac_payload_ready), .mac_busy(mac_busy),
|
||||
.mac_frame_done(mac_frame_done), .packet_sequence(packet_sequence),
|
||||
.frame_activity_pulse(frame_activity_pulse)
|
||||
);
|
||||
ethernet_tx_mac u_mac (
|
||||
.clk(eth_clk), .rst(eth_rst), .frame_start(mac_frame_start),
|
||||
.payload_length(mac_payload_length), .payload_data(mac_payload_data),
|
||||
.payload_valid(mac_payload_valid), .payload_ready(mac_payload_ready),
|
||||
.gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er),
|
||||
.busy(mac_busy), .frame_done(mac_frame_done),
|
||||
.frames_transmitted(frames_transmitted),
|
||||
.payload_bytes_transmitted(payload_bytes_transmitted)
|
||||
);
|
||||
rgmii_tx_efinix u_rgmii_tx (
|
||||
.gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er),
|
||||
.eth_txd_HI(eth_txd_HI), .eth_txd_LO(eth_txd_LO),
|
||||
.eth_txctl_HI(eth_txctl_HI), .eth_txctl_LO(eth_txctl_LO),
|
||||
.eth_txc_HI(eth_txc_HI), .eth_txc_LO(eth_txc_LO)
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
user_led[0] = pll_locked || (!pll_locked && (pll_dummy_clk ^ eth_clk90));
|
||||
user_led[1] = link_ready;
|
||||
user_led[2] = heartbeat[22] || (!pll_locked &&
|
||||
(rf_clk_pmod ^ (^rf_data_pmod_HI) ^
|
||||
(^rf_data_pmod_LO)));
|
||||
user_led[3] = activity_toggle;
|
||||
user_led[4] = 1'b0;
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
@@ -0,0 +1,202 @@
|
||||
`default_nettype none
|
||||
|
||||
module ti375_max2771_recorder_top #(
|
||||
parameter bit CAPTURE_RISING = 1'b1,
|
||||
parameter bit EARLIER_SAMPLE_HIGH_NIBBLE = 1'b1,
|
||||
parameter int unsigned FIFO_DEPTH = 16384
|
||||
) (
|
||||
// Core clocks and status generated by the Efinity periphery PLL.
|
||||
input wire logic pll_dummy_clk,
|
||||
input wire logic eth_clk,
|
||||
input wire logic eth_clk90,
|
||||
input wire logic pll_locked,
|
||||
output logic pll_resetn,
|
||||
input wire logic rf_clk_pmod,
|
||||
input wire logic [3:0] rf_data_pmod_HI,
|
||||
input wire logic [3:0] rf_data_pmod_LO,
|
||||
|
||||
output logic eth_mdc,
|
||||
input wire logic eth_mdio_IN,
|
||||
output logic eth_mdio_OUT,
|
||||
output logic eth_mdio_OE,
|
||||
output logic eth_phyrst_n,
|
||||
output logic [3:0] eth_txd_HI,
|
||||
output logic [3:0] eth_txd_LO,
|
||||
output logic eth_txctl_HI,
|
||||
output logic eth_txctl_LO,
|
||||
output logic eth_txc_HI,
|
||||
output logic eth_txc_LO,
|
||||
output logic [4:0] user_led
|
||||
);
|
||||
localparam int unsigned FIFO_LEVEL_W = $clog2(FIFO_DEPTH) + 1;
|
||||
logic eth_rst, rf_rst;
|
||||
logic [3:0] selected_rf_data;
|
||||
logic rf_fifo_clk;
|
||||
logic fifo_w_en, fifo_full;
|
||||
logic [68:0] fifo_w_data;
|
||||
(* keep = "true" *) logic [FIFO_LEVEL_W-1:0] fifo_w_level, fifo_r_level;
|
||||
(* keep = "true" *) logic [63:0] samples_seen, samples_captured, samples_dropped;
|
||||
logic [63:0] dropped_samples_eth;
|
||||
logic loss_latched_rf, loss_sync1, loss_sync2;
|
||||
logic sample_activity_rf, sample_activity_eth;
|
||||
logic fifo_rd_en, fifo_rd_valid, fifo_empty;
|
||||
logic [68:0] fifo_rd_data;
|
||||
(* keep = "true" *) logic [63:0] fifo_overflow_attempts, fifo_underflow_attempts;
|
||||
|
||||
logic phy_reset_complete;
|
||||
logic mdio_start, mdio_write, mdio_busy, mdio_done, mdio_read_valid;
|
||||
logic [4:0] mdio_phy_address, mdio_register_address;
|
||||
logic [15:0] mdio_write_data, mdio_read_data;
|
||||
logic phy_init_complete, link_ready;
|
||||
(* keep = "true" *) logic [63:0] link_down_events;
|
||||
|
||||
logic mac_frame_start, mac_payload_valid, mac_payload_ready, mac_busy, mac_frame_done;
|
||||
logic [10:0] mac_payload_length;
|
||||
logic [7:0] mac_payload_data;
|
||||
logic [7:0] gmii_txd;
|
||||
logic gmii_tx_en, gmii_tx_er;
|
||||
(* keep = "true" *) logic [63:0] frames_transmitted, payload_bytes_transmitted;
|
||||
logic [31:0] packet_sequence;
|
||||
logic frame_activity_pulse;
|
||||
logic [23:0] sample_led_stretch;
|
||||
logic [12:0] frame_activity_divider;
|
||||
logic frame_activity_toggle;
|
||||
|
||||
// Efinity requires CLKOUT0 to stay within 4x of the reference clock. It is
|
||||
// a 100 MHz housekeeping output. The pre-lock LED probe below also keeps
|
||||
// both PLL clock interface ports present for generated SDC constraints.
|
||||
assign pll_resetn = 1'b1;
|
||||
assign selected_rf_data = CAPTURE_RISING ? rf_data_pmod_HI : rf_data_pmod_LO;
|
||||
|
||||
reset_sync u_eth_reset (.clk(eth_clk), .arst(!pll_locked), .srst(eth_rst));
|
||||
|
||||
// Both physical edges are captured in Titanium GPIO DDIO registers. The
|
||||
// selected half-cycle is then passed through the common capture/index block.
|
||||
max2771_capture #(.CAPTURE_RISING(1'b1)) u_capture (
|
||||
.rf_clk_pmod(rf_clk_pmod), .rst(rf_rst), .rf_data_pmod(selected_rf_data),
|
||||
.fifo_full(fifo_full), .fifo_w_clk(rf_fifo_clk), .fifo_w_en(fifo_w_en),
|
||||
.fifo_w_data(fifo_w_data), .samples_seen(samples_seen),
|
||||
.samples_captured(samples_captured), .samples_dropped(samples_dropped),
|
||||
.loss_latched(loss_latched_rf), .sample_activity_pulse(sample_activity_rf)
|
||||
);
|
||||
reset_sync u_rf_reset (
|
||||
.clk(rf_fifo_clk), .arst(!pll_locked), .srst(rf_rst)
|
||||
);
|
||||
|
||||
async_fifo_gray #(.DATA_WIDTH(69), .DEPTH(FIFO_DEPTH)) u_sample_fifo (
|
||||
.w_clk(rf_fifo_clk), .w_rst(rf_rst), .w_en(fifo_w_en), .w_data(fifo_w_data),
|
||||
.w_full(fifo_full), .w_level(fifo_w_level),
|
||||
.overflow_attempt_count(fifo_overflow_attempts),
|
||||
.r_clk(eth_clk), .r_rst(eth_rst), .r_en(fifo_rd_en), .r_data(fifo_rd_data),
|
||||
.r_valid(fifo_rd_valid), .r_empty(fifo_empty), .r_level(fifo_r_level),
|
||||
.underflow_attempt_count(fifo_underflow_attempts)
|
||||
);
|
||||
|
||||
gray_counter_sync #(.WIDTH(64)) u_drop_sync (
|
||||
.src_clk(rf_fifo_clk), .src_rst(rf_rst), .src_binary(samples_dropped),
|
||||
.dst_clk(eth_clk), .dst_rst(eth_rst), .dst_binary(dropped_samples_eth)
|
||||
);
|
||||
pulse_sync u_sample_pulse_sync (
|
||||
.src_clk(rf_fifo_clk), .src_rst(rf_rst), .src_pulse(sample_activity_rf),
|
||||
.dst_clk(eth_clk), .dst_rst(eth_rst), .dst_pulse(sample_activity_eth)
|
||||
);
|
||||
|
||||
always_ff @(posedge eth_clk) begin
|
||||
if (eth_rst) begin
|
||||
loss_sync1 <= 1'b0;
|
||||
loss_sync2 <= 1'b0;
|
||||
end else begin
|
||||
loss_sync1 <= loss_latched_rf;
|
||||
loss_sync2 <= loss_sync1;
|
||||
end
|
||||
end
|
||||
|
||||
phy_reset_ctrl #(.CLK_HZ(125_000_000), .RESET_LOW_MS(10)) u_phy_reset (
|
||||
.clk(eth_clk), .rst(eth_rst), .phy_reset_n(eth_phyrst_n),
|
||||
.reset_complete(phy_reset_complete)
|
||||
);
|
||||
phy_init_rtl8211f u_phy_init (
|
||||
.clk(eth_clk), .rst(eth_rst), .phy_reset_complete(phy_reset_complete),
|
||||
.mdio_start(mdio_start), .mdio_write(mdio_write),
|
||||
.mdio_phy_address(mdio_phy_address),
|
||||
.mdio_register_address(mdio_register_address), .mdio_write_data(mdio_write_data),
|
||||
.mdio_busy(mdio_busy), .mdio_done(mdio_done), .mdio_read_data(mdio_read_data),
|
||||
.initialization_complete(phy_init_complete), .link_ready(link_ready),
|
||||
.link_down_events(link_down_events)
|
||||
);
|
||||
mdio_master #(.MDC_DIV(25)) u_mdio (
|
||||
.clk(eth_clk), .rst(eth_rst), .start(mdio_start),
|
||||
.command_write(mdio_write), .phy_address(mdio_phy_address),
|
||||
.register_address(mdio_register_address), .write_data(mdio_write_data),
|
||||
.busy(mdio_busy), .done(mdio_done), .read_data(mdio_read_data),
|
||||
.read_valid(mdio_read_valid), .mdc(eth_mdc),
|
||||
.mdio_i(eth_mdio_IN), .mdio_o(eth_mdio_OUT), .mdio_oe(eth_mdio_OE)
|
||||
);
|
||||
|
||||
ethernet_packetizer #(
|
||||
.FIFO_DEPTH(FIFO_DEPTH), .FULL_SAMPLES(2936),
|
||||
.EARLIER_SAMPLE_HIGH_NIBBLE(EARLIER_SAMPLE_HIGH_NIBBLE)
|
||||
) u_packetizer (
|
||||
.clk(eth_clk), .rst(eth_rst), .link_ready(link_ready),
|
||||
.dropped_samples_low(dropped_samples_eth[31:0]),
|
||||
.fifo_empty(fifo_empty), .fifo_level(fifo_r_level),
|
||||
.fifo_rd_en(fifo_rd_en), .fifo_rd_data(fifo_rd_data),
|
||||
.fifo_rd_valid(fifo_rd_valid), .mac_frame_start(mac_frame_start),
|
||||
.mac_payload_length(mac_payload_length), .mac_payload_data(mac_payload_data),
|
||||
.mac_payload_valid(mac_payload_valid), .mac_payload_ready(mac_payload_ready),
|
||||
.mac_busy(mac_busy), .mac_frame_done(mac_frame_done),
|
||||
.packet_sequence(packet_sequence), .frame_activity_pulse(frame_activity_pulse)
|
||||
);
|
||||
ethernet_tx_mac u_mac (
|
||||
.clk(eth_clk), .rst(eth_rst), .frame_start(mac_frame_start),
|
||||
.payload_length(mac_payload_length), .payload_data(mac_payload_data),
|
||||
.payload_valid(mac_payload_valid), .payload_ready(mac_payload_ready),
|
||||
.gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er),
|
||||
.busy(mac_busy), .frame_done(mac_frame_done),
|
||||
.frames_transmitted(frames_transmitted),
|
||||
.payload_bytes_transmitted(payload_bytes_transmitted)
|
||||
);
|
||||
rgmii_tx_efinix u_rgmii_tx (
|
||||
.gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er),
|
||||
.eth_txd_HI(eth_txd_HI), .eth_txd_LO(eth_txd_LO),
|
||||
.eth_txctl_HI(eth_txctl_HI), .eth_txctl_LO(eth_txctl_LO),
|
||||
.eth_txc_HI(eth_txc_HI), .eth_txc_LO(eth_txc_LO)
|
||||
);
|
||||
|
||||
always_ff @(posedge eth_clk) begin
|
||||
if (eth_rst) begin
|
||||
sample_led_stretch <= 24'd0;
|
||||
frame_activity_divider <= 13'd0;
|
||||
frame_activity_toggle <= 1'b0;
|
||||
end else begin
|
||||
if (sample_activity_eth) sample_led_stretch <= 24'hffffff;
|
||||
else if (sample_led_stretch != 24'd0)
|
||||
sample_led_stretch <= sample_led_stretch - 24'd1;
|
||||
|
||||
if (frame_activity_pulse) begin
|
||||
if (frame_activity_divider == 13'd4095) begin
|
||||
frame_activity_divider <= 13'd0;
|
||||
frame_activity_toggle <= !frame_activity_toggle;
|
||||
end else begin
|
||||
frame_activity_divider <= frame_activity_divider + 13'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
// Ti375 C529 has five verified user LEDs (LED9 through LED13).
|
||||
user_led[0] = (pll_locked && !eth_rst) ||
|
||||
(!pll_locked && (pll_dummy_clk ^ eth_clk90));
|
||||
user_led[1] = link_ready;
|
||||
// The pre-lock term keeps both physical DDIO capture edges in the
|
||||
// implemented design even when CAPTURE_RISING is a constant parameter.
|
||||
user_led[2] = (sample_led_stretch != 24'd0) ||
|
||||
(!pll_locked && (^rf_data_pmod_LO));
|
||||
user_led[3] = !fifo_empty && (frame_activity_toggle || !link_ready);
|
||||
user_led[4] = loss_sync2;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
Reference in New Issue
Block a user