Jump to content

escou64

Members
  • Posts

    3
  • Joined

  • Last visited

Everything posted by escou64

  1. Hi, I am trying to design an ethernet controller for my Genesys 2. From specifications (RGMII, Realtek RTL8211E-VL PHY) or other projects (special thanks to @zygot and his Ethernet PHY Test Tool project), I have successfully implemented the Tx transmitter part: I can now see the different packets with WireShark. However, I am now facing a problem in the Rx receiver part. After analyzing the signals, I've noticed that the issue seems to come from the signals that are received from the PHY. Below is a screenshot of a received packet observed from an ILA: the sampling clock is at 500MHz (so the waveform accuracy must be put into perspective). The original packet starts with: ff ff ff ff ff ff a4 b1 c1 31 d8 05 08 00 45 00 ... But as early as the preamble/SFD, it seems that a shift exists with the first 4 bits received on a falling edge. So my frame becomes 5X 55 55 55 55 55 55 fd ff ... instead of the expected 55 55 55 55 55 55 55 5d ff... And it stays like that until the end of the frame, and for all the received frames. Here are the corresponding Verilog and constraints parts inspired by the previously mentioned sources: // Verilog top file input logic i_eth_mii_rx_clk; // Input Rx Clock input logic i_eth_mii_rx_ctl; // Input Rx CTL input logic [3:0] i_eth_mii_rx_data; // Input Rx Data logic w_eth_mii_rx_clk; // Internal Rx Clock logic w_eth_mii_rx_rst; // Internal Rx Reset logic [1:0] w_eth_mii_rx_ctl; // Internal Rx CTL logic w_eth_mii_rx_en; // Internal Rx Enable logic w_eth_mii_rx_err; // Internal Rx Error logic [7:0] w_eth_mii_rx_data; // Internal Rx Data ... assign w_eth_mii_rx_clk = i_eth_mii_rx_clk; ... IDDR #( .DDR_CLK_EDGE ( "SAME_EDGE_PIPELINED" ), .INIT_Q1 ( 1'b0 ), .INIT_Q2 ( 1'b0 ), .SRTYPE ( "SYNC" ) ) m_IDDR_eth_mii_rx_en ( .Q1 ( w_eth_mii_rx_ctl[0] ), .Q2 ( w_eth_mii_rx_ctl[1] ), .C ( w_eth_mii_rx_clk ), .CE ( 1'b1 ), .D ( i_eth_mii_rx_ctl ), .R ( w_eth_mii_rx_rst ), .S ( 1'b0 ) ); assign w_eth_mii_rx_en = w_eth_mii_rx_ctl[0]; assign w_eth_mii_rx_err = w_eth_mii_rx_ctl[1] ^ w_eth_mii_rx_ctl[0]; genvar et; generate for (et = 0; et < 4; et = et + 1) begin IDDR #( .DDR_CLK_EDGE ( "SAME_EDGE_PIPELINED" ), .INIT_Q1 ( 1'b0 ), .INIT_Q2 ( 1'b0 ), .SRTYPE ( "SYNC" ) ) m_IDDR_eth_mii_rx_data ( .Q1 ( w_eth_mii_rx_data[et + 0] ), .Q2 ( w_eth_mii_rx_data[et + 4] ), .C ( w_eth_mii_rx_clk ), .CE ( 1'b1 ), .D ( i_eth_mii_rx_data[et] ), .R ( w_eth_mii_rx_rst ), .S ( 1'b0 ) ); end endgenerate # Top constraints file ... ## Ethernet PHY set_property -dict { PACKAGE_PIN AK16 IOSTANDARD LVCMOS18 } [get_ports { i_eth_int_b }]; set_property -dict { PACKAGE_PIN AK15 IOSTANDARD LVCMOS18 } [get_ports { i_eth_pme_b }]; set_property -dict { PACKAGE_PIN AH24 IOSTANDARD LVCMOS33 } [get_ports { o_eth_phy_rstn }]; set_property -dict { PACKAGE_PIN AF12 IOSTANDARD LVCMOS15 } [get_ports { o_eth_mii_mdc }]; set_property -dict { PACKAGE_PIN AG12 IOSTANDARD LVCMOS15 } [get_ports { t_eth_mii_mdio }]; set_property -dict { PACKAGE_PIN AE10 IOSTANDARD LVCMOS15 } [get_ports { o_eth_mii_tx_clk }]; set_property -dict { PACKAGE_PIN AK14 IOSTANDARD LVCMOS15 } [get_ports { o_eth_mii_tx_ctl }]; set_property -dict { PACKAGE_PIN AJ12 IOSTANDARD LVCMOS15 } [get_ports { o_eth_mii_tx_data[0] }]; set_property -dict { PACKAGE_PIN AK11 IOSTANDARD LVCMOS15 } [get_ports { o_eth_mii_tx_data[1] }]; set_property -dict { PACKAGE_PIN AJ11 IOSTANDARD LVCMOS15 } [get_ports { o_eth_mii_tx_data[2] }]; set_property -dict { PACKAGE_PIN AK10 IOSTANDARD LVCMOS15 } [get_ports { o_eth_mii_tx_data[3] }]; set_property -dict { PACKAGE_PIN AG10 IOSTANDARD LVCMOS15 } [get_ports { i_eth_mii_rx_clk }]; set_property -dict { PACKAGE_PIN AH11 IOSTANDARD LVCMOS15 } [get_ports { i_eth_mii_rx_ctl }]; set_property -dict { PACKAGE_PIN AJ14 IOSTANDARD LVCMOS15 } [get_ports { i_eth_mii_rx_data[0] }]; set_property -dict { PACKAGE_PIN AH14 IOSTANDARD LVCMOS15 } [get_ports { i_eth_mii_rx_data[1] }]; set_property -dict { PACKAGE_PIN AK13 IOSTANDARD LVCMOS15 } [get_ports { i_eth_mii_rx_data[2] }]; set_property -dict { PACKAGE_PIN AJ13 IOSTANDARD LVCMOS15 } [get_ports { i_eth_mii_rx_data[3] }]; ## Clocks create_clock -add -name CLK_ETH_MII_RX -period 8.00 -waveform {0.0 4.0} [get_ports {i_eth_mii_rx_clk}]; create_generated_clock -name CLK_25MHZ [get_pins m_MMCME2_BASE/CLKOUT1] create_generated_clock -name CLK_50MHZ [get_pins m_MMCME2_BASE/CLKOUT3] # Design Cock create_generated_clock -name CLK_125MHZ [get_pins m_MMCME2_BASE/CLKOUT4] # Tx Clock create_generated_clock -name CLK_125MHZ_P90 [get_pins m_MMCME2_BASE/CLKOUT5] # Tx Clock with 90 Phase Shift create_generated_clock -name CLK_500MHZ [get_pins m_MMCME2_BASE/CLKOUT6] # ILA Clock set_clock_groups -asynchronous -group {CLK_50MHZ CLK_ETH_MII_RX CLK_125MHZ} After several checks, I seem to have used the same blocks (IDDR) and constraints as in the examples I've seen. However, what I'm observing doesn't seem to be consistent with what I expected. Any idea what I might have missed as a problem or constraint? I'm pretty sure it must be an obvious problem, but impossible for me to identify it ... Thanks for your help!
  2. Thanks for you answer: I'll take a closer look on this post to make sure I haven't missed anything. Just to to be sure that I am clear on my issue: I'm not trying to redesign a more complex MIG. I am just using the one available on Vivado which has one use interface port. It's in my own system where I have a module which receives requests coming from two ports and tries to redirect them to the one MIG port. It acts like a "multiplexer" with priorities. That's why I am surprised when I see the MIG not responding after many cycles while it seems to work fine in the beginning of the execution ... I am not sure to understand how I can debug the design without the ILA here: simulate my own design with MIG seems completely impossible and I do not have any other way to observe signals during execution ... However, I did not try to use the debug feature of the MIG. If I understand correctly, it adds some signals to the MIG interface (dbg_*) which allow to view internal states of the MIG. Am I right ?
  3. I am currently trying to implement an interface between multiple ports of a custom memory bus and the MIG IP of my Arty A7-35T board.Basically in my current example design, the first port reads a memory range 128-bit by 128-bit (it is for a custom VDMA). In the same time, the second port writes values in the same memory range (it is to emulate a CPU activity). The first port has the priority: if it is not busy, it sends its read request and else, its the second port which tries to write. I try to debug my design with an ILA. (See picture normal_read) In the first cycles after the reset, the system looks to work as expected. The app_rd_valid is asserted some cycles after the request (r_rpend indicates how many read requests are pending, r_mig_not is simply used to try to visualize the clock, r_mig_cycle indicates the number of cycles since the last reset). But later during the execution, the whole system seems to be locked (or slowed down). Particularly, the MIG becomes really slow during read requests. We can see (on pictures rpend_increase and long_read) that app_rd_valid is now asserted only after many cycles (512+ cycles if we consider the r_mig_cycle[15:8]) while the app_rdy is high. This hypothesis is validated by the value of r_mig_rpend which stays at 7 most of the time ... Finally, it seems that the MIG does not respond at all to my read requests since the trigger on app_rd_valid is never activated again. I thought that the MIG asserts a read request in only some cycles (~22 cycles). Is that correct ? Do you have any ideas of what conditions I have possibly missed which leads to this strange working ? Or a possible strategy to debug my design ? Thanks for your help!
×
×
  • Create New...