Line 67... |
Line 67... |
MTxClk, TxStartFrm, TxEndFrm, TxUsedData, TxData,
|
MTxClk, TxStartFrm, TxEndFrm, TxUsedData, TxData,
|
TxRetry, TxAbort, TxUnderRun, TxDone, PerPacketCrcEn,
|
TxRetry, TxAbort, TxUnderRun, TxDone, PerPacketCrcEn,
|
PerPacketPad,
|
PerPacketPad,
|
|
|
//RX
|
//RX
|
MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm, RxAbort, RxStatusWriteLatched_sync2,
|
MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm, RxAbort,
|
|
RxStatusWriteLatched_sync2,
|
|
|
// Register
|
// Register
|
r_TxEn, r_RxEn, r_TxBDNum, r_RxFlow, r_PassAll,
|
r_TxEn, r_RxEn, r_TxBDNum, r_RxFlow, r_PassAll,
|
|
|
// Interrupts
|
// Interrupts
|
TxB_IRQ, TxE_IRQ, RxB_IRQ, RxE_IRQ, Busy_IRQ,
|
TxB_IRQ, TxE_IRQ, RxB_IRQ, RxE_IRQ, Busy_IRQ,
|
|
|
// Rx Status
|
// Rx Status
|
InvalidSymbol, LatchedCrcError, RxLateCollision, ShortFrame, DribbleNibble,
|
InvalidSymbol, LatchedCrcError, RxLateCollision, ShortFrame, DribbleNibble,
|
ReceivedPacketTooBig, RxLength, LoadRxStatus, ReceivedPacketGood, AddressMiss,
|
ReceivedPacketTooBig, RxLength, LoadRxStatus, ReceivedPacketGood,
|
|
AddressMiss,
|
ReceivedPauseFrm,
|
ReceivedPauseFrm,
|
|
|
// Tx Status
|
// Tx Status
|
RetryCntLatched, RetryLimit, LateCollLatched, DeferLatched, RstDeferLatched, CarrierSenseLost
|
RetryCntLatched, RetryLimit, LateCollLatched, DeferLatched, RstDeferLatched,
|
|
CarrierSenseLost
|
|
|
// Bist
|
// Bist
|
`ifdef ETH_BIST
|
`ifdef ETH_BIST
|
,
|
,
|
// debug chain signals
|
// debug chain signals
|
Line 101... |
Line 104... |
|
|
|
|
);
|
);
|
|
|
|
|
//parameter Tp = 1;
|
|
parameter Tp = 0;
|
|
|
|
|
|
// WISHBONE common
|
// WISHBONE common
|
input WB_CLK_I; // WISHBONE clock
|
input WB_CLK_I; // WISHBONE clock
|
input [31:0] WB_DAT_I; // WISHBONE data input
|
input [31:0] WB_DAT_I; // WISHBONE data input
|
output [31:0] WB_DAT_O; // WISHBONE data output
|
output [31:0] WB_DAT_O; // WISHBONE data output
|
|
|
Line 259... |
Line 258... |
reg TxDonePacket;
|
reg TxDonePacket;
|
reg TxDonePacket_NotCleared;
|
reg TxDonePacket_NotCleared;
|
reg TxAbortPacket;
|
reg TxAbortPacket;
|
reg TxAbortPacket_NotCleared;
|
reg TxAbortPacket_NotCleared;
|
reg RxBDReady;
|
reg RxBDReady;
|
reg RxBDOK;
|
reg RxBDOK/* synthesis syn_allow_retiming=0*/;
|
reg TxBDReady;
|
reg TxBDReady;
|
|
|
reg RxBDRead;
|
reg RxBDRead;
|
|
|
reg [31:0] TxDataLatched;
|
reg [31:0] TxDataLatched;
|
Line 338... |
Line 337... |
|
|
wire [8:0] RxStatusIn;
|
wire [8:0] RxStatusIn;
|
reg [8:0] RxStatusInLatched;
|
reg [8:0] RxStatusInLatched;
|
|
|
reg WbEn, WbEn_q;
|
reg WbEn, WbEn_q;
|
reg RxEn, RxEn_q;
|
reg RxEn, RxEn_q /* synthesis syn_allow_retiming=0; syn_noprune=1; syn_keep=1 */;
|
reg TxEn, TxEn_q;
|
reg TxEn, TxEn_q /* synthesis syn_allow_retiming=0; syn_noprune=1; syn_keep=1 */;
|
reg r_TxEn_q;
|
reg r_TxEn_q;
|
reg r_RxEn_q;
|
reg r_RxEn_q;
|
|
|
wire ram_ce;
|
wire ram_ce;
|
wire [3:0] ram_we;
|
wire [3:0] ram_we;
|
Line 356... |
Line 355... |
reg TxPointerRead;
|
reg TxPointerRead;
|
reg TxEn_needed;
|
reg TxEn_needed;
|
reg RxEn_needed;
|
reg RxEn_needed;
|
|
|
wire StartRxPointerRead;
|
wire StartRxPointerRead;
|
reg RxPointerRead;
|
reg RxPointerRead/* synthesis syn_allow_retiming=0*/;
|
|
|
// RX shift ending signals
|
// RX shift ending signals
|
reg ShiftEnded_rck;
|
reg ShiftEnded_rck;
|
reg ShiftEndedSync1;
|
reg ShiftEndedSync1;
|
reg ShiftEndedSync2;
|
reg ShiftEndedSync2;
|
Line 374... |
Line 373... |
reg rx_wb_writeback_finished;
|
reg rx_wb_writeback_finished;
|
// Indicator of last set of writes from the Wishbone master coming up
|
// Indicator of last set of writes from the Wishbone master coming up
|
reg rx_wb_last_writes;
|
reg rx_wb_last_writes;
|
|
|
|
|
`ifdef TXBD_POLL
|
reg StartOccured;
|
reg [31:0] TxBDReadySamples; // -- jb
|
reg TxStartFrm_sync1;
|
wire TxBDNotReady; // -- jb
|
reg TxStartFrm_sync2;
|
`endif
|
reg TxStartFrm_syncb1;
|
|
reg TxStartFrm_syncb2;
|
|
|
|
|
|
wire TxFifoClear;
|
|
wire TxBufferAlmostFull;
|
|
wire TxBufferFull;
|
|
wire TxBufferEmpty;
|
|
wire TxBufferAlmostEmpty;
|
|
wire SetReadTxDataFromMemory;
|
|
reg BlockReadTxDataFromMemory/* synthesis syn_allow_retiming=0*/;
|
|
|
|
reg tx_burst_en;
|
|
reg rx_burst_en;
|
|
reg [`ETH_BURST_CNT_WIDTH-1:0] tx_burst_cnt;
|
|
|
|
wire ReadTxDataFromMemory_2;
|
|
wire tx_burst;
|
|
|
|
wire [31:0] TxData_wb;
|
|
wire ReadTxDataFromFifo_wb;
|
|
|
|
wire [`ETH_TX_FIFO_CNT_WIDTH-1:0] txfifo_cnt;
|
|
wire [`ETH_RX_FIFO_CNT_WIDTH-1:0] rxfifo_cnt;
|
|
|
|
reg [`ETH_BURST_CNT_WIDTH-1:0] rx_burst_cnt;
|
|
|
|
wire rx_burst;
|
|
wire enough_data_in_rxfifo_for_burst;
|
|
wire enough_data_in_rxfifo_for_burst_plus1;
|
|
|
|
reg ReadTxDataFromMemory/* synthesis syn_allow_retiming=0*/;
|
|
wire WriteRxDataToMemory;
|
|
reg WriteRxDataToMemory_r ;
|
|
|
|
reg MasterWbTX;
|
|
reg MasterWbRX;
|
|
|
|
reg [29:0] m_wb_adr_o;
|
|
reg m_wb_cyc_o;
|
|
reg [3:0] m_wb_sel_o;
|
|
reg m_wb_we_o;
|
|
|
|
wire TxLengthEq0;
|
|
wire TxLengthLt4;
|
|
|
|
reg BlockingIncrementTxPointer;
|
|
reg [31:2] TxPointerMSB;
|
|
reg [1:0] TxPointerLSB;
|
|
reg [1:0] TxPointerLSB_rst;
|
|
reg [31:2] RxPointerMSB;
|
|
reg [1:0] RxPointerLSB_rst;
|
|
|
|
wire RxBurstAcc;
|
|
wire RxWordAcc;
|
|
wire RxHalfAcc;
|
|
wire RxByteAcc;
|
|
|
|
|
`ifdef ETH_WISHBONE_B3
|
`ifdef ETH_WISHBONE_B3
|
`ifndef BURST_4BEAT
|
`ifndef BURST_4BEAT
|
assign m_wb_bte_o = 2'b00; // Linear burst
|
assign m_wb_bte_o = 2'b00; // Linear burst
|
`endif
|
`endif
|
Line 406... |
Line 462... |
.ce (ram_ce),
|
.ce (ram_ce),
|
.we (ram_we[0]),
|
.we (ram_we[0]),
|
.oe (ram_oe),
|
.oe (ram_oe),
|
.addr (ram_addr),
|
.addr (ram_addr),
|
.di (ram_di),
|
.di (ram_di),
|
.do (ram_do)
|
.dato (ram_do)
|
`ifdef ETH_BIST
|
`ifdef ETH_BIST
|
,
|
,
|
.mbist_si_i (mbist_si_i),
|
.mbist_si_i (mbist_si_i),
|
.mbist_so_o (mbist_so_o),
|
.mbist_so_o (mbist_so_o),
|
.mbist_ctrl_i (mbist_ctrl_i)
|
.mbist_ctrl_i (mbist_ctrl_i)
|
Line 446... |
Line 502... |
RxEn <= 1'b0;
|
RxEn <= 1'b0;
|
TxEn <= 1'b0;
|
TxEn <= 1'b0;
|
ram_addr <= 8'h0;
|
ram_addr <= 8'h0;
|
ram_di <= 32'h0;
|
ram_di <= 32'h0;
|
BDRead <= 1'b0;
|
BDRead <= 1'b0;
|
BDWrite <= 1'b0;
|
BDWrite <= 0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// Switching between three stages depends on enable signals
|
// Switching between three stages depends on enable signals
|
|
/* verilator lint_off CASEINCOMPLETE */ // JB
|
case ({WbEn_q, RxEn_q, TxEn_q, RxEn_needed, TxEn_needed}) // synopsys parallel_case
|
case ({WbEn_q, RxEn_q, TxEn_q, RxEn_needed, TxEn_needed}) // synopsys parallel_case
|
5'b100_10, 5'b100_11 :
|
5'b100_10, 5'b100_11 :
|
begin
|
begin
|
WbEn <= 1'b0;
|
WbEn <= 1'b0;
|
RxEn <= 1'b1; // wb access stage and r_RxEn is enabled
|
RxEn <= 1'b1; // wb access stage and r_RxEn is enabled
|
Line 514... |
Line 571... |
ram_addr <= WB_ADR_I[9:2];
|
ram_addr <= WB_ADR_I[9:2];
|
ram_di <= WB_DAT_I;
|
ram_di <= WB_DAT_I;
|
BDWrite <= BDCs[3:0] & {4{WB_WE_I}};
|
BDWrite <= BDCs[3:0] & {4{WB_WE_I}};
|
BDRead <= (|BDCs) & ~WB_WE_I;
|
BDRead <= (|BDCs) & ~WB_WE_I;
|
end
|
end
|
endcase
|
endcase //case ({WbEn_q, RxEn_q, TxEn_q, RxEn_needed, TxEn_needed})
|
|
/* verilator lint_on CASEINCOMPLETE */
|
end
|
end
|
end
|
end
|
|
|
|
|
// Delayed stage signals
|
// Delayed stage signals
|
Line 571... |
Line 629... |
// Only packets larger then 4 bytes are transmitted.
|
// Only packets larger then 4 bytes are transmitted.
|
if(ResetTxBDReady)
|
if(ResetTxBDReady)
|
TxBDReady <= 1'b0;
|
TxBDReady <= 1'b0;
|
end
|
end
|
|
|
`ifdef TXBD_POLL
|
|
// Register TxBDReady 4 times, when all are low we know this one is not
|
|
// good to transmit
|
|
always @(posedge WB_CLK_I or posedge Reset) // -- jb
|
|
begin
|
|
if (Reset) TxBDReadySamples <= 32'hffffffff;
|
|
else begin
|
|
if (r_TxEn)
|
|
begin
|
|
if (TxBDNotReady)
|
|
TxBDReadySamples <= 32'hffffffff;
|
|
else
|
|
TxBDReadySamples[31:0] <= {TxBDReadySamples[30:0],TxBDReady};
|
|
end
|
|
else
|
|
TxBDReadySamples <= 32'hffffffff;
|
|
end // else: !if(Reset)
|
|
end // always @ (posedge WB_CLK_I or posedge Reset)
|
|
// When all low, this goes high -- jb
|
|
assign TxBDNotReady = ~(|TxBDReadySamples);
|
|
|
|
|
|
`endif
|
|
|
|
// Reading the Tx buffer descriptor
|
// Reading the Tx buffer descriptor
|
assign StartTxBDRead = (TxRetryPacket_NotCleared | TxStatusWrite) &
|
assign StartTxBDRead = (TxRetryPacket_NotCleared | TxStatusWrite) &
|
~BlockingTxBDRead & ~TxBDReady;
|
~BlockingTxBDRead & ~TxBDReady;
|
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
Line 709... |
Line 743... |
else
|
else
|
if(TxEn & TxEn_q & TxBDRead)
|
if(TxEn & TxEn_q & TxBDRead)
|
TxStatus <= ram_do[14:11];
|
TxStatus <= ram_do[14:11];
|
end
|
end
|
|
|
reg ReadTxDataFromMemory;
|
|
wire WriteRxDataToMemory;
|
|
reg WriteRxDataToMemory_r;
|
|
|
|
// Register WriteRxDataToMemory in Wishbone clock domain
|
// Register WriteRxDataToMemory in Wishbone clock domain
|
// so it doesn't get out of sync with burst capability indication signals
|
// so it doesn't get out of sync with burst capability indication signals
|
always @(posedge WB_CLK_I or posedge Reset)
|
always @(posedge WB_CLK_I or posedge Reset)
|
if (Reset)
|
if (Reset)
|
WriteRxDataToMemory_r <= 0;
|
WriteRxDataToMemory_r <= 0;
|
else
|
else
|
WriteRxDataToMemory_r <= WriteRxDataToMemory;
|
WriteRxDataToMemory_r <= WriteRxDataToMemory;
|
|
|
reg MasterWbTX;
|
|
reg MasterWbRX;
|
|
|
|
reg [29:0] m_wb_adr_o;
|
|
reg m_wb_cyc_o;
|
|
reg [3:0] m_wb_sel_o;
|
|
reg m_wb_we_o;
|
|
|
|
wire TxLengthEq0;
|
|
wire TxLengthLt4;
|
|
|
|
reg BlockingIncrementTxPointer;
|
|
reg [31:2] TxPointerMSB;
|
|
reg [1:0] TxPointerLSB;
|
|
reg [1:0] TxPointerLSB_rst;
|
|
reg [31:2] RxPointerMSB;
|
|
reg [1:0] RxPointerLSB_rst;
|
|
|
|
wire RxBurstAcc;
|
|
wire RxWordAcc;
|
|
wire RxHalfAcc;
|
|
wire RxByteAcc;
|
|
|
|
//Latching length from the buffer descriptor;
|
//Latching length from the buffer descriptor;
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(Reset)
|
if(Reset)
|
Line 759... |
Line 768... |
begin
|
begin
|
if(TxLengthLt4)
|
if(TxLengthLt4)
|
TxLength <= 16'h0;
|
TxLength <= 16'h0;
|
else
|
else
|
if(TxPointerLSB_rst==2'h0)
|
if(TxPointerLSB_rst==2'h0)
|
TxLength <= TxLength - 3'h4; // Length is subtracted at
|
TxLength <= TxLength - 16'd4; // Length is subtracted at
|
// the data request
|
// the data request
|
else
|
else
|
if(TxPointerLSB_rst==2'h1)
|
if(TxPointerLSB_rst==2'h1)
|
TxLength <= TxLength - 3'h3; // Length is subtracted
|
TxLength <= TxLength - 16'd3; // Length is subtracted
|
// at the data request
|
// at the data request
|
else
|
else
|
if(TxPointerLSB_rst==2'h2)
|
if(TxPointerLSB_rst==2'h2)
|
TxLength <= TxLength - 3'h2; // Length is subtracted
|
TxLength <= TxLength - 16'd2; // Length is subtracted
|
// at the data request
|
// at the data request
|
else
|
else
|
if(TxPointerLSB_rst==2'h3)
|
if(TxPointerLSB_rst==2'h3)
|
TxLength <= TxLength - 3'h1; // Length is subtracted
|
TxLength <= TxLength - 16'd1; // Length is subtracted
|
// at the data request
|
// at the data request
|
end
|
end
|
end
|
end
|
|
|
|
|
Line 807... |
Line 816... |
if(TxEn & TxEn_q & TxPointerRead)
|
if(TxEn & TxEn_q & TxPointerRead)
|
TxPointerMSB <= ram_do[31:2];
|
TxPointerMSB <= ram_do[31:2];
|
else
|
else
|
if(IncrTxPointer & ~BlockingIncrementTxPointer)
|
if(IncrTxPointer & ~BlockingIncrementTxPointer)
|
// TxPointer is word-aligned
|
// TxPointer is word-aligned
|
TxPointerMSB <= TxPointerMSB + 1'b1;
|
TxPointerMSB <= TxPointerMSB + 1;
|
end
|
end
|
|
|
|
|
// Latching 2 MSB bits of the buffer descriptor. Since word accesses are
|
// Latching 2 MSB bits of the buffer descriptor. Since word accesses are
|
// performed, valid data does not necesserly start at byte 0 (could be byte
|
// performed, valid data does not necesserly start at byte 0 (could be byte
|
Line 860... |
Line 869... |
if(IncrTxPointer)
|
if(IncrTxPointer)
|
BlockingIncrementTxPointer <= 1'b1;
|
BlockingIncrementTxPointer <= 1'b1;
|
end
|
end
|
|
|
|
|
wire TxBufferAlmostFull;
|
|
wire TxBufferFull;
|
|
wire TxBufferEmpty;
|
|
wire TxBufferAlmostEmpty;
|
|
wire SetReadTxDataFromMemory;
|
|
|
|
reg BlockReadTxDataFromMemory;
|
|
|
|
assign SetReadTxDataFromMemory = TxEn & TxEn_q & TxPointerRead;
|
assign SetReadTxDataFromMemory = TxEn & TxEn_q & TxPointerRead;
|
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(Reset)
|
if(Reset)
|
Line 882... |
Line 883... |
else
|
else
|
if(SetReadTxDataFromMemory)
|
if(SetReadTxDataFromMemory)
|
ReadTxDataFromMemory <= 1'b1;
|
ReadTxDataFromMemory <= 1'b1;
|
end
|
end
|
|
|
reg tx_burst_en;
|
|
reg rx_burst_en;
|
|
reg [`ETH_BURST_CNT_WIDTH-1:0] tx_burst_cnt;
|
|
|
|
wire ReadTxDataFromMemory_2;
|
|
wire tx_burst;
|
|
|
|
|
|
wire [31:0] TxData_wb;
|
|
wire ReadTxDataFromFifo_wb;
|
|
|
|
assign ReadTxDataFromMemory_2 = ReadTxDataFromMemory &
|
assign ReadTxDataFromMemory_2 = ReadTxDataFromMemory &
|
~BlockReadTxDataFromMemory | (|tx_burst_cnt);
|
~BlockReadTxDataFromMemory | (|tx_burst_cnt);
|
|
|
assign tx_burst = ReadTxDataFromMemory_2 & tx_burst_en;
|
assign tx_burst = ReadTxDataFromMemory_2 & tx_burst_en;
|
|
|
Line 913... |
Line 903... |
if(ReadTxDataFromFifo_wb | TxDonePacket | TxAbortPacket |
|
if(ReadTxDataFromFifo_wb | TxDonePacket | TxAbortPacket |
|
TxRetryPacket)
|
TxRetryPacket)
|
BlockReadTxDataFromMemory <= 1'b0;
|
BlockReadTxDataFromMemory <= 1'b0;
|
end
|
end
|
|
|
`define TX_BURST_EN_CONDITION (txfifo_cnt<(`ETH_TX_FIFO_DEPTH-`ETH_BURST_LENGTH) & (TxLength>(`ETH_BURST_LENGTH*4+4)))
|
`define TX_BURST_EN_CONDITION ({1'b0,txfifo_cnt}<(`ETH_TX_FIFO_DEPTH-`ETH_BURST_LENGTH) & (TxLength>(`ETH_BURST_LENGTH*4+4)))
|
|
|
assign MasterAccessFinished = m_wb_ack_i | m_wb_err_i;
|
assign MasterAccessFinished = m_wb_ack_i | m_wb_err_i;
|
wire [`ETH_TX_FIFO_CNT_WIDTH-1:0] txfifo_cnt;
|
|
wire [`ETH_RX_FIFO_CNT_WIDTH-1:0] rxfifo_cnt;
|
|
|
|
reg [`ETH_BURST_CNT_WIDTH-1:0] rx_burst_cnt;
|
|
|
|
wire rx_burst;
|
|
wire enough_data_in_rxfifo_for_burst;
|
|
wire enough_data_in_rxfifo_for_burst_plus1;
|
|
|
|
// Enabling master wishbone access to the memory for two devices TX and RX.
|
// Enabling master wishbone access to the memory for two devices TX and RX.
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(Reset)
|
if(Reset)
|
Line 952... |
Line 934... |
`endif
|
`endif
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// Switching between two stages depends on enable signals
|
// Switching between two stages depends on enable signals
|
casex ({MasterWbTX,
|
casez ({MasterWbTX,
|
MasterWbRX,
|
MasterWbRX,
|
ReadTxDataFromMemory_2,
|
ReadTxDataFromMemory_2,
|
WriteRxDataToMemory_r,
|
WriteRxDataToMemory_r,
|
MasterAccessFinished,
|
MasterAccessFinished,
|
cyc_cleared,
|
cyc_cleared,
|
tx_burst,
|
tx_burst,
|
rx_burst}) // synopsys parallel_case
|
rx_burst}) // synopsys parallel_case
|
|
|
8'b00_10_00_10, // Idle and MRB needed
|
8'b00_10_00_10, // Idle and MRB needed
|
8'b10_1x_10_1x, // MRB continues
|
8'b10_1?_10_1?, // MRB continues
|
8'b10_10_01_10, // Clear (previously MR) and MRB needed
|
8'b10_10_01_10, // Clear (previously MR) and MRB needed
|
8'b01_1x_01_1x: // Clear (previously MW) and MRB needed
|
8'b01_1?_01_1?: // Clear (previously MW) and MRB needed
|
begin
|
begin
|
MasterWbTX <= 1'b1; // tx burst
|
MasterWbTX <= 1'b1; // tx burst
|
MasterWbRX <= 1'b0;
|
MasterWbRX <= 1'b0;
|
m_wb_cyc_o <= 1'b1;
|
m_wb_cyc_o <= 1'b1;
|
m_wb_we_o <= 1'b0;
|
m_wb_we_o <= 1'b0;
|
Line 977... |
Line 959... |
IncrTxPointer<= 1'b1;
|
IncrTxPointer<= 1'b1;
|
tx_burst_cnt <= tx_burst_cnt+3'h1;
|
tx_burst_cnt <= tx_burst_cnt+3'h1;
|
if(tx_burst_cnt==0)
|
if(tx_burst_cnt==0)
|
m_wb_adr_o <= TxPointerMSB;
|
m_wb_adr_o <= TxPointerMSB;
|
else
|
else
|
m_wb_adr_o <= m_wb_adr_o+1'b1;
|
m_wb_adr_o <= m_wb_adr_o + 1;
|
|
|
if(tx_burst_cnt==(`ETH_BURST_LENGTH-1))
|
if(tx_burst_cnt==(`ETH_BURST_LENGTH-1))
|
begin
|
begin
|
tx_burst_en<= 1'b0;
|
tx_burst_en<= 1'b0;
|
`ifdef ETH_WISHBONE_B3
|
`ifdef ETH_WISHBONE_B3
|
Line 997... |
Line 979... |
`endif
|
`endif
|
`endif
|
`endif
|
end
|
end
|
end // case: 8'b00_10_00_10,...
|
end // case: 8'b00_10_00_10,...
|
`ifdef ETH_RX_BURST_EN
|
`ifdef ETH_RX_BURST_EN
|
8'b00_x1_00_x1, // Idle and MWB needed
|
8'b00_?1_00_?1, // Idle and MWB needed
|
8'b01_x1_10_x1, // MWB continues
|
8'b01_?1_10_?1, // MWB continues
|
8'b01_01_01_01, // Clear (previously MW) and MWB needed
|
8'b01_01_01_01, // Clear (previously MW) and MWB needed
|
8'b10_x1_01_x1 : // Clear (previously MR) and MWB needed
|
8'b10_?1_01_?1 : // Clear (previously MR) and MWB needed
|
begin
|
begin
|
MasterWbTX <= 1'b0; // rx burst
|
MasterWbTX <= 1'b0; // rx burst
|
MasterWbRX <= 1'b1;
|
MasterWbRX <= 1'b1;
|
m_wb_cyc_o <= 1'b1;
|
m_wb_cyc_o <= 1'b1;
|
m_wb_we_o <= 1'b1;
|
m_wb_we_o <= 1'b1;
|
m_wb_sel_o <= RxByteSel;
|
m_wb_sel_o <= RxByteSel;
|
IncrTxPointer<= 1'b0;
|
IncrTxPointer<= 1'b0;
|
cyc_cleared<= 1'b0;
|
cyc_cleared<= 1'b0;
|
rx_burst_cnt <= rx_burst_cnt+3'h1;
|
rx_burst_cnt <= rx_burst_cnt+3'd1;
|
|
|
if(rx_burst_cnt==0)
|
if(rx_burst_cnt==0)
|
m_wb_adr_o <= RxPointerMSB;
|
m_wb_adr_o <= RxPointerMSB;
|
else
|
else
|
m_wb_adr_o <= m_wb_adr_o+1'b1;
|
m_wb_adr_o <= m_wb_adr_o + 1;
|
|
|
if(rx_burst_cnt==(`ETH_BURST_LENGTH-1))
|
if(rx_burst_cnt==(`ETH_BURST_LENGTH-1))
|
begin
|
begin
|
rx_burst_en<= 1'b0;
|
rx_burst_en<= 1'b0;
|
`ifdef ETH_WISHBONE_B3
|
`ifdef ETH_WISHBONE_B3
|
Line 1034... |
Line 1016... |
`endif
|
`endif
|
`endif
|
`endif
|
end
|
end
|
end // case: 8'b00_x1_00_x1,...
|
end // case: 8'b00_x1_00_x1,...
|
`endif // `ifdef ETH_RX_BURST_EN
|
`endif // `ifdef ETH_RX_BURST_EN
|
8'b00_x1_00_x0 ,//idle and MW is needed (data write to rx buffer)
|
8'b00_?1_00_?0 ,//idle and MW is needed (data write to rx buffer)
|
8'b01_x1_00_x0 :// Sometimes gets caught changing states - JB
|
8'b01_?1_00_?0 :// Sometimes gets caught changing states - JB
|
begin
|
begin
|
MasterWbTX <= 1'b0;
|
MasterWbTX <= 1'b0;
|
MasterWbRX <= !RxBufferEmpty;
|
MasterWbRX <= !RxBufferEmpty;
|
m_wb_adr_o <= RxPointerMSB;
|
m_wb_adr_o <= RxPointerMSB;
|
m_wb_cyc_o <= !RxBufferEmpty;
|
m_wb_cyc_o <= !RxBufferEmpty;
|
Line 1094... |
Line 1076... |
`endif
|
`endif
|
end
|
end
|
`endif
|
`endif
|
end
|
end
|
8'b10_10_01_00,// MR and MR is needed (data read from tx buffer)
|
8'b10_10_01_00,// MR and MR is needed (data read from tx buffer)
|
8'b01_1x_01_0x :// MW and MR is needed (data read from tx
|
8'b01_1?_01_0? :// MW and MR is needed (data read from tx
|
// buffer)
|
// buffer)
|
begin
|
begin
|
MasterWbTX <= 1'b1; // Only switch to TX here
|
MasterWbTX <= 1'b1; // Only switch to TX here
|
// when not end of RX
|
// when not end of RX
|
MasterWbRX <= 1'b0;
|
MasterWbRX <= 1'b0;
|
Line 1130... |
Line 1112... |
end
|
end
|
`endif
|
`endif
|
|
|
end
|
end
|
8'b01_01_01_00,// MW and MW needed (data write to rx buffer)
|
8'b01_01_01_00,// MW and MW needed (data write to rx buffer)
|
8'b10_x1_01_x0 ://MR and MW is needed (data write to rx buffer)
|
8'b10_?1_01_?0 ://MR and MW is needed (data write to rx buffer)
|
begin
|
begin
|
MasterWbTX <= 1'b0;
|
MasterWbTX <= 1'b0;
|
MasterWbRX <= !RxBufferEmpty;
|
MasterWbRX <= !RxBufferEmpty;
|
rx_burst_cnt<= 0;
|
rx_burst_cnt<= 0;
|
m_wb_adr_o <= RxPointerMSB;
|
m_wb_adr_o <= RxPointerMSB;
|
Line 1161... |
Line 1143... |
cyc_cleared<= 1'b0;
|
cyc_cleared<= 1'b0;
|
IncrTxPointer<= 1'b0;
|
IncrTxPointer<= 1'b0;
|
end
|
end
|
8'b01_01_10_00,// MW and MW needed (cycle is cleared between
|
8'b01_01_10_00,// MW and MW needed (cycle is cleared between
|
// previous and next access)
|
// previous and next access)
|
8'b01_1x_10_x0,// MW and MW or MR or MRB needed (cycle is
|
8'b01_1?_10_?0,// MW and MW or MR or MRB needed (cycle is
|
// cleared between previous and next access)
|
// cleared between previous and next access)
|
8'b10_10_10_00,// MR and MR needed (cycle is cleared between
|
8'b10_10_10_00,// MR and MR needed (cycle is cleared between
|
// previous and next access)
|
// previous and next access)
|
8'b10_x1_10_0x :// MR and MR or MW or MWB (cycle is cleared
|
8'b10_?1_10_0? :// MR and MR or MW or MWB (cycle is cleared
|
// between previous and next access)
|
// between previous and next access)
|
begin
|
begin
|
m_wb_cyc_o <= 1'b0;// whatever and master read or write is
|
m_wb_cyc_o <= 1'b0;// whatever and master read or write is
|
// needed. We need to clear m_wb_cyc_o
|
// needed. We need to clear m_wb_cyc_o
|
// before next access is started
|
// before next access is started
|
Line 1188... |
Line 1170... |
`ifdef ETH_WISHBONE_B3
|
`ifdef ETH_WISHBONE_B3
|
m_wb_bte_o <= 2'b00;
|
m_wb_bte_o <= 2'b00;
|
m_wb_cti_o <= 3'b0;
|
m_wb_cti_o <= 3'b0;
|
`endif
|
`endif
|
end
|
end
|
8'bxx_00_10_00,// whatever and no master read or write is needed
|
8'b??_00_10_00,// whatever and no master read or write is needed
|
// (ack or err comes finishing previous access)
|
// (ack or err comes finishing previous access)
|
8'bxx_00_01_00 : // Between cyc_cleared request was cleared
|
8'b??_00_01_00 : // Between cyc_cleared request was cleared
|
begin
|
begin
|
MasterWbTX <= 1'b0;
|
MasterWbTX <= 1'b0;
|
MasterWbRX <= 1'b0;
|
MasterWbRX <= 1'b0;
|
m_wb_cyc_o <= 1'b0;
|
m_wb_cyc_o <= 1'b0;
|
cyc_cleared<= 1'b0;
|
cyc_cleared<= 1'b0;
|
Line 1242... |
Line 1224... |
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
|
|
wire TxFifoClear;
|
|
|
|
assign TxFifoClear = (TxAbortPacket | TxRetryPacket | StartTxPointerRead);
|
assign TxFifoClear = (TxAbortPacket | TxRetryPacket | StartTxPointerRead);
|
|
|
eth_fifo
|
eth_fifo
|
#(
|
#(
|
`ETH_TX_FIFO_DATA_WIDTH,
|
`ETH_TX_FIFO_DATA_WIDTH,
|
Line 1269... |
Line 1248... |
.almost_empty(TxBufferAlmostEmpty),
|
.almost_empty(TxBufferAlmostEmpty),
|
.empty(TxBufferEmpty),
|
.empty(TxBufferEmpty),
|
.cnt(txfifo_cnt)
|
.cnt(txfifo_cnt)
|
);
|
);
|
|
|
|
// Start: Generation of the TxStartFrm_wb which is then synchronized to the
|
reg StartOccured;
|
// MTxClk
|
reg TxStartFrm_sync1;
|
|
reg TxStartFrm_sync2;
|
|
reg TxStartFrm_syncb1;
|
|
reg TxStartFrm_syncb2;
|
|
|
|
|
|
|
|
// Start: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(Reset)
|
if(Reset)
|
TxStartFrm_wb <= 1'b0;
|
TxStartFrm_wb <= 1'b0;
|
else
|
else
|
Line 1419... |
Line 1390... |
assign RxIRQEn = RxStatus[14];
|
assign RxIRQEn = RxStatus[14];
|
assign WrapRxStatusBit = RxStatus[13];
|
assign WrapRxStatusBit = RxStatus[13];
|
|
|
|
|
// Temporary Tx and Rx buffer descriptor address
|
// Temporary Tx and Rx buffer descriptor address
|
`ifdef TXBD_POLL
|
assign TempTxBDAddress[7:1] = {7{ TxStatusWrite & ~WrapTxStatusBit}} & (TxBDAddress + 1) ; // Tx BD increment or wrap (last BD)
|
assign TempTxBDAddress[7:1] = {7{ (TxStatusWrite|TxBDNotReady) & ~WrapTxStatusBit}} & (TxBDAddress + 1'b1) ; // Tx BD increment or wrap (last BD) -- jb
|
|
`else
|
|
assign TempTxBDAddress[7:1] = {7{ TxStatusWrite & ~WrapTxStatusBit}} & (TxBDAddress + 1'b1) ; // Tx BD increment or wrap (last BD)
|
|
`endif
|
|
assign TempRxBDAddress[7:1] = {7{ WrapRxStatusBit}} & (r_TxBDNum[6:0]) | // Using first Rx BD
|
assign TempRxBDAddress[7:1] = {7{ WrapRxStatusBit}} & (r_TxBDNum[6:0]) | // Using first Rx BD
|
{7{~WrapRxStatusBit}} & (RxBDAddress + 1'b1) ; // Using next Rx BD (incremenrement address)
|
{7{~WrapRxStatusBit}} & (RxBDAddress + 1) ; // Using next Rx BD (incremenrement address)
|
|
|
|
|
// Latching Tx buffer descriptor address
|
// Latching Tx buffer descriptor address
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(Reset)
|
if(Reset)
|
TxBDAddress <= 7'h0;
|
TxBDAddress <= 7'h0;
|
else if (r_TxEn & (~r_TxEn_q))
|
else if (r_TxEn & (~r_TxEn_q))
|
TxBDAddress <= 7'h0;
|
TxBDAddress <= 7'h0;
|
`ifdef TXBD_POLL
|
|
else if (TxStatusWrite | TxBDNotReady) // -- jb
|
|
`else
|
|
else if (TxStatusWrite)
|
else if (TxStatusWrite)
|
`endif
|
|
TxBDAddress <= TempTxBDAddress;
|
TxBDAddress <= TempTxBDAddress;
|
end
|
end
|
|
|
|
|
// Latching Rx buffer descriptor address
|
// Latching Rx buffer descriptor address
|
Line 1964... |
Line 1928... |
rx_just_read_bd <= 0;
|
rx_just_read_bd <= 0;
|
else
|
else
|
rx_just_read_bd <= (RxEn & RxEn_q & RxBDRead);
|
rx_just_read_bd <= (RxEn & RxEn_q & RxBDRead);
|
|
|
// Signal to indicate we've checked and the RxBD we want to use is not free
|
// Signal to indicate we've checked and the RxBD we want to use is not free
|
reg rx_waiting_for_bd_to_become_free;
|
reg rx_waiting_for_bd_to_become_free/*syn_allow_retiming=0; syn_keep=1; syn_preserve=1*/;
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
if(Reset)
|
if(Reset)
|
rx_waiting_for_bd_to_become_free <= 0;
|
rx_waiting_for_bd_to_become_free <= 0;
|
else if (rx_just_read_bd & !RxBDReady)
|
else if (rx_just_read_bd & !RxBDReady)
|
// Assert if we read the BD and it's not cool
|
// Assert if we read the BD and it's not cool
|
Line 2032... |
Line 1996... |
RxPointerMSB <= ram_do[31:2];
|
RxPointerMSB <= ram_do[31:2];
|
else
|
else
|
if(MasterWbRX & m_wb_ack_i)
|
if(MasterWbRX & m_wb_ack_i)
|
// Word access (always word access. m_wb_sel_o are used for
|
// Word access (always word access. m_wb_sel_o are used for
|
// selecting bytes)
|
// selecting bytes)
|
RxPointerMSB <= RxPointerMSB + 1'b1;
|
RxPointerMSB <= RxPointerMSB + 1;
|
end
|
end
|
|
|
|
|
//Latching last addresses from buffer descriptor (used as byte-half-word
|
//Latching last addresses from buffer descriptor (used as byte-half-word
|
// indicator);
|
// indicator);
|
Line 2129... |
Line 2093... |
2'h2 : RxByteCnt <= 2'h3;
|
2'h2 : RxByteCnt <= 2'h3;
|
2'h3 : RxByteCnt <= 2'h0;
|
2'h3 : RxByteCnt <= 2'h0;
|
endcase
|
endcase
|
else
|
else
|
if(RxValid & RxEnableWindow /*& RxReady*/ | LastByteIn)
|
if(RxValid & RxEnableWindow /*& RxReady*/ | LastByteIn)
|
RxByteCnt <= RxByteCnt + 1'b1;
|
RxByteCnt <= RxByteCnt + 1;
|
end
|
end
|
|
|
|
|
// Indicates how many bytes are valid within the last word
|
// Indicates how many bytes are valid within the last word
|
always @ (posedge MRxClk or posedge Reset)
|
always @ (posedge MRxClk or posedge Reset)
|
Line 2148... |
Line 2112... |
2'h2 : RxValidBytes <= 2'h3;
|
2'h2 : RxValidBytes <= 2'h3;
|
2'h3 : RxValidBytes <= 2'h0;
|
2'h3 : RxValidBytes <= 2'h0;
|
endcase
|
endcase
|
else
|
else
|
if(RxValid & ~LastByteIn & ~RxStartFrm & RxEnableWindow)
|
if(RxValid & ~LastByteIn & ~RxStartFrm & RxEnableWindow)
|
RxValidBytes <= RxValidBytes + 1'b1;
|
RxValidBytes <= RxValidBytes + 1;
|
end
|
end
|
|
|
|
|
always @ (posedge MRxClk or posedge Reset)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
Line 2209... |
Line 2173... |
reg WriteRxDataToFifoSync2;
|
reg WriteRxDataToFifoSync2;
|
reg WriteRxDataToFifoSync3;
|
reg WriteRxDataToFifoSync3;
|
|
|
|
|
// Indicating start of the reception process
|
// Indicating start of the reception process
|
assign SetWriteRxDataToFifo = (RxValid &/* RxReady &*/ ~RxStartFrm &
|
assign SetWriteRxDataToFifo = (RxValid & ~RxStartFrm &
|
RxEnableWindow & (&RxByteCnt)) |
|
RxEnableWindow & (&RxByteCnt))
|
(RxValid &/* RxReady &*/ RxStartFrm &
|
/*| (RxValid & RxStartFrm &
|
(&RxPointerLSB_rst)) |
|
(&RxPointerLSB_rst)) */
|
(ShiftWillEnd & LastByteIn & (&RxByteCnt));
|
|(ShiftWillEnd & LastByteIn & (&RxByteCnt));
|
|
|
always @ (posedge MRxClk or posedge Reset)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(Reset)
|
if(Reset)
|
WriteRxDataToFifo <= 1'b0;
|
WriteRxDataToFifo <= 1'b0;
|
Line 2261... |
Line 2225... |
wire WriteRxDataToFifo_wb;
|
wire WriteRxDataToFifo_wb;
|
assign WriteRxDataToFifo_wb = WriteRxDataToFifoSync2 &
|
assign WriteRxDataToFifo_wb = WriteRxDataToFifoSync2 &
|
~WriteRxDataToFifoSync3;
|
~WriteRxDataToFifoSync3;
|
// Receive fifo selection register - JB
|
// Receive fifo selection register - JB
|
reg [3:0] rx_shift_ended_wb_shr;
|
reg [3:0] rx_shift_ended_wb_shr;
|
reg rx_ethside_fifo_sel;
|
reg rx_ethside_fifo_sel /* synthesis syn_allow_retiming=0; syn_noprune=1; syn_keep=1 */;
|
reg rx_wbside_fifo_sel;
|
reg rx_wbside_fifo_sel /* synthesis syn_allow_retiming=0; syn_noprune=1; syn_keep=1 */;
|
|
|
// Shift in this - our detection of end of data RX
|
// Shift in this - our detection of end of data RX
|
always @(posedge WB_CLK_I)
|
always @(posedge WB_CLK_I)
|
rx_shift_ended_wb_shr <= {rx_shift_ended_wb_shr[2:0],
|
rx_shift_ended_wb_shr <= {rx_shift_ended_wb_shr[2:0],
|
ShiftEndedSync1 & ~ShiftEndedSync2};
|
ShiftEndedSync1 & ~ShiftEndedSync2};
|
Line 2452... |
Line 2416... |
`ifdef ETH_RX_BURST_EN
|
`ifdef ETH_RX_BURST_EN
|
assign enough_data_in_rxfifo_for_burst = rxfifo_cnt>=(`ETH_BURST_LENGTH);
|
assign enough_data_in_rxfifo_for_burst = rxfifo_cnt>=(`ETH_BURST_LENGTH);
|
assign enough_data_in_rxfifo_for_burst_plus1 = rxfifo_cnt>(`ETH_BURST_LENGTH - 1);
|
assign enough_data_in_rxfifo_for_burst_plus1 = rxfifo_cnt>(`ETH_BURST_LENGTH - 1);
|
// While receiving, don't flog the bus too hard, only write out when
|
// While receiving, don't flog the bus too hard, only write out when
|
// we can burst. But when finishing keep going until we've emptied the fifo
|
// we can burst. But when finishing keep going until we've emptied the fifo
|
assign write_rx_data_to_memory_go =
|
assign write_rx_data_to_memory_go
|
RxEnableWindow & (rx_wbside_fifo_sel == rx_ethside_fifo_sel) ?
|
= RxEnableWindow & (rx_wbside_fifo_sel == rx_ethside_fifo_sel) ?
|
(rxfifo_cnt>(`ETH_BURST_LENGTH)+2) |
|
(rxfifo_cnt>(`ETH_BURST_LENGTH) + 2) | (|rx_burst_cnt) : ~RxBufferEmpty;
|
(|rx_burst_cnt) : ~RxBufferEmpty;
|
|
|
|
`else
|
`else
|
assign enough_data_in_rxfifo_for_burst = rxfifo_cnt>=`ETH_BURST_LENGTH;
|
assign enough_data_in_rxfifo_for_burst = rxfifo_cnt>=`ETH_BURST_LENGTH;
|
assign enough_data_in_rxfifo_for_burst_plus1 = rxfifo_cnt>`ETH_BURST_LENGTH;
|
assign enough_data_in_rxfifo_for_burst_plus1 = rxfifo_cnt>`ETH_BURST_LENGTH;
|
assign write_rx_data_to_memory_go = ~RxBufferEmpty;
|
assign write_rx_data_to_memory_go = ~RxBufferEmpty;
|
`endif // !`ifdef ETH_RX_BURST_EN
|
`endif // !`ifdef ETH_RX_BURST_EN
|
|
|
assign WriteRxDataToMemory = write_rx_data_to_memory_go & !write_rx_data_to_memory_wait;
|
assign WriteRxDataToMemory = write_rx_data_to_memory_go &
|
|
!write_rx_data_to_memory_wait;
|
|
|
assign rx_burst = rx_burst_en & WriteRxDataToMemory;
|
assign rx_burst = rx_burst_en & WriteRxDataToMemory;
|
|
|
|
|
// Generation of the end-of-frame signal
|
// Generation of the end-of-frame signal
|
Line 2812... |
Line 2776... |
|
|
// Assign the debug output
|
// Assign the debug output
|
`ifdef WISHBONE_DEBUG
|
`ifdef WISHBONE_DEBUG
|
// Top byte, burst progress counters
|
// Top byte, burst progress counters
|
assign dbg_dat0[31] = 0;
|
assign dbg_dat0[31] = 0;
|
assign dbg_dat0[30] = 0;
|
assign dbg_dat0[30:28] = rx_burst_cnt;
|
assign dbg_dat0[29:28] = rx_burst_cnt;
|
|
assign dbg_dat0[27] = 0;
|
assign dbg_dat0[27] = 0;
|
assign dbg_dat0[26] = 0;
|
assign dbg_dat0[26:24] = tx_burst_cnt;
|
assign dbg_dat0[25:24] = tx_burst_cnt;
|
|
|
|
// Third byte
|
// Third byte
|
assign dbg_dat0[23] = 0;
|
assign dbg_dat0[23] = 0;
|
assign dbg_dat0[22] = 0;
|
assign dbg_dat0[22] = 0;
|
assign dbg_dat0[21] = rx_burst;
|
assign dbg_dat0[21] = rx_burst;
|