Implement generic MAX2771 raw Ethernet recorder

This commit is contained in:
onur
2026-08-01 01:15:47 +03:00
commit 79d07fdda7
57 changed files with 4810 additions and 0 deletions
@@ -0,0 +1,93 @@
`timescale 1ns/1ps
`default_nettype none
module tb_phy_init_rtl8211f;
logic clk = 1'b0;
logic rst = 1'b1;
logic reset_complete = 1'b0;
logic start, write_cmd, busy = 1'b0, done = 1'b0;
logic [4:0] phy_addr, reg_addr;
logic [15:0] write_data, read_data = 16'd0;
logic init_complete, link_ready;
logic [63:0] link_down_events;
integer transaction = 0;
integer response_delay = 0;
always #5 clk = !clk;
phy_init_rtl8211f #(
.CLK_HZ(1000), .SETTLE_MS(1), .POLL_MS(1), .PHY_ADDRESS(5'd2)
) dut (
.clk(clk), .rst(rst), .phy_reset_complete(reset_complete),
.mdio_start(start), .mdio_write(write_cmd), .mdio_phy_address(phy_addr),
.mdio_register_address(reg_addr), .mdio_write_data(write_data),
.mdio_busy(busy), .mdio_done(done), .mdio_read_data(read_data),
.initialization_complete(init_complete), .link_ready(link_ready),
.link_down_events(link_down_events)
);
// Minimal transaction-level MDIO responder. First PHYSR poll resolves
// 1000/full; the second reports link down to exercise the event counter.
always_ff @(posedge clk) begin
done <= 1'b0;
if (start && !busy) begin
if (phy_addr !== 5'd2)
$fatal(1, "wrong PHY address");
busy <= 1'b1;
response_delay <= 2;
end else if (busy && response_delay != 0) begin
response_delay <= response_delay - 1;
end else if (busy) begin
busy <= 1'b0;
done <= 1'b1;
case (transaction)
0: begin
if (reg_addr !== 5'h1f || !write_cmd || write_data !== 16'h0a43)
$fatal(1, "expected PHYSR page-select write");
end
1: begin
if (reg_addr !== 5'h1a || write_cmd)
$fatal(1, "expected PHYSR read");
read_data <= 16'h002c; // 1000 Mb/s + full duplex + link
end
2: begin
if (reg_addr !== 5'h1f || !write_cmd || write_data !== 16'h0000)
$fatal(1, "expected page-zero restore");
end
3: begin
if (reg_addr !== 5'h1f || !write_cmd || write_data !== 16'h0a43)
$fatal(1, "expected second page-select write");
end
4: begin
if (reg_addr !== 5'h1a || write_cmd)
$fatal(1, "expected link-down PHYSR read");
read_data <= 16'h0028; // 1000 Mb/s + full duplex, link clear
end
default: begin
if (reg_addr !== 5'h1f || !write_cmd || write_data !== 16'h0000)
$fatal(1, "expected second page-zero restore");
end
endcase
transaction <= transaction + 1;
end
end
initial begin
repeat (3) @(posedge clk);
rst <= 1'b0;
reset_complete <= 1'b1;
wait (init_complete && link_ready);
if (link_down_events !== 64'd0) $fatal(1, "spurious link-down event");
wait (!link_ready);
if (link_down_events !== 64'd1) $fatal(1, "link-down event not counted");
$display("PASS tb_phy_init_rtl8211f");
$finish;
end
initial begin
#5000;
$fatal(1, "timeout");
end
endmodule
`default_nettype wire
@@ -0,0 +1,36 @@
`timescale 1ns/1ps
`default_nettype none
module tb_rgmii_tx_efinix;
logic [7:0] gmii_txd;
logic gmii_tx_en, gmii_tx_er;
logic [3:0] hi, lo;
logic ctl_hi, ctl_lo, txc_hi, txc_lo;
rgmii_tx_efinix dut (
.gmii_txd(gmii_txd), .gmii_tx_en(gmii_tx_en), .gmii_tx_er(gmii_tx_er),
.eth_txd_HI(hi), .eth_txd_LO(lo),
.eth_txctl_HI(ctl_hi), .eth_txctl_LO(ctl_lo),
.eth_txc_HI(txc_hi), .eth_txc_LO(txc_lo)
);
initial begin
gmii_txd = 8'ha5; gmii_tx_en = 1'b1; gmii_tx_er = 1'b0; #1;
if (hi !== 4'h5 || lo !== 4'ha || ctl_hi !== 1'b1 || ctl_lo !== 1'b1)
$fatal(1, "RGMII normal-data mapping failed");
if (txc_hi !== 1'b1 || txc_lo !== 1'b0)
$fatal(1, "RGMII forwarded-clock values failed");
gmii_txd = 8'h3c; gmii_tx_en = 1'b1; gmii_tx_er = 1'b1; #1;
if (hi !== 4'hc || lo !== 4'h3 || ctl_hi !== 1'b1 || ctl_lo !== 1'b0)
$fatal(1, "RGMII TX error-control encoding failed");
gmii_tx_en = 1'b0; gmii_tx_er = 1'b0; #1;
if (ctl_hi !== 1'b0 || ctl_lo !== 1'b0)
$fatal(1, "RGMII idle-control encoding failed");
$display("PASS tb_rgmii_tx_efinix");
$finish;
end
endmodule
`default_nettype wire