From 0933dbae83a375ea3cf99304fcb722172c7768fb Mon Sep 17 00:00:00 2001 From: matt Date: Tue, 31 Mar 2009 18:03:20 +0000 Subject: we now inhibit our own sending when a received pause frame comes. _rx.v is currently only a skeleton for testing pause git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10721 221aa14e-8319-0410-a670-987f0aec2ac5 --- usrp2/fpga/simple_gemac/flow_ctrl_tx.v | 11 ++++++---- usrp2/fpga/simple_gemac/simple_gemac.v | 12 +++++------ usrp2/fpga/simple_gemac/simple_gemac_rx.v | 34 +++++++++++++++++++++++++++++++ usrp2/fpga/simple_gemac/simple_gemac_tb.v | 10 +++++++-- usrp2/fpga/simple_gemac/simple_gemac_tx.v | 13 ++++++++++-- 5 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 usrp2/fpga/simple_gemac/simple_gemac_rx.v diff --git a/usrp2/fpga/simple_gemac/flow_ctrl_tx.v b/usrp2/fpga/simple_gemac/flow_ctrl_tx.v index 9f7556de4..f80f5a76d 100644 --- a/usrp2/fpga/simple_gemac/flow_ctrl_tx.v +++ b/usrp2/fpga/simple_gemac/flow_ctrl_tx.v @@ -11,13 +11,16 @@ module flow_ctrl_tx input pause_quanta_val, // MAC_tx_ctrl output pause_apply, - input pause_quanta_sub); + input paused); // ****************************************************************************** // Inhibit our TX from transmitting because they sent us a PAUSE frame // ****************************************************************************** - reg [15:0] pause_quanta_counter; + // Pauses are in units of 512 bit times, or 64 bytes/clock cycles, and can be + // as big as 16 bits, so 22 bits are needed for the counter + + reg [15+6:0] pause_quanta_counter; reg pqval_d1, pqval_d2; always @(posedge tx_clk) pqval_d1 <= pause_quanta_val; @@ -27,8 +30,8 @@ module flow_ctrl_tx if (rst) pause_quanta_counter <= 0; else if (pqval_d1 & ~pqval_d2) - pause_quanta_counter <= pause_quanta; - else if((pause_quanta_counter!=0) & pause_quanta_sub) + pause_quanta_counter <= {pause_quanta, 6'b0}; + else if((pause_quanta_counter!=0) & paused) pause_quanta_counter <= pause_quanta_counter - 1; assign pause_apply = tx_pause_en & (pause_quanta_counter != 0); diff --git a/usrp2/fpga/simple_gemac/simple_gemac.v b/usrp2/fpga/simple_gemac/simple_gemac.v index 0769fe615..e6f9c982a 100644 --- a/usrp2/fpga/simple_gemac/simple_gemac.v +++ b/usrp2/fpga/simple_gemac/simple_gemac.v @@ -31,24 +31,24 @@ module simple_gemac .tx_clk(tx_clk), .tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack), .ifg(SGE_IFG), .mac_addr(48'hF1_F2_F3_F4_F5_F6), .pause_req(pause_req), .pause_time(pause_time), // We request flow control - .pause_apply(pause_apply), .pause_applied(pause_applied) // We respect flow control + .pause_apply(pause_apply), .paused(paused) // We respect flow control ); -/* + simple_gemac_rx simple_gemac_rx (.reset(rst_rxclk), .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV), .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD), .rx_clk(rx_clk), .rx_data(rx_data), .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack), - .pause_quanta_rcvd(pause_qanta_rcvd), .pause_rcvd(pause_rcvd) + .pause_quanta_rcvd(pause_quanta_rcvd), .pause_rcvd(pause_rcvd) ); - */ + flow_ctrl_tx flow_ctrl_tx - (.rst(reset_txclk), .tx_clk(tx_clk), + (.rst(rst_txclk), .tx_clk(tx_clk), .tx_pause_en(SGE_RESPECT_FLOW_CTRL), .pause_quanta(pause_quanta_rcvd), // 16 bit value .pause_quanta_val(pause_rcvd), .pause_apply(pause_apply), - .pause_quanta_sub(pause_applied) + .paused(paused) ); diff --git a/usrp2/fpga/simple_gemac/simple_gemac_rx.v b/usrp2/fpga/simple_gemac/simple_gemac_rx.v new file mode 100644 index 000000000..8650a69a9 --- /dev/null +++ b/usrp2/fpga/simple_gemac/simple_gemac_rx.v @@ -0,0 +1,34 @@ + + +module simple_gemac_rx + (input clk125, input reset, + input GMII_RX_CLK, input GMII_RX_DV, input GMII_RX_ER, input [7:0] GMII_RXD, + output rx_clk, output [7:0] rx_data, output rx_valid, output rx_error, output rx_ack, + output reg [15:0] pause_quanta_rcvd, output reg pause_rcvd ); + + + + initial + begin + pause_rcvd <= 0; + pause_quanta_rcvd = 10; + #50000 pause_rcvd <= 1; + @(posedge rx_clk) + pause_rcvd <= 0; + repeat (100) + @(posedge rx_clk); + pause_quanta_rcvd <= 15; + pause_rcvd <= 1; + @(posedge rx_clk) + pause_rcvd <= 0; + repeat (1200) + @(posedge rx_clk); + pause_rcvd <= 1; + @(posedge rx_clk) + pause_rcvd <= 0; + + end + + assign rx_clk = GMII_RX_CLK; + +endmodule // simple_gemac_rx diff --git a/usrp2/fpga/simple_gemac/simple_gemac_tb.v b/usrp2/fpga/simple_gemac/simple_gemac_tb.v index 231a8b2ec..481c6ebab 100644 --- a/usrp2/fpga/simple_gemac/simple_gemac_tb.v +++ b/usrp2/fpga/simple_gemac/simple_gemac_tb.v @@ -9,7 +9,7 @@ module simple_gemac_tb; initial #1000 reset = 0; always #50 clk = ~clk; - wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER; + wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK; wire [7:0] GMII_RXD, GMII_TXD; wire rx_valid, rx_error, rx_ack; @@ -20,7 +20,13 @@ module simple_gemac_tb; reg [7:0] tx_data; wire [15:0] pause_time = 16'hBEEF; - reg pause_req = 0; + reg pause_req = 0; + + reg GMII_RX_CLK; + always @(GMII_GTX_CLK) + GMII_RX_CLK <= #30 GMII_GTX_CLK; + +// wire GMII_RX_CLK = #30 GMII_GTX_CLK; simple_gemac simple_gemac (.clk125(clk), .reset(reset), diff --git a/usrp2/fpga/simple_gemac/simple_gemac_tx.v b/usrp2/fpga/simple_gemac/simple_gemac_tx.v index ffc8f6e99..690fd5c37 100644 --- a/usrp2/fpga/simple_gemac/simple_gemac_tx.v +++ b/usrp2/fpga/simple_gemac/simple_gemac_tx.v @@ -5,7 +5,7 @@ module simple_gemac_tx output tx_clk, input [7:0] tx_data, input tx_valid, input tx_error, output tx_ack, input [7:0] ifg, input [47:0] mac_addr, input pause_req, input [15:0] pause_time, - input pause_apply, output pause_applied + input pause_apply, output reg paused ); reg tx_en_pre, tx_er_pre; @@ -72,7 +72,7 @@ module simple_gemac_tx if(~in_ifg) if(send_pause) tx_state <= TX_PAUSE; - else if(tx_valid) + else if(tx_valid & ~pause_apply) tx_state <= TX_PREAMBLE; TX_FIRSTBYTE : if(tx_error) @@ -223,6 +223,15 @@ module simple_gemac_tx GMII_TXD <= txd_pre; endcase // case (tx_state) end + + // report that we are paused only when we get back to IDLE + always @(posedge tx_clk) + if(reset) + paused <= 0; + else if(~pause_apply) + paused <= 0; + else if(tx_state == TX_IDLE) + paused <= 1; endmodule // simple_gemac_tx -- cgit