298 lines
10 KiB
Systemverilog
298 lines
10 KiB
Systemverilog
`timescale 1 ns / 1 ns
|
|
|
|
module eth_ctrl_debug_top #(
|
|
parameter int unsigned DAC_DATA_WIDTH = 12
|
|
)(
|
|
input sys_clk_p,
|
|
input sys_clk_n,
|
|
input rst_n,
|
|
|
|
output [3:0] led,
|
|
|
|
output e_reset,
|
|
output e_mdc,
|
|
inout e_mdio,
|
|
|
|
output [3:0] rgmii_txd,
|
|
output rgmii_txctl,
|
|
output rgmii_txc,
|
|
input [3:0] rgmii_rxd,
|
|
input rgmii_rxctl,
|
|
input rgmii_rxc
|
|
);
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Internal GMII-side signals
|
|
// -------------------------------------------------------------------------
|
|
wire [7:0] gmii_txd;
|
|
wire gmii_tx_en;
|
|
wire gmii_tx_er;
|
|
wire gmii_tx_clk;
|
|
wire gmii_crs;
|
|
wire gmii_col;
|
|
wire [7:0] gmii_rxd_i;
|
|
wire gmii_rx_dv;
|
|
wire gmii_rx_er;
|
|
wire gmii_rx_clk;
|
|
|
|
wire [31:0] pack_total_len;
|
|
|
|
wire e_rx_dv;
|
|
wire [7:0] e_rxd;
|
|
wire e_tx_en;
|
|
wire [7:0] e_txd;
|
|
wire e_rst_n;
|
|
wire sys_clk;
|
|
|
|
wire duplex_mode;
|
|
|
|
assign duplex_mode = 1'b1;
|
|
|
|
// -------------------------------------------------------------------------
|
|
// System clock buffer (200 MHz differential input)
|
|
// -------------------------------------------------------------------------
|
|
IBUFDS sys_clk_ibufgds (
|
|
.O (sys_clk),
|
|
.I (sys_clk_p),
|
|
.IB (sys_clk_n)
|
|
);
|
|
|
|
// -------------------------------------------------------------------------
|
|
// IDELAYCTRL
|
|
// -------------------------------------------------------------------------
|
|
(* IODELAY_GROUP = "rgmii_idelay_group" *)
|
|
IDELAYCTRL IDELAYCTRL_inst (
|
|
.RDY (),
|
|
.REFCLK (sys_clk),
|
|
.RST (1'b0)
|
|
);
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Generated clocks for controller
|
|
// Need to create this IP in Vivado:
|
|
// input : 200 MHz
|
|
// output0: 130 MHz
|
|
// output1: 65 MHz
|
|
// -------------------------------------------------------------------------
|
|
wire dac_clk;
|
|
wire adc_clk;
|
|
wire clk_wiz_locked;
|
|
|
|
clk_wiz_ctrl_inst clk_wiz_ctrl_inst (
|
|
.clk_in1 (sys_clk),
|
|
.reset (~rst_n),
|
|
.clk_out1 (dac_clk), // 130 MHz
|
|
.clk_out2 (adc_clk), // 65 MHz
|
|
.locked (clk_wiz_locked)
|
|
);
|
|
|
|
// -------------------------------------------------------------------------
|
|
// GMII <-> RGMII conversion
|
|
// -------------------------------------------------------------------------
|
|
util_gmii_to_rgmii util_gmii_to_rgmii_m0 (
|
|
.reset (1'b0),
|
|
.rgmii_td (rgmii_txd),
|
|
.rgmii_tx_ctl (rgmii_txctl),
|
|
.rgmii_txc (rgmii_txc),
|
|
.rgmii_rd (rgmii_rxd),
|
|
.rgmii_rx_ctl (rgmii_rxctl),
|
|
.gmii_rx_clk (gmii_rx_clk),
|
|
.gmii_txd (e_txd),
|
|
.gmii_tx_en (e_tx_en),
|
|
.gmii_tx_er (1'b0),
|
|
.gmii_tx_clk (gmii_tx_clk),
|
|
.gmii_crs (gmii_crs),
|
|
.gmii_col (gmii_col),
|
|
.gmii_rxd (gmii_rxd_i),
|
|
.rgmii_rxc (rgmii_rxc),
|
|
.gmii_rx_dv (gmii_rx_dv),
|
|
.gmii_rx_er (gmii_rx_er),
|
|
.speed_selection (2'b10),
|
|
.duplex_mode (duplex_mode)
|
|
);
|
|
|
|
// -------------------------------------------------------------------------
|
|
// GMII arbitration / adaptation
|
|
// -------------------------------------------------------------------------
|
|
gmii_arbi arbi_inst (
|
|
.clk (gmii_tx_clk),
|
|
.rst_n (rst_n),
|
|
.speed (2'b10),
|
|
.link (1'b1),
|
|
.pack_total_len (pack_total_len),
|
|
.e_rst_n (e_rst_n),
|
|
.gmii_rx_dv (gmii_rx_dv),
|
|
.gmii_rxd (gmii_rxd_i),
|
|
.gmii_tx_en (gmii_tx_en),
|
|
.gmii_txd (gmii_txd),
|
|
.e_rx_dv (e_rx_dv),
|
|
.e_rxd (e_rxd),
|
|
.e_tx_en (e_tx_en),
|
|
.e_txd (e_txd)
|
|
);
|
|
|
|
// -------------------------------------------------------------------------
|
|
// axis_mac interface
|
|
// RX stream from Ethernet goes into controller
|
|
// TX stream is unused for now
|
|
// -------------------------------------------------------------------------
|
|
wire req_ready;
|
|
|
|
reg send_req;
|
|
reg [15:0] data_length;
|
|
|
|
reg [7:0] s_axis_tx_tdata;
|
|
reg s_axis_tx_tvalid;
|
|
wire s_axis_tx_tready;
|
|
reg s_axis_tx_tlast;
|
|
|
|
(* MARK_DEBUG="true" *) wire [7:0] m_axis_rx_tdata;
|
|
(* MARK_DEBUG="true" *) wire m_axis_rx_tvalid;
|
|
(* MARK_DEBUG="true" *) wire m_axis_rx_tlast;
|
|
(* MARK_DEBUG="true" *) wire m_axis_rx_tready;
|
|
|
|
// Always ready to accept RX payload bytes
|
|
assign m_axis_rx_tready = 1'b1;
|
|
|
|
// TX disabled
|
|
always @(*) begin
|
|
send_req = 1'b0;
|
|
data_length = 16'd0;
|
|
s_axis_tx_tdata = 8'd0;
|
|
s_axis_tx_tvalid= 1'b0;
|
|
s_axis_tx_tlast = 1'b0;
|
|
end
|
|
|
|
axis_mac axis_mac0 (
|
|
.gmii_tx_clk (gmii_tx_clk),
|
|
.gmii_rx_clk (gmii_rx_clk),
|
|
.rst_n (e_rst_n),
|
|
|
|
.gmii_rx_dv (e_rx_dv),
|
|
.gmii_rxd (e_rxd),
|
|
.gmii_tx_en (gmii_tx_en),
|
|
.gmii_txd (gmii_txd),
|
|
|
|
.send_req (send_req),
|
|
.data_length (data_length),
|
|
.req_ready (req_ready),
|
|
|
|
.s_axis_tx_tdata (s_axis_tx_tdata),
|
|
.s_axis_tx_tvalid (s_axis_tx_tvalid),
|
|
.s_axis_tx_tready (s_axis_tx_tready),
|
|
.s_axis_tx_tlast (s_axis_tx_tlast),
|
|
|
|
.m_axis_rx_tdata (m_axis_rx_tdata),
|
|
.m_axis_rx_tvalid (m_axis_rx_tvalid),
|
|
.m_axis_rx_tready (m_axis_rx_tready),
|
|
.m_axis_rx_tlast (m_axis_rx_tlast)
|
|
);
|
|
|
|
// PHY reset helper from your original example
|
|
reset reset_m0 (
|
|
.clk (sys_clk),
|
|
.key1 (rst_n),
|
|
.rst_n (e_reset)
|
|
);
|
|
|
|
// MDIO lines are not driven here yet
|
|
assign e_mdc = 1'b0;
|
|
assign e_mdio = 1'bz;
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Controller reset
|
|
// Use both external reset and clk_wiz lock
|
|
// -------------------------------------------------------------------------
|
|
wire ctrl_rst_n = rst_n & clk_wiz_locked;
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Debug finish generator
|
|
//
|
|
// After each adc_start pulse generates one finish pulse after some delay.
|
|
// This is just for first bring-up so the controller can leave busy state
|
|
// If you don't want this, replace with:
|
|
// wire finish_dbg = 1'b0;
|
|
// -------------------------------------------------------------------------
|
|
(* MARK_DEBUG="true" *) logic finish_dbg;
|
|
(* MARK_DEBUG="true" *) logic [7:0] finish_cnt;
|
|
(* MARK_DEBUG="true" *) logic finish_pending;
|
|
|
|
// Controller outputs to debug
|
|
(* MARK_DEBUG="true" *) wire [31:0] dac_pulse_width_dbg;
|
|
(* MARK_DEBUG="true" *) wire [31:0] dac_pulse_period_dbg;
|
|
(* MARK_DEBUG="true" *) wire [DAC_DATA_WIDTH-1:0] dac_pulse_height_dbg;
|
|
(* MARK_DEBUG="true" *) wire [15:0] dac_pulse_num_dbg;
|
|
|
|
(* MARK_DEBUG="true" *) wire [31:0] adc_pulse_period_dbg;
|
|
(* MARK_DEBUG="true" *) wire [15:0] adc_pulse_num_dbg;
|
|
|
|
(* MARK_DEBUG="true" *) wire dac_start_dbg;
|
|
(* MARK_DEBUG="true" *) wire adc_start_dbg;
|
|
(* MARK_DEBUG="true" *) wire dac_rst_dbg;
|
|
(* MARK_DEBUG="true" *) wire adc_rst_dbg;
|
|
|
|
always_ff @(posedge adc_clk or negedge ctrl_rst_n) begin
|
|
if (!ctrl_rst_n) begin
|
|
finish_dbg <= 1'b0;
|
|
finish_cnt <= 8'd0;
|
|
finish_pending <= 1'b0;
|
|
end else begin
|
|
finish_dbg <= 1'b0;
|
|
|
|
if (adc_start_dbg) begin
|
|
finish_pending <= 1'b1;
|
|
finish_cnt <= 8'd80;
|
|
end else if (finish_pending) begin
|
|
if (finish_cnt == 8'd0) begin
|
|
finish_dbg <= 1'b1;
|
|
finish_pending <= 1'b0;
|
|
end else begin
|
|
finish_cnt <= finish_cnt - 8'd1;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Controller
|
|
// ETH domain = gmii_rx_clk, because RX AXI master comes from axis_mac RX side
|
|
// -------------------------------------------------------------------------
|
|
control #(
|
|
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
|
) udp_ctrl_inst (
|
|
.eth_clk_in (gmii_rx_clk),
|
|
.dac_clk_in (dac_clk),
|
|
.adc_clk_in (adc_clk),
|
|
.rst_n (ctrl_rst_n),
|
|
|
|
.s_axis_tdata (m_axis_rx_tdata),
|
|
.s_axis_tvalid (m_axis_rx_tvalid),
|
|
.s_axis_tready (), // controller internally always ready in current version
|
|
.s_axis_tlast (m_axis_rx_tlast),
|
|
|
|
.finish (finish_dbg),
|
|
|
|
.dac_pulse_width (dac_pulse_width_dbg),
|
|
.dac_pulse_period (dac_pulse_period_dbg),
|
|
.dac_pulse_height (dac_pulse_height_dbg),
|
|
.dac_pulse_num (dac_pulse_num_dbg),
|
|
|
|
.adc_pulse_period (adc_pulse_period_dbg),
|
|
.adc_pulse_num (adc_pulse_num_dbg),
|
|
|
|
.dac_start (dac_start_dbg),
|
|
.adc_start (adc_start_dbg),
|
|
|
|
.dac_rst (dac_rst_dbg),
|
|
.adc_rst (adc_rst_dbg)
|
|
);
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Simple LED status
|
|
// -------------------------------------------------------------------------
|
|
assign led[0] = clk_wiz_locked;
|
|
assign led[1] = m_axis_rx_tvalid;
|
|
assign led[2] = dac_start_dbg;
|
|
assign led[3] = adc_rst_dbg;
|
|
|
|
endmodule |