`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/09/15 09:47:23
// Design Name: qyw
// Module Name: rgmii_gmii
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module gmii_to_rgmii
(
input idelay_clk , //IDELAY时钟
//以太网GMII接口
output gmii_rx_clk , //GMII接收时钟
output gmii_rx_dv , //GMII接收数据有效信号
output [7:0] gmii_rxd , //GMII接收数据
output gmii_tx_clk , //GMII发送时钟
input gmii_tx_en , //GMII发送数据使能信号
input [7:0] gmii_txd , //GMII发送数据
//以太网RGMII接口
input rgmii_rxc , //RGMII接收时钟
input rgmii_rx_ctl, //RGMII接收数据控制信号
input [3:0] rgmii_rxd , //RGMII接收数据
output rgmii_txc , //RGMII发送时钟
output rgmii_tx_ctl, //RGMII发送数据控制信号
output [3:0] rgmii_txd //RGMII发送数据
);
/******************************************************************************\
Rgmii rx
\******************************************************************************/
//parameter define
parameter IDELAY_VALUE = 0;
//wire define
wire rgmii_rxc_bufg; //全局时钟缓存
wire rgmii_rxc_bufio; //全局时钟IO缓存
wire [3:0] rgmii_rxd_delay; //rgmii_rxd输入延时
wire rgmii_rx_ctl_delay; //rgmii_rx_ctl输入延时
wire [1:0] gmii_rxdv_t; //两位GMII接收有效信号
//*****************************************************
//** main code
//*****************************************************
assign gmii_rx_clk = rgmii_rxc_bufg;
assign gmii_rx_dv = gmii_rxdv_t[0] & gmii_rxdv_t[1];
assign gmii_tx_clk = gmii_rx_clk;
//全局时钟缓存
BUFG BUFG_inst (
.I (rgmii_rxc), // 1-bit input: Clock input
.O (rgmii_rxc_bufg) // 1-bit output: Clock output
);
//全局时钟IO缓存
BUFIO BUFIO_inst (
.I (rgmii_rxc), // 1-bit input: Clock input
.O (rgmii_rxc_bufio) // 1-bit output: Clock output
);
//输入延时控制
// Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
(* IODELAY_GROUP = "rgmii_rx_delay" *)
IDELAYCTRL IDELAYCTRL_inst (
.RDY(), // 1-bit output: Ready output
.REFCLK(idelay_clk), // 1-bit input: Reference clock input
.RST(1'b0) // 1-bit input: Active high reset input
);
//rgmii_rx_ctl输入延时与双沿采样
(* IODELAY_GROUP = "rgmii_rx_delay" *)
IDELAYE2 #(
.IDELAY_TYPE ("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.IDELAY_VALUE (IDELAY_VALUE), // Input delay tap setting (0-31)
.REFCLK_FREQUENCY(200.0) // IDELAYCTRL clock input frequency in MHz
)
u_delay_rx_ctrl (
.CNTVALUEOUT (), // 5-bit output: Counter value output
.DATAOUT (rgmii_rx_ctl_delay),// 1-bit output: Delayed data output
.C (1'b0), // 1-bit input: Clock input
.CE (1'b0), // 1-bit input: enable increment/decrement
.CINVCTRL (1'b0), // 1-bit input: Dynamic clock inversion input
.CNTVALUEIN (5'b0), // 5-bit input: Counter value input
.DATAIN (1'b0), // 1-bit input: Internal delay data input
.IDATAIN (rgmii_rx_ctl), // 1-bit input: Data input from the I/O
.INC (1'b0), // 1-bit input: Increment / Decrement tap delay
.LD (1'b0), // 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN (1'b0), // 1-bit input: Enable PIPELINE register
.REGRST (1'b0) // 1-bit input: Active-high reset tap-delay input
);
//输入双沿采样寄存器
IDDR #(
.DDR_CLK_EDGE("SAME_EDGE_PIPELINED"),// "OPPOSITE_EDGE", "SAME_EDGE"
// or "SAME_EDGE_PIPELINED"
.INIT_Q1 (1'b0), // Initial value of Q1: 1'b0 or 1'b1
.INIT_Q2 (1'b0), // Initial value of Q2: 1'b0 or 1'b1
.SRTYPE ("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
) u_iddr_rx_ctl (
.Q1 (gmii_rxdv_t[0]), // 1-bit output for positive edge of clock
.Q2 (gmii_rxdv_t[1]), // 1-bit output for negative edge of clock
.C (rgmii_rxc_bufio), // 1-bit clock input
.CE (1'b1), // 1-bit clock enable input
.D (rgmii_rx_ctl_delay), // 1-bit DDR data input
.R (1'b0), // 1-bit reset
.S (1'b0) // 1-bit set
);
//rgmii_rxd输入延时与双沿采样
genvar n;
generate for (n=0; n<4; n=n+1)
(* IODELAY_GROUP = "rgmii_rx_delay" *)
begin : rxdata_bus
//输入延时
(* IODELAY_GROUP = "rgmii_rx_delay" *)
IDELAYE2 #(
.IDELAY_TYPE ("FIXED"), // FIXED,VARIABLE,VAR_LOAD,VAR_LOAD_PIPE
.IDELAY_VALUE (IDELAY_VALUE), // Input delay tap setting (0-31)
.REFCLK_FREQUENCY(200.0) // IDELAYCTRL clock input frequency in MHz
)
u_delay_rxd (
.CNTVALUEOUT (), // 5-bit output: Counter value output
.DATAOUT (rgmii_rxd_delay[n]),// 1-bit output: Delayed data output
.C (1'b0), // 1-bit input: Clock input
.CE (1'b0), // 1-bit input: enable increment/decrement
.CINVCTRL (1'b0), // 1-bit input: Dynamic clock inversion
.CNTVALUEIN (5'b0), // 5-bit input: Counter value input
.DATAIN (1'b0), // 1-bit input: Internal delay data input
.IDATAIN (rgmii_rxd[n]), // 1-bit input: Data input from the I/O
.INC (1'b0), // 1-bit input: Inc/Decrement tap delay
.LD (1'b0), // 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN (1'b0), // 1-bit input: Enable PIPELINE register
.REGRST (1'b0) // 1-bit input: Active-high reset tap-delay
);
//输入双沿采样寄存器
IDDR #(
.DDR_CLK_EDGE("SAME_EDGE_PIPELINED"),// "OPPOSITE_EDGE", "SAME_EDGE"
// or "SAME_EDGE_PIPELINED"
.INIT_Q1 (1'b0), // Initial value of Q1: 1'b0 or 1'b1
.INIT_Q2 (1'b0), // Initial value of Q2: 1'b0 or 1'b1
.SRTYPE ("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
) u_iddr_rxd (
.Q1 (gmii_rxd[n]), // 1-bit output for positive edge of clock
.Q2 (gmii_rxd[4+n]), // 1-bit output for negative edge of clock
.C (rgmii_rxc_bufio), // 1-bit clock input rgmii_rxc_bufio
.CE (1'b1), // 1-bit clock enable input
.D (rgmii_rxd_delay[n]), // 1-bit DDR data input
.R (1'b0), // 1-bit reset
.S (1'b0) // 1-bit set
);
end
endgenerate
/******************************************************************************\
Rgmii tx
\******************************************************************************/
assign rgmii_txc = gmii_tx_clk;
//输出双沿采样寄存器 (rgmii_tx_ctl)
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
.INIT (1'b0), // Initial value of Q: 1'b0 or 1'b1
.SRTYPE ("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_inst (
.Q (rgmii_tx_ctl), // 1-bit DDR output
.C (gmii_tx_clk), // 1-bit clock input
.CE (1'b1), // 1-bit clock enable input
.D1 (gmii_tx_en), // 1-bit data input (positive edge)
.D2 (gmii_tx_en), // 1-bit data input (negative edge)
.R (1'b0), // 1-bit reset
.S (1'b0) // 1-bit set
);
genvar i;
generate for (i=0; i<4; i=i+1)
begin : txdata_bus
//输出双沿采样寄存器 (rgmii_txd)
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
.INIT (1'b0), // Initial value of Q: 1'b0 or 1'b1
.SRTYPE ("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_inst (
.Q (rgmii_txd[i]), // 1-bit DDR output
.C (gmii_tx_clk), // 1-bit clock input
.CE (1'b1), // 1-bit clock enable input
.D1 (gmii_txd[i]), // 1-bit data input (positive edge)
.D2 (gmii_txd[4+i]),// 1-bit data input (negative edge)
.R (1'b0), // 1-bit reset
.S (1'b0) // 1-bit set
);
end
endgenerate
/*
gmii_to_rgmii
#(
.IDELAY_VALUE (IDELAY_VALUE)
)
u_gmii_to_rgmii(
.idelay_clk (clk_200m ),
.gmii_rx_clk (gmii_rx_clk ),
.gmii_rx_dv (gmii_rx_dv ),
.gmii_rxd (gmii_rxd ),
.gmii_tx_clk (gmii_tx_clk ),
.gmii_tx_en (gmii_tx_en ),
.gmii_txd (gmii_txd ),
.rgmii_rxc (eth_rxc ),
.rgmii_rx_ctl (eth_rx_ctl ),
.rgmii_rxd (eth_rxd ),
.rgmii_txc (eth_txc ),
.rgmii_tx_ctl (eth_tx_ctl ),
.rgmii_txd (eth_txd )
);
*/
endmodule
rgmii与gmii相互转换
最新推荐文章于 2024-03-06 00:29:15 发布