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 45... |
Line 39... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.2 2002/02/01 12:46:51 mohor
|
|
// Tx part finished. TxStatus needs to be fixed. Pause request needs to be
|
|
// added.
|
|
//
|
// Revision 1.1 2002/01/23 10:47:59 mohor
|
// Revision 1.1 2002/01/23 10:47:59 mohor
|
// Initial version. Equals to eth_wishbonedma.v at this moment.
|
// Initial version. Equals to eth_wishbonedma.v at this moment.
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
//
|
|
|
|
// igor !!!
|
|
// 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)
|
|
|
|
// Naj m_wb_err_i vzge status underrun ali uverrun
|
|
|
`include "eth_defines.v"
|
`include "eth_defines.v"
|
`include "timescale.v"
|
`include "timescale.v"
|
|
|
|
|
module eth_wishbone
|
module eth_wishbone
|
(
|
(
|
|
|
// WISHBONE common
|
// WISHBONE common
|
WB_CLK_I, WB_RST_I, WB_DAT_I, WB_DAT_O,
|
WB_CLK_I, WB_DAT_I, WB_DAT_O,
|
|
|
// 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,
|
BDCs,
|
|
|
|
Reset,
|
|
|
// WISHBONE master
|
// WISHBONE master
|
m_wb_adr_o, m_wb_sel_o, m_wb_we_o,
|
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_dat_o, m_wb_dat_i, m_wb_cyc_o,
|
m_wb_stb_o, m_wb_ack_i, m_wb_err_i,
|
m_wb_stb_o, m_wb_ack_i, m_wb_err_i,
|
Line 78... |
Line 86... |
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,
|
|
|
//RX
|
//RX
|
MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm,
|
MRxClk, RxData, RxValid, RxStartFrm, RxEndFrm, RxAbort,
|
|
|
// 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, // igor !!! WillSendControlFrame gre najbrz ven
|
WillSendControlFrame, TxCtrlEndFrm, // igor !!! WillSendControlFrame gre najbrz ven
|
Line 95... |
Line 103... |
|
|
parameter Tp = 1;
|
parameter Tp = 1;
|
|
|
// WISHBONE common
|
// WISHBONE common
|
input WB_CLK_I; // WISHBONE clock
|
input WB_CLK_I; // WISHBONE clock
|
input WB_RST_I; // WISHBONE reset
|
|
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
|
|
|
// WISHBONE slave
|
// WISHBONE slave
|
input [9:2] WB_ADR_I; // WISHBONE address input
|
input [9:2] WB_ADR_I; // WISHBONE address input
|
Line 117... |
Line 124... |
output m_wb_stb_o; //
|
output m_wb_stb_o; //
|
input [31:0] m_wb_dat_i; //
|
input [31:0] m_wb_dat_i; //
|
input m_wb_ack_i; //
|
input m_wb_ack_i; //
|
input m_wb_err_i; //
|
input m_wb_err_i; //
|
|
|
|
input Reset; // Reset signal
|
|
|
|
|
|
|
// 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
|
|
|
// Tx
|
// Tx
|
input MTxClk; // Transmit clock (from PHY)
|
input MTxClk; // Transmit clock (from PHY)
|
input TxUsedData; // Transmit packet used data
|
input TxUsedData; // Transmit packet used data
|
input [15:0] StatusIzTxEthMACModula;
|
input [15:0] StatusIzTxEthMACModula;
|
Line 150... |
Line 158... |
input MRxClk; // Receive clock (from PHY)
|
input MRxClk; // Receive clock (from PHY)
|
input [7:0] RxData; // Received data byte (from PHY)
|
input [7:0] RxData; // Received data byte (from PHY)
|
input RxValid; //
|
input RxValid; //
|
input RxStartFrm; //
|
input RxStartFrm; //
|
input RxEndFrm; //
|
input RxEndFrm; //
|
|
input RxAbort; // This signal is set when address doesn't match.
|
|
|
//Register
|
//Register
|
input r_TxEn; // Transmit enable
|
input r_TxEn; // Transmit enable
|
input r_RxEn; // Receive enable
|
input r_RxEn; // Receive enable
|
input [7:0] r_TxBDNum; // Receive buffer descriptor number
|
input [7:0] r_TxBDNum; // Receive buffer descriptor number
|
Line 165... |
Line 174... |
output TxE_IRQ;
|
output TxE_IRQ;
|
output RxB_IRQ;
|
output RxB_IRQ;
|
output RxF_IRQ;
|
output RxF_IRQ;
|
output Busy_IRQ;
|
output Busy_IRQ;
|
|
|
reg WB_REQ_O_RX;
|
|
reg WB_ND_O_TX; // New descriptor
|
|
reg WB_RD_O; // Restart descriptor
|
|
|
|
reg TxStartFrm;
|
reg TxStartFrm;
|
reg TxEndFrm;
|
reg TxEndFrm;
|
reg [7:0] TxData;
|
reg [7:0] TxData;
|
|
|
reg TxUnderRun;
|
reg TxUnderRun;
|
|
|
reg RxStartFrm_wb;
|
|
reg [31:0] RxData_wb;
|
|
reg RxDataValid_wb;
|
|
reg RxEndFrm_wb;
|
|
|
|
reg [7:0] BDAddress; // BD address for access from MAC side
|
|
reg BDRead_q;
|
|
|
|
reg TxBDRead;
|
reg TxBDRead;
|
wire TxStatusWrite;
|
wire TxStatusWrite;
|
|
|
reg [1:0] TxValidBytesLatched;
|
reg [1:0] TxValidBytesLatched;
|
|
|
Line 198... |
Line 195... |
reg TxStartFrm_wb;
|
reg TxStartFrm_wb;
|
reg TxRetry_wb;
|
reg TxRetry_wb;
|
reg TxAbort_wb;
|
reg TxAbort_wb;
|
reg TxDone_wb;
|
reg TxDone_wb;
|
|
|
reg RxStatusWriteOccured;
|
|
|
|
reg TxDone_wb_q;
|
reg TxDone_wb_q;
|
reg TxAbort_wb_q;
|
reg TxAbort_wb_q;
|
reg TxRetry_wb_q;
|
reg TxRetry_wb_q;
|
reg RxBDReady;
|
reg RxBDReady;
|
reg TxBDReady;
|
reg TxBDReady;
|
|
|
reg RxBDRead;
|
reg RxBDRead;
|
reg RxStatusWrite;
|
wire RxStatusWrite;
|
reg WbWriteError;
|
|
|
|
reg [31:0] TxDataLatched;
|
reg [31:0] TxDataLatched;
|
reg [1:0] TxByteCnt;
|
reg [1:0] TxByteCnt;
|
reg LastWord;
|
reg LastWord;
|
reg ReadTxDataFromFifo_tck;
|
reg ReadTxDataFromFifo_tck;
|
|
|
reg Div2;
|
|
reg Flop;
|
|
|
|
reg BlockingTxStatusWrite;
|
reg BlockingTxStatusWrite;
|
reg BlockingTxBDRead;
|
reg BlockingTxBDRead;
|
|
|
|
reg Flop;
|
|
|
reg [7:0] TxBDAddress;
|
reg [7:0] TxBDAddress;
|
reg [7:0] RxBDAddress;
|
reg [7:0] RxBDAddress;
|
|
|
reg GotDataSync1;
|
|
reg GotDataSync2;
|
|
wire GotDataSync3;
|
|
|
|
reg GotData;
|
|
reg TxRetrySync1;
|
reg TxRetrySync1;
|
reg TxAbortSync1;
|
reg TxAbortSync1;
|
reg TxDoneSync1;
|
reg TxDoneSync1;
|
|
|
reg TxAbort_q;
|
reg TxAbort_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 [23:0] RxDataLatched1;
|
reg [1:0] RxValidBytes;
|
reg [1:0] RxValidBytes;
|
reg [1:0] RxByteCnt;
|
reg [1:0] RxByteCnt;
|
reg LastByteIn;
|
reg LastByteIn;
|
reg ShiftWillEnd;
|
reg ShiftWillEnd;
|
|
|
reg StartShifting;
|
reg WriteRxDataToFifo;
|
reg Shifting_wb_Sync1;
|
|
reg Shifting_wb_Sync2;
|
|
reg LatchNow_wb;
|
|
|
|
reg ShiftEndedSync1;
|
reg ShiftEnded;
|
reg ShiftEndedSync2;
|
|
reg ShiftEndedSync3;
|
|
wire ShiftEnded;
|
|
|
|
reg RxStartFrmSync1;
|
reg BDWrite; // BD Write Enable for access from WISHBONE side
|
reg RxStartFrmSync2;
|
reg BDRead; // BD Read access from WISHBONE side
|
wire RxStartFrmSync3;
|
|
|
|
wire DWord; // Only 32-bit accesses are valid
|
|
wire BDWrite; // BD Write Enable for access from WISHBONE side
|
|
wire BDRead; // BD Read access from WISHBONE side
|
|
wire [31:0] RxBDDataIn; // Rx BD data in
|
wire [31:0] RxBDDataIn; // Rx BD data in
|
wire [31:0] TxBDDataIn; // Tx BD data in
|
wire [31:0] TxBDDataIn; // Tx BD data in
|
wire [31:0] BDDataOut; // BD data out
|
|
|
|
reg TxEndFrm_wb;
|
reg TxEndFrm_wb;
|
|
|
wire TxRetryPulse;
|
wire TxRetryPulse;
|
wire TxDonePulse;
|
wire TxDonePulse;
|
wire TxAbortPulse;
|
wire TxAbortPulse;
|
|
|
wire StartRxBDRead;
|
wire StartRxBDRead;
|
wire ResetRxBDRead;
|
|
wire StartRxStatusWrite;
|
wire StartRxStatusWrite;
|
|
|
wire ResetShifting_wb;
|
|
wire StartShifting_wb;
|
|
wire DMACycleFinishedRx;
|
|
|
|
wire [31:0] WB_BDDataOut;
|
|
|
|
wire StartTxBDRead;
|
wire StartTxBDRead;
|
wire StartTxStatusWrite;
|
|
wire ResetTxStatusWrite;
|
|
|
|
wire TxIRQEn;
|
wire TxIRQEn;
|
wire WrapTxStatusBit;
|
wire WrapTxStatusBit;
|
|
|
wire WrapRxStatusBit;
|
wire WrapRxStatusBit;
|
Line 297... |
Line 262... |
wire [1:0] TxValidBytes;
|
wire [1:0] TxValidBytes;
|
|
|
wire [7:0] TempTxBDAddress;
|
wire [7:0] TempTxBDAddress;
|
wire [7:0] TempRxBDAddress;
|
wire [7:0] TempRxBDAddress;
|
|
|
wire [15:0] RxLength;
|
reg [15:0] RxLength;
|
wire [15:0] NewRxStatus;
|
wire [15:0] NewRxStatus;
|
|
|
wire SetGotData;
|
wire SetGotData;
|
wire ResetGotData;
|
|
wire GotDataEvaluate;
|
wire GotDataEvaluate;
|
wire ResetTxDoneSync;
|
|
wire ResetTxRetrySync;
|
|
wire ResetTxAbortSync;
|
|
|
|
wire SetTxAbortSync;
|
|
wire ResetShiftEnded;
|
|
wire ResetRxStartFrmSync1;
|
|
wire StartShiftEnded;
|
|
wire StartRxStartFrmSync1;
|
|
|
|
reg temp_ack;
|
reg temp_ack;
|
|
|
`ifdef ETH_REGISTERED_OUTPUTS
|
`ifdef ETH_REGISTERED_OUTPUTS
|
reg temp_ack2;
|
reg temp_ack2;
|
Line 335... |
Line 290... |
|
|
wire StartTxPointerRead;
|
wire StartTxPointerRead;
|
wire ResetTxPointerRead;
|
wire ResetTxPointerRead;
|
reg TxPointerRead;
|
reg TxPointerRead;
|
reg TxEn_needed;
|
reg TxEn_needed;
|
|
reg RxEn_needed;
|
|
|
//assign BDWrite = BDCs & WB_WE_I & WbEn & ~WbEn_q;
|
wire StartRxPointerRead;
|
assign BDWrite = BDCs & WB_WE_I & WbEn & WbEn_q;
|
reg RxPointerRead;
|
assign BDRead = BDCs & ~WB_WE_I & WbEn_q; // Read cycle is longer for one cycle
|
|
|
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
begin
|
begin
|
temp_ack <=#Tp 1'b0;
|
temp_ack <=#Tp 1'b0;
|
`ifdef ETH_REGISTERED_OUTPUTS
|
`ifdef ETH_REGISTERED_OUTPUTS
|
temp_ack2 <=#Tp 1'b0;
|
temp_ack2 <=#Tp 1'b0;
|
registered_ram_do <=#Tp 32'h0;
|
registered_ram_do <=#Tp 32'h0;
|
`endif
|
`endif
|
end
|
end
|
else
|
else
|
begin
|
begin
|
temp_ack <=#Tp BDWrite | BDRead & ~WbEn;
|
temp_ack <=#Tp BDWrite & WbEn & WbEn_q | BDRead & WbEn & ~WbEn_q;
|
`ifdef ETH_REGISTERED_OUTPUTS
|
`ifdef ETH_REGISTERED_OUTPUTS
|
temp_ack2 <=#Tp temp_ack;
|
temp_ack2 <=#Tp temp_ack;
|
registered_ram_do <=#Tp ram_do;
|
registered_ram_do <=#Tp ram_do;
|
`endif
|
`endif
|
end
|
end
|
Line 376... |
Line 331... |
|
|
// 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(BDWrite),
|
.clk_a(WB_CLK_I), .rst_a(Reset), .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),
|
.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(Reset), .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),
|
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));
|
.CLK(WB_CLK_I), .WE(ram_we), .RST(Reset));
|
RAMB4_S16 ram2 (.DO(ram_do[31:16]), .ADDR(ram_addr), .DI(ram_di[31:16]), .EN(ram_ce),
|
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));
|
.CLK(WB_CLK_I), .WE(ram_we), .RST(Reset));
|
|
|
|
|
|
|
/*
|
/*
|
generic_spram #(8, 32) ram (
|
generic_spram #(8, 32) ram (
|
// Generic synchronous single-port RAM interface
|
// 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)
|
.clk(WB_CLK_I), .rst(Reset), .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_ce = 1'b1;
|
assign ram_we = BDWrite | TxStatusWrite; // tu manjka se write kad se vpisuje RxBD status
|
assign ram_we = BDWrite & WbEn & WbEn_q | TxStatusWrite | RxStatusWrite;
|
assign ram_oe = BDRead | TxEn & TxEn_q & TxBDRead; // Tu manjka se read kadar se bere RxBD
|
assign ram_oe = BDRead & WbEn & WbEn_q | TxEn & TxEn_q & (TxBDRead | TxPointerRead) | RxEn & RxEn_q & (RxBDRead | RxPointerRead); // Tu manjka se read kadar se bere RxBD
|
|
|
reg [3:0] xxx_debug;
|
|
|
|
//assign TxEn_needed = ~TxBDReady | TxPointerRead;
|
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxEn_needed <=#Tp 1'b0;
|
TxEn_needed <=#Tp 1'b0;
|
else
|
else
|
if(~TxBDReady & WbEn)
|
if(~TxBDReady & r_TxEn & WbEn & ~WbEn_q)
|
TxEn_needed <=#Tp 1'b1;
|
TxEn_needed <=#Tp 1'b1;
|
else
|
else
|
if(TxPointerRead & TxEn & TxEn_q)
|
if(TxPointerRead & TxEn & TxEn_q)
|
TxEn_needed <=#Tp 1'b0;
|
TxEn_needed <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
|
reg [3:0] debug;
|
|
|
|
|
// Enabling access to the RAM for three devices.
|
// Enabling access to the RAM for three devices.
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
begin
|
begin
|
WbEn <=#Tp 1'b1;
|
WbEn <=#Tp 1'b1;
|
RxEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
ram_addr <=#Tp 8'h0;
|
ram_addr <=#Tp 8'h0;
|
ram_di <=#Tp 32'h0;
|
ram_di <=#Tp 32'h0;
|
xxx_debug <=#Tp 0; // igor !!! zbrisi xxx_debug, debug, ...
|
debug <=#Tp 4'h0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// Switching between three stages depends on enable signals
|
// 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, RxEn_needed, TxEn_needed}) // synopsys parallel_case
|
casex ({WbEn_q, RxEn_q, TxEn_q, r_RxEn, r_TxEn & TxEn_needed}) // synopsys parallel_case
|
|
5'b100_1x :
|
5'b100_1x :
|
begin
|
begin
|
WbEn <=#Tp 1'b0;
|
WbEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b1; // wb access stage and r_RxEn is enabled
|
RxEn <=#Tp 1'b1; // wb access stage and r_RxEn is enabled
|
TxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
ram_addr <=#Tp RxBDAddress;
|
ram_addr <=#Tp RxBDAddress + RxPointerRead;
|
ram_di <=#Tp RxBDDataIn;
|
ram_di <=#Tp RxBDDataIn;
|
xxx_debug <=#Tp 1;
|
debug <=#Tp 4'h1;
|
end
|
end
|
5'b100_01 :
|
5'b100_01 :
|
begin
|
begin
|
WbEn <=#Tp 1'b0;
|
WbEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b1; // wb access stage, r_RxEn is disabled but r_TxEn is enabled
|
TxEn <=#Tp 1'b1; // wb access stage, r_RxEn is disabled but r_TxEn is enabled
|
ram_addr <=#Tp TxBDAddress + TxPointerRead;
|
ram_addr <=#Tp TxBDAddress + TxPointerRead;
|
ram_di <=#Tp TxBDDataIn;
|
ram_di <=#Tp TxBDDataIn;
|
xxx_debug <=#Tp 2;
|
debug <=#Tp 4'h2;
|
end
|
end
|
5'b010_x0 :
|
5'b010_x0 :
|
begin
|
begin
|
WbEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is disabled
|
WbEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is disabled
|
RxEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
ram_di <=#Tp WB_DAT_I;
|
ram_di <=#Tp WB_DAT_I;
|
xxx_debug <=#Tp 3;
|
BDWrite <=#Tp BDCs & WB_WE_I;
|
|
BDRead <=#Tp BDCs & ~WB_WE_I;
|
|
debug <=#Tp 4'h3;
|
end
|
end
|
5'b010_x1 :
|
5'b010_x1 :
|
begin
|
begin
|
WbEn <=#Tp 1'b0;
|
WbEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is enabled
|
TxEn <=#Tp 1'b1; // RxEn access stage and r_TxEn is enabled
|
ram_addr <=#Tp TxBDAddress + TxPointerRead;
|
ram_addr <=#Tp TxBDAddress + TxPointerRead;
|
ram_di <=#Tp TxBDDataIn;
|
ram_di <=#Tp TxBDDataIn;
|
xxx_debug <=#Tp 4;
|
debug <=#Tp 4'h4;
|
end
|
end
|
5'b001_xx :
|
5'b001_xx :
|
begin
|
begin
|
WbEn <=#Tp 1'b1; // TxEn access stage (we always go to wb access stage)
|
WbEn <=#Tp 1'b1; // TxEn access stage (we always go to wb access stage)
|
RxEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
ram_di <=#Tp WB_DAT_I;
|
ram_di <=#Tp WB_DAT_I;
|
xxx_debug <=#Tp 5;
|
BDWrite <=#Tp BDCs & WB_WE_I;
|
|
BDRead <=#Tp BDCs & ~WB_WE_I;
|
|
debug <=#Tp 4'h5;
|
end
|
end
|
5'b100_00 :
|
5'b100_00 :
|
begin
|
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
|
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;
|
debug <=#Tp 4'h6;
|
end
|
end
|
5'b000_00 :
|
5'b000_00 :
|
begin
|
begin
|
WbEn <=#Tp 1'b1; // Idle state. We go to WbEn access stage.
|
WbEn <=#Tp 1'b1; // Idle state. We go to WbEn access stage.
|
RxEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
ram_di <=#Tp WB_DAT_I;
|
ram_di <=#Tp WB_DAT_I;
|
xxx_debug <=#Tp 7;
|
BDWrite <=#Tp BDCs & WB_WE_I;
|
|
BDRead <=#Tp BDCs & ~WB_WE_I;
|
|
debug <=#Tp 4'h7;
|
end
|
end
|
default :
|
default :
|
begin
|
begin
|
WbEn <=#Tp 1'b1; // We go to wb access stage
|
WbEn <=#Tp 1'b1; // We go to wb access stage
|
RxEn <=#Tp 1'b0;
|
RxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
TxEn <=#Tp 1'b0;
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
ram_addr <=#Tp WB_ADR_I[9:2];
|
ram_di <=#Tp WB_DAT_I;
|
ram_di <=#Tp WB_DAT_I;
|
xxx_debug <=#Tp 8;
|
BDWrite <=#Tp BDCs & WB_WE_I;
|
|
BDRead <=#Tp BDCs & ~WB_WE_I;
|
|
debug <=#Tp 4'h8;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
|
|
// Delayed stage signals
|
// Delayed stage signals
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
begin
|
begin
|
WbEn_q <=#Tp 1'b0;
|
WbEn_q <=#Tp 1'b0;
|
RxEn_q <=#Tp 1'b0;
|
RxEn_q <=#Tp 1'b0;
|
TxEn_q <=#Tp 1'b0;
|
TxEn_q <=#Tp 1'b0;
|
end
|
end
|
Line 531... |
Line 489... |
TxEn_q <=#Tp TxEn;
|
TxEn_q <=#Tp TxEn;
|
end
|
end
|
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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
Flop <=#Tp 1'b0;
|
Flop <=#Tp 1'b0;
|
else
|
else
|
if(TxDone | TxAbort | TxRetry_q)
|
if(TxDone | TxAbort | TxRetry_q)
|
Flop <=#Tp 1'b0;
|
Flop <=#Tp 1'b0;
|
else
|
else
|
Line 547... |
Line 505... |
|
|
wire ResetTxBDReady;
|
wire ResetTxBDReady;
|
assign ResetTxBDReady = TxDonePulse | TxAbortPulse | TxRetryPulse;
|
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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxBDReady <=#Tp 1'b0;
|
TxBDReady <=#Tp 1'b0;
|
else
|
else
|
if(TxEn & TxEn_q & TxBDRead & ~TxPointerRead)
|
if(TxEn & TxEn_q & TxBDRead)
|
TxBDReady <=#Tp ram_do[15]; // TxBDReady is sampled only once at the beginning
|
TxBDReady <=#Tp ram_do[15] & (ram_do[31:16] > 4); // TxBDReady is sampled only once at the beginning.
|
else
|
else // Only packets larger then 4 bytes are transmitted.
|
if(ResetTxBDReady)
|
if(ResetTxBDReady)
|
TxBDReady <=#Tp 1'b0;
|
TxBDReady <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// Reading the Tx buffer descriptor
|
// Reading the Tx buffer descriptor
|
assign StartTxBDRead = (TxRetry_wb | TxStatusWrite) & ~BlockingTxBDRead;
|
assign StartTxBDRead = (TxRetry_wb | TxStatusWrite) & ~BlockingTxBDRead;
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxBDRead <=#Tp 1'b1;
|
TxBDRead <=#Tp 1'b1;
|
else
|
else
|
if(StartTxBDRead)
|
if(StartTxBDRead)
|
TxBDRead <=#Tp 1'b1;
|
TxBDRead <=#Tp 1'b1;
|
else
|
else
|
Line 580... |
Line 538... |
|
|
// Reading Tx BD pointer
|
// Reading Tx BD pointer
|
assign StartTxPointerRead = TxBDRead & TxBDReady;
|
assign StartTxPointerRead = TxBDRead & TxBDReady;
|
|
|
// Reading Tx BD Pointer
|
// Reading Tx BD Pointer
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxPointerRead <=#Tp 1'b0;
|
TxPointerRead <=#Tp 1'b0;
|
else
|
else
|
if(StartTxPointerRead)
|
if(StartTxPointerRead)
|
TxPointerRead <=#Tp 1'b1;
|
TxPointerRead <=#Tp 1'b1;
|
else
|
else
|
Line 599... |
Line 557... |
assign TxStatusWrite = (TxDone_wb | TxAbort_wb) & TxEn & TxEn_q & ~BlockingTxStatusWrite;
|
assign TxStatusWrite = (TxDone_wb | TxAbort_wb) & TxEn & TxEn_q & ~BlockingTxStatusWrite;
|
|
|
|
|
|
|
// Status writing must occur only once. Meanwhile it is blocked.
|
// 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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
BlockingTxStatusWrite <=#Tp 1'b0;
|
BlockingTxStatusWrite <=#Tp 1'b0;
|
else
|
else
|
if(TxStatusWrite)
|
if(TxStatusWrite)
|
BlockingTxStatusWrite <=#Tp 1'b1;
|
BlockingTxStatusWrite <=#Tp 1'b1;
|
else
|
else
|
Line 613... |
Line 571... |
BlockingTxStatusWrite <=#Tp 1'b0;
|
BlockingTxStatusWrite <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// TxBDRead state is activated only once.
|
// TxBDRead state is activated only once.
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
BlockingTxBDRead <=#Tp 1'b0;
|
BlockingTxBDRead <=#Tp 1'b0;
|
else
|
else
|
if(StartTxBDRead)
|
if(StartTxBDRead)
|
BlockingTxBDRead <=#Tp 1'b1;
|
BlockingTxBDRead <=#Tp 1'b1;
|
else
|
else
|
Line 628... |
Line 586... |
end
|
end
|
|
|
|
|
// Latching status from the tx buffer descriptor
|
// 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)
|
// 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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxStatus <=#Tp 15'h0;
|
TxStatus <=#Tp 15'h0;
|
else
|
else
|
if(TxEn & TxEn_q & TxBDRead & ~TxPointerRead)
|
if(TxEn & TxEn_q & TxBDRead)
|
TxStatus <=#Tp ram_do[15:0];
|
TxStatus <=#Tp ram_do[15:0];
|
end
|
end
|
|
|
reg ReadDataFromTxBuffer;
|
reg ReadTxDataFromMemory;
|
wire WriteDataToRxBuffer = 0; // igor !!! Popravi to, da bo pravilno
|
wire WriteRxDataToMemory;
|
|
|
reg MasterWbTX;
|
reg MasterWbTX;
|
reg MasterWbRX;
|
reg MasterWbRX;
|
|
|
reg [31:0] m_wb_dat_o;
|
|
reg [31:0] m_wb_adr_o;
|
reg [31:0] m_wb_adr_o;
|
reg m_wb_cyc_o;
|
reg m_wb_cyc_o;
|
reg m_wb_stb_o;
|
reg m_wb_stb_o;
|
reg m_wb_we_o;
|
reg m_wb_we_o;
|
wire [31:0] rx_fifo_data_out = 0; // Spremeni to, da bo pravilno
|
|
wire TxLengthEq0;
|
wire TxLengthEq0;
|
wire TxLengthLt4;
|
wire TxLengthLt4;
|
|
|
|
|
//Latching length from the buffer descriptor;
|
//Latching length from the buffer descriptor;
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxLength <=#Tp 16'h0;
|
TxLength <=#Tp 16'h0;
|
else
|
else
|
if(TxEn & TxEn_q & TxBDRead)
|
if(TxEn & TxEn_q & TxBDRead)
|
TxLength <=#Tp ram_do[31:16];
|
TxLength <=#Tp ram_do[31:16];
|
else
|
else
|
Line 681... |
Line 638... |
|
|
reg [31:0] TxPointer;
|
reg [31:0] TxPointer;
|
reg [31:0] RxPointer;
|
reg [31:0] RxPointer;
|
|
|
//Latching Tx buffer pointer from buffer descriptor;
|
//Latching Tx buffer pointer from buffer descriptor;
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxPointer <=#Tp 0;
|
TxPointer <=#Tp 0;
|
else
|
else
|
if(TxEn & TxEn_q & TxPointerRead)
|
if(TxEn & TxEn_q & TxPointerRead)
|
TxPointer <=#Tp ram_do;
|
TxPointer <=#Tp ram_do;
|
else
|
else
|
Line 697... |
Line 654... |
|
|
wire MasterAccessFinished;
|
wire MasterAccessFinished;
|
|
|
|
|
//Latching Tx buffer pointer from buffer descriptor;
|
//Latching Tx buffer pointer from buffer descriptor;
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
BlockingIncrementTxPointer <=#Tp 0;
|
BlockingIncrementTxPointer <=#Tp 0;
|
else
|
else
|
if(MasterAccessFinished)
|
if(MasterAccessFinished)
|
BlockingIncrementTxPointer <=#Tp 0;
|
BlockingIncrementTxPointer <=#Tp 0;
|
else
|
else
|
if(MasterWbTX)
|
if(MasterWbTX)
|
BlockingIncrementTxPointer <=#Tp 1'b1;
|
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 TxBufferAlmostFull;
|
wire TxBufferFull;
|
wire TxBufferFull;
|
wire TxBufferEmpty;
|
wire TxBufferEmpty;
|
wire TxBufferAlmostEmpty;
|
wire TxBufferAlmostEmpty;
|
wire ResetReadDataFromTxBuffer;
|
wire ResetReadTxDataFromMemory;
|
wire SetReadDataFromTxBuffer;
|
wire SetReadTxDataFromMemory;
|
|
|
reg BlockReadDataFromTxBuffer;
|
reg BlockReadTxDataFromMemory;
|
|
|
//assign ResetReadDataFromTxBuffer = (TxLength < 4) | TxAbortPulse | TxRetryPulse;
|
assign ResetReadTxDataFromMemory = (TxLengthEq0) | TxAbortPulse | TxRetryPulse;
|
assign ResetReadDataFromTxBuffer = (TxLengthEq0) | TxAbortPulse | TxRetryPulse;
|
assign SetReadTxDataFromMemory = TxEn & TxEn_q & TxPointerRead;
|
assign SetReadDataFromTxBuffer = TxEn & TxEn_q & TxPointerRead;
|
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
ReadDataFromTxBuffer <=#Tp 1'b0;
|
ReadTxDataFromMemory <=#Tp 1'b0;
|
else
|
else
|
if(ResetReadDataFromTxBuffer)
|
if(ResetReadTxDataFromMemory)
|
ReadDataFromTxBuffer <=#Tp 1'b0;
|
ReadTxDataFromMemory <=#Tp 1'b0;
|
else
|
else
|
if(SetReadDataFromTxBuffer)
|
if(SetReadTxDataFromMemory)
|
ReadDataFromTxBuffer <=#Tp 1'b1;
|
ReadTxDataFromMemory <=#Tp 1'b1;
|
end
|
end
|
|
|
wire ReadDataFromTxBuffer_2 = ReadDataFromTxBuffer & ~BlockReadDataFromTxBuffer;
|
wire ReadTxDataFromMemory_2 = ReadTxDataFromMemory & ~BlockReadTxDataFromMemory;
|
wire [31:0] TxData_wb;
|
wire [31:0] TxData_wb;
|
wire ReadTxDataFromFifo_wb;
|
wire ReadTxDataFromFifo_wb;
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
BlockReadDataFromTxBuffer <=#Tp 1'b0;
|
BlockReadTxDataFromMemory <=#Tp 1'b0;
|
else
|
else
|
if(ReadTxDataFromFifo_wb)
|
if(ReadTxDataFromFifo_wb)
|
BlockReadDataFromTxBuffer <=#Tp 1'b0;
|
BlockReadTxDataFromMemory <=#Tp 1'b0;
|
else
|
else
|
// if((TxBufferAlmostFull | TxLengthLt4)& MasterWbTX)
|
|
if((TxBufferAlmostFull | TxLength <= 4)& MasterWbTX)
|
if((TxBufferAlmostFull | TxLength <= 4)& MasterWbTX)
|
BlockReadDataFromTxBuffer <=#Tp 1'b1;
|
BlockReadTxDataFromMemory <=#Tp 1'b1;
|
end
|
end
|
|
|
|
|
|
|
assign MasterAccessFinished = m_wb_ack_i | m_wb_err_i;
|
assign MasterAccessFinished = m_wb_ack_i | m_wb_err_i;
|
|
|
assign m_wb_sel_o = 4'hf;
|
assign m_wb_sel_o = 4'hf;
|
|
|
|
|
reg [3:0]debug;
|
|
|
|
|
|
// 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 WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
begin
|
begin
|
MasterWbTX <=#Tp 1'b0;
|
MasterWbTX <=#Tp 1'b0;
|
MasterWbRX <=#Tp 1'b0;
|
MasterWbRX <=#Tp 1'b0;
|
m_wb_dat_o <=#Tp 32'h0;
|
|
m_wb_adr_o <=#Tp 32'h0;
|
m_wb_adr_o <=#Tp 32'h0;
|
m_wb_cyc_o <=#Tp 1'b0;
|
m_wb_cyc_o <=#Tp 1'b0;
|
m_wb_stb_o <=#Tp 1'b0;
|
m_wb_stb_o <=#Tp 1'b0;
|
m_wb_we_o <=#Tp 1'b0;
|
m_wb_we_o <=#Tp 1'b0;
|
debug <=#Tp 0;
|
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// Switching between two stages depends on enable signals
|
// Switching between two stages depends on enable signals
|
casex ({MasterWbTX, MasterWbRX, ReadDataFromTxBuffer_2, WriteDataToRxBuffer, MasterAccessFinished}) // synopsys parallel_case full_case
|
casex ({MasterWbTX, MasterWbRX, ReadTxDataFromMemory_2, WriteRxDataToMemory, MasterAccessFinished}) // synopsys parallel_case full_case
|
5'b00_x1_x :
|
5'b00_x1_x :
|
begin
|
begin
|
MasterWbTX <=#Tp 1'b0; // idle and master write is needed (data write to rx buffer)
|
MasterWbTX <=#Tp 1'b0; // idle and master write is needed (data write to rx buffer)
|
MasterWbRX <=#Tp 1'b1;
|
MasterWbRX <=#Tp 1'b1;
|
m_wb_dat_o <=#Tp rx_fifo_data_out;
|
|
m_wb_adr_o <=#Tp RxPointer;
|
m_wb_adr_o <=#Tp RxPointer;
|
m_wb_cyc_o <=#Tp 1'b1;
|
m_wb_cyc_o <=#Tp 1'b1;
|
m_wb_stb_o <=#Tp 1'b1;
|
m_wb_stb_o <=#Tp 1'b1;
|
m_wb_we_o <=#Tp 1'b1;
|
m_wb_we_o <=#Tp 1'b1;
|
debug <=#Tp 1;
|
|
end
|
end
|
5'b00_10_x :
|
5'b00_10_x :
|
begin
|
begin
|
$display("\n\tHere we go again");
|
|
MasterWbTX <=#Tp 1'b1; // idle and master read is needed (data read from tx buffer)
|
MasterWbTX <=#Tp 1'b1; // idle and master read is needed (data read from tx buffer)
|
MasterWbRX <=#Tp 1'b0;
|
MasterWbRX <=#Tp 1'b0;
|
m_wb_adr_o <=#Tp TxPointer;
|
m_wb_adr_o <=#Tp TxPointer;
|
m_wb_cyc_o <=#Tp 1'b1;
|
m_wb_cyc_o <=#Tp 1'b1;
|
m_wb_stb_o <=#Tp 1'b1;
|
m_wb_stb_o <=#Tp 1'b1;
|
m_wb_we_o <=#Tp 1'b0;
|
m_wb_we_o <=#Tp 1'b0;
|
debug <=#Tp 2;
|
|
end
|
end
|
5'b10_10_1 :
|
5'b10_10_1 :
|
begin
|
begin
|
$display("\n\tHere we go again");
|
|
MasterWbTX <=#Tp 1'b1; // master read and master read is needed (data read from tx buffer)
|
MasterWbTX <=#Tp 1'b1; // master read and master read is needed (data read from tx buffer)
|
MasterWbRX <=#Tp 1'b0;
|
MasterWbRX <=#Tp 1'b0;
|
m_wb_adr_o <=#Tp TxPointer;
|
m_wb_adr_o <=#Tp TxPointer;
|
m_wb_cyc_o <=#Tp 1'b1;
|
m_wb_cyc_o <=#Tp 1'b1;
|
m_wb_stb_o <=#Tp 1'b1;
|
m_wb_stb_o <=#Tp 1'b1;
|
m_wb_we_o <=#Tp 1'b0;
|
m_wb_we_o <=#Tp 1'b0;
|
debug <=#Tp 6;
|
|
end
|
end
|
5'b01_01_1 :
|
5'b01_01_1 :
|
begin
|
begin
|
MasterWbTX <=#Tp 1'b0; // master write and master write is needed (data write to rx buffer)
|
MasterWbTX <=#Tp 1'b0; // master write and master write is needed (data write to rx buffer)
|
MasterWbRX <=#Tp 1'b1;
|
MasterWbRX <=#Tp 1'b1;
|
m_wb_dat_o <=#Tp rx_fifo_data_out;
|
|
m_wb_adr_o <=#Tp RxPointer;
|
m_wb_adr_o <=#Tp RxPointer;
|
m_wb_we_o <=#Tp 1'b1;
|
m_wb_we_o <=#Tp 1'b1;
|
debug <=#Tp 7;
|
|
end
|
end
|
5'b10_x1_1 :
|
5'b10_x1_1 :
|
begin
|
begin
|
MasterWbTX <=#Tp 1'b0; // master read and master write is needed (data write to rx buffer)
|
MasterWbTX <=#Tp 1'b0; // master read and master write is needed (data write to rx buffer)
|
MasterWbRX <=#Tp 1'b1;
|
MasterWbRX <=#Tp 1'b1;
|
m_wb_dat_o <=#Tp rx_fifo_data_out;
|
|
m_wb_adr_o <=#Tp RxPointer;
|
m_wb_adr_o <=#Tp RxPointer;
|
m_wb_we_o <=#Tp 1'b1;
|
m_wb_we_o <=#Tp 1'b1;
|
debug <=#Tp 3;
|
|
end
|
end
|
5'b01_1x_1 :
|
5'b01_1x_1 :
|
begin
|
begin
|
MasterWbTX <=#Tp 1'b1; // master write and master read is needed (data read from tx buffer)
|
MasterWbTX <=#Tp 1'b1; // master write and master read is needed (data read from tx buffer)
|
MasterWbRX <=#Tp 1'b0;
|
MasterWbRX <=#Tp 1'b0;
|
m_wb_adr_o <=#Tp TxPointer;
|
m_wb_adr_o <=#Tp TxPointer;
|
m_wb_we_o <=#Tp 1'b0;
|
m_wb_we_o <=#Tp 1'b0;
|
debug <=#Tp 4;
|
|
end
|
end
|
5'bxx_00_1 :
|
5'bxx_00_1 :
|
begin
|
begin
|
MasterWbTX <=#Tp 1'b0; // whatever and no master read or write is needed (ack or err comes finishing previous access)
|
MasterWbTX <=#Tp 1'b0; // whatever and no master read or write is needed (ack or err comes finishing previous access)
|
MasterWbRX <=#Tp 1'b0;
|
MasterWbRX <=#Tp 1'b0;
|
m_wb_cyc_o <=#Tp 1'b0;
|
m_wb_cyc_o <=#Tp 1'b0;
|
m_wb_stb_o <=#Tp 1'b0;
|
m_wb_stb_o <=#Tp 1'b0;
|
debug <=#Tp 8;
|
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
wire TxFifoClear;
|
wire TxFifoClear;
|
assign TxFifoClear = (TxAbort_wb | TxRetry_wb) & ~TxBDReady;
|
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),
|
eth_fifo #(`TX_FIFO_DATA_WIDTH, `TX_FIFO_DEPTH, `TX_FIFO_CNT_WIDTH)
|
|
tx_fifo (.data_in(m_wb_dat_i), .data_out(TxData_wb), .clk(WB_CLK_I),
|
|
.reset(Reset), .write(MasterWbTX & m_wb_ack_i), .read(ReadTxDataFromFifo_wb),
|
.clear(TxFifoClear), .full(TxBufferFull), .almost_full(TxBufferAlmostFull),
|
.clear(TxFifoClear), .full(TxBufferFull), .almost_full(TxBufferAlmostFull),
|
.almost_empty(TxBufferAlmostEmpty), .empty(TxBufferEmpty));
|
.almost_empty(TxBufferAlmostEmpty), .empty(TxBufferEmpty));
|
|
|
|
|
|
|
|
|
|
|
// Latching Rx buffer descriptor status
|
|
// 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)
|
|
begin
|
|
if(WB_RST_I)
|
|
RxStatus <=#Tp 16'h0;
|
|
else
|
|
if(RxBDRead & RxEn)
|
|
RxStatus <=#Tp BDDataOut[15:0];
|
|
end
|
|
|
|
|
|
reg StartOccured;
|
reg StartOccured;
|
reg TxStartFrm_sync1;
|
reg TxStartFrm_sync1;
|
reg TxStartFrm_sync2;
|
reg TxStartFrm_sync2;
|
reg TxStartFrm_syncb1;
|
reg TxStartFrm_syncb1;
|
reg TxStartFrm_syncb2;
|
reg TxStartFrm_syncb2;
|
|
|
|
|
|
|
// Start: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
|
// 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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxStartFrm_wb <=#Tp 1'b0;
|
TxStartFrm_wb <=#Tp 1'b0;
|
else
|
else
|
if(TxBDReady & ~StartOccured & (TxBufferFull | TxLengthEq0))
|
if(TxBDReady & ~StartOccured & (TxBufferFull | TxLengthEq0))
|
TxStartFrm_wb <=#Tp 1'b1;
|
TxStartFrm_wb <=#Tp 1'b1;
|
else
|
else
|
if(TxStartFrm_syncb2)
|
if(TxStartFrm_syncb2)
|
TxStartFrm_wb <=#Tp 1'b0;
|
TxStartFrm_wb <=#Tp 1'b0;
|
end
|
end
|
|
|
// StartOccured: TxStartFrm_wb occurs only ones at the beginning. Then it's blocked.
|
// StartOccured: TxStartFrm_wb occurs only ones at the beginning. Then it's blocked.
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
StartOccured <=#Tp 1'b0;
|
StartOccured <=#Tp 1'b0;
|
else
|
else
|
if(TxStartFrm_wb)
|
if(TxStartFrm_wb)
|
StartOccured <=#Tp 1'b1;
|
StartOccured <=#Tp 1'b1;
|
else
|
else
|
if(ResetTxBDReady)
|
if(ResetTxBDReady)
|
StartOccured <=#Tp 1'b0;
|
StartOccured <=#Tp 1'b0;
|
end
|
end
|
|
|
// Synchronizing TxStartFrm_wb to MTxClk
|
// Synchronizing TxStartFrm_wb to MTxClk
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxStartFrm_sync1 <=#Tp 1'b0;
|
TxStartFrm_sync1 <=#Tp 1'b0;
|
else
|
else
|
TxStartFrm_sync1 <=#Tp TxStartFrm_wb;
|
TxStartFrm_sync1 <=#Tp TxStartFrm_wb;
|
end
|
end
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxStartFrm_sync2 <=#Tp 1'b0;
|
TxStartFrm_sync2 <=#Tp 1'b0;
|
else
|
else
|
TxStartFrm_sync2 <=#Tp TxStartFrm_sync1;
|
TxStartFrm_sync2 <=#Tp TxStartFrm_sync1;
|
end
|
end
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxStartFrm_syncb1 <=#Tp 1'b0;
|
TxStartFrm_syncb1 <=#Tp 1'b0;
|
else
|
else
|
TxStartFrm_syncb1 <=#Tp TxStartFrm_sync2;
|
TxStartFrm_syncb1 <=#Tp TxStartFrm_sync2;
|
end
|
end
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxStartFrm_syncb2 <=#Tp 1'b0;
|
TxStartFrm_syncb2 <=#Tp 1'b0;
|
else
|
else
|
TxStartFrm_syncb2 <=#Tp TxStartFrm_syncb1;
|
TxStartFrm_syncb2 <=#Tp TxStartFrm_syncb1;
|
end
|
end
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxStartFrm <=#Tp 1'b0;
|
TxStartFrm <=#Tp 1'b0;
|
else
|
else
|
if(TxStartFrm_sync2)
|
if(TxStartFrm_sync2)
|
TxStartFrm <=#Tp 1'b1; // igor !!! Dodaj se pogoj, da ni vmes prisel kaksen abort ali kaj podobnega
|
TxStartFrm <=#Tp 1'b1; // igor !!! Dodaj se pogoj, da ni vmes prisel kaksen abort ali kaj podobnega
|
else
|
else
|
Line 965... |
Line 880... |
TxStartFrm <=#Tp 1'b0;
|
TxStartFrm <=#Tp 1'b0;
|
end
|
end
|
// End: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
|
// End: Generation of the TxStartFrm_wb which is then synchronized to the MTxClk
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TxEndFrm_wb: indicator of the end of frame
|
// 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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxEndFrm_wb <=#Tp 1'b0;
|
TxEndFrm_wb <=#Tp 1'b0;
|
else
|
else
|
if(TxLengthLt4 & TxBufferAlmostEmpty & TxUsedData)
|
if(TxLengthLt4 & TxBufferAlmostEmpty & TxUsedData)
|
TxEndFrm_wb <=#Tp 1'b1;
|
TxEndFrm_wb <=#Tp 1'b1;
|
else
|
else
|
Line 1000... |
Line 900... |
assign TxValidBytes = TxLengthLt4 ? TxLength[1:0] : 2'b0;
|
assign TxValidBytes = TxLengthLt4 ? TxLength[1:0] : 2'b0;
|
|
|
reg LatchValidBytes;
|
reg LatchValidBytes;
|
reg LatchValidBytes_q;
|
reg LatchValidBytes_q;
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
LatchValidBytes <=#Tp 1'b0;
|
LatchValidBytes <=#Tp 1'b0;
|
else
|
else
|
if(TxLengthLt4 & TxBDReady)
|
if(TxLengthLt4 & TxBDReady)
|
LatchValidBytes <=#Tp 1'b1;
|
LatchValidBytes <=#Tp 1'b1;
|
else
|
else
|
LatchValidBytes <=#Tp 1'b0;
|
LatchValidBytes <=#Tp 1'b0;
|
end
|
end
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
LatchValidBytes_q <=#Tp 1'b0;
|
LatchValidBytes_q <=#Tp 1'b0;
|
else
|
else
|
LatchValidBytes_q <=#Tp LatchValidBytes;
|
LatchValidBytes_q <=#Tp LatchValidBytes;
|
end
|
end
|
|
|
|
|
// Latching valid bytes
|
// Latching valid bytes
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxValidBytesLatched <=#Tp 2'h0;
|
TxValidBytesLatched <=#Tp 2'h0;
|
else
|
else
|
if(LatchValidBytes & ~LatchValidBytes_q)
|
if(LatchValidBytes & ~LatchValidBytes_q)
|
TxValidBytesLatched <=#Tp TxValidBytes;
|
TxValidBytesLatched <=#Tp TxValidBytes;
|
else
|
else
|
Line 1037... |
Line 937... |
|
|
|
|
// 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.
|
|
|
|
|
|
|
// TX
|
// TX
|
// bit 15 od tx je ready
|
// bit 15 od tx je ready
|
// bit 14 od tx je interrupt (Tx buffer ali tx error bit se postavi v interrupt registru, ko se ta buffer odda)
|
// bit 14 od tx je interrupt (Tx buffer ali tx error bit se postavi v interrupt registru, ko se ta buffer odda)
|
// bit 13 od tx je wrap
|
// bit 13 od tx je wrap
|
// bit 12 od tx je pad
|
// bit 12 od tx je pad
|
Line 1060... |
Line 958... |
//assign TxBDReady = TxStatus[15]; // already used
|
//assign TxBDReady = TxStatus[15]; // already used
|
assign TxIRQEn = TxStatus[14];
|
assign TxIRQEn = TxStatus[14];
|
assign WrapTxStatusBit = TxStatus[13]; // ok povezan
|
assign WrapTxStatusBit = TxStatus[13]; // ok povezan
|
assign PerPacketPad = TxStatus[12]; // ok povezan
|
assign PerPacketPad = TxStatus[12]; // ok povezan
|
assign PerPacketCrcEn = TxStatus[11] & TxStatus[10]; // When last is also set // ok povezan
|
assign PerPacketCrcEn = TxStatus[11] & TxStatus[10]; // When last is also set // ok povezan
|
//assign TxPauseRq = TxStatus[9]; // already used
|
//assign TxPauseRq = TxStatus[9]; // already used Ta gre ven, ker bo stvar izvedena preko registrov
|
|
|
|
|
|
|
// RX
|
// RX
|
// bit 15 od rx je empty
|
// bit 15 od rx je empty
|
Line 1090... |
Line 988... |
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 + 2'h2) ; // 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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxBDAddress <=#Tp 8'h0;
|
TxBDAddress <=#Tp 8'h0;
|
else
|
else
|
if(TxStatusWrite)
|
if(TxStatusWrite)
|
TxBDAddress <=#Tp TempTxBDAddress;
|
TxBDAddress <=#Tp TempTxBDAddress;
|
end
|
end
|
|
|
|
|
// Latching Rx buffer descriptor address
|
// Latching Rx buffer descriptor address
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxBDAddress <=#Tp 8'h0;
|
RxBDAddress <=#Tp 8'h0;
|
else
|
else
|
if(TX_BD_NUM_Wr) // When r_TxBDNum is updated, RxBDAddress is also
|
if(TX_BD_NUM_Wr) // When r_TxBDNum is updated, RxBDAddress is also igor !!! ta del bi se lahko popravil
|
RxBDAddress <=#Tp WB_DAT_I[7:0];
|
RxBDAddress <=#Tp WB_DAT_I[7:0];
|
else
|
else
|
if(RxStatusWrite)
|
if(RxStatusWrite)
|
RxBDAddress <=#Tp TempRxBDAddress;
|
RxBDAddress <=#Tp TempRxBDAddress;
|
end
|
end
|
|
|
|
assign NewRxStatus[15:0] = 16'hdead;
|
// Selecting Tx or Rx buffer descriptor address
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
BDAddress <=#Tp 8'h0;
|
|
else
|
|
if(TxEn)
|
|
BDAddress <=#Tp TxBDAddress;
|
|
else
|
|
BDAddress <=#Tp RxBDAddress;
|
|
end
|
|
|
|
|
|
assign RxLength[15:0] = 16'h1399;
|
|
assign NewRxStatus[15:0] = {1'b0, WbWriteError, RxStatus[13:0]};
|
|
|
|
|
|
//assign BDDataIn = TxStatusWrite ? {TxLength[15:0], StatusIzTxEthMACModula} : {RxLength, NewRxStatus};
|
|
//assign BDDataIn = TxStatusWrite ? {TxStatus[31:9], 9'h0}
|
|
// : {RxLength, NewRxStatus};
|
|
assign RxBDDataIn = {RxLength, NewRxStatus}; // tu dopolni, da se bo vpisoval status
|
assign RxBDDataIn = {RxLength, NewRxStatus}; // tu dopolni, da se bo vpisoval status
|
//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
|
assign TxBDDataIn = {32'h004380ef}; // tu dopolni, da se bo vpisoval status
|
|
|
|
|
// Generating delayed signals
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
begin
|
|
TxRetry_wb_q <=#Tp 1'b0;
|
|
BDRead_q <=#Tp 1'b0;
|
|
end
|
|
else
|
|
begin
|
|
TxRetry_wb_q <=#Tp TxRetry_wb;
|
|
BDRead_q <=#Tp BDRead;
|
|
end
|
|
end
|
|
|
|
|
|
// Signals used for various purposes
|
// Signals used for various purposes
|
assign TxRetryPulse = TxRetry_wb & ~TxRetry_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
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
WB_ND_O_TX <=#Tp 1'b0;
|
|
else
|
|
if(TxDonePulse | TxAbortPulse)
|
|
WB_ND_O_TX <=#Tp 1'b1;
|
|
else
|
|
if(WB_ND_O_TX)
|
|
WB_ND_O_TX <=#Tp 1'b0;
|
|
end
|
|
|
|
|
|
// Force next descriptor on DMA channel 0 (Tx)
|
|
assign WB_ND_O[0] = WB_ND_O_TX;
|
|
|
|
|
|
|
|
// Restart descriptor for DMA channel 0 (Tx)
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
WB_RD_O <=#Tp 1'b0;
|
|
else
|
|
if(TxRetryPulse)
|
|
WB_RD_O <=#Tp 1'b1;
|
|
else
|
|
if(WB_RD_O)
|
|
WB_RD_O <=#Tp 1'b0;
|
|
end
|
|
|
|
|
|
// assign ClearTxBDReady = ~TxUsedData & TxUsedData_q;
|
// assign ClearTxBDReady = ~TxUsedData & TxUsedData_q;
|
|
|
assign TPauseRq = 0; // igor !!! v koncni fazi mora tu biti pause request
|
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
|
assign TxPauseTV[15:0] = TxLength[15:0]; // igor !!! v koncni fazi mora tu biti pause request
|
|
|
// reg WillSendControlFrameSync1;
|
|
// reg WillSendControlFrameSync2;
|
|
// reg WillSendControlFrameSync3;
|
|
// wire WillSendControlFrame_wb;
|
|
|
|
|
|
// always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
// begin
|
|
// if(WB_RST_I)
|
|
// 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;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Generating delayed signals
|
// Generating delayed signals
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
begin
|
begin
|
TxAbort_q <=#Tp 1'b0;
|
TxAbort_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;
|
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
|
// Generating delayed signals
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
begin
|
begin
|
TxDone_wb_q <=#Tp 1'b0;
|
TxDone_wb_q <=#Tp 1'b0;
|
TxAbort_wb_q <=#Tp 1'b0;
|
TxAbort_wb_q <=#Tp 1'b0;
|
|
TxRetry_wb_q <=#Tp 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
TxDone_wb_q <=#Tp TxDone_wb;
|
TxDone_wb_q <=#Tp TxDone_wb;
|
TxAbort_wb_q <=#Tp TxAbort_wb;
|
TxAbort_wb_q <=#Tp TxAbort_wb;
|
|
TxRetry_wb_q <=#Tp TxRetry_wb;
|
end
|
end
|
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
|
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),
|
|
.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) & (TxStartFrm));
|
//assign GotDataEvaluate = GotDataSync3 & ~GotData & (~TxRetry & ~TxAbort | (TxRetry | TxAbort) & (TxStartFrm));
|
|
assign GotDataEvaluate = (~TxRetry & ~TxAbort | (TxRetry | TxAbort) & (TxStartFrm));
|
|
|
// Indication of good data
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
|
begin
|
|
if(WB_RST_I)
|
|
GotData <=#Tp 1'b0;
|
|
else
|
|
if(GotDataEvaluate)
|
|
GotData <=#Tp 1'b1;
|
|
else
|
|
GotData <=#Tp 1'b0;
|
|
end
|
|
|
|
|
|
// // Tx start frame generation
|
|
// always @ (posedge MTxClk or posedge WB_RST_I)
|
|
// begin
|
|
// if(WB_RST_I)
|
|
// TxStartFrm <=#Tp 1'b0;
|
|
// else
|
|
// if(TxUsedData_q | TxAbort & ~TxAbort_q | TxRetry & ~TxRetry_q)
|
|
// TxStartFrm <=#Tp 1'b0;
|
|
// else
|
|
// if(TxBDReady & GotData & TxStartFrmRequest)
|
|
// TxStartFrm <=#Tp 1'b1;
|
|
// end
|
|
//
|
|
|
|
// Indication of the last word
|
// Indication of the last word
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
LastWord <=#Tp 1'b0;
|
LastWord <=#Tp 1'b0;
|
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_wb;
|
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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxEndFrm <=#Tp 1'b0;
|
TxEndFrm <=#Tp 1'b0;
|
else
|
else
|
if(Flop & TxEndFrm | TxAbort | TxRetry_q) // igor !!! zakaj je tu TxRetry_q ?
|
if(Flop & TxEndFrm | TxAbort | TxRetry_q) // igor !!! zakaj je tu TxRetry_q ?
|
TxEndFrm <=#Tp 1'b0;
|
TxEndFrm <=#Tp 1'b0;
|
else
|
else
|
Line 1351... |
Line 1111... |
end
|
end
|
end
|
end
|
|
|
|
|
// Tx data selection (latching)
|
// Tx data selection (latching)
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxData <=#Tp 8'h0;
|
TxData <=#Tp 8'h0;
|
else
|
else
|
if(TxStartFrm_sync2 & ~TxStartFrm)
|
if(TxStartFrm_sync2 & ~TxStartFrm)
|
TxData <=#Tp TxData_wb[7:0];
|
TxData <=#Tp TxData_wb[7:0];
|
else
|
else
|
Line 1372... |
Line 1132... |
end
|
end
|
end
|
end
|
|
|
|
|
// Latching tx data
|
// Latching tx data
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxDataLatched[31:0] <=#Tp 32'h0;
|
TxDataLatched[31:0] <=#Tp 32'h0;
|
else
|
else
|
if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3)
|
if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3)
|
TxDataLatched[31:0] <=#Tp TxData_wb[31:0];
|
TxDataLatched[31:0] <=#Tp TxData_wb[31:0];
|
end
|
end
|
|
|
|
|
// Tx under run
|
// Tx under run
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxUnderRun <=#Tp 1'b0;
|
TxUnderRun <=#Tp 1'b0;
|
else
|
else
|
if(TxAbortPulse)
|
if(TxAbortPulse)
|
TxUnderRun <=#Tp 1'b0;
|
TxUnderRun <=#Tp 1'b0;
|
else
|
else
|
Line 1398... |
Line 1158... |
end
|
end
|
|
|
|
|
|
|
// Tx Byte counter
|
// Tx Byte counter
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxByteCnt <=#Tp 2'h0;
|
TxByteCnt <=#Tp 2'h0;
|
else
|
else
|
if(TxAbort_q | TxRetry_q)
|
if(TxAbort_q | TxRetry_q)
|
TxByteCnt <=#Tp 2'h0;
|
TxByteCnt <=#Tp 2'h0;
|
else
|
else
|
Line 1422... |
Line 1182... |
reg ReadTxDataFromFifo_sync3;
|
reg ReadTxDataFromFifo_sync3;
|
reg ReadTxDataFromFifo_syncb1;
|
reg ReadTxDataFromFifo_syncb1;
|
reg ReadTxDataFromFifo_syncb2;
|
reg ReadTxDataFromFifo_syncb2;
|
|
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
ReadTxDataFromFifo_tck <=#Tp 1'b0;
|
ReadTxDataFromFifo_tck <=#Tp 1'b0;
|
else
|
else
|
if(ReadTxDataFromFifo_syncb2)
|
if(ReadTxDataFromFifo_syncb2)
|
ReadTxDataFromFifo_tck <=#Tp 1'b0;
|
ReadTxDataFromFifo_tck <=#Tp 1'b0;
|
else
|
else
|
// if(TxUsedData & ~TxEndFrm_wbLatched & TxByteCnt == 2'h3)
|
|
// ReadTxDataFromFifo_tck <=#Tp ~LastWord;
|
|
// if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3)
|
|
if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord)
|
if(TxStartFrm_sync2 & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3 & ~LastWord)
|
ReadTxDataFromFifo_tck <=#Tp 1'b1;
|
ReadTxDataFromFifo_tck <=#Tp 1'b1;
|
end
|
end
|
|
|
// Synchronizing TxStartFrm_wb to MTxClk
|
// Synchronizing TxStartFrm_wb to MTxClk
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
ReadTxDataFromFifo_sync1 <=#Tp 1'b0;
|
ReadTxDataFromFifo_sync1 <=#Tp 1'b0;
|
else
|
else
|
ReadTxDataFromFifo_sync1 <=#Tp ReadTxDataFromFifo_tck;
|
ReadTxDataFromFifo_sync1 <=#Tp ReadTxDataFromFifo_tck;
|
end
|
end
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
ReadTxDataFromFifo_sync2 <=#Tp 1'b0;
|
ReadTxDataFromFifo_sync2 <=#Tp 1'b0;
|
else
|
else
|
ReadTxDataFromFifo_sync2 <=#Tp ReadTxDataFromFifo_sync1;
|
ReadTxDataFromFifo_sync2 <=#Tp ReadTxDataFromFifo_sync1;
|
end
|
end
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
ReadTxDataFromFifo_syncb1 <=#Tp 1'b0;
|
ReadTxDataFromFifo_syncb1 <=#Tp 1'b0;
|
else
|
else
|
ReadTxDataFromFifo_syncb1 <=#Tp ReadTxDataFromFifo_sync2;
|
ReadTxDataFromFifo_syncb1 <=#Tp ReadTxDataFromFifo_sync2;
|
end
|
end
|
|
|
always @ (posedge MTxClk or posedge WB_RST_I)
|
always @ (posedge MTxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
ReadTxDataFromFifo_syncb2 <=#Tp 1'b0;
|
ReadTxDataFromFifo_syncb2 <=#Tp 1'b0;
|
else
|
else
|
ReadTxDataFromFifo_syncb2 <=#Tp ReadTxDataFromFifo_syncb1;
|
ReadTxDataFromFifo_syncb2 <=#Tp ReadTxDataFromFifo_syncb1;
|
end
|
end
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
ReadTxDataFromFifo_sync3 <=#Tp 1'b0;
|
ReadTxDataFromFifo_sync3 <=#Tp 1'b0;
|
else
|
else
|
ReadTxDataFromFifo_sync3 <=#Tp ReadTxDataFromFifo_sync2;
|
ReadTxDataFromFifo_sync3 <=#Tp ReadTxDataFromFifo_sync2;
|
end
|
end
|
|
|
assign ReadTxDataFromFifo_wb = ReadTxDataFromFifo_sync2 & ~ReadTxDataFromFifo_sync3;
|
assign ReadTxDataFromFifo_wb = ReadTxDataFromFifo_sync2 & ~ReadTxDataFromFifo_sync3;
|
// End: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
|
// End: Generation of the ReadTxDataFromFifo_tck signal and synchronization to the WB_CLK_I
|
|
|
|
|
// Synchronizing TxRetry signal (synchronized 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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxRetrySync1 <=#Tp 1'b0;
|
TxRetrySync1 <=#Tp 1'b0;
|
else
|
else
|
TxRetrySync1 <=#Tp TxRetry;
|
TxRetrySync1 <=#Tp TxRetry;
|
end
|
end
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxRetry_wb <=#Tp 1'b0;
|
TxRetry_wb <=#Tp 1'b0;
|
else
|
else
|
TxRetry_wb <=#Tp TxRetrySync1;
|
TxRetry_wb <=#Tp TxRetrySync1;
|
end
|
end
|
|
|
|
|
// Synchronized TxDone_wb signal (synchronized to WISHBONE clock)
|
// 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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxDoneSync1 <=#Tp 1'b0;
|
TxDoneSync1 <=#Tp 1'b0;
|
else
|
else
|
TxDoneSync1 <=#Tp TxDone;
|
TxDoneSync1 <=#Tp TxDone;
|
end
|
end
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxDone_wb <=#Tp 1'b0;
|
TxDone_wb <=#Tp 1'b0;
|
else
|
else
|
TxDone_wb <=#Tp TxDoneSync1;
|
TxDone_wb <=#Tp TxDoneSync1;
|
end
|
end
|
|
|
// Synchronizing TxAbort signal (synchronized to WISHBONE clock)
|
// Synchronizing TxAbort signal (synchronized to WISHBONE clock)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxAbortSync1 <=#Tp 1'b0;
|
TxAbortSync1 <=#Tp 1'b0;
|
else
|
else
|
TxAbortSync1 <=#Tp TxAbort;
|
TxAbortSync1 <=#Tp TxAbort;
|
end
|
end
|
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
TxAbort_wb <=#Tp 1'b0;
|
TxAbort_wb <=#Tp 1'b0;
|
else
|
else
|
TxAbort_wb <=#Tp TxAbortSync1;
|
TxAbort_wb <=#Tp TxAbortSync1;
|
end
|
end
|
|
|
|
|
|
assign StartRxBDRead = RxStatusWrite | RxAbort;
|
|
|
|
// Reading the Rx buffer descriptor
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
|
begin
|
|
if(Reset)
|
|
RxBDRead <=#Tp 1'b1;
|
|
else
|
|
if(StartRxBDRead)
|
|
RxBDRead <=#Tp 1'b1;
|
|
else
|
|
if(RxBDReady)
|
|
RxBDRead <=#Tp 1'b0;
|
|
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 ResetRxBDRead = RxBDRead & RxBDReady; // Rx BD is read until READY bit is set.
|
|
|
|
|
|
// Latching READY status of the Rx buffer descriptor
|
// Latching READY status of the Rx buffer descriptor
|
always @ (negedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxBDReady <=#Tp 1'b0;
|
RxBDReady <=#Tp 1'b0;
|
else
|
else
|
if(RxEn & RxBDRead)
|
if(RxEn & RxEn_q & RxBDRead)
|
RxBDReady <=#Tp BDDataOut[15];
|
RxBDReady <=#Tp ram_do[15]; // RxBDReady is sampled only once at the beginning
|
else
|
else
|
if(RxStatusWrite)
|
if(ShiftEnded | RxAbort) // igor !!! tx del ima tu ResetTxBDReady
|
RxBDReady <=#Tp 1'b0;
|
RxBDReady <=#Tp 1'b0;
|
end
|
end
|
|
|
|
// Latching Rx buffer descriptor status
|
// Reading the Rx buffer descriptor
|
// 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 Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxBDRead <=#Tp 1'b1;
|
RxStatus <=#Tp 16'h0;
|
else
|
|
if(StartRxBDRead)
|
|
RxBDRead <=#Tp 1'b1;
|
|
else
|
else
|
if(ResetRxBDRead)
|
if(RxEn & RxEn_q & RxBDRead)
|
RxBDRead <=#Tp 1'b0;
|
RxStatus <=#Tp ram_do[15:0];
|
end
|
end
|
|
|
|
|
// Reception status is written back to the buffer descriptor after the end of frame is detected.
|
|
//assign StartRxStatusWrite = RxEn & RxEndFrm_wb;
|
|
assign StartRxStatusWrite = RxEn & RxEndFrm_wb;
|
|
|
|
|
|
// Writing status back to the Rx buffer descriptor
|
// Reading Rx BD pointer
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
|
|
|
assign StartRxPointerRead = RxBDRead & RxBDReady;
|
|
|
|
// Reading Tx BD Pointer
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxStatusWrite <=#Tp 1'b0;
|
RxPointerRead <=#Tp 1'b0;
|
else
|
else
|
if(StartRxStatusWrite)
|
if(StartRxPointerRead)
|
RxStatusWrite <=#Tp 1'b1;
|
RxPointerRead <=#Tp 1'b1;
|
else
|
else
|
RxStatusWrite <=#Tp 1'b0;
|
if(RxEn_q)
|
|
RxPointerRead <=#Tp 1'b0;
|
end
|
end
|
|
|
|
reg BlockingIncrementRxPointer;
|
// Forcing next descriptor on DMA channel 1 (Rx)
|
//Latching Rx buffer pointer from buffer descriptor;
|
assign WB_ND_O[1] = RxStatusWrite;
|
always @ (posedge WB_CLK_I or posedge Reset)
|
|
begin
|
|
if(Reset)
|
|
RxPointer <=#Tp 32'h0;
|
|
else
|
|
if(RxEn & RxEn_q & RxPointerRead)
|
|
RxPointer <=#Tp ram_do;
|
|
else
|
|
if(MasterWbRX & ~BlockingIncrementRxPointer)
|
|
RxPointer <=#Tp RxPointer + 4; // Pointer increment
|
|
end
|
|
|
|
|
// Latched status that a status write occured.
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxStatusWriteOccured <=#Tp 1'b0;
|
BlockingIncrementRxPointer <=#Tp 0;
|
else
|
else
|
if(StartRxStatusWrite)
|
if(MasterAccessFinished)
|
RxStatusWriteOccured <=#Tp 1'b1;
|
BlockingIncrementRxPointer <=#Tp 0;
|
else
|
else
|
if(StartRxBDRead)
|
if(MasterWbRX)
|
RxStatusWriteOccured <=#Tp 1'b0;
|
BlockingIncrementRxPointer <=#Tp 1'b1;
|
end
|
end
|
|
|
|
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
|
begin
|
|
if(Reset)
|
|
RxEn_needed <=#Tp 1'b0;
|
|
else
|
|
if(~RxBDReady & r_RxEn & WbEn & ~WbEn_q)
|
|
RxEn_needed <=#Tp 1'b1;
|
|
else
|
|
if(RxPointerRead & RxEn & RxEn_q)
|
|
RxEn_needed <=#Tp 1'b0;
|
|
end
|
|
|
|
|
// Generation of the synchronized signal ShiftEnded that indicates end of reception
|
// Reception status is written back to the buffer descriptor after the end of frame is detected.
|
eth_sync_clk1_clk2 syn8 (.clk1(MRxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
assign RxStatusWrite = ShiftEnded & RxEn & RxEn_q;
|
.set2(RxEndFrm_wb), .sync_out(ShiftEnded)
|
|
);
|
|
|
|
|
reg RxEnableWindow;
|
|
|
// Indicating that last byte is being reveived
|
// Indicating that last byte is being reveived
|
always @ (posedge MRxClk or posedge WB_RST_I)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
LastByteIn <=#Tp 1'b0;
|
LastByteIn <=#Tp 1'b0;
|
else
|
else
|
if(ShiftWillEnd & (&RxByteCnt))
|
if(ShiftWillEnd & (&RxByteCnt) | RxAbort)
|
LastByteIn <=#Tp 1'b0;
|
LastByteIn <=#Tp 1'b0;
|
else
|
else
|
if(RxValid & RxBDReady & RxEndFrm & ~(&RxByteCnt))
|
if(RxValid & RxBDReady & RxEndFrm & ~(&RxByteCnt) & RxEnableWindow)
|
LastByteIn <=#Tp 1'b1;
|
LastByteIn <=#Tp 1'b1;
|
end
|
end
|
|
|
|
reg ShiftEnded_tck;
|
|
reg ShiftEndedSync1;
|
|
reg ShiftEndedSync2;
|
|
wire StartShiftWillEnd;
|
|
assign StartShiftWillEnd = LastByteIn & (&RxByteCnt) | RxValid & RxEndFrm & (&RxByteCnt) & RxEnableWindow;
|
|
|
// Indicating that data reception will end
|
// Indicating that data reception will end
|
always @ (posedge MRxClk or posedge WB_RST_I)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
ShiftWillEnd <=#Tp 1'b0;
|
ShiftWillEnd <=#Tp 1'b0;
|
else
|
else
|
if(ShiftEnded)
|
if(ShiftEnded_tck | RxAbort)
|
ShiftWillEnd <=#Tp 1'b0;
|
ShiftWillEnd <=#Tp 1'b0;
|
else
|
else
|
if(LastByteIn & (&RxByteCnt) | RxValid & RxEndFrm & (&RxByteCnt))
|
if(StartShiftWillEnd)
|
ShiftWillEnd <=#Tp 1'b1;
|
ShiftWillEnd <=#Tp 1'b1;
|
end
|
end
|
|
|
|
|
|
|
// Receive byte counter
|
// Receive byte counter
|
always @ (posedge MRxClk or posedge WB_RST_I)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxByteCnt <=#Tp 2'h0;
|
RxByteCnt <=#Tp 2'h0;
|
else
|
else
|
if(ShiftEnded)
|
if(ShiftEnded_tck | RxAbort)
|
RxByteCnt <=#Tp 2'h0;
|
RxByteCnt <=#Tp 2'h0;
|
else
|
else
|
if(RxValid & RxBDReady | LastByteIn)
|
if(RxValid & (RxStartFrm | RxEnableWindow) & RxBDReady | LastByteIn)
|
RxByteCnt <=#Tp RxByteCnt + 1;
|
RxByteCnt <=#Tp RxByteCnt + 1'b1;
|
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 WB_RST_I)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxValidBytes <=#Tp 2'h1;
|
RxValidBytes <=#Tp 2'h1;
|
else
|
else
|
if(ShiftEnded)
|
if(ShiftEnded_tck | RxAbort)
|
RxValidBytes <=#Tp 2'h1;
|
RxValidBytes <=#Tp 2'h1;
|
else
|
else
|
if(RxValid & ~LastByteIn & ~RxStartFrm)
|
if(RxValid & ~LastByteIn & ~RxStartFrm & RxEnableWindow)
|
RxValidBytes <=#Tp RxValidBytes + 1;
|
RxValidBytes <=#Tp RxValidBytes + 1;
|
end
|
end
|
|
|
|
|
// There is a maximum 3 MRxClk delay between RxDataLatched2 and RxData_wb. In the meantime data
|
always @ (posedge MRxClk or posedge Reset)
|
// is stored to the RxDataLatched1.
|
|
always @ (posedge MRxClk or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxDataLatched1 <=#Tp 16'h0;
|
RxDataLatched1 <=#Tp 24'h0;
|
else
|
else
|
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h0)
|
if(RxValid & RxBDReady & ~LastByteIn & (RxStartFrm | RxEnableWindow))
|
RxDataLatched1[7:0] <=#Tp RxData;
|
begin
|
else
|
case(RxByteCnt) // synopsys parallel_case
|
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h1)
|
2'h0: RxDataLatched1[7:0] <=#Tp RxData;
|
RxDataLatched1[15:8] <=#Tp RxData;
|
2'h1: RxDataLatched1[15:8] <=#Tp RxData;
|
|
2'h2: RxDataLatched1[23:16] <=#Tp RxData;
|
|
2'h3: RxDataLatched1 <=#Tp RxDataLatched1;
|
|
endcase
|
|
end
|
end
|
end
|
|
|
|
wire SetWriteRxDataToFifo;
|
|
|
// Latching incoming data to buffer
|
// Assembling data that will be written to the rx_fifo
|
always @ (posedge MRxClk or posedge WB_RST_I)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxDataLatched2 <=#Tp 32'h0;
|
RxDataLatched2 <=#Tp 32'h0;
|
else
|
else
|
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h2)
|
if(SetWriteRxDataToFifo & ~ShiftWillEnd)
|
RxDataLatched2[23:0] <=#Tp {RxData,RxDataLatched1};
|
RxDataLatched2 <=#Tp {RxData, RxDataLatched1[23:0]};
|
else
|
else
|
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h3)
|
if(SetWriteRxDataToFifo & ShiftWillEnd)
|
RxDataLatched2[31:24] <=#Tp RxData;
|
case(RxValidBytes)
|
|
0 : RxDataLatched2 <=#Tp {RxData, RxDataLatched1[23:0]};
|
|
1 : RxDataLatched2 <=#Tp { 24'h0, RxDataLatched1[7:0]};
|
|
2 : RxDataLatched2 <=#Tp { 16'h0, RxDataLatched1[15:0]};
|
|
3 : RxDataLatched2 <=#Tp { 8'h0, RxDataLatched1[23:0]};
|
|
endcase
|
end
|
end
|
|
|
|
// Assembling data that will be written to the rx_fifo
|
// Indicating start of the reception process
|
always @ (posedge MRxClk or posedge Reset)
|
always @ (posedge MRxClk or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
StartShifting <=#Tp 1'b0;
|
RxLength <=#Tp 16'h0;
|
else
|
else
|
if((RxValid & RxBDReady & ~RxStartFrm & (&RxByteCnt)) | (ShiftWillEnd & LastByteIn & (&RxByteCnt)))
|
if(RxStartFrm)
|
StartShifting <=#Tp 1'b1;
|
RxLength <=#Tp 16'h1;
|
else
|
else
|
StartShifting <=#Tp 1'b0;
|
if(RxValid & (RxStartFrm | RxEnableWindow))
|
|
RxLength <=#Tp RxLength + 1'b1;
|
end
|
end
|
|
|
|
|
// Synchronizing Rx start frame to the WISHBONE clock
|
reg WriteRxDataToFifoSync1;
|
assign StartRxStartFrmSync1 = RxStartFrm & RxBDReady;
|
reg WriteRxDataToFifoSync2;
|
|
|
eth_sync_clk1_clk2 syn9 (.clk1(WB_CLK_I), .clk2(MRxClk), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
|
.set2(SetGotData), .sync_out(RxStartFrmSync3)
|
|
);
|
|
|
|
|
// Indicating start of the reception process
|
|
assign SetWriteRxDataToFifo = (RxValid & RxBDReady & ~RxStartFrm & RxEnableWindow & (&RxByteCnt)) | (ShiftWillEnd & LastByteIn & (&RxByteCnt));
|
|
|
// Generating synchronized Rx start frame
|
always @ (posedge MRxClk or posedge Reset)
|
always @ ( posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxStartFrm_wb <=#Tp 1'b0;
|
WriteRxDataToFifo <=#Tp 1'b0;
|
else
|
else
|
if(RxStartFrmSync3 & ~RxStartFrm_wb)
|
if(SetWriteRxDataToFifo & ~RxAbort)
|
RxStartFrm_wb <=#Tp 1'b1;
|
WriteRxDataToFifo <=#Tp 1'b1;
|
else
|
else
|
RxStartFrm_wb <=#Tp 1'b0;
|
if(WriteRxDataToFifoSync1 | RxAbort)
|
|
WriteRxDataToFifo <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
//Synchronizing signal for latching data that will be written to the WISHBONE
|
|
//eth_sync_clk1_clk2 syn10 (.clk1(WB_CLK_I), .clk2(MRxClk), .reset1(WB_RST_I), .reset2(WB_RST_I),
|
|
// .set2(StartShifting), .sync_out(LatchNow_wb)
|
|
// );
|
|
|
|
// This section still needs to be changed due to ASIC demands
|
|
assign ResetShifting_wb = LatchNow_wb | WB_RST_I;
|
|
assign StartShifting_wb = StartShifting;
|
|
|
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
|
begin
|
|
if(Reset)
|
|
WriteRxDataToFifoSync1 <=#Tp 1'b0;
|
|
else
|
|
if(WriteRxDataToFifo)
|
|
WriteRxDataToFifoSync1 <=#Tp 1'b1;
|
|
else
|
|
WriteRxDataToFifoSync1 <=#Tp 1'b0;
|
|
end
|
|
|
// Sync. stage 1
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge StartShifting_wb or posedge ResetShifting_wb)
|
|
begin
|
begin
|
if(ResetShifting_wb)
|
if(Reset)
|
Shifting_wb_Sync1 <=#Tp 1'b0;
|
WriteRxDataToFifoSync2 <=#Tp 1'b0;
|
else
|
else
|
Shifting_wb_Sync1 <=#Tp 1'b1;
|
WriteRxDataToFifoSync2 <=#Tp WriteRxDataToFifoSync1;
|
end
|
end
|
|
|
|
wire WriteRxDataToFifo_wb;
|
|
assign WriteRxDataToFifo_wb = WriteRxDataToFifoSync1 & ~WriteRxDataToFifoSync2;
|
|
|
|
reg RxAbortLatched;
|
|
reg RxAbortSync1;
|
|
reg RxAbortSync2;
|
|
reg RxAbortSyncb1;
|
|
reg RxAbortSyncb2;
|
|
|
|
|
|
eth_fifo #(`RX_FIFO_DATA_WIDTH, `RX_FIFO_DEPTH, `RX_FIFO_CNT_WIDTH)
|
|
rx_fifo (.data_in(RxDataLatched2), .data_out(m_wb_dat_o), .clk(WB_CLK_I),
|
|
.reset(Reset), .write(WriteRxDataToFifo_wb), .read(MasterWbRX & m_wb_ack_i),
|
|
.clear(RxAbortSync2), .full(RxBufferFull), .almost_full(RxBufferAlmostFull),
|
|
.almost_empty(RxBufferAlmostEmpty), .empty(RxBufferEmpty));
|
|
|
|
assign WriteRxDataToMemory = ~RxBufferEmpty & (~MasterWbRX | ~RxBufferAlmostEmpty);
|
|
|
|
|
// Sync. stage 2
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
// Generation of the end-of-frame signal
|
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
Shifting_wb_Sync2 <=#Tp 1'b0;
|
ShiftEnded_tck <=#Tp 1'b0;
|
else
|
else
|
if(Shifting_wb_Sync1 & ~RxDataValid_wb)
|
if(SetWriteRxDataToFifo & StartShiftWillEnd & ~RxAbort)
|
Shifting_wb_Sync2 <=#Tp 1'b1;
|
ShiftEnded_tck <=#Tp 1'b1;
|
else
|
else
|
Shifting_wb_Sync2 <=#Tp 1'b0;
|
if(ShiftEndedSync2 | RxAbort)
|
|
ShiftEnded_tck <=#Tp 1'b0;
|
end
|
end
|
|
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
|
begin
|
|
if(Reset)
|
|
ShiftEndedSync1 <=#Tp 1'b0;
|
|
else
|
|
ShiftEndedSync1 <=#Tp ShiftEnded_tck;
|
|
end
|
|
|
// Generating synchronized signal that will latch data for writing to the WISHBONE
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
LatchNow_wb <=#Tp 1'b0;
|
ShiftEndedSync2 <=#Tp 1'b0;
|
else
|
else
|
if(Shifting_wb_Sync2 & ~RxDataValid_wb)
|
if(ShiftEndedSync1)
|
LatchNow_wb <=#Tp 1'b1;
|
ShiftEndedSync2 <=#Tp 1'b1;
|
else
|
else
|
LatchNow_wb <=#Tp 1'b0;
|
if(ShiftEnded)
|
|
ShiftEndedSync2 <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// Indicating that valid data is avaliable
|
// Generation of the end-of-frame signal
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge WB_CLK_I or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxDataValid_wb <=#Tp 1'b0;
|
ShiftEnded <=#Tp 1'b0;
|
else
|
else
|
if(LatchNow_wb & ~RxDataValid_wb)
|
if(ShiftEndedSync2 & MasterWbRX & m_wb_ack_i & RxBufferAlmostEmpty)
|
RxDataValid_wb <=#Tp 1'b1;
|
ShiftEnded <=#Tp 1'b1;
|
else
|
else
|
if(RxDataValid_wb)
|
if(RxStatusWrite)
|
RxDataValid_wb <=#Tp 1'b0;
|
ShiftEnded <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// Forcing next descriptor in the DMA (Channel 1 is used for rx)
|
// Generation of the end-of-frame signal
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
WB_REQ_O_RX <=#Tp 1'b0;
|
RxEnableWindow <=#Tp 1'b0;
|
else
|
else
|
if(LatchNow_wb & ~RxDataValid_wb & r_DmaEn)
|
if(RxStartFrm)
|
WB_REQ_O_RX <=#Tp 1'b1;
|
RxEnableWindow <=#Tp 1'b1;
|
else
|
else
|
if(DMACycleFinishedRx)
|
if(RxEndFrm | RxAbort)
|
WB_REQ_O_RX <=#Tp 1'b0;
|
RxEnableWindow <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
assign WB_REQ_O[1] = WB_REQ_O_RX;
|
|
assign DMACycleFinishedRx = WB_REQ_O[1] & WB_ACK_I[1];
|
|
|
|
|
|
// WbWriteError is generated when the previous word is not written to the wishbone on time
|
// Generation of the end-of-frame signal
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
always @ (posedge MRxClk or posedge Reset)
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
WbWriteError <=#Tp 1'b0;
|
RxAbortLatched <=#Tp 1'b0;
|
else
|
else
|
if(LatchNow_wb & ~RxDataValid_wb)
|
if(RxAbort)
|
begin
|
RxAbortLatched <=#Tp 1'b1;
|
if(WB_REQ_O[1] & ~WB_ACK_I[1])
|
|
WbWriteError <=#Tp 1'b1;
|
|
end
|
|
else
|
else
|
if(RxStartFrm_wb)
|
if(RxAbortSyncb2 | RxStartFrm)
|
WbWriteError <=#Tp 1'b0;
|
RxAbortLatched <=#Tp 1'b0;
|
end
|
end
|
|
|
|
|
// Assembling data that will be written to the WISHBONE
|
always @ (posedge WB_CLK_I or posedge Reset)
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxData_wb <=#Tp 32'h0;
|
RxAbortSync1 <=#Tp 1'b0;
|
else
|
|
if(LatchNow_wb & ~RxDataValid_wb & ~ShiftWillEnd)
|
|
RxData_wb <=#Tp RxDataLatched2;
|
|
else
|
else
|
if(LatchNow_wb & ~RxDataValid_wb & ShiftWillEnd)
|
RxAbortSync1 <=#Tp RxAbort;
|
case(RxValidBytes)
|
|
0 : RxData_wb <=#Tp {RxDataLatched2[31:16], RxDataLatched1[15:0]};
|
|
1 : RxData_wb <=#Tp {24'h0, RxDataLatched1[7:0]};
|
|
2 : RxData_wb <=#Tp {16'h0, RxDataLatched1[15:0]};
|
|
3 : RxData_wb <=#Tp {8'h0, RxDataLatched2[23:16], RxDataLatched1[15:0]};
|
|
endcase
|
|
end
|
end
|
|
|
|
always @ (posedge WB_CLK_I or posedge Reset)
|
|
begin
|
|
if(Reset)
|
|
RxAbortSync2 <=#Tp 1'b0;
|
|
else
|
|
RxAbortSync2 <=#Tp RxAbortSync1;
|
|
end
|
|
|
// Selecting the data for the WISHBONE
|
always @ (posedge MRxClk or posedge Reset)
|
//assign WB_DAT_O[31:0] = BDRead? WB_BDDataOut : RxData_wb;
|
|
|
|
|
|
// Generation of the end-of-frame signal
|
|
always @ (posedge WB_CLK_I or posedge WB_RST_I)
|
|
begin
|
begin
|
if(WB_RST_I)
|
if(Reset)
|
RxEndFrm_wb <=#Tp 1'b0;
|
RxAbortSyncb1 <=#Tp 1'b0;
|
else
|
else
|
if(LatchNow_wb & ~RxDataValid_wb & ShiftWillEnd)
|
RxAbortSyncb1 <=#Tp RxAbortSync2;
|
RxEndFrm_wb <=#Tp 1'b1;
|
end
|
|
|
|
always @ (posedge MRxClk or posedge Reset)
|
|
begin
|
|
if(Reset)
|
|
RxAbortSyncb2 <=#Tp 1'b0;
|
else
|
else
|
if(StartRxStatusWrite)
|
RxAbortSyncb2 <=#Tp RxAbortSyncb1;
|
RxEndFrm_wb <=#Tp 1'b0;
|
|
end
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
// Interrupts
|
// Interrupts
|
assign TxB_IRQ = 1'b0;
|
assign TxB_IRQ = 1'b0;
|
assign TxE_IRQ = 1'b0;
|
assign TxE_IRQ = 1'b0;
|
assign RxB_IRQ = 1'b0;
|
assign RxB_IRQ = 1'b0;
|
assign RxF_IRQ = 1'b0;
|
assign RxF_IRQ = 1'b0;
|