URL
https://opencores.org/ocsvn/ethmac/ethmac/trunk
Subversion Repositories ethmac
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 41 to Rev 40
- ↔ Reverse comparison
Rev 41 → Rev 40
/trunk/rtl/verilog/eth_wishbone.v
41,11 → 41,6
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2002/02/05 16:44:39 mohor |
// Both rx and tx part are finished. Tested with wb_clk_i between 10 and 200 |
// MHz. Statuses, overrun, control frame transmission and reception still need |
// to be fixed. |
// |
// Revision 1.2 2002/02/01 12:46:51 mohor |
// Tx part finished. TxStatus needs to be fixed. Pause request needs to be |
// added. |
332,12 → 327,35
`endif |
|
|
// Generic synchronous single-port RAM interface |
|
|
// Generic synchronous two-port RAM interface |
/* |
generic_tpram #(8, 32) i_generic_tpram |
( |
.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), |
|
.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) |
); |
*/ |
|
|
|
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(Reset)); |
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(Reset)); |
|
|
|
/* |
generic_spram #(8, 32) ram ( |
// Generic synchronous single-port RAM interface |
.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_we = BDWrite & WbEn & WbEn_q | TxStatusWrite | RxStatusWrite; |
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 |
1541,6 → 1559,7
wire WriteRxDataToFifo_wb; |
assign WriteRxDataToFifo_wb = WriteRxDataToFifoSync1 & ~WriteRxDataToFifoSync2; |
|
reg RxAbortLatched; |
reg RxAbortSync1; |
reg RxAbortSync2; |
reg RxAbortSyncb1; |
1619,6 → 1638,21
end |
|
|
|
// Generation of the end-of-frame signal |
always @ (posedge MRxClk or posedge Reset) |
begin |
if(Reset) |
RxAbortLatched <=#Tp 1'b0; |
else |
if(RxAbort) |
RxAbortLatched <=#Tp 1'b1; |
else |
if(RxAbortSyncb2 | RxStartFrm) |
RxAbortLatched <=#Tp 1'b0; |
end |
|
|
always @ (posedge WB_CLK_I or posedge Reset) |
begin |
if(Reset) |
/trunk/rtl/verilog/eth_wishbonedma.v
41,9 → 41,6
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.10 2002/01/23 10:28:16 mohor |
// Link in the header changed. |
// |
// Revision 1.9 2001/12/05 15:00:16 mohor |
// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors |
// instead of the number of RX descriptors). |
101,7 → 98,7
( |
|
// WISHBONE common |
WB_CLK_I, Reset, WB_DAT_I, WB_DAT_O, |
WB_CLK_I, WB_RST_I, WB_DAT_I, WB_DAT_O, |
|
// WISHBONE slave |
WB_ADR_I, WB_SEL_I, WB_WE_I, WB_ACK_O, |
130,7 → 127,7
|
// WISHBONE common |
input WB_CLK_I; // WISHBONE clock |
input Reset; // WISHBONE reset |
input WB_RST_I; // WISHBONE reset |
input [31:0] WB_DAT_I; // WISHBONE data input |
output [31:0] WB_DAT_O; // WISHBONE data output |
|
265,7 → 262,7
reg GotDataSync1; |
reg GotDataSync2; |
wire TPauseRqSync2; |
wire GotDataSync3; |
wire GotDataSync3; |
reg GotData; |
reg SyncGetNewTxData_wb1; |
reg SyncGetNewTxData_wb2; |
272,7 → 269,7
reg SyncGetNewTxData_wb3; |
reg TxDoneSync1; |
reg TxDoneSync2; |
wire TxDoneSync3; |
wire TxDoneSync3; |
reg TxRetrySync1; |
reg TxRetrySync2; |
wire TxRetrySync3; |
398,9 → 395,9
|
|
reg EnableRAM; |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
EnableRAM <=#Tp 1'b0; |
else |
if(BDWe) |
413,18 → 410,18
// Generic synchronous two-port RAM interface |
generic_tpram #(8, 32) i_generic_tpram |
( |
.clk_a(WB_CLK_I), .rst_a(Reset), .ce_a(1'b1), .we_a(BDWe), |
.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_b(WB_CLK_I), .rst_b(Reset), .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) |
); |
|
|
// 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 Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
Div2 <=#Tp 1'h0; |
else |
Div2 <=#Tp ~Div2; |
437,9 → 434,9
|
|
// Changes for tx occur every second clock. Flop is used for this manner. |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
Flop <=#Tp 1'b0; |
else |
if(TxDone | TxAbort | TxRetry_q) |
451,9 → 448,9
|
|
// Latching READY status of the Tx buffer descriptor |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxBDReady <=#Tp 1'b0; |
else |
if(TxEn & TxBDRead) |
465,9 → 462,9
|
|
// Latching READY status of the Tx buffer descriptor |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
begin |
TxPauseRq <=#Tp 1'b0; |
end |
486,9 → 483,9
// Reading the Tx buffer descriptor |
assign StartTxBDRead = TxEn & ~BlockingTxBDRead & (TxRetry_wb | TxStatusWriteOccured); |
|
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxBDRead <=#Tp 1'b1; |
else |
if(StartTxBDRead) |
506,9 → 503,9
|
|
// Reading data |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxDataRead <=#Tp 1'b0; |
else |
if(StartTxDataRead & r_DmaEn) |
527,9 → 524,9
assign StartTxStatusWrite = TxEn & ~BlockingTxStatusWrite & (TxDone_wb | TxAbort_wb | TxCtrlEndFrm_wb); |
assign ResetTxStatusWrite = TxStatusWrite; |
|
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxStatusWrite <=#Tp 1'b0; |
else |
if(StartTxStatusWrite) |
541,9 → 538,9
|
|
// Status writing must occur only once. Meanwhile it is blocked. |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
BlockingTxStatusWrite <=#Tp 1'b0; |
else |
if(StartTxStatusWrite) |
556,9 → 553,9
|
// After a tx status write is finished, a new tx buffer descriptor is read. Signal must be |
// latched because new BD read doesn't occur immediately. |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxStatusWriteOccured <=#Tp 1'b0; |
else |
if(StartTxStatusWrite) |
570,9 → 567,9
|
|
// TxBDRead state is activated only once. |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
BlockingTxBDRead <=#Tp 1'b0; |
else |
if(StartTxBDRead) |
585,9 → 582,9
|
// 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 Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxStatus <=#Tp 32'h0; |
else |
if(TxBDRead & TxEn) |
596,9 → 593,9
|
|
//Latching length from the buffer descriptor; |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxLength <=#Tp 16'h0; |
else |
if(TxBDRead & TxEn) |
616,9 → 613,9
|
// 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 Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxStatus <=#Tp 16'h0; |
else |
if(RxBDRead & RxEn) |
628,9 → 625,9
|
// Signal GetNewTxData_wb that requests new data from the DMA must be latched since the DMA response |
// might be delayed. |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
GetNewTxData_wb_latched <=#Tp 1'b0; |
else |
if(GetNewTxData_wb) |
642,9 → 639,9
|
|
// New tx data is avaliable after the DMA access is finished |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
NewTxDataAvaliable_wb <=#Tp 1'b0; |
else |
if(DMACycleFinishedTx & GetNewTxData_wb_latched) |
657,9 → 654,9
|
// Tx Buffer descriptor is only read at the beginning. This signal is used for generation of the |
// TxStartFrm_wb signal. |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxBDAccessed <=#Tp 1'b0; |
else |
if(TxBDRead) |
671,9 → 668,9
|
|
// TxStartFrm_wb: indicator of the start frame (synchronized to WB_CLK_I) |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxStartFrm_wb <=#Tp 1'b0; |
else |
if(DMACycleFinishedTx & TxBDAccessed & ~TxStartFrm_wb) |
689,9 → 686,9
|
|
// Input latch of the end-of-frame indicator |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxEndFrm_wbLatched <=#Tp 1'b0; |
else |
if(TxEndFrm_wb) |
707,9 → 704,9
|
|
// Latching valid bytes |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxValidBytesLatched <=#Tp 2'h0; |
else |
if(TxEndFrm_wb & ~TxEndFrm_wbLatched) |
721,9 → 718,9
|
|
// Input Tx data latch |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxDataLatched_wb <=#Tp 32'h0; |
else |
if(DMACycleFinishedTx) |
732,9 → 729,9
|
|
// TxStartFrmRequest is set when a new frame is avaliable or when new data of the same frame is avaliable) |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxStartFrmRequest <=#Tp 1'b0; |
else |
if(TxStartFrm_wb | NewTxDataAvaliable_wb) |
798,9 → 795,9
|
|
// Latching Tx buffer descriptor address |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxBDAddress <=#Tp 8'h0; |
else |
if(TxStatusWrite) |
809,9 → 806,9
|
|
// Latching Rx buffer descriptor address |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxBDAddress <=#Tp 8'h0; |
else |
if(TX_BD_NUM_Wr) // When r_TxBDNum is updated, RxBDAddress is also |
823,9 → 820,9
|
|
// Selecting Tx or Rx buffer descriptor address |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
BDAddress <=#Tp 8'h0; |
else |
if(TxEn) |
847,9 → 844,9
|
|
// Generating delayed signals |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
begin |
TxRestart_wb_q <=#Tp 1'b0; |
TxDone_wb_q <=#Tp 1'b0; |
875,9 → 872,9
|
|
// Next descriptor for Tx DMA channel |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
WB_ND_O_TX <=#Tp 1'b0; |
else |
if(TxDonePulse | TxAbortPulse) |
894,9 → 891,9
|
|
// Restart descriptor for DMA channel 0 (Tx) |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
WB_RD_O <=#Tp 1'b0; |
else |
if(TxRestartPulse) |
908,7 → 905,7
|
|
assign SetClearTxBDReady = ~TxUsedData & TxUsedData_q; |
assign ResetClearTxBDReady = ClearTxBDReady | Reset; |
assign ResetClearTxBDReady = ClearTxBDReady | WB_RST_I; |
|
|
always @ (posedge SetClearTxBDReady or posedge ResetClearTxBDReady) |
919,9 → 916,9
ClearTxBDReadySync1 <=#Tp 1'b1; |
end |
|
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
ClearTxBDReadySync2 <=#Tp 1'b0; |
else |
if(ClearTxBDReadySync1 & ~ClearTxBDReady) |
931,9 → 928,9
end |
|
|
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
ClearTxBDReady <=#Tp 1'b0; |
else |
if(ClearTxBDReadySync2 & ~ClearTxBDReady) |
945,14 → 942,14
|
|
// Latching and synchronizing the Tx pause request signal |
eth_sync_clk1_clk2 syn1 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(Reset), |
.reset2(Reset), .set2(TxPauseRq), .sync_out(TPauseRqSync2) |
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 Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TPauseRq <=#Tp 1'b0; |
else |
if(TPauseRq ) |
965,9 → 962,9
|
|
// Generating delayed signals |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
begin |
TxAbort_q <=#Tp 1'b0; |
TxDone_q <=#Tp 1'b0; |
988,8 → 985,8
// Sinchronizing and evaluating tx data |
assign SetGotData = (TxStartFrm_wb | NewTxDataAvaliable_wb & ~TxAbort_wb & ~TxRetry_wb) & ~WB_CLK_I; |
|
eth_sync_clk1_clk2 syn2 (.clk1(MTxClk), .clk2(WB_CLK_I), .reset1(Reset), |
.reset2(Reset), .set2(SetGotData), .sync_out(GotDataSync3)); |
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. |
997,9 → 994,9
|
|
// Indication of good data |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
GotData <=#Tp 1'b0; |
else |
if(GotDataEvaluate) |
1010,9 → 1007,9
|
|
// Tx start frame generation |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxStartFrm <=#Tp 1'b0; |
else |
if(TxUsedData_q | TxAbort & ~TxAbort_q | TxRetry & ~TxRetry_q) |
1024,9 → 1021,9
|
|
// Indication of the last word |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
LastWord <=#Tp 1'b0; |
else |
if((TxEndFrm | TxAbort | TxRetry) & Flop) |
1038,9 → 1035,9
|
|
// Tx end frame generation |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxEndFrm <=#Tp 1'b0; |
else |
if(Flop & TxEndFrm | TxAbort | TxRetry_q) |
1060,9 → 1057,9
|
|
// Tx data selection (latching) |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxData <=#Tp 8'h0; |
else |
if(GotData & ~TxStartFrm & ~TxUsedData) |
1081,9 → 1078,9
|
|
// Latching tx data |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxDataLatched[31:0] <=#Tp 32'h0; |
else |
if(GotData & ~TxUsedData & ~TxStartFrm) |
1095,7 → 1092,7
|
|
// Generation of the DataNotAvaliable signal which is used for the generation of the TxUnderRun signal |
assign ResetDataNotAvaliable = DMACycleFinishedTx_q | Reset; |
assign ResetDataNotAvaliable = DMACycleFinishedTx_q | WB_RST_I; |
assign SetDataNotAvaliable = GotData & ~TxUsedData & ~TxStartFrm | TxUsedData & Flop & TxByteCnt == 2'h3; |
|
always @ (posedge MTxClk or posedge ResetDataNotAvaliable) |
1109,9 → 1106,9
|
|
// Tx under run |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxUnderRun <=#Tp 1'b0; |
else |
if(TxAbort & ~TxAbort_q) |
1124,9 → 1121,9
|
|
// Tx Byte counter |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxByteCnt <=#Tp 2'h0; |
else |
if(TxAbort_q | TxRetry_q) |
1141,9 → 1138,9
|
|
// Generation of the GetNewTxData signal |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
GetNewTxData <=#Tp 1'b0; |
else |
if(GetNewTxData) |
1158,9 → 1155,9
|
|
// TxRetryLatched |
always @ (posedge MTxClk or posedge Reset) |
always @ (posedge MTxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxRetryLatched <=#Tp 1'b0; |
else |
if(TxStartFrm) |
1171,8 → 1168,14
end |
|
|
|
// 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 | Reset; |
assign ResetSyncGetNewTxData_wb = SyncGetNewTxData_wb3 | TxAbort_wb | TxRetry_wb | WB_RST_I; |
assign SetSyncGetNewTxData_wb = GetNewTxData; |
|
|
1187,9 → 1190,9
|
|
// Sync. stage 2 |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
SyncGetNewTxData_wb2 <=#Tp 1'b0; |
else |
if(SyncGetNewTxData_wb1 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb) |
1200,9 → 1203,9
|
|
// Sync. stage 3 |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
SyncGetNewTxData_wb3 <=#Tp 1'b0; |
else |
if(SyncGetNewTxData_wb2 & ~GetNewTxData_wb & ~TxAbort_wb & ~TxRetry_wb) |
1213,9 → 1216,9
|
|
// Synchronized request for a new tx data |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
GetNewTxData_wb <=#Tp 1'b0; |
else |
if(GetNewTxData_wb) |
1228,15 → 1231,15
|
// Synchronizine transmit done signal |
// Sinchronizing and evaluating tx data |
eth_sync_clk1_clk2 syn4 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(Reset), |
.reset2(Reset), .set2(TxDone), .sync_out(TxDoneSync3) |
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) |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxDone_wb <=#Tp 1'b0; |
else |
if(TxStartFrm_wb | WillSendControlFrame) |
1247,7 → 1250,7
end |
|
|
assign ResetTxCtrlEndFrm_wb = TxCtrlEndFrm_wb | Reset; |
assign ResetTxCtrlEndFrm_wb = TxCtrlEndFrm_wb | WB_RST_I; |
assign SetTxCtrlEndFrm_wb = TxCtrlEndFrm; |
|
|
1262,9 → 1265,9
|
|
// Sync stage 2 |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxCtrlEndFrm_wbSync2 <=#Tp 1'b0; |
else |
if(TxCtrlEndFrm_wbSync1 & ~TxCtrlEndFrm_wb) |
1275,9 → 1278,9
|
|
// Synchronized Tx control end frame |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxCtrlEndFrm_wb <=#Tp 1'b0; |
else |
if(TxCtrlEndFrm_wbSync2 & ~TxCtrlEndFrm_wb) |
1289,14 → 1292,14
|
|
// Synchronizing TxRetry signal |
eth_sync_clk1_clk2 syn6 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(Reset), |
.reset2(Reset), .set2(TxRetryLatched), .sync_out(TxRetrySync3)); |
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 Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxRetry_wb <=#Tp 1'b0; |
else |
if(TxStartFrm_wb | WillSendControlFrame) |
1308,14 → 1311,14
|
|
// Synchronizing TxAbort signal |
eth_sync_clk1_clk2 syn7 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(Reset), |
.reset2(Reset), .set2(TxAbort), .sync_out(TxAbortSync3)); |
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 Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
TxAbort_wb <=#Tp 1'b0; |
else |
if(TxStartFrm_wb) |
1333,9 → 1336,9
|
|
// Latching READY status of the Rx buffer descriptor |
always @ (negedge WB_CLK_I or posedge Reset) |
always @ (negedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxBDReady <=#Tp 1'b0; |
else |
if(RxEn & RxBDRead) |
1347,9 → 1350,9
|
|
// Reading the Rx buffer descriptor |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxBDRead <=#Tp 1'b1; |
else |
if(StartRxBDRead) |
1366,9 → 1369,9
|
|
// Writing status back to the Rx buffer descriptor |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxStatusWrite <=#Tp 1'b0; |
else |
if(StartRxStatusWrite) |
1383,9 → 1386,9
|
|
// 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 |
if(Reset) |
if(WB_RST_I) |
RxStatusWriteOccured <=#Tp 1'b0; |
else |
if(StartRxStatusWrite) |
1398,15 → 1401,15
|
|
// Generation of the synchronized signal ShiftEnded that indicates end of reception |
eth_sync_clk1_clk2 syn8 (.clk1(MRxClk), .clk2(WB_CLK_I), .reset1(Reset), |
.reset2(Reset), .set2(RxEndFrm_wb), .sync_out(ShiftEnded) |
eth_sync_clk1_clk2 syn8 (.clk1(MRxClk), .clk2(WB_CLK_I), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(RxEndFrm_wb), .sync_out(ShiftEnded) |
); |
|
|
// Indicating that last byte is being reveived |
always @ (posedge MRxClk or posedge Reset) |
always @ (posedge MRxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
LastByteIn <=#Tp 1'b0; |
else |
if(ShiftWillEnd & (&RxByteCnt)) |
1418,9 → 1421,9
|
|
// Indicating that data reception will end |
always @ (posedge MRxClk or posedge Reset) |
always @ (posedge MRxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
ShiftWillEnd <=#Tp 1'b0; |
else |
if(ShiftEnded) |
1432,9 → 1435,9
|
|
// Receive byte counter |
always @ (posedge MRxClk or posedge Reset) |
always @ (posedge MRxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxByteCnt <=#Tp 2'h0; |
else |
if(ShiftEnded) |
1446,9 → 1449,9
|
|
// Indicates how many bytes are valid within the last word |
always @ (posedge MRxClk or posedge Reset) |
always @ (posedge MRxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxValidBytes <=#Tp 2'h1; |
else |
if(ShiftEnded) |
1461,9 → 1464,9
|
// There is a maximum 3 MRxClk delay between RxDataLatched2 and RxData_wb. In the meantime data |
// is stored to the RxDataLatched1. |
always @ (posedge MRxClk or posedge Reset) |
always @ (posedge MRxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxDataLatched1 <=#Tp 16'h0; |
else |
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h0) |
1475,9 → 1478,9
|
|
// Latching incoming data to buffer |
always @ (posedge MRxClk or posedge Reset) |
always @ (posedge MRxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxDataLatched2 <=#Tp 32'h0; |
else |
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h2) |
1489,9 → 1492,9
|
|
// Indicating start of the reception process |
always @ (posedge MRxClk or posedge Reset) |
always @ (posedge MRxClk or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
StartShifting <=#Tp 1'b0; |
else |
if((RxValid & RxBDReady & ~RxStartFrm & (&RxByteCnt)) | (ShiftWillEnd & LastByteIn & (&RxByteCnt))) |
1504,15 → 1507,15
// Synchronizing Rx start frame to the WISHBONE clock |
assign StartRxStartFrmSync1 = RxStartFrm & RxBDReady; |
|
eth_sync_clk1_clk2 syn9 (.clk1(WB_CLK_I), .clk2(MRxClk), .reset1(Reset), |
.reset2(Reset), .set2(SetGotData), .sync_out(RxStartFrmSync3) |
eth_sync_clk1_clk2 syn9 (.clk1(WB_CLK_I), .clk2(MRxClk), .reset1(WB_RST_I), .reset2(WB_RST_I), |
.set2(SetGotData), .sync_out(RxStartFrmSync3) |
); |
|
|
// Generating synchronized Rx start frame |
always @ ( posedge WB_CLK_I or posedge Reset) |
always @ ( posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxStartFrm_wb <=#Tp 1'b0; |
else |
if(RxStartFrmSync3 & ~RxStartFrm_wb) |
1522,8 → 1525,13
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 | Reset; |
assign ResetShifting_wb = LatchNow_wb | WB_RST_I; |
assign StartShifting_wb = StartShifting; |
|
|
1538,9 → 1546,9
|
|
// Sync. stage 2 |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
Shifting_wb_Sync2 <=#Tp 1'b0; |
else |
if(Shifting_wb_Sync1 & ~RxDataValid_wb) |
1551,9 → 1559,9
|
|
// 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 |
if(Reset) |
if(WB_RST_I) |
LatchNow_wb <=#Tp 1'b0; |
else |
if(Shifting_wb_Sync2 & ~RxDataValid_wb) |
1564,9 → 1572,9
|
|
// Indicating that valid data is avaliable |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxDataValid_wb <=#Tp 1'b0; |
else |
if(LatchNow_wb & ~RxDataValid_wb) |
1578,9 → 1586,9
|
|
// Forcing next descriptor in the DMA (Channel 1 is used for rx) |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
WB_REQ_O_RX <=#Tp 1'b0; |
else |
if(LatchNow_wb & ~RxDataValid_wb & r_DmaEn) |
1596,9 → 1604,9
|
|
// WbWriteError is generated when the previous word is not written to the wishbone on time |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
WbWriteError <=#Tp 1'b0; |
else |
if(LatchNow_wb & ~RxDataValid_wb) |
1613,9 → 1621,9
|
|
// 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 |
if(Reset) |
if(WB_RST_I) |
RxData_wb <=#Tp 32'h0; |
else |
if(LatchNow_wb & ~RxDataValid_wb & ~ShiftWillEnd) |
1636,9 → 1644,9
|
|
// Generation of the end-of-frame signal |
always @ (posedge WB_CLK_I or posedge Reset) |
always @ (posedge WB_CLK_I or posedge WB_RST_I) |
begin |
if(Reset) |
if(WB_RST_I) |
RxEndFrm_wb <=#Tp 1'b0; |
else |
if(LatchNow_wb & ~RxDataValid_wb & ShiftWillEnd) |
/trunk/rtl/verilog/eth_top.v
41,9 → 41,6
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.9 2002/01/23 10:28:16 mohor |
// Link in the header changed. |
// |
// Revision 1.8 2001/12/05 15:00:16 mohor |
// RX_BD_NUM changed to TX_BD_NUM (holds number of TX descriptors |
// instead of the number of RX descriptors). |
103,23 → 100,13
|
// WISHBONE slave |
wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i, wb_stb_i, wb_ack_o, wb_err_o, |
wb_ack_i, |
wb_req_o, wb_ack_i, wb_nd_o, wb_rd_o, |
|
`ifdef WISHBONE_DMA |
wb_req_o, wb_nd_o, wb_rd_o, |
`else |
// 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, |
`endif |
|
//TX |
mtx_clk_pad_i, mtxd_pad_o, mtxen_pad_o, mtxerr_pad_o, |
|
//RX |
mrx_clk_pad_i, mrxd_pad_i, mrxdv_pad_i, mrxerr_pad_i, mcoll_pad_i, mcrs_pad_i, |
RxAbort, |
|
// MIIM |
mdc_pad_o, md_pad_i, md_pad_o, md_padoen_o, |
148,26 → 135,12
input wb_stb_i; // WISHBONE strobe input |
output wb_ack_o; // WISHBONE acknowledge output |
|
`ifdef WISHBONE_DMA |
// DMA |
input [1:0] wb_ack_i; // DMA acknowledge input |
output [1:0] wb_req_o; // DMA request output |
output [1:0] wb_nd_o; // DMA force new descriptor output |
output wb_rd_o; // DMA restart descriptor output |
`else |
// WISHBONE master |
output [31:0] m_wb_adr_o; |
output [3:0] m_wb_sel_o; |
output m_wb_we_o; |
input [31:0] m_wb_dat_i; |
output [31:0] m_wb_dat_o; |
output m_wb_cyc_o; |
output m_wb_stb_o; |
input m_wb_ack_i; |
input m_wb_err_i; |
`endif |
|
input [1:0] wb_ack_i; // DMA acknowledge input |
|
// Tx |
input mtx_clk_pad_i; // Transmit clock (from PHY) |
output [3:0] mtxd_pad_o; // Transmit nibble (to PHY) |
183,8 → 156,6
// Common Tx and Rx |
input mcoll_pad_i; // Collision (from PHY) |
input mcrs_pad_i; // Carrier sense (from PHY) |
input RxAbort; // igor !!! Ta se mora preseliti da bo prisel iz enega izmed modulov. Tu je le zaradi |
// testiranja. Pove, kdaj adresa ni ustrezala in se paketi sklirajo, stevci pa resetirajo. |
|
// MII Management interface |
input md_pad_i; // MII data input (from I/O cell) |
328,7 → 299,6
wire RxValid; |
wire RxStartFrm; |
wire RxEndFrm; |
wire RxAbort; |
|
wire WillTransmit; // Will transmit (to RxEthMAC) |
wire ResetCollision; // Reset Collision (for synchronizing collision) |
343,7 → 313,7
// Connecting MACControl |
eth_maccontrol maccontrol1 |
( |
.MTxClk(mtx_clk_pad_i), .TPauseRq(TPauseRq), |
.MTxClk(mtx_clk_pad_i), .TPauseRq(TPauseRq), |
.TxPauseTV(TxPauseTV), .TxDataIn(TxData), |
.TxStartFrmIn(TxStartFrm), .TxEndFrmIn(TxEndFrm), |
.TxUsedDataIn(TxUsedDataIn), .TxDoneIn(TxDoneIn), |
525,33 → 495,17
|
|
// Connecting WishboneDMA module |
`ifdef WISHBONE_DMA |
eth_wishbonedma wishbone |
`else |
eth_wishbone wishbone |
`endif |
eth_wishbonedma wbdma |
( |
.WB_CLK_I(wb_clk_i), .WB_DAT_I(wb_dat_i), |
.WB_CLK_I(wb_clk_i), .WB_RST_I(wb_rst_i), .WB_DAT_I(wb_dat_i), |
.WB_DAT_O(DMA_WB_DAT_O), |
|
// WISHBONE slave |
.WB_ADR_I(wb_adr_i[9:2]), .WB_SEL_I(wb_sel_i), .WB_WE_I(wb_we_i), |
.BDCs(BDCs), .WB_ACK_O(BDAck), |
.WB_REQ_O(wb_req_o), .WB_ACK_I(wb_ack_i), .WB_ND_O(wb_nd_o), |
.WB_RD_O(wb_rd_o), |
|
.Reset(wb_rst_i), |
|
`ifdef WISHBONE_DMA |
.WB_REQ_O(wb_req_o), .WB_ND_O(wb_nd_o), .WB_RD_O(wb_rd_o), |
.WB_ACK_I(wb_ack_i), |
`else |
// WISHBONE master |
.m_wb_adr_o(m_wb_adr_o), .m_wb_sel_o(m_wb_sel_o), .m_wb_we_o(m_wb_we_o), |
.m_wb_dat_i(m_wb_dat_i), .m_wb_dat_o(m_wb_dat_o), .m_wb_cyc_o(m_wb_cyc_o), |
.m_wb_stb_o(m_wb_stb_o), .m_wb_ack_i(m_wb_ack_i), .m_wb_err_i(m_wb_err_i), |
`endif |
|
|
|
//TX |
.MTxClk(mtx_clk_pad_i), .TxStartFrm(TxStartFrm), .TxEndFrm(TxEndFrm), |
.TxUsedData(TxUsedData), .TxData(TxData), .StatusIzTxEthMACModula(16'h0), |
566,16 → 520,10
|
//RX |
.MRxClk(mrx_clk_pad_i), .RxData(RxData), .RxValid(RxValid), |
.RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), |
.RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), |
.Busy_IRQ(Busy_IRQ), .RxF_IRQ(RxF_IRQ), .RxB_IRQ(RxB_IRQ), |
.TxE_IRQ(TxE_IRQ), .TxB_IRQ(TxB_IRQ) |
|
`ifdef WISHBONE_DMA |
`else |
, |
.RxAbort(RxAbort) |
`endif |
|
); |
|
|
583,7 → 531,7
// Connecting MacStatus module |
eth_macstatus macstatus1 |
( |
.MRxClk(mrx_clk_pad_i), .Reset(r_Rst), .TransmitEnd(), |
.MRxClk(mrx_clk_pad_i), .Reset(r_Rst), .TransmitEnd(), |
.ReceiveEnd(ReceiveEnd), .ReceivedPacketGood(ReceivedPacketGood), .ReceivedLengthOK(ReceivedLengthOK), |
.RxCrcError(RxCrcError), .MRxErr(MRxErr_Lb), .MRxDV(MRxDV_Lb), |
.RxStateSFD(RxStateSFD), .RxStateData(RxStateData), .RxStatePreamble(RxStatePreamble), |
/trunk/bench/verilog/tb_eth_top.v
3,7 → 3,7
//// tb_eth_top.v //// |
//// //// |
//// This file is part of the Ethernet IP core project //// |
//// http://www.opencores.org/projects/ethmac/ //// |
//// http://www.opencores.org/cores/ethmac/ //// |
//// //// |
//// Author(s): //// |
//// - Igor Mohor (igorM@opencores.org) //// |
41,9 → 41,6
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.6 2001/12/08 12:36:00 mohor |
// TX_BD_NUM register added instead of the RB_BD_ADDR. |
// |
// Revision 1.5 2001/10/19 11:24:04 mohor |
// Number of addresses (wb_adr_i) minimized. |
// |
98,28 → 95,14
reg WB_WE_I; |
reg WB_CYC_I; |
reg WB_STB_I; |
reg [1:0] WB_ACK_I; |
|
wire [31:0] WB_DAT_O; |
wire WB_ACK_O; |
wire WB_ERR_O; |
reg [1:0] WB_ACK_I; |
|
`ifdef WISHBONE_DMA |
wire [1:0] WB_REQ_O; |
wire [1:0] WB_ND_O; |
wire WB_RD_O; |
`else |
// WISHBONE master |
wire [31:0] m_wb_adr_o; |
wire [3:0] m_wb_sel_o; |
wire m_wb_we_o; |
reg [31:0] m_wb_dat_i; |
wire [31:0] m_wb_dat_o; |
wire m_wb_cyc_o; |
wire m_wb_stb_o; |
reg m_wb_ack_i; |
reg m_wb_err_i; |
`endif |
|
reg MTxClk; |
wire [3:0] MTxD; |
132,7 → 115,6
reg MRxErr; |
reg MColl; |
reg MCrs; |
reg RxAbort; |
|
reg Mdi_I; |
wire Mdo_O; |
148,12 → 130,8
reg [9:0] TxBDIndex; |
reg [9:0] RxBDIndex; |
|
`ifdef WISHBONE_DMA |
`else |
integer mcd1; |
integer mcd2; |
`endif |
|
|
// Connecting Ethernet top module |
|
eth_top ethtop |
163,16 → 141,8
|
// WISHBONE slave |
.wb_adr_i(WB_ADR_I[11:2]), .wb_sel_i(WB_SEL_I), .wb_we_i(WB_WE_I), .wb_cyc_i(WB_CYC_I), |
.wb_stb_i(WB_STB_I), .wb_ack_o(WB_ACK_O), .wb_err_o(WB_ERR_O), .wb_ack_i(WB_ACK_I), |
|
`ifdef WISHBONE_DMA |
.wb_req_o(WB_REQ_O), .wb_nd_o(WB_ND_O), .wb_rd_o(WB_RD_O), |
`else |
// WISHBONE master |
.m_wb_adr_o(m_wb_adr_o), .m_wb_sel_o(m_wb_sel_o), .m_wb_we_o(m_wb_we_o), .m_wb_dat_i(m_wb_dat_i), |
.m_wb_dat_o(m_wb_dat_o), .m_wb_cyc_o(m_wb_cyc_o), .m_wb_stb_o(m_wb_stb_o), .m_wb_ack_i(m_wb_ack_i), |
.m_wb_err_i(m_wb_err_i), |
`endif |
.wb_stb_i(WB_STB_I), .wb_ack_o(WB_ACK_O), .wb_err_o(WB_ERR_O), .wb_req_o(WB_REQ_O), |
.wb_ack_i(WB_ACK_I), .wb_nd_o(WB_ND_O), .wb_rd_o(WB_RD_O), |
|
//TX |
.mtx_clk_pad_i(MTxClk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr), |
180,8 → 150,6
//RX |
.mrx_clk_pad_i(MRxClk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr), |
.mcoll_pad_i(MColl), .mcrs_pad_i(MCrs), |
.RxAbort(RxAbort), // igor !!! Ta se mora preseliti da bo prisel iz enega izmed modulov. Tu je le zaradi |
// testiranja. Pove, kdaj adresa ni ustrezala in se paketi sklirajo, stevci pa resetirajo. |
|
// MIIM |
.mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoen_o(Mdo_OE), |
204,13 → 172,7
WB_WE_I = 1'b0; |
WB_CYC_I = 1'b0; |
WB_STB_I = 1'b0; |
|
`ifdef WISHBONE_DMA |
WB_ACK_I = 2'h0; |
`else |
m_wb_ack_i = 0; |
m_wb_err_i = 0; |
`endif |
MTxClk = 1'b0; |
MRxClk = 1'b0; |
MRxD = 4'h0; |
218,7 → 180,6
MRxErr = 1'b0; |
MColl = 1'b0; |
MCrs = 1'b0; |
RxAbort = 1'b0; |
Mdi_I = 1'b0; |
|
WishboneBusy = 1'b0; |
230,13 → 191,10
// Reset pulse |
initial |
begin |
`ifdef WISHBONE_DMA |
`else |
mcd1 = $fopen("ethernet_tx.log"); |
mcd2 = $fopen("ethernet_rx.log"); |
`endif |
WB_RST_I = 1'b1; |
GSR = 1'b1; |
WB_RST_I = 1'b1; |
#100 WB_RST_I = 1'b1; |
GSR = 1'b1; |
#100 WB_RST_I = 1'b0; |
GSR = 1'b0; |
#100 StartTB = 1'b1; |
250,14 → 208,11
// Generating WB_CLK_I clock |
always |
begin |
// forever #2.5 WB_CLK_I = ~WB_CLK_I; // 2*2.5 ns -> 200.0 MHz |
// forever #5 WB_CLK_I = ~WB_CLK_I; // 2*5 ns -> 100.0 MHz |
// forever #10 WB_CLK_I = ~WB_CLK_I; // 2*10 ns -> 50.0 MHz |
forever #15 WB_CLK_I = ~WB_CLK_I; // 2*10 ns -> 33.3 MHz |
// forever #18 WB_CLK_I = ~WB_CLK_I; // 2*18 ns -> 27.7 MHz |
// forever #25 WB_CLK_I = ~WB_CLK_I; // 2*25 ns -> 20.0 MHz |
// forever #50 WB_CLK_I = ~WB_CLK_I; // 2*50 ns -> 10.0 MHz |
// forever #55 WB_CLK_I = ~WB_CLK_I; // 2*55 ns -> 9.1 MHz |
// forever #100 WB_CLK_I = ~WB_CLK_I; |
end |
|
// Generating MTxClk clock |
274,7 → 229,8
// #16 forever #250 MRxClk = ~MRxClk; |
end |
|
`ifdef WISHBONE_DMA |
|
|
initial |
begin |
wait(StartTB); // Start of testbench |
693,373 → 649,6
end |
endtask |
|
`else // No WISHBONE_DMA |
|
initial |
begin |
wait(StartTB); // Start of testbench |
|
WishboneWrite(32'h00000800, {26'h0, `ETH_MODER_ADR<<2}); // r_Rst = 1 |
WishboneWrite(32'h00000000, {26'h0, `ETH_MODER_ADR<<2}); // r_Rst = 0 |
WishboneWrite(32'h00000080, {26'h0, `ETH_TX_BD_NUM_ADR<<2}); // r_RxBDAddress = 0x80 |
|
WishboneWrite(32'h0002A443, {26'h0, `ETH_MODER_ADR<<2}); // RxEn, Txen, FullD, CrcEn, Pad, DmaEn, r_IFG |
|
WishboneWrite(32'h00000004, {26'h0, `ETH_CTRLMODER_ADR<<2}); //r_TxFlow = 1 |
|
|
SendPacket(16'h0010, 1'b0); |
SendPacket(16'h0011, 1'b0); |
SendPacket(16'h0012, 1'b0); |
SendPacket(16'h0013, 1'b0); |
SendPacket(16'h0014, 1'b0); |
|
SendPacket(16'h0030, 1'b0); |
SendPacket(16'h0031, 1'b0); |
SendPacket(16'h0032, 1'b0); |
SendPacket(16'h0033, 1'b0); |
SendPacket(16'h0025, 1'b0); |
SendPacket(16'h0045, 1'b0); |
SendPacket(16'h0025, 1'b0); |
SendPacket(16'h0017, 1'b0); |
|
// ReceivePacket(16'h0012, 1'b1, 1'b0); // Initializes RxBD and then Sends a control packet on the MRxD[3:0] signals. |
ReceivePacket(16'h0015, 1'b0, 1'b0); // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
ReceivePacket(16'h0016, 1'b0, 1'b0); // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
ReceivePacket(16'h0017, 1'b0, 1'b0); // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
ReceivePacket(16'h0018, 1'b0, 1'b0); // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
|
repeat(5000) @ (posedge MRxClk); // Waiting some time for all accesses to finish before reading out the statuses. |
|
WishboneRead({26'h0, `ETH_MODER_ADR}); // Read from MODER register |
|
WishboneRead({24'h04, (8'h0<<2)}); // Read from TxBD register |
WishboneRead({24'h04, (8'h1<<2)}); // Read from TxBD register |
WishboneRead({24'h04, (8'h2<<2)}); // Read from TxBD register |
WishboneRead({24'h04, (8'h3<<2)}); // Read from TxBD register |
WishboneRead({24'h04, (8'h4<<2)}); // Read from TxBD register |
|
|
WishboneRead({22'h01, (10'h80<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h81<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h82<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h83<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h84<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h85<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h86<<2)}); // Read from RxBD register |
WishboneRead({22'h01, (10'h87<<2)}); // Read from RxBD register |
|
#100000 $stop; |
end |
|
//integer ijk; |
|
//initial |
//ijk = 0; // for stoping generation of the m_wb_ack_i signal at the right moment so we get underrun |
|
// Answering to master Wishbone requests |
always @ (posedge WB_CLK_I) |
begin |
if(m_wb_cyc_o & m_wb_stb_o) // Add valid address range |
begin |
repeat(3) @ (posedge WB_CLK_I); |
begin |
// if(ijk==41) |
// begin |
// repeat(1000) @ (posedge WB_CLK_I); |
// end |
// else |
m_wb_ack_i <=#Tp 1'b1; |
if(~m_wb_we_o) |
begin |
#Tp m_wb_dat_i = m_wb_adr_o + 1'b1; // For easier following of the data |
$fdisplay(mcd1, "(%0t) master read (0x%0x) = 0x%0x", $time, m_wb_adr_o, m_wb_dat_i); |
// ijk = ijk + 1; |
end |
else |
$fdisplay(mcd2, "(%0t) master write (0x%0x) = 0x%0x", $time, m_wb_adr_o, m_wb_dat_o); |
end |
@ (posedge WB_CLK_I); |
m_wb_ack_i <=#Tp 1'b0; |
end |
end |
|
// Generating error |
always @ (posedge WB_CLK_I) |
begin |
if(m_wb_cyc_o & m_wb_stb_o & ~(&m_wb_sel_o)) // Add false address range |
m_wb_err_i <=#Tp 1'b1; |
end |
|
always @ (posedge WB_CLK_I) |
if(tb_eth_top.ethtop.wishbone.RxStatusWrite) |
$fdisplay(mcd2, ""); // newline added |
|
task WishboneWrite; |
input [31:0] Data; |
input [31:0] Address; |
integer ii; |
|
begin |
wait (~WishboneBusy); |
WishboneBusy = 1; |
@ (posedge WB_CLK_I); |
#1; |
WB_ADR_I = Address; |
WB_DAT_I = Data; |
WB_WE_I = 1'b1; |
WB_CYC_I = 1'b1; |
WB_STB_I = 1'b1; |
WB_SEL_I = 4'hf; |
|
|
wait(WB_ACK_O); // waiting for acknowledge response |
|
// Writing information about the access to the screen |
@ (posedge WB_CLK_I); |
if(~Address[11] & ~Address[10]) |
$write("\n(%0t) Write to register (Data: 0x%x, Reg. Addr: 0x%0x)", $time, Data, Address); |
else |
if(~Address[11] & Address[10]) |
if(Address[9:2] < tb_eth_top.ethtop.r_TxBDNum) |
begin |
$write("\n(%0t) Write to TxBD (Data: 0x%x, TxBD Addr: 0x%0x)", $time, Data, Address); |
if(Data[9]) |
$write("(%0t) Send Control packet (PAUSE = 0x%0h)\n", $time, Data[31:16]); |
end |
else |
$write("\n(%0t) Write to RxBD (Data: 0x%x, RxBD Addr: 0x%0x)", $time, Data, Address); |
else |
$write("\n(%0t) WB write ?????????????? Data: 0x%x Addr: 0x%0x", $time, Data, Address); |
#1; |
WB_ADR_I = 32'hx; |
WB_DAT_I = 32'hx; |
WB_WE_I = 1'bx; |
WB_CYC_I = 1'b0; |
WB_STB_I = 1'b0; |
WB_SEL_I = 4'hx; |
#5 WishboneBusy = 0; |
end |
endtask |
|
|
task WishboneRead; |
input [31:0] Address; |
|
begin |
wait (~WishboneBusy); |
WishboneBusy = 1; |
@ (posedge WB_CLK_I); |
#1; |
WB_ADR_I = Address; |
WB_WE_I = 1'b0; |
WB_CYC_I = 1'b1; |
WB_STB_I = 1'b1; |
WB_SEL_I = 4'hf; |
|
wait(WB_ACK_O); // waiting for acknowledge response |
@ (posedge WB_CLK_I); |
|
if(~Address[11] & ~Address[10]) |
$write("\n(%0t) Read from register (Data: 0x%x, Reg. Addr: 0x%0x)", $time, WB_DAT_O, Address); |
else |
if(~Address[11] & Address[10]) |
if(Address[9:2] < tb_eth_top.ethtop.r_TxBDNum) |
begin |
$write("\n(%0t) Read from TxBD (Data: 0x%x, TxBD Addr: 0x%0x)", $time, WB_DAT_O, Address); |
end |
else |
$write("\n(%0t) Read from RxBD (Data: 0x%x, RxBD Addr: 0x%0x)", $time, WB_DAT_O, Address); |
else |
$write("\n(%0t) WB read ????????? Data: 0x%x Addr: 0x%0x", $time, WB_DAT_O, Address); |
#1; |
WB_ADR_I = 32'hx; |
WB_WE_I = 1'bx; |
WB_CYC_I = 1'b0; |
WB_STB_I = 1'b0; |
WB_SEL_I = 4'hx; |
#5 WishboneBusy = 0; |
end |
endtask |
|
|
|
|
task SendPacket; |
input [15:0] Length; |
input ControlFrame; |
reg Wrap; |
reg [31:0] TempAddr; |
reg [31:0] TempData; |
|
begin |
// if(TxBDIndex == 6) // Only 3 buffer descriptors are used |
// Wrap = 1'b1; |
// else |
Wrap = 1'b0; // At the moment no wrap bit is set |
|
// Writing buffer pointer |
TempAddr = {22'h01, ((TxBDIndex + 1'b1)<<2)}; |
TempData = 32'h78563411; |
WishboneWrite(TempData, TempAddr); // buffer pointer |
|
|
TempAddr = {22'h01, (TxBDIndex<<2)}; // igor !!! zbrisi spodnjo vrstico |
// TempAddr = {22'h01, 10'b1010010100}; |
|
TempData = {Length[15:0], 1'b1, 1'b0, Wrap, 3'h0, ControlFrame, 1'b0, TxBDIndex[7:0]}; // Ready and Wrap = 1 |
|
#1; |
// if(TxBDIndex == 6) // Only 4 buffer descriptors are used |
// TxBDIndex = 0; |
// else |
TxBDIndex = TxBDIndex + 2; |
|
WishboneWrite(TempData, TempAddr); // Writing status to TxBD |
end |
endtask |
|
|
|
task ReceivePacket; // Initializes RxBD and then generates traffic on the MRxD[3:0] signals. |
input [15:0] LengthRx; |
input RxControlFrame; |
input Abort; |
reg WrapRx; |
reg [31:0] TempRxAddr; |
reg [31:0] TempRxData; |
reg abc; |
begin |
// if(RxBDIndex == 6) // Only 3 buffer descriptors are used |
// WrapRx = 1'b1; |
// else |
WrapRx = 1'b0; |
|
TempRxAddr = {22'h01, ((tb_eth_top.ethtop.r_TxBDNum + RxBDIndex + 1'b1)<<2)}; |
TempRxData = 32'h73507350 + RxBDIndex; |
WishboneWrite(TempRxData, TempRxAddr); // Writing Rx pointer |
|
|
TempRxAddr = {22'h01, ((tb_eth_top.ethtop.r_TxBDNum + RxBDIndex)<<2)}; |
// TempRxData = {LengthRx[15:0], 1'b1, 1'b0, WrapRx, 5'h0, RxBDIndex[7:0]}; // Ready and WrapRx = 1 or 0 |
TempRxData = {16'h0, 1'b1, 1'b0, WrapRx, 5'h0, RxBDIndex[7:0]}; // Ready and WrapRx = 1 or 0 |
|
#1; |
// if(RxBDIndex == 6) // Only 4 buffer descriptors are used |
// RxBDIndex = 0; |
// else |
RxBDIndex = RxBDIndex + 2; |
|
abc=1; |
WishboneWrite(TempRxData, TempRxAddr); // Writing status to RxBD |
abc=0; |
|
begin |
#200; |
if(RxControlFrame) |
GetControlDataOnMRxD(LengthRx); // LengthRx = PAUSE timer value. |
else |
GetDataOnMRxD(LengthRx, Abort); // LengthRx bytes is comming on MRxD[3:0] signals |
end |
|
end |
endtask |
|
|
task GetDataOnMRxD; |
input [15:0] Len; |
input abort; |
integer tt; |
|
begin |
@ (posedge MRxClk); |
MRxDV=1'b1; |
|
for(tt=0; tt<15; tt=tt+1) |
begin |
MRxD=4'h5; // preamble |
@ (posedge MRxClk); |
end |
MRxD=4'hd; // SFD |
|
for(tt=1; tt<(Len+1); tt=tt+1) |
begin |
@ (posedge MRxClk); |
MRxD=tt[3:0]; |
if(tt==9) |
RxAbort<=#1 abort; |
@ (posedge MRxClk); |
MRxD=tt[7:4]; |
RxAbort<=#1 0; |
end |
@ (posedge MRxClk); |
MRxDV=1'b0; |
end |
endtask |
|
|
task GetControlDataOnMRxD; |
input [15:0] Timer; |
reg [127:0] Packet; |
reg [127:0] Data; |
reg [31:0] Crc; |
integer tt; |
|
begin |
Packet = 128'h10082C000010_deadbeef0013_8880_0010; // 0180c2000001 + 8808 + 0001 |
Crc = 32'h6014fe08; // not a correct value |
|
@ (posedge MRxClk); |
MRxDV=1'b1; |
|
for(tt=0; tt<15; tt=tt+1) |
begin |
MRxD=4'h5; // preamble |
@ (posedge MRxClk); |
end |
MRxD=4'hd; // SFD |
|
for(tt=0; tt<32; tt=tt+1) |
begin |
Data = Packet << (tt*4); |
@ (posedge MRxClk); |
MRxD=Data[127:124]; |
end |
|
for(tt=0; tt<2; tt=tt+1) // timer |
begin |
Data[15:0] = Timer << (tt*8); |
@ (posedge MRxClk); |
MRxD=Data[11:8]; |
@ (posedge MRxClk); |
MRxD=Data[15:12]; |
end |
|
for(tt=0; tt<42; tt=tt+1) // padding |
begin |
Data[7:0] = 8'h0; |
@ (posedge MRxClk); |
MRxD=Data[3:0]; |
@ (posedge MRxClk); |
MRxD=Data[3:0]; |
end |
|
for(tt=0; tt<4; tt=tt+1) // crc |
begin |
Data[31:0] = Crc << (tt*8); |
@ (posedge MRxClk); |
MRxD=Data[27:24]; |
@ (posedge MRxClk); |
MRxD=Data[31:28]; |
end |
|
|
|
@ (posedge MRxClk); |
MRxDV=1'b0; |
end |
endtask |
`endif |
|
|
endmodule |