Line 1... |
Line 1... |
|
// Napravi, pause frame
|
|
|
|
// Poskusi spremeniti vse signale na wb strani da bodo imeli enake koncnice (npr _wb),
|
|
// vsi na MTxClk strani pa _txclk
|
|
// Evaluiraj dato da pre start framom ni prisel abort ali kaj podobnega (kot je bilo v GotData, ki ga zbrisi)
|
|
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// eth_wishbone.v ////
|
//// eth_wishbone.v ////
|
//// ////
|
//// ////
|
//// This file is part of the Ethernet IP core project ////
|
//// This file is part of the Ethernet IP core project ////
|
Line 39... |
Line 45... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.1 2002/01/23 10:47:59 mohor
|
|
// Initial version. Equals to eth_wishbonedma.v at this moment.
|
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
|
|
|
|
Line 58... |
Line 67... |
|
|
// WISHBONE slave
|
// WISHBONE slave
|
WB_ADR_I, WB_SEL_I, WB_WE_I, WB_ACK_O,
|
WB_ADR_I, WB_SEL_I, WB_WE_I, WB_ACK_O,
|
WB_REQ_O, WB_ACK_I, WB_ND_O, WB_RD_O, BDCs,
|
WB_REQ_O, WB_ACK_I, WB_ND_O, WB_RD_O, BDCs,
|
|
|
|
// WISHBONE master
|
|
m_wb_adr_o, m_wb_sel_o, m_wb_we_o,
|
|
m_wb_dat_o, m_wb_dat_i, m_wb_cyc_o,
|
|
m_wb_stb_o, m_wb_ack_i, m_wb_err_i,
|
|
|
//TX
|
//TX
|
MTxClk, TxStartFrm, TxEndFrm, TxUsedData, TxData, StatusIzTxEthMACModula,
|
MTxClk, TxStartFrm, TxEndFrm, TxUsedData, TxData, StatusIzTxEthMACModula,
|
TxRetry, TxAbort, TxUnderRun, TxDone, TPauseRq, TxPauseTV, PerPacketCrcEn,
|
TxRetry, TxAbort, TxUnderRun, TxDone, TPauseRq, TxPauseTV, PerPacketCrcEn,
|
PerPacketPad,
|
PerPacketPad,
|
|
|
Line 69... |
Line 83... |
MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm,
|
MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm,
|
|
|
// Register
|
// Register
|
r_TxEn, r_RxEn, r_TxBDNum, r_DmaEn, TX_BD_NUM_Wr,
|
r_TxEn, r_RxEn, r_TxBDNum, r_DmaEn, TX_BD_NUM_Wr,
|
|
|
WillSendControlFrame, TxCtrlEndFrm,
|
WillSendControlFrame, TxCtrlEndFrm, // igor !!! WillSendControlFrame gre najbrz ven
|
|
|
// Interrupts
|
// Interrupts
|
TxB_IRQ, TxE_IRQ, RxB_IRQ, RxF_IRQ, Busy_IRQ
|
TxB_IRQ, TxE_IRQ, RxB_IRQ, RxF_IRQ, Busy_IRQ
|
|
|
);
|
);
|
Line 92... |
Line 106... |
input [3:0] WB_SEL_I; // WISHBONE byte select input
|
input [3:0] WB_SEL_I; // WISHBONE byte select input
|
input WB_WE_I; // WISHBONE write enable input
|
input WB_WE_I; // WISHBONE write enable input
|
input BDCs; // Buffer descriptors are selected
|
input BDCs; // Buffer descriptors are selected
|
output WB_ACK_O; // WISHBONE acknowledge output
|
output WB_ACK_O; // WISHBONE acknowledge output
|
|
|
|
// WISHBONE master
|
|
output [31:0] m_wb_adr_o; //
|
|
output [3:0] m_wb_sel_o; //
|
|
output m_wb_we_o; //
|
|
output [31:0] m_wb_dat_o; //
|
|
output m_wb_cyc_o; //
|
|
output m_wb_stb_o; //
|
|
input [31:0] m_wb_dat_i; //
|
|
input m_wb_ack_i; //
|
|
input m_wb_err_i; //
|
|
|
|
|
|
|
|
|
// DMA
|
// DMA
|
input [1:0] WB_ACK_I; // DMA acknowledge input
|
input [1:0] WB_ACK_I; // DMA acknowledge input
|
output [1:0] WB_REQ_O; // DMA request output
|
output [1:0] WB_REQ_O; // DMA request output
|
output [1:0] WB_ND_O; // DMA force new descriptor output
|
output [1:0] WB_ND_O; // DMA force new descriptor output
|
output WB_RD_O; // DMA restart descriptor output
|
output WB_RD_O; // DMA restart descriptor output
|
Line 146... |
Line 174... |
reg TxStartFrm;
|
reg TxStartFrm;
|
reg TxEndFrm;
|
reg TxEndFrm;
|
reg [7:0] TxData;
|
reg [7:0] TxData;
|
|
|
reg TxUnderRun;
|
reg TxUnderRun;
|
reg TPauseRq;
|
|
reg TxPauseRq;
|
|
|
|
reg RxStartFrm_wb;
|
reg RxStartFrm_wb;
|
reg [31:0] RxData_wb;
|
reg [31:0] RxData_wb;
|
reg RxDataValid_wb;
|
reg RxDataValid_wb;
|
reg RxEndFrm_wb;
|
reg RxEndFrm_wb;
|
|
|
reg [7:0] BDAddress; // BD address for access from MAC side
|
reg [7:0] BDAddress; // BD address for access from MAC side
|
reg BDRead_q;
|
reg BDRead_q;
|
|
|
reg TxBDRead;
|
reg TxBDRead;
|
reg TxDataRead;
|
wire TxStatusWrite;
|
reg TxStatusWrite;
|
|
|
|
reg [1:0] TxValidBytesLatched;
|
reg [1:0] TxValidBytesLatched;
|
reg TxEndFrm_wbLatched;
|
|
|
|
reg [15:0] TxLength;
|
reg [15:0] TxLength;
|
reg [31:0] TxStatus;
|
reg [15:0] TxStatus;
|
|
|
reg [15:0] RxStatus;
|
reg [15:0] RxStatus;
|
|
|
reg TxStartFrm_wb;
|
reg TxStartFrm_wb;
|
reg TxRetry_wb;
|
reg TxRetry_wb;
|
reg GetNewTxData_wb;
|
|
reg TxDone_wb;
|
|
reg TxAbort_wb;
|
reg TxAbort_wb;
|
|
reg TxDone_wb;
|
|
|
reg TxStartFrmRequest;
|
|
reg [31:0] TxDataLatched_wb;
|
|
|
|
reg RxStatusWriteOccured;
|
reg RxStatusWriteOccured;
|
|
|
reg TxRestart_wb_q;
|
|
reg TxDone_wb_q;
|
reg TxDone_wb_q;
|
reg TxAbort_wb_q;
|
reg TxAbort_wb_q;
|
|
reg TxRetry_wb_q;
|
reg RxBDReady;
|
reg RxBDReady;
|
reg TxBDReady;
|
reg TxBDReady;
|
|
|
reg RxBDRead;
|
reg RxBDRead;
|
reg RxStatusWrite;
|
reg RxStatusWrite;
|
reg WbWriteError;
|
reg WbWriteError;
|
|
|
reg [31:0] TxDataLatched;
|
reg [31:0] TxDataLatched;
|
reg [1:0] TxByteCnt;
|
reg [1:0] TxByteCnt;
|
reg LastWord;
|
reg LastWord;
|
reg GetNewTxData;
|
reg ReadTxDataFromFifo_tck;
|
reg TxRetryLatched;
|
|
|
|
reg Div2;
|
reg Div2;
|
reg Flop;
|
reg Flop;
|
|
|
reg BlockingTxStatusWrite;
|
reg BlockingTxStatusWrite;
|
reg TxStatusWriteOccured;
|
|
reg BlockingTxBDRead;
|
reg BlockingTxBDRead;
|
|
|
reg GetNewTxData_wb_latched;
|
|
|
|
reg NewTxDataAvaliable_wb;
|
|
|
|
reg TxBDAccessed;
|
|
|
|
reg [7:0] TxBDAddress;
|
reg [7:0] TxBDAddress;
|
reg [7:0] RxBDAddress;
|
reg [7:0] RxBDAddress;
|
|
|
reg GotDataSync1;
|
reg GotDataSync1;
|
reg GotDataSync2;
|
reg GotDataSync2;
|
wire TPauseRqSync2;
|
|
wire GotDataSync3;
|
wire GotDataSync3;
|
|
|
reg GotData;
|
reg GotData;
|
reg SyncGetNewTxData_wb1;
|
|
reg SyncGetNewTxData_wb2;
|
|
reg SyncGetNewTxData_wb3;
|
|
reg TxDoneSync1;
|
|
reg TxDoneSync2;
|
|
wire TxDoneSync3;
|
|
reg TxRetrySync1;
|
reg TxRetrySync1;
|
reg TxRetrySync2;
|
|
wire TxRetrySync3;
|
|
reg TxAbortSync1;
|
reg TxAbortSync1;
|
reg TxAbortSync2;
|
reg TxDoneSync1;
|
wire TxAbortSync3;
|
|
|
|
reg TxAbort_q;
|
reg TxAbort_q;
|
reg TxDone_q;
|
|
reg TxRetry_q;
|
reg TxRetry_q;
|
reg TxUsedData_q;
|
reg TxUsedData_q;
|
|
reg TxCtrlEndFrm_q;
|
|
|
reg [31:0] RxDataLatched2;
|
reg [31:0] RxDataLatched2;
|
reg [15:0] RxDataLatched1;
|
reg [15:0] RxDataLatched1;
|
reg [1:0] RxValidBytes;
|
reg [1:0] RxValidBytes;
|
reg [1:0] RxByteCnt;
|
reg [1:0] RxByteCnt;
|
Line 257... |
Line 260... |
|
|
reg RxStartFrmSync1;
|
reg RxStartFrmSync1;
|
reg RxStartFrmSync2;
|
reg RxStartFrmSync2;
|
wire RxStartFrmSync3;
|
wire RxStartFrmSync3;
|
|
|
reg DMACycleFinishedTx_q;
|
|
reg DataNotAvaliable;
|
|
|
|
reg ClearTxBDReadySync1;
|
|
reg ClearTxBDReadySync2;
|
|
reg ClearTxBDReady;
|
|
|
|
reg TxCtrlEndFrm_wbSync1;
|
|
reg TxCtrlEndFrm_wbSync2;
|
|
wire TxCtrlEndFrm_wbSync3;
|
|
reg TxCtrlEndFrm_wb;
|
|
|
|
wire [15:0] TxPauseTV;
|
|
wire ResetDataNotAvaliable;
|
|
wire SetDataNotAvaliable;
|
|
wire DWord; // Only 32-bit accesses are valid
|
wire DWord; // Only 32-bit accesses are valid
|
wire BDWe; // BD Write Enable for access from WISHBONE side
|
wire BDWrite; // BD Write Enable for access from WISHBONE side
|
wire BDRead; // BD Read access from WISHBONE side
|
wire BDRead; // BD Read access from WISHBONE side
|
wire [31:0] BDDataIn; // BD data in
|
wire [31:0] RxBDDataIn; // Rx BD data in
|
|
wire [31:0] TxBDDataIn; // Tx BD data in
|
wire [31:0] BDDataOut; // BD data out
|
wire [31:0] BDDataOut; // BD data out
|
|
|
wire TxEndFrm_wb;
|
reg TxEndFrm_wb;
|
|
|
wire DMACycleFinishedTx;
|
wire TxRetryPulse;
|
wire BDStatusWrite;
|
|
|
|
wire TxEn;
|
|
wire RxEn;
|
|
wire TxRestartPulse;
|
|
wire TxDonePulse;
|
wire TxDonePulse;
|
wire TxAbortPulse;
|
wire TxAbortPulse;
|
|
|
wire StartRxBDRead;
|
wire StartRxBDRead;
|
wire ResetRxBDRead;
|
wire ResetRxBDRead;
|
Line 300... |
Line 284... |
wire DMACycleFinishedRx;
|
wire DMACycleFinishedRx;
|
|
|
wire [31:0] WB_BDDataOut;
|
wire [31:0] WB_BDDataOut;
|
|
|
wire StartTxBDRead;
|
wire StartTxBDRead;
|
wire StartTxDataRead;
|
|
wire ResetTxDataRead;
|
|
wire StartTxStatusWrite;
|
wire StartTxStatusWrite;
|
wire ResetTxStatusWrite;
|
wire ResetTxStatusWrite;
|
|
|
wire TxIRQEn;
|
wire TxIRQEn;
|
wire WrapTxStatusBit;
|
wire WrapTxStatusBit;
|
Line 321... |
Line 303... |
wire [15:0] NewRxStatus;
|
wire [15:0] NewRxStatus;
|
|
|
wire SetGotData;
|
wire SetGotData;
|
wire ResetGotData;
|
wire ResetGotData;
|
wire GotDataEvaluate;
|
wire GotDataEvaluate;
|
wire ResetSyncGetNewTxData_wb;
|
|
wire ResetTxDoneSync;
|
wire ResetTxDoneSync;
|
wire ResetTxRetrySync;
|
wire ResetTxRetrySync;
|
wire ResetTxAbortSync;
|
wire ResetTxAbortSync;
|
wire SetSyncGetNewTxData_wb;
|
|
|
|
wire SetTxAbortSync;
|
wire SetTxAbortSync;
|
wire ResetShiftEnded;
|
wire ResetShiftEnded;
|
wire ResetRxStartFrmSync1;
|
wire ResetRxStartFrmSync1;
|
wire StartShiftEnded;
|
wire StartShiftEnded;
|
wire StartRxStartFrmSync1;
|
wire StartRxStartFrmSync1;
|
|
|
wire SetClearTxBDReady;
|
reg temp_ack;
|
wire ResetClearTxBDReady;
|
|
|
|
wire ResetTxCtrlEndFrm_wb;
|
|
wire SetTxCtrlEndFrm_wb;
|
|
|
|
|
`ifdef ETH_REGISTERED_OUTPUTS
|
|
reg temp_ack2;
|
|
reg [31:0] registered_ram_do;
|
|
`endif
|
|
|
|
reg WbEn, WbEn_q;
|
|
reg RxEn, RxEn_q;
|
|
reg TxEn, TxEn_q;
|
|
|
|
wire ram_ce;
|
|
wire ram_we;
|
|
wire ram_oe;
|
|
reg [7:0] ram_addr;
|
|
reg [31:0] ram_di;
|
|
wire [31:0] ram_do;
|
|
|
assign BDWe = BDCs & WB_WE_I;
|
wire StartTxPointerRead;
|
assign BDRead = BDCs & ~WB_WE_I;
|
wire ResetTxPointerRead;
|
assign WB_ACK_O = BDWe | BDRead & BDRead_q; // ACK is delayed one clock because of BLOCKRAM properties when performing read
|
reg TxPointerRead;
|
|
reg TxEn_needed;
|
|
|
|
//assign BDWrite = BDCs & WB_WE_I & WbEn & ~WbEn_q;
|
|
assign BDWrite = BDCs & WB_WE_I & WbEn & WbEn_q;
|
|
assign BDRead = BDCs & ~WB_WE_I & WbEn_q; // Read cycle is longer for one cycle
|
|
|
|
|
reg EnableRAM;
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
EnableRAM <=#Tp 1'b0;
|
begin
|
else
|
temp_ack <=#Tp 1'b0;
|
if(BDWe)
|
`ifdef ETH_REGISTERED_OUTPUTS
|
EnableRAM <=#Tp 1'b1;
|
temp_ack2 <=#Tp 1'b0;
|
|
registered_ram_do <=#Tp 32'h0;
|
|
`endif
|
|
end
|
else
|
else
|
EnableRAM <=#Tp EnableRAM;
|
begin
|
|
temp_ack <=#Tp BDWrite | BDRead & ~WbEn;
|
|
`ifdef ETH_REGISTERED_OUTPUTS
|
|
temp_ack2 <=#Tp temp_ack;
|
|
registered_ram_do <=#Tp ram_do;
|
|
`endif
|
end
|
end
|
|
end
|
|
|
|
`ifdef ETH_REGISTERED_OUTPUTS
|
|
assign WB_ACK_O = temp_ack2;
|
|
assign WB_DAT_O = registered_ram_do;
|
|
`else
|
|
assign WB_ACK_O = temp_ack;
|
|
assign WB_DAT_O = ram_do;
|
|
`endif
|
|
|
|
|
|
|
|
|
// Generic synchronous two-port RAM interface
|
// Generic synchronous two-port RAM interface
|
generic_tpram #(8, 32) i_generic_tpram
|
/*
|
(
|
generic_tpram #(8, 32) i_generic_tpram
|
.clk_a(WB_CLK_I), .rst_a(WB_RST_I), .ce_a(1'b1), .we_a(BDWe),
|
(
|
.oe_a(EnableRAM), .addr_a(WB_ADR_I[9:2]), .di_a(WB_DAT_I), .do_a(WB_BDDataOut),
|
.clk_a(WB_CLK_I), .rst_a(WB_RST_I), .ce_a(1'b1), .we_a(BDWrite),
|
|
.oe_a(EnableRAM), .addr_a(WB_ADR_I[9:2]), .di_a(WB_DAT_I), .do_a(WB_BDDataOut),
|
|
|
.clk_b(WB_CLK_I), .rst_b(WB_RST_I), .ce_b(EnableRAM), .we_b(BDStatusWrite),
|
.clk_b(WB_CLK_I), .rst_b(WB_RST_I), .ce_b(EnableRAM), .we_b(BDStatusWrite),
|
.oe_b(EnableRAM), .addr_b(BDAddress[7:0]), .di_b(BDDataIn), .do_b(BDDataOut)
|
.oe_b(EnableRAM), .addr_b(BDAddress[7:0]), .di_b(BDDataIn), .do_b(BDDataOut)
|
);
|
);
|
|
*/
|
|
|
|
|
|
|
|
RAMB4_S16 ram1 (.DO(ram_do[15:0]), .ADDR(ram_addr), .DI(ram_di[15:0]), .EN(ram_ce),
|
|
.CLK(WB_CLK_I), .WE(ram_we), .RST(WB_RST_I));
|
|
RAMB4_S16 ram2 (.DO(ram_do[31:16]), .ADDR(ram_addr), .DI(ram_di[31:16]), .EN(ram_ce),
|
|
.CLK(WB_CLK_I), .WE(ram_we), .RST(WB_RST_I));
|
|
|
|
|
|
|
|
/*
|
|
generic_spram #(8, 32) ram (
|
|
// Generic synchronous single-port RAM interface
|
|
.clk(WB_CLK_I), .rst(WB_RST_I), .ce(ram_ce), .we(ram_we), .oe(ram_oe), .addr(ram_addr), .di(ram_di), .do(ram_do)
|
|
);
|
|
*/
|
|
assign ram_ce = 1'b1;
|
|
assign ram_we = BDWrite | TxStatusWrite; // tu manjka se write kad se vpisuje RxBD status
|
|
assign ram_oe = BDRead | TxEn & TxEn_q & TxBDRead; // Tu manjka se read kadar se bere RxBD
|
|
|
|
reg [3:0] xxx_debug;
|
|
|
|
//assign TxEn_needed = ~TxBDReady | TxPointerRead;
|
|
|
// WB_CLK_I is divided by 2. This signal is used for enabling tx and rx operations sequentially
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
Div2 <=#Tp 1'h0;
|
TxEn_needed <=#Tp 1'b0;
|
|
else
|
|
if(~TxBDReady & WbEn)
|
|
TxEn_needed <=#Tp 1'b1;
|
else
|
else
|
Div2 <=#Tp ~Div2;
|
if(TxPointerRead & TxEn & TxEn_q)
|
|
TxEn_needed <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// Tx_En and Rx_En select who can access the BD memory (Tx or Rx)
|
|
assign TxEn = Div2 & r_TxEn;
|
|
assign RxEn = ~Div2 & r_RxEn;
|
|
|
|
|
|
|
|
|
// Enabling access to the RAM for three devices.
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
begin
|
|
WbEn <=#Tp 1'b1;
|
|
RxEn <=#Tp 1'b0;
|
|
TxEn <=#Tp 1'b0;
|
|
ram_addr <=#Tp 8'h0;
|
|
ram_di <=#Tp 32'h0;
|
|
xxx_debug <=#Tp 0; // igor !!! zbrisi xxx_debug, debug, ...
|
|
end
|
|
else
|
|
begin
|
|
// Switching between three stages depends on enable signals
|
|
// casex ({WbEn_q, RxEn_q, TxEn_q, r_RxEn, r_TxEn, TxEn_needed}) // synopsys parallel_case
|
|
casex ({WbEn_q, RxEn_q, TxEn_q, r_RxEn, r_TxEn & TxEn_needed}) // synopsys parallel_case
|
|
5'b100_1x :
|
|
begin
|
|
WbEn <=#Tp 1'b0;
|
|
RxEn <=#Tp 1'b1; // wb access stage and r_RxEn is enabled
|
|
TxEn <=#Tp 1'b0;
|
|
ram_addr <=#Tp RxBDAddress;
|
|
ram_di <=#Tp RxBDDataIn;
|
|
xxx_debug <=#Tp 1;
|
|
end
|
|
5'b100_01 :
|
|
begin
|
|
WbEn <=#Tp 1'b0;
|
|
RxEn <=#Tp 1'b0;
|
|
TxEn <=#Tp 1'b1; // wb access stage, r_RxEn is disabled but r_TxEn is enabled
|
|
ram_addr <=#Tp TxBDAddress + TxPointerRead;
|
|
ram_di <=#Tp TxBDDataIn;
|
|
xxx_debug <=#Tp 2;
|
|
end
|
|
5'b010_x0 :
|
|
begin
|
|
WbEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is disabled
|
|
RxEn <=#Tp 1'b0;
|
|
TxEn <=#Tp 1'b0;
|
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
|
ram_di <=#Tp WB_DAT_I;
|
|
xxx_debug <=#Tp 3;
|
|
end
|
|
5'b010_x1 :
|
|
begin
|
|
WbEn <=#Tp 1'b0;
|
|
RxEn <=#Tp 1'b0;
|
|
TxEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is enabled
|
|
ram_addr <=#Tp TxBDAddress + TxPointerRead;
|
|
ram_di <=#Tp TxBDDataIn;
|
|
xxx_debug <=#Tp 4;
|
|
end
|
|
5'b001_xx :
|
|
begin
|
|
WbEn <=#Tp 1'b1; // TxEn access stage (we always go to wb access stage)
|
|
RxEn <=#Tp 1'b0;
|
|
TxEn <=#Tp 1'b0;
|
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
|
ram_di <=#Tp WB_DAT_I;
|
|
xxx_debug <=#Tp 5;
|
|
end
|
|
5'b100_00 :
|
|
begin
|
|
WbEn <=#Tp 1'b0; // WbEn access stage and there is no need for other stages. WbEn needs to be switched off for a bit
|
|
xxx_debug <=#Tp 6;
|
|
end
|
|
5'b000_00 :
|
|
begin
|
|
WbEn <=#Tp 1'b1; // Idle state. We go to WbEn access stage.
|
|
RxEn <=#Tp 1'b0;
|
|
TxEn <=#Tp 1'b0;
|
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
|
ram_di <=#Tp WB_DAT_I;
|
|
xxx_debug <=#Tp 7;
|
|
end
|
|
default :
|
|
begin
|
|
WbEn <=#Tp 1'b1; // We go to wb access stage
|
|
RxEn <=#Tp 1'b0;
|
|
TxEn <=#Tp 1'b0;
|
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
|
ram_di <=#Tp WB_DAT_I;
|
|
xxx_debug <=#Tp 8;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
// Delayed stage signals
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
begin
|
|
WbEn_q <=#Tp 1'b0;
|
|
RxEn_q <=#Tp 1'b0;
|
|
TxEn_q <=#Tp 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
WbEn_q <=#Tp WbEn;
|
|
RxEn_q <=#Tp RxEn;
|
|
TxEn_q <=#Tp TxEn;
|
|
end
|
|
end
|
|
|
// Changes for tx occur every second clock. Flop is used for this manner.
|
// Changes for tx occur every second clock. Flop is used for this manner.
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
Flop <=#Tp 1'b0;
|
Flop <=#Tp 1'b0;
|
Line 400... |
Line 543... |
else
|
else
|
if(TxUsedData)
|
if(TxUsedData)
|
Flop <=#Tp ~Flop;
|
Flop <=#Tp ~Flop;
|
end
|
end
|
|
|
|
wire ResetTxBDReady;
|
|
assign ResetTxBDReady = TxDonePulse | TxAbortPulse | TxRetryPulse;
|
|
|
// Latching READY status of the Tx buffer descriptor
|
// Latching READY status of the Tx buffer descriptor
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxBDReady <=#Tp 1'b0;
|
TxBDReady <=#Tp 1'b0;
|
else
|
else
|
if(TxEn & TxBDRead)
|
if(TxEn & TxEn_q & TxBDRead & ~TxPointerRead)
|
TxBDReady <=#Tp BDDataOut[15]; // TxBDReady=BDDataOut[15] // TxBDReady is sampled only once at the beginning
|
TxBDReady <=#Tp ram_do[15]; // TxBDReady is sampled only once at the beginning
|
else
|
else
|
if(TxDone & ~TxDone_q | TxAbort & ~TxAbort_q | TxRetry & ~TxRetry_q | ClearTxBDReady | TxPauseRq)
|
if(ResetTxBDReady)
|
TxBDReady <=#Tp 1'b0;
|
TxBDReady <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// Latching READY status of the Tx buffer descriptor
|
// Reading the Tx buffer descriptor
|
|
assign StartTxBDRead = (TxRetry_wb | TxStatusWrite) & ~BlockingTxBDRead;
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
begin
|
TxBDRead <=#Tp 1'b1;
|
TxPauseRq <=#Tp 1'b0;
|
|
end
|
|
else
|
else
|
if(TxEn & TxBDRead)
|
if(StartTxBDRead)
|
begin
|
TxBDRead <=#Tp 1'b1;
|
TxPauseRq <=#Tp BDDataOut[9]; // Tx PAUSE request
|
|
end
|
|
else
|
else
|
TxPauseRq <=#Tp 1'b0;
|
if(TxBDReady)
|
|
TxBDRead <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
assign TxPauseTV[15:0] = TxLength[15:0];
|
// Reading Tx BD pointer
|
|
assign StartTxPointerRead = TxBDRead & TxBDReady;
|
// Reading the Tx buffer descriptor
|
|
assign StartTxBDRead = TxEn & ~BlockingTxBDRead & (TxRetry_wb | TxStatusWriteOccured);
|
|
|
|
|
// Reading Tx BD Pointer
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxBDRead <=#Tp 1'b1;
|
TxPointerRead <=#Tp 1'b0;
|
else
|
else
|
if(StartTxBDRead)
|
if(StartTxPointerRead)
|
TxBDRead <=#Tp 1'b1;
|
TxPointerRead <=#Tp 1'b1;
|
else
|
else
|
if(StartTxDataRead | TxPauseRq)
|
if(TxEn_q)
|
TxBDRead <=#Tp 1'b0;
|
TxPointerRead <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
|
// Writing status back to the Tx buffer descriptor
|
|
assign TxStatusWrite = (TxDone_wb | TxAbort_wb) & TxEn & TxEn_q & ~BlockingTxStatusWrite;
|
|
|
// Requesting data (DMA)
|
|
assign StartTxDataRead = TxBDRead & TxBDReady & ~TxPauseRq | GetNewTxData_wb;
|
|
assign ResetTxDataRead = DMACycleFinishedTx | TxRestartPulse | TxAbortPulse | TxDonePulse;
|
|
|
|
|
|
// Reading data
|
// Status writing must occur only once. Meanwhile it is blocked.
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxDataRead <=#Tp 1'b0;
|
BlockingTxStatusWrite <=#Tp 1'b0;
|
else
|
else
|
if(StartTxDataRead & r_DmaEn)
|
if(TxStatusWrite)
|
TxDataRead <=#Tp 1'b1;
|
BlockingTxStatusWrite <=#Tp 1'b1;
|
else
|
else
|
if(ResetTxDataRead)
|
if(~TxDone_wb & ~TxAbort_wb)
|
TxDataRead <=#Tp 1'b0;
|
BlockingTxStatusWrite <=#Tp 1'b0;
|
end
|
end
|
|
|
// Requesting tx data from the DMA
|
|
assign WB_REQ_O[0] = TxDataRead;
|
|
assign DMACycleFinishedTx = WB_REQ_O[0] & WB_ACK_I[0] & TxBDReady;
|
|
|
|
|
// TxBDRead state is activated only once.
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
BlockingTxBDRead <=#Tp 1'b0;
|
|
else
|
|
if(StartTxBDRead)
|
|
BlockingTxBDRead <=#Tp 1'b1;
|
|
else
|
|
if(TxStartFrm_wb)
|
|
BlockingTxBDRead <=#Tp 1'b0;
|
|
end
|
|
|
// Writing status back to the Tx buffer descriptor
|
|
assign StartTxStatusWrite = TxEn & ~BlockingTxStatusWrite & (TxDone_wb | TxAbort_wb | TxCtrlEndFrm_wb);
|
|
assign ResetTxStatusWrite = TxStatusWrite;
|
|
|
|
|
// Latching status from the tx buffer descriptor
|
|
// Data is avaliable one cycle after the access is started (at that time signal TxEn is not active)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxStatusWrite <=#Tp 1'b0;
|
TxStatus <=#Tp 15'h0;
|
else
|
|
if(StartTxStatusWrite)
|
|
TxStatusWrite <=#Tp 1'b1;
|
|
else
|
else
|
if(ResetTxStatusWrite)
|
if(TxEn & TxEn_q & TxBDRead & ~TxPointerRead)
|
TxStatusWrite <=#Tp 1'b0;
|
TxStatus <=#Tp ram_do[15:0];
|
end
|
end
|
|
|
|
reg ReadDataFromTxBuffer;
|
|
wire WriteDataToRxBuffer = 0; // igor !!! Popravi to, da bo pravilno
|
|
|
// Status writing must occur only once. Meanwhile it is blocked.
|
reg MasterWbTX;
|
|
reg MasterWbRX;
|
|
|
|
reg [31:0] m_wb_dat_o;
|
|
reg [31:0] m_wb_adr_o;
|
|
reg m_wb_cyc_o;
|
|
reg m_wb_stb_o;
|
|
reg m_wb_we_o;
|
|
wire [31:0] rx_fifo_data_out = 0; // Spremeni to, da bo pravilno
|
|
wire TxLengthEq0;
|
|
wire TxLengthLt4;
|
|
|
|
|
|
//Latching length from the buffer descriptor;
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
BlockingTxStatusWrite <=#Tp 1'b0;
|
TxLength <=#Tp 16'h0;
|
else
|
else
|
if(StartTxStatusWrite)
|
if(TxEn & TxEn_q & TxBDRead)
|
BlockingTxStatusWrite <=#Tp 1'b1;
|
TxLength <=#Tp ram_do[31:16];
|
else
|
else
|
if(~TxDone_wb & ~TxAbort_wb)
|
if(MasterWbTX & m_wb_ack_i)
|
BlockingTxStatusWrite <=#Tp 1'b0;
|
begin
|
|
if(TxLengthLt4)
|
|
TxLength <=#Tp 16'h0;
|
|
else
|
|
TxLength <=#Tp TxLength - 3'h4; // Length is subtracted at the data request
|
end
|
end
|
|
end
|
|
|
|
assign TxLengthEq0 = TxLength == 0;
|
|
assign TxLengthLt4 = TxLength < 4;
|
|
|
|
|
|
reg BlockingIncrementTxPointer;
|
|
|
// After a tx status write is finished, a new tx buffer descriptor is read. Signal must be
|
reg [31:0] TxPointer;
|
// latched because new BD read doesn't occur immediately.
|
reg [31:0] RxPointer;
|
|
|
|
//Latching Tx buffer pointer from buffer descriptor;
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxStatusWriteOccured <=#Tp 1'b0;
|
TxPointer <=#Tp 0;
|
else
|
else
|
if(StartTxStatusWrite)
|
if(TxEn & TxEn_q & TxPointerRead)
|
TxStatusWriteOccured <=#Tp 1'b1;
|
TxPointer <=#Tp ram_do;
|
else
|
else
|
if(StartTxBDRead)
|
if(MasterWbTX & ~BlockingIncrementTxPointer)
|
TxStatusWriteOccured <=#Tp 1'b0;
|
TxPointer <=#Tp TxPointer + 4; // Pointer increment
|
end
|
end
|
|
|
|
wire MasterAccessFinished;
|
|
|
// TxBDRead state is activated only once.
|
|
|
//Latching Tx buffer pointer from buffer descriptor;
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
BlockingTxBDRead <=#Tp 1'b0;
|
BlockingIncrementTxPointer <=#Tp 0;
|
else
|
else
|
if(StartTxBDRead)
|
if(MasterAccessFinished)
|
BlockingTxBDRead <=#Tp 1'b1;
|
BlockingIncrementTxPointer <=#Tp 0;
|
else
|
else
|
if(TxStartFrm_wb | TxCtrlEndFrm_wb)
|
if(MasterWbTX)
|
BlockingTxBDRead <=#Tp 1'b0;
|
BlockingIncrementTxPointer <=#Tp 1'b1;
|
end
|
end
|
|
|
|
wire RxPointerRead = 0; // igor !!! spremeni to da bo pravilno
|
|
//Latching Rx buffer pointer from buffer descriptor;
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
RxPointer <=#Tp 15'h0;
|
|
else
|
|
if(RxEn & RxEn_q & RxPointerRead)
|
|
RxPointer <=#Tp ram_do;
|
|
end
|
|
|
|
wire TxBufferAlmostFull;
|
|
wire TxBufferFull;
|
|
wire TxBufferEmpty;
|
|
wire TxBufferAlmostEmpty;
|
|
wire ResetReadDataFromTxBuffer;
|
|
wire SetReadDataFromTxBuffer;
|
|
|
|
reg BlockReadDataFromTxBuffer;
|
|
|
|
//assign ResetReadDataFromTxBuffer = (TxLength < 4) | TxAbortPulse | TxRetryPulse;
|
|
assign ResetReadDataFromTxBuffer = (TxLengthEq0) | TxAbortPulse | TxRetryPulse;
|
|
assign SetReadDataFromTxBuffer = TxEn & TxEn_q & TxPointerRead;
|
|
|
// Latching status from the tx buffer descriptor
|
|
// Data is avaliable one cycle after the access is started (at that time signal TxEn is not active)
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxStatus <=#Tp 32'h0;
|
ReadDataFromTxBuffer <=#Tp 1'b0;
|
else
|
else
|
if(TxBDRead & TxEn)
|
if(ResetReadDataFromTxBuffer)
|
TxStatus <=#Tp BDDataOut;
|
ReadDataFromTxBuffer <=#Tp 1'b0;
|
|
else
|
|
if(SetReadDataFromTxBuffer)
|
|
ReadDataFromTxBuffer <=#Tp 1'b1;
|
end
|
end
|
|
|
|
wire ReadDataFromTxBuffer_2 = ReadDataFromTxBuffer & ~BlockReadDataFromTxBuffer;
|
|
wire [31:0] TxData_wb;
|
|
wire ReadTxDataFromFifo_wb;
|
|
|
//Latching length from the buffer descriptor;
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxLength <=#Tp 16'h0;
|
BlockReadDataFromTxBuffer <=#Tp 1'b0;
|
else
|
else
|
if(TxBDRead & TxEn)
|
if(ReadTxDataFromFifo_wb)
|
TxLength <=#Tp BDDataOut[31:16];
|
BlockReadDataFromTxBuffer <=#Tp 1'b0;
|
else
|
else
|
if(GetNewTxData_wb & ~WillSendControlFrame)
|
// if((TxBufferAlmostFull | TxLengthLt4)& MasterWbTX)
|
|
if((TxBufferAlmostFull | TxLength <= 4)& MasterWbTX)
|
|
BlockReadDataFromTxBuffer <=#Tp 1'b1;
|
|
end
|
|
|
|
|
|
|
|
assign MasterAccessFinished = m_wb_ack_i | m_wb_err_i;
|
|
|
|
assign m_wb_sel_o = 4'hf;
|
|
|
|
|
|
reg [3:0]debug;
|
|
|
|
|
|
// Enabling master wishbone access to the memory for two devices TX and RX.
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
begin
|
begin
|
if(TxLength > 4)
|
MasterWbTX <=#Tp 1'b0;
|
TxLength <=#Tp TxLength - 4; // Length is subtracted at the data request
|
MasterWbRX <=#Tp 1'b0;
|
|
m_wb_dat_o <=#Tp 32'h0;
|
|
m_wb_adr_o <=#Tp 32'h0;
|
|
m_wb_cyc_o <=#Tp 1'b0;
|
|
m_wb_stb_o <=#Tp 1'b0;
|
|
m_wb_we_o <=#Tp 1'b0;
|
|
debug <=#Tp 0;
|
|
end
|
else
|
else
|
TxLength <=#Tp 16'h0;
|
begin
|
|
// Switching between two stages depends on enable signals
|
|
casex ({MasterWbTX, MasterWbRX, ReadDataFromTxBuffer_2, WriteDataToRxBuffer, MasterAccessFinished}) // synopsys parallel_case full_case
|
|
5'b00_x1_x :
|
|
begin
|
|
MasterWbTX <=#Tp 1'b0; // idle and master write is needed (data write to rx buffer)
|
|
MasterWbRX <=#Tp 1'b1;
|
|
m_wb_dat_o <=#Tp rx_fifo_data_out;
|
|
m_wb_adr_o <=#Tp RxPointer;
|
|
m_wb_cyc_o <=#Tp 1'b1;
|
|
m_wb_stb_o <=#Tp 1'b1;
|
|
m_wb_we_o <=#Tp 1'b1;
|
|
debug <=#Tp 1;
|
|
end
|
|
5'b00_10_x :
|
|
begin
|
|
$display("\n\tHere we go again");
|
|
MasterWbTX <=#Tp 1'b1; // idle and master read is needed (data read from tx buffer)
|
|
MasterWbRX <=#Tp 1'b0;
|
|
m_wb_adr_o <=#Tp TxPointer;
|
|
m_wb_cyc_o <=#Tp 1'b1;
|
|
m_wb_stb_o <=#Tp 1'b1;
|
|
m_wb_we_o <=#Tp 1'b0;
|
|
debug <=#Tp 2;
|
|
end
|
|
5'b10_10_1 :
|
|
begin
|
|
$display("\n\tHere we go again");
|
|
MasterWbTX <=#Tp 1'b1; // master read and master read is needed (data read from tx buffer)
|
|
MasterWbRX <=#Tp 1'b0;
|
|
m_wb_adr_o <=#Tp TxPointer;
|
|
m_wb_cyc_o <=#Tp 1'b1;
|
|
m_wb_stb_o <=#Tp 1'b1;
|
|
m_wb_we_o <=#Tp 1'b0;
|
|
debug <=#Tp 6;
|
|
end
|
|
5'b01_01_1 :
|
|
begin
|
|
MasterWbTX <=#Tp 1'b0; // master write and master write is needed (data write to rx buffer)
|
|
MasterWbRX <=#Tp 1'b1;
|
|
m_wb_dat_o <=#Tp rx_fifo_data_out;
|
|
m_wb_adr_o <=#Tp RxPointer;
|
|
m_wb_we_o <=#Tp 1'b1;
|
|
debug <=#Tp 7;
|
|
end
|
|
5'b10_x1_1 :
|
|
begin
|
|
MasterWbTX <=#Tp 1'b0; // master read and master write is needed (data write to rx buffer)
|
|
MasterWbRX <=#Tp 1'b1;
|
|
m_wb_dat_o <=#Tp rx_fifo_data_out;
|
|
m_wb_adr_o <=#Tp RxPointer;
|
|
m_wb_we_o <=#Tp 1'b1;
|
|
debug <=#Tp 3;
|
end
|
end
|
|
5'b01_1x_1 :
|
|
begin
|
|
MasterWbTX <=#Tp 1'b1; // master write and master read is needed (data read from tx buffer)
|
|
MasterWbRX <=#Tp 1'b0;
|
|
m_wb_adr_o <=#Tp TxPointer;
|
|
m_wb_we_o <=#Tp 1'b0;
|
|
debug <=#Tp 4;
|
|
end
|
|
5'bxx_00_1 :
|
|
begin
|
|
MasterWbTX <=#Tp 1'b0; // whatever and no master read or write is needed (ack or err comes finishing previous access)
|
|
MasterWbRX <=#Tp 1'b0;
|
|
m_wb_cyc_o <=#Tp 1'b0;
|
|
m_wb_stb_o <=#Tp 1'b0;
|
|
debug <=#Tp 8;
|
end
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
wire TxFifoClear;
|
|
assign TxFifoClear = (TxAbort_wb | TxRetry_wb) & ~TxBDReady;
|
|
eth_fifo tx_fifo (.data_in(m_wb_dat_i), .data_out(TxData_wb), .clk(WB_CLK_I),
|
|
.reset(WB_RST_I), .write(MasterWbTX & m_wb_ack_i), .read(ReadTxDataFromFifo_wb),
|
|
.clear(TxFifoClear), .full(TxBufferFull), .almost_full(TxBufferAlmostFull),
|
|
.almost_empty(TxBufferAlmostEmpty), .empty(TxBufferEmpty));
|
|
|
|
|
|
|
|
|
|
|
// Latching Rx buffer descriptor status
|
// Latching Rx buffer descriptor status
|
// Data is avaliable one cycle after the access is started (at that time signal RxEn is not active)
|
// Data is avaliable one cycle after the access is started (at that time signal RxEn is not active)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
Line 577... |
Line 884... |
if(RxBDRead & RxEn)
|
if(RxBDRead & RxEn)
|
RxStatus <=#Tp BDDataOut[15:0];
|
RxStatus <=#Tp BDDataOut[15:0];
|
end
|
end
|
|
|
|
|
// Signal GetNewTxData_wb that requests new data from the DMA must be latched since the DMA response
|
reg StartOccured;
|
// might be delayed.
|
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 WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
GetNewTxData_wb_latched <=#Tp 1'b0;
|
TxStartFrm_wb <=#Tp 1'b0;
|
else
|
else
|
if(GetNewTxData_wb)
|
if(TxBDReady & ~StartOccured & (TxBufferFull | TxLengthEq0))
|
GetNewTxData_wb_latched <=#Tp 1'b1;
|
TxStartFrm_wb <=#Tp 1'b1;
|
else
|
else
|
if(DMACycleFinishedTx)
|
if(TxStartFrm_syncb2)
|
GetNewTxData_wb_latched <=#Tp 1'b0;
|
TxStartFrm_wb <=#Tp 1'b0;
|
end
|
end
|
|
|
|
// StartOccured: TxStartFrm_wb occurs only ones at the beginning. Then it's blocked.
|
// New tx data is avaliable after the DMA access is finished
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
NewTxDataAvaliable_wb <=#Tp 1'b0;
|
StartOccured <=#Tp 1'b0;
|
else
|
else
|
if(DMACycleFinishedTx & GetNewTxData_wb_latched)
|
if(TxStartFrm_wb)
|
NewTxDataAvaliable_wb <=#Tp 1'b1;
|
StartOccured <=#Tp 1'b1;
|
else
|
else
|
if(NewTxDataAvaliable_wb)
|
if(ResetTxBDReady)
|
NewTxDataAvaliable_wb <=#Tp 1'b0;
|
StartOccured <=#Tp 1'b0;
|
end
|
end
|
|
|
|
// Synchronizing TxStartFrm_wb to MTxClk
|
// Tx Buffer descriptor is only read at the beginning. This signal is used for generation of the
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
// TxStartFrm_wb signal.
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxBDAccessed <=#Tp 1'b0;
|
TxStartFrm_sync1 <=#Tp 1'b0;
|
else
|
else
|
if(TxBDRead)
|
TxStartFrm_sync1 <=#Tp TxStartFrm_wb;
|
TxBDAccessed <=#Tp 1'b1;
|
end
|
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
TxStartFrm_sync2 <=#Tp 1'b0;
|
else
|
else
|
if(TxStartFrm_wb)
|
TxStartFrm_sync2 <=#Tp TxStartFrm_sync1;
|
TxBDAccessed <=#Tp 1'b0;
|
|
end
|
end
|
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
TxStartFrm_syncb1 <=#Tp 1'b0;
|
|
else
|
|
TxStartFrm_syncb1 <=#Tp TxStartFrm_sync2;
|
|
end
|
|
|
// TxStartFrm_wb: indicator of the start frame (synchronized to WB_CLK_I)
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxStartFrm_wb <=#Tp 1'b0;
|
TxStartFrm_syncb2 <=#Tp 1'b0;
|
else
|
else
|
if(DMACycleFinishedTx & TxBDAccessed & ~TxStartFrm_wb)
|
TxStartFrm_syncb2 <=#Tp TxStartFrm_syncb1;
|
TxStartFrm_wb <=#Tp 1'b1;
|
end
|
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
TxStartFrm <=#Tp 1'b0;
|
else
|
else
|
if(TxStartFrm_wb)
|
if(TxStartFrm_sync2)
|
TxStartFrm_wb <=#Tp 1'b0;
|
TxStartFrm <=#Tp 1'b1; // igor !!! Dodaj se pogoj, da ni vmes prisel kaksen abort ali kaj podobnega
|
|
else
|
|
if(TxUsedData_q)
|
|
TxStartFrm <=#Tp 1'b0;
|
end
|
end
|
|
// End: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TxEndFrm_wb: indicator of the end of frame
|
|
assign TxEndFrm_wb = (TxLength <= 4) & TxUsedData;
|
|
|
|
|
|
// Input latch of the end-of-frame indicator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TxEndFrm_wb: indicator of the end of frame
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxEndFrm_wbLatched <=#Tp 1'b0;
|
TxEndFrm_wb <=#Tp 1'b0;
|
else
|
else
|
if(TxEndFrm_wb)
|
if(TxLengthLt4 & TxBufferAlmostEmpty & TxUsedData)
|
TxEndFrm_wbLatched <=#Tp 1'b1;
|
TxEndFrm_wb <=#Tp 1'b1;
|
else
|
else
|
if(TxRestartPulse | TxDonePulse | TxAbortPulse)
|
if(TxRetryPulse | TxDonePulse | TxAbortPulse)
|
TxEndFrm_wbLatched <=#Tp 1'b0;
|
TxEndFrm_wb <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// Marks which bytes are valid within the word.
|
// Marks which bytes are valid within the word.
|
assign TxValidBytes = (TxLength >= 4)? 2'b0 : TxLength[1:0];
|
assign TxValidBytes = TxLengthLt4 ? TxLength[1:0] : 2'b0;
|
|
|
|
reg LatchValidBytes;
|
|
reg LatchValidBytes_q;
|
|
|
// Latching valid bytes
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxValidBytesLatched <=#Tp 2'h0;
|
LatchValidBytes <=#Tp 1'b0;
|
else
|
else
|
if(TxEndFrm_wb & ~TxEndFrm_wbLatched)
|
if(TxLengthLt4 & TxBDReady)
|
TxValidBytesLatched <=#Tp TxValidBytes;
|
LatchValidBytes <=#Tp 1'b1;
|
else
|
else
|
if(TxRestartPulse | TxDonePulse | TxAbortPulse)
|
LatchValidBytes <=#Tp 1'b0;
|
TxValidBytesLatched <=#Tp 2'h0;
|
|
end
|
end
|
|
|
|
|
// Input Tx data latch
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxDataLatched_wb <=#Tp 32'h0;
|
LatchValidBytes_q <=#Tp 1'b0;
|
else
|
else
|
if(DMACycleFinishedTx)
|
LatchValidBytes_q <=#Tp LatchValidBytes;
|
TxDataLatched_wb <=#Tp WB_DAT_I;
|
|
end
|
end
|
|
|
|
|
// TxStartFrmRequest is set when a new frame is avaliable or when new data of the same frame is avaliable)
|
// Latching valid bytes
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxStartFrmRequest <=#Tp 1'b0;
|
TxValidBytesLatched <=#Tp 2'h0;
|
|
else
|
|
if(LatchValidBytes & ~LatchValidBytes_q)
|
|
TxValidBytesLatched <=#Tp TxValidBytes;
|
else
|
else
|
if(TxStartFrm_wb | NewTxDataAvaliable_wb)
|
if(TxRetryPulse | TxDonePulse | TxAbortPulse)
|
TxStartFrmRequest <=#Tp TxStartFrm_wb;
|
TxValidBytesLatched <=#Tp 2'h0;
|
end
|
end
|
|
|
|
|
// Bit 14 is used as a wrap bit. When active it indicates the last buffer descriptor in a row. After
|
// Bit 14 is used as a wrap bit. When active it indicates the last buffer descriptor in a row. After
|
// using this descriptor, first BD will be used again.
|
// using this descriptor, first BD will be used again.
|
Line 743... |
Line 1084... |
|
|
assign WrapRxStatusBit = RxStatus[13];
|
assign WrapRxStatusBit = RxStatus[13];
|
|
|
|
|
// Temporary Tx and Rx buffer descriptor address
|
// Temporary Tx and Rx buffer descriptor address
|
assign TempTxBDAddress[7:0] = {8{ TxStatusWrite & ~WrapTxStatusBit}} & (TxBDAddress + 1) ; // Tx BD increment or wrap (last BD)
|
assign TempTxBDAddress[7:0] = {8{ TxStatusWrite & ~WrapTxStatusBit}} & (TxBDAddress + 2'h2) ; // Tx BD increment or wrap (last BD)
|
assign TempRxBDAddress[7:0] = {8{ WrapRxStatusBit}} & (r_TxBDNum) | // Using first Rx BD
|
assign TempRxBDAddress[7:0] = {8{ WrapRxStatusBit}} & (r_TxBDNum) | // Using first Rx BD
|
{8{~WrapRxStatusBit}} & (RxBDAddress + 1) ; // Using next Rx BD (incremenrement address)
|
{8{~WrapRxStatusBit}} & (RxBDAddress + 2'h2) ; // Using next Rx BD (incremenrement address)
|
|
|
|
|
// Latching Tx buffer descriptor address
|
// Latching Tx buffer descriptor address
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
Line 791... |
Line 1132... |
assign RxLength[15:0] = 16'h1399;
|
assign RxLength[15:0] = 16'h1399;
|
assign NewRxStatus[15:0] = {1'b0, WbWriteError, RxStatus[13:0]};
|
assign NewRxStatus[15:0] = {1'b0, WbWriteError, RxStatus[13:0]};
|
|
|
|
|
//assign BDDataIn = TxStatusWrite ? {TxLength[15:0], StatusIzTxEthMACModula} : {RxLength, NewRxStatus};
|
//assign BDDataIn = TxStatusWrite ? {TxLength[15:0], StatusIzTxEthMACModula} : {RxLength, NewRxStatus};
|
assign BDDataIn = TxStatusWrite ? {TxStatus[31:9], 9'h0}
|
//assign BDDataIn = TxStatusWrite ? {TxStatus[31:9], 9'h0}
|
: {RxLength, NewRxStatus};
|
// : {RxLength, NewRxStatus};
|
|
assign RxBDDataIn = {RxLength, NewRxStatus}; // tu dopolni, da se bo vpisoval status
|
assign BDStatusWrite = TxStatusWrite | RxStatusWrite;
|
//assign TxBDDataIn = {16'h0, TxStatus[15:9], 9'h0}; // tu dopolni, da se bo vpisoval status
|
|
//assign TxBDDataIn = {32'hdead00ef}; // tu dopolni, da se bo vpisoval status
|
|
assign TxBDDataIn = {32'h004380ef}; // tu dopolni, da se bo vpisoval status
|
|
|
|
|
// Generating delayed signals
|
// Generating delayed signals
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
begin
|
begin
|
TxRestart_wb_q <=#Tp 1'b0;
|
TxRetry_wb_q <=#Tp 1'b0;
|
TxDone_wb_q <=#Tp 1'b0;
|
|
TxAbort_wb_q <=#Tp 1'b0;
|
|
BDRead_q <=#Tp 1'b0;
|
BDRead_q <=#Tp 1'b0;
|
DMACycleFinishedTx_q <=#Tp 1'b0;
|
|
end
|
end
|
else
|
else
|
begin
|
begin
|
TxRestart_wb_q <=#Tp TxRetry_wb;
|
TxRetry_wb_q <=#Tp TxRetry_wb;
|
TxDone_wb_q <=#Tp TxDone_wb;
|
|
TxAbort_wb_q <=#Tp TxAbort_wb;
|
|
BDRead_q <=#Tp BDRead;
|
BDRead_q <=#Tp BDRead;
|
DMACycleFinishedTx_q <=#Tp DMACycleFinishedTx;
|
|
end
|
end
|
end
|
end
|
|
|
|
|
// Signals used for various purposes
|
// Signals used for various purposes
|
assign TxRestartPulse = TxRetry_wb & ~TxRestart_wb_q;
|
assign TxRetryPulse = TxRetry_wb & ~TxRetry_wb_q;
|
assign TxDonePulse = TxDone_wb & ~TxDone_wb_q;
|
assign TxDonePulse = TxDone_wb & ~TxDone_wb_q;
|
assign TxAbortPulse = TxAbort_wb & ~TxAbort_wb_q;
|
assign TxAbortPulse = TxAbort_wb & ~TxAbort_wb_q;
|
|
|
|
|
// Next descriptor for Tx DMA channel
|
// Next descriptor for Tx DMA channel
|
Line 850... |
Line 1187... |
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
WB_RD_O <=#Tp 1'b0;
|
WB_RD_O <=#Tp 1'b0;
|
else
|
else
|
if(TxRestartPulse)
|
if(TxRetryPulse)
|
WB_RD_O <=#Tp 1'b1;
|
WB_RD_O <=#Tp 1'b1;
|
else
|
else
|
if(WB_RD_O)
|
if(WB_RD_O)
|
WB_RD_O <=#Tp 1'b0;
|
WB_RD_O <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
assign SetClearTxBDReady = ~TxUsedData & TxUsedData_q;
|
// assign ClearTxBDReady = ~TxUsedData & TxUsedData_q;
|
assign ResetClearTxBDReady = ClearTxBDReady | WB_RST_I;
|
|
|
|
|
|
always @ (posedge SetClearTxBDReady or posedge ResetClearTxBDReady)
|
|
begin
|
|
if(ResetClearTxBDReady)
|
|
ClearTxBDReadySync1 <=#Tp 1'b0;
|
|
else
|
|
ClearTxBDReadySync1 <=#Tp 1'b1;
|
|
end
|
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
ClearTxBDReadySync2 <=#Tp 1'b0;
|
|
else
|
|
if(ClearTxBDReadySync1 & ~ClearTxBDReady)
|
|
ClearTxBDReadySync2 <=#Tp 1'b1;
|
|
else
|
|
ClearTxBDReadySync2 <=#Tp 1'b0;
|
|
end
|
|
|
|
|
assign TPauseRq = 0; // igor !!! v koncni fazi mora tu biti pause request
|
|
assign TxPauseTV[15:0] = TxLength[15:0]; // igor !!! v koncni fazi mora tu biti pause request
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
// reg WillSendControlFrameSync1;
|
begin
|
// reg WillSendControlFrameSync2;
|
if(WB_RST_I)
|
// reg WillSendControlFrameSync3;
|
ClearTxBDReady <=#Tp 1'b0;
|
// wire WillSendControlFrame_wb;
|
else
|
|
if(ClearTxBDReadySync2 & ~ClearTxBDReady)
|
|
ClearTxBDReady <=#Tp 1'b1;
|
// always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
else
|
// begin
|
ClearTxBDReady <=#Tp 1'b0;
|
// if(WB_RST_I)
|
end
|
// WillSendControlFrameSync1 <=#Tp 1'b0;
|
|
// else
|
|
// WillSendControlFrameSync1 <=#Tp WillSendControlFrame;
|
|
// end
|
|
//
|
|
// always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
// begin
|
|
// if(WB_RST_I)
|
|
// WillSendControlFrameSync2 <=#Tp 1'b0;
|
|
// else
|
|
// WillSendControlFrameSync2 <=#Tp WillSendControlFrameSync1;
|
|
// end
|
|
//
|
|
// always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
// begin
|
|
// if(WB_RST_I)
|
|
// WillSendControlFrameSync3 <=#Tp 1'b0;
|
|
// else
|
|
// WillSendControlFrameSync3 <=#Tp WillSendControlFrameSync2;
|
|
// end
|
|
//
|
|
// assign WillSendControlFrame_wb = WillSendControlFrameSync2 & ~WillSendControlFrameSync3;
|
|
|
|
|
|
|
// Latching and synchronizing the Tx pause request signal
|
|
eth_sync_clk1_clk2 syn1 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
|
.set2(TxPauseRq), .sync_out(TPauseRqSync2)
|
|
);
|
|
|
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
TPauseRq <=#Tp 1'b0;
|
|
else
|
|
if(TPauseRq )
|
|
TPauseRq <=#Tp 1'b0;
|
|
else
|
|
if(TPauseRqSync2)
|
|
TPauseRq <=#Tp 1'b1;
|
|
end
|
|
|
|
|
|
|
|
// Generating delayed signals
|
// Generating delayed signals
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
begin
|
begin
|
TxAbort_q <=#Tp 1'b0;
|
TxAbort_q <=#Tp 1'b0;
|
TxDone_q <=#Tp 1'b0;
|
|
TxRetry_q <=#Tp 1'b0;
|
TxRetry_q <=#Tp 1'b0;
|
TxUsedData_q <=#Tp 1'b0;
|
TxUsedData_q <=#Tp 1'b0;
|
|
TxCtrlEndFrm_q <=#Tp 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
TxAbort_q <=#Tp TxAbort;
|
TxAbort_q <=#Tp TxAbort;
|
TxDone_q <=#Tp TxDone;
|
|
TxRetry_q <=#Tp TxRetry;
|
TxRetry_q <=#Tp TxRetry;
|
TxUsedData_q <=#Tp TxUsedData;
|
TxUsedData_q <=#Tp TxUsedData;
|
|
TxCtrlEndFrm_q <=#Tp TxCtrlEndFrm;
|
end
|
end
|
end
|
end
|
|
|
|
// Generating delayed signals
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
begin
|
|
TxDone_wb_q <=#Tp 1'b0;
|
|
TxAbort_wb_q <=#Tp 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
TxDone_wb_q <=#Tp TxDone_wb;
|
|
TxAbort_wb_q <=#Tp TxAbort_wb;
|
|
end
|
|
end
|
|
|
|
|
// Sinchronizing and evaluating tx data
|
// Sinchronizing and evaluating tx data
|
assign SetGotData = (TxStartFrm_wb | NewTxDataAvaliable_wb & ~TxAbort_wb & ~TxRetry_wb) & ~WB_CLK_I;
|
//assign SetGotData = (TxStartFrm_wb | NewTxDataAvaliable_wb & ~TxAbort_wb & ~TxRetry_wb) & ~WB_CLK_I;
|
|
assign SetGotData = (TxStartFrm_wb); // igor namesto zgornje
|
|
|
eth_sync_clk1_clk2 syn2 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
eth_sync_clk1_clk2 syn2 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
.set2(SetGotData), .sync_out(GotDataSync3));
|
.set2(SetGotData), .sync_out(GotDataSync3));
|
|
|
|
|
// Evaluating data. If abort or retry occured meanwhile than data is ignored.
|
// Evaluating data. If abort or retry occured meanwhile than data is ignored.
|
assign GotDataEvaluate = GotDataSync3 & ~GotData & (~TxRetry & ~TxAbort | (TxRetry | TxAbort) & (TxStartFrmRequest | TxStartFrm));
|
assign GotDataEvaluate = GotDataSync3 & ~GotData & (~TxRetry & ~TxAbort | (TxRetry | TxAbort) & (TxStartFrm));
|
|
|
|
|
// Indication of good data
|
// Indication of good data
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
begin
|
Line 960... |
Line 1299... |
else
|
else
|
GotData <=#Tp 1'b0;
|
GotData <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// Tx start frame generation
|
// // Tx start frame generation
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
// always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
// begin
|
if(WB_RST_I)
|
// if(WB_RST_I)
|
TxStartFrm <=#Tp 1'b0;
|
// TxStartFrm <=#Tp 1'b0;
|
else
|
// else
|
if(TxUsedData_q | TxAbort & ~TxAbort_q | TxRetry & ~TxRetry_q)
|
// if(TxUsedData_q | TxAbort & ~TxAbort_q | TxRetry & ~TxRetry_q)
|
TxStartFrm <=#Tp 1'b0;
|
// TxStartFrm <=#Tp 1'b0;
|
else
|
// else
|
if(TxBDReady & GotData & TxStartFrmRequest)
|
// if(TxBDReady & GotData & TxStartFrmRequest)
|
TxStartFrm <=#Tp 1'b1;
|
// TxStartFrm <=#Tp 1'b1;
|
end
|
// end
|
|
//
|
|
|
// Indication of the last word
|
// Indication of the last word
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
Line 984... |
Line 1323... |
else
|
else
|
if((TxEndFrm | TxAbort | TxRetry) & Flop)
|
if((TxEndFrm | TxAbort | TxRetry) & Flop)
|
LastWord <=#Tp 1'b0;
|
LastWord <=#Tp 1'b0;
|
else
|
else
|
if(TxUsedData & Flop & TxByteCnt == 2'h3)
|
if(TxUsedData & Flop & TxByteCnt == 2'h3)
|
LastWord <=#Tp TxEndFrm_wbLatched;
|
// LastWord <=#Tp TxEndFrm_wbLatched;
|
|
LastWord <=#Tp TxEndFrm_wb;
|
end
|
end
|
|
|
|
|
// Tx end frame generation
|
// Tx end frame generation
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxEndFrm <=#Tp 1'b0;
|
TxEndFrm <=#Tp 1'b0;
|
else
|
else
|
if(Flop & TxEndFrm | TxAbort | TxRetry_q)
|
if(Flop & TxEndFrm | TxAbort | TxRetry_q) // igor !!! zakaj je tu TxRetry_q ?
|
TxEndFrm <=#Tp 1'b0;
|
TxEndFrm <=#Tp 1'b0;
|
else
|
else
|
if(Flop & LastWord)
|
if(Flop & LastWord)
|
begin
|
begin
|
case (TxValidBytesLatched)
|
case (TxValidBytesLatched)
|
Line 1016... |
Line 1356... |
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxData <=#Tp 8'h0;
|
TxData <=#Tp 8'h0;
|
else
|
else
|
if(GotData & ~TxStartFrm & ~TxUsedData)
|
if(TxStartFrm_sync2 & ~TxStartFrm)
|
TxData <=#Tp TxDataLatched_wb[7:0];
|
TxData <=#Tp TxData_wb[7:0];
|
else
|
else
|
if(TxUsedData & Flop)
|
if(TxUsedData & Flop)
|
begin
|
begin
|
case(TxByteCnt)
|
case(TxByteCnt)
|
0 : TxData <=#Tp TxDataLatched[7:0];
|
0 : TxData <=#Tp TxDataLatched[7:0];
|
Line 1037... |
Line 1377... |
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxDataLatched[31:0] <=#Tp 32'h0;
|
TxDataLatched[31:0] <=#Tp 32'h0;
|
else
|
else
|
if(GotData & ~TxUsedData & ~TxStartFrm)
|
if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3)
|
TxDataLatched[31:0] <=#Tp TxDataLatched_wb[31:0];
|
TxDataLatched[31:0] <=#Tp TxData_wb[31:0];
|
else
|
|
if(TxUsedData & Flop & TxByteCnt == 2'h3)
|
|
TxDataLatched[31:0] <=#Tp TxDataLatched_wb[31:0];
|
|
end
|
|
|
|
|
|
// Generation of the DataNotAvaliable signal which is used for the generation of the TxUnderRun signal
|
|
assign ResetDataNotAvaliable = DMACycleFinishedTx_q | WB_RST_I;
|
|
assign SetDataNotAvaliable = GotData & ~TxUsedData & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3;
|
|
|
|
always @ (posedge MTxClk or posedge ResetDataNotAvaliable)
|
|
begin
|
|
if(ResetDataNotAvaliable)
|
|
DataNotAvaliable <=#Tp 1'b0;
|
|
else
|
|
if(SetDataNotAvaliable) // data is latched here
|
|
DataNotAvaliable <=#Tp 1'b1;
|
|
end
|
end
|
|
|
|
|
// Tx under run
|
// Tx under run
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxUnderRun <=#Tp 1'b0;
|
TxUnderRun <=#Tp 1'b0;
|
else
|
else
|
if(TxAbort & ~TxAbort_q)
|
if(TxAbortPulse)
|
TxUnderRun <=#Tp 1'b0;
|
TxUnderRun <=#Tp 1'b0;
|
else
|
else
|
if(TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord & DataNotAvaliable)
|
if(TxBufferEmpty & ReadTxDataFromFifo_wb)
|
TxUnderRun <=#Tp 1'b1;
|
TxUnderRun <=#Tp 1'b1;
|
end
|
end
|
|
|
|
|
|
|
Line 1091... |
Line 1414... |
if(TxUsedData & Flop)
|
if(TxUsedData & Flop)
|
TxByteCnt <=#Tp TxByteCnt + 1;
|
TxByteCnt <=#Tp TxByteCnt + 1;
|
end
|
end
|
|
|
|
|
// Generation of the GetNewTxData signal
|
// Start: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
|
|
reg ReadTxDataFromFifo_sync1;
|
|
reg ReadTxDataFromFifo_sync2;
|
|
reg ReadTxDataFromFifo_sync3;
|
|
reg ReadTxDataFromFifo_syncb1;
|
|
reg ReadTxDataFromFifo_syncb2;
|
|
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
GetNewTxData <=#Tp 1'b0;
|
ReadTxDataFromFifo_tck <=#Tp 1'b0;
|
else
|
|
if(GetNewTxData)
|
|
GetNewTxData <=#Tp 1'b0;
|
|
else
|
else
|
if(TxBDReady & GotData & ~(TxStartFrm | TxUsedData))
|
if(ReadTxDataFromFifo_syncb2)
|
GetNewTxData <=#Tp 1'b1;
|
ReadTxDataFromFifo_tck <=#Tp 1'b0;
|
else
|
else
|
if(TxUsedData & ~TxEndFrm_wbLatched & TxByteCnt == 2'h3)
|
// if(TxUsedData & ~TxEndFrm_wbLatched & TxByteCnt == 2'h3)
|
GetNewTxData <=#Tp ~LastWord;
|
// ReadTxDataFromFifo_tck <=#Tp ~LastWord;
|
|
// if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3)
|
|
if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord)
|
|
ReadTxDataFromFifo_tck <=#Tp 1'b1;
|
end
|
end
|
|
|
|
// Synchronizing TxStartFrm_wb to MTxClk
|
// TxRetryLatched
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxRetryLatched <=#Tp 1'b0;
|
ReadTxDataFromFifo_sync1 <=#Tp 1'b0;
|
else
|
else
|
if(TxStartFrm)
|
ReadTxDataFromFifo_sync1 <=#Tp ReadTxDataFromFifo_tck;
|
TxRetryLatched <=#Tp 1'b0;
|
|
else
|
|
if(TxRetry)
|
|
TxRetryLatched <=#Tp 1'b1;
|
|
end
|
end
|
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
|
// Synchronizing request for a new tx data
|
|
|
|
//ne eth_sync_clk1_clk2 syn3 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
|
// .set2(SetGotData), .sync_out(GotDataSync3));
|
|
|
|
// This section still needs to be changed due to ASIC demands
|
|
assign ResetSyncGetNewTxData_wb = SyncGetNewTxData_wb3 | TxAbort_wb | TxRetry_wb | WB_RST_I;
|
|
assign SetSyncGetNewTxData_wb = GetNewTxData;
|
|
|
|
|
|
// Sync. stage 1
|
|
always @ (posedge SetSyncGetNewTxData_wb or posedge ResetSyncGetNewTxData_wb)
|
|
begin
|
begin
|
if(ResetSyncGetNewTxData_wb)
|
if(WB_RST_I)
|
SyncGetNewTxData_wb1 <=#Tp 1'b0;
|
ReadTxDataFromFifo_sync2 <=#Tp 1'b0;
|
else
|
else
|
SyncGetNewTxData_wb1 <=#Tp 1'b1;
|
ReadTxDataFromFifo_sync2 <=#Tp ReadTxDataFromFifo_sync1;
|
end
|
end
|
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
// Sync. stage 2
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
SyncGetNewTxData_wb2 <=#Tp 1'b0;
|
ReadTxDataFromFifo_syncb1 <=#Tp 1'b0;
|
else
|
else
|
if(SyncGetNewTxData_wb1 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb)
|
ReadTxDataFromFifo_syncb1 <=#Tp ReadTxDataFromFifo_sync2;
|
SyncGetNewTxData_wb2 <=#Tp 1'b1;
|
|
else
|
|
SyncGetNewTxData_wb2 <=#Tp 1'b0;
|
|
end
|
end
|
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
// Sync. stage 3
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
SyncGetNewTxData_wb3 <=#Tp 1'b0;
|
ReadTxDataFromFifo_syncb2 <=#Tp 1'b0;
|
else
|
|
if(SyncGetNewTxData_wb2 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb)
|
|
SyncGetNewTxData_wb3 <=#Tp 1'b1;
|
|
else
|
else
|
SyncGetNewTxData_wb3 <=#Tp 1'b0;
|
ReadTxDataFromFifo_syncb2 <=#Tp ReadTxDataFromFifo_syncb1;
|
end
|
end
|
|
|
|
|
// Synchronized request for a new tx data
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
GetNewTxData_wb <=#Tp 1'b0;
|
ReadTxDataFromFifo_sync3 <=#Tp 1'b0;
|
else
|
else
|
if(GetNewTxData_wb)
|
ReadTxDataFromFifo_sync3 <=#Tp ReadTxDataFromFifo_sync2;
|
GetNewTxData_wb <=#Tp 1'b0;
|
|
else
|
|
if(SyncGetNewTxData_wb3 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb)
|
|
GetNewTxData_wb <=#Tp 1'b1;
|
|
end
|
end
|
|
|
|
assign ReadTxDataFromFifo_wb = ReadTxDataFromFifo_sync2 & ~ReadTxDataFromFifo_sync3;
|
// Synchronizine transmit done signal
|
// End: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
|
// Sinchronizing and evaluating tx data
|
|
eth_sync_clk1_clk2 syn4 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
|
.set2(TxDone), .sync_out(TxDoneSync3)
|
|
);
|
|
|
|
|
|
// Syncronized signal TxDone_wb (sync. to WISHBONE clock)
|
// Synchronizing TxRetry signal (synchronized to WISHBONE clock)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxDone_wb <=#Tp 1'b0;
|
TxRetrySync1 <=#Tp 1'b0;
|
else
|
|
if(TxStartFrm_wb | WillSendControlFrame)
|
|
TxDone_wb <=#Tp 1'b0;
|
|
else
|
else
|
if(TxDoneSync3 & ~TxStartFrmRequest)
|
TxRetrySync1 <=#Tp TxRetry;
|
TxDone_wb <=#Tp 1'b1;
|
|
end
|
end
|
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
assign ResetTxCtrlEndFrm_wb = TxCtrlEndFrm_wb | WB_RST_I;
|
|
assign SetTxCtrlEndFrm_wb = TxCtrlEndFrm;
|
|
|
|
|
|
// Sync stage 1
|
|
always @ (posedge SetTxCtrlEndFrm_wb or posedge ResetTxCtrlEndFrm_wb)
|
|
begin
|
begin
|
if(ResetTxCtrlEndFrm_wb)
|
if(WB_RST_I)
|
TxCtrlEndFrm_wbSync1 <=#Tp 1'b0;
|
TxRetry_wb <=#Tp 1'b0;
|
else
|
else
|
TxCtrlEndFrm_wbSync1 <=#Tp 1'b1;
|
TxRetry_wb <=#Tp TxRetrySync1;
|
end
|
end
|
|
|
|
|
// Sync stage 2
|
// Synchronized TxDone_wb signal (synchronized to WISHBONE clock)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxCtrlEndFrm_wbSync2 <=#Tp 1'b0;
|
TxDoneSync1 <=#Tp 1'b0;
|
else
|
|
if(TxCtrlEndFrm_wbSync1 & ~TxCtrlEndFrm_wb)
|
|
TxCtrlEndFrm_wbSync2 <=#Tp 1'b1;
|
|
else
|
else
|
TxCtrlEndFrm_wbSync2 <=#Tp 1'b0;
|
TxDoneSync1 <=#Tp TxDone;
|
end
|
end
|
|
|
|
|
// Synchronized Tx control end frame
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxCtrlEndFrm_wb <=#Tp 1'b0;
|
TxDone_wb <=#Tp 1'b0;
|
else
|
|
if(TxCtrlEndFrm_wbSync2 & ~TxCtrlEndFrm_wb)
|
|
TxCtrlEndFrm_wb <=#Tp 1'b1;
|
|
else
|
else
|
if(StartTxStatusWrite)
|
TxDone_wb <=#Tp TxDoneSync1;
|
TxCtrlEndFrm_wb <=#Tp 1'b0;
|
|
end
|
end
|
|
|
|
// Synchronizing TxAbort signal (synchronized to WISHBONE clock)
|
// Synchronizing TxRetry signal
|
|
eth_sync_clk1_clk2 syn6 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
|
.set2(TxRetryLatched), .sync_out(TxRetrySync3));
|
|
|
|
|
|
// Synchronized signal TxRetry_wb (synchronized to WISHBONE clock)
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxRetry_wb <=#Tp 1'b0;
|
TxAbortSync1 <=#Tp 1'b0;
|
else
|
else
|
if(TxStartFrm_wb | WillSendControlFrame)
|
TxAbortSync1 <=#Tp TxAbort;
|
TxRetry_wb <=#Tp 1'b0;
|
|
else
|
|
if(TxRetrySync3)
|
|
TxRetry_wb <=#Tp 1'b1;
|
|
end
|
end
|
|
|
|
|
// Synchronizing TxAbort signal
|
|
eth_sync_clk1_clk2 syn7 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
|
.set2(TxAbort), .sync_out(TxAbortSync3));
|
|
|
|
|
|
// Synchronized TxAbort_wb signal (synchronized to WISHBONE clock)
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|
if(WB_RST_I)
|
if(WB_RST_I)
|
TxAbort_wb <=#Tp 1'b0;
|
TxAbort_wb <=#Tp 1'b0;
|
else
|
else
|
if(TxStartFrm_wb)
|
TxAbort_wb <=#Tp TxAbortSync1;
|
TxAbort_wb <=#Tp 1'b0;
|
|
else
|
|
if(TxAbortSync3 & ~TxStartFrmRequest)
|
|
TxAbort_wb <=#Tp 1'b1;
|
|
end
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Reading of the next receive buffer descriptor starts after reception status is
|
// Reading of the next receive buffer descriptor starts after reception status is
|
// written to the previous one.
|
// written to the previous one.
|
assign StartRxBDRead = RxEn & RxStatusWriteOccured;
|
assign StartRxBDRead = RxEn & RxStatusWriteOccured;
|
assign ResetRxBDRead = RxBDRead & RxBDReady; // Rx BD is read until READY bit is set.
|
assign ResetRxBDRead = RxBDRead & RxBDReady; // Rx BD is read until READY bit is set.
|
|
|
Line 1594... |
Line 1858... |
endcase
|
endcase
|
end
|
end
|
|
|
|
|
// Selecting the data for the WISHBONE
|
// Selecting the data for the WISHBONE
|
assign WB_DAT_O[31:0] = BDRead? WB_BDDataOut : RxData_wb;
|
//assign WB_DAT_O[31:0] = BDRead? WB_BDDataOut : RxData_wb;
|
|
|
|
|
// Generation of the end-of-frame signal
|
// Generation of the end-of-frame signal
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
begin
|
begin
|