📄 eth_wishbonedma.v
字号:
// Sync stage 1
always @ (posedge SetTxCtrlEndFrm_wb or posedge ResetTxCtrlEndFrm_wb)
begin
if(ResetTxCtrlEndFrm_wb)
TxCtrlEndFrm_wbSync1 <=#Tp 1'b0;
else
TxCtrlEndFrm_wbSync1 <=#Tp 1'b1;
end
// Sync stage 2
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
TxCtrlEndFrm_wbSync2 <=#Tp 1'b0;
else
if(TxCtrlEndFrm_wbSync1 & ~TxCtrlEndFrm_wb)
TxCtrlEndFrm_wbSync2 <=#Tp 1'b1;
else
TxCtrlEndFrm_wbSync2 <=#Tp 1'b0;
end
// Synchronized Tx control end frame
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
TxCtrlEndFrm_wb <=#Tp 1'b0;
else
if(TxCtrlEndFrm_wbSync2 & ~TxCtrlEndFrm_wb)
TxCtrlEndFrm_wb <=#Tp 1'b1;
else
if(StartTxStatusWrite)
TxCtrlEndFrm_wb <=#Tp 1'b0;
end
// Synchronizing TxRetry signal
eth_sync_clk1_clk2 syn6 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I),
.set2(TxRetryLatched), .sync_out(TxRetrySync3));
// Synchronized signal TxRetry_wb (synchronized to WISHBONE clock)
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
TxRetry_wb <=#Tp 1'b0;
else
if(TxStartFrm_wb | WillSendControlFrame)
TxRetry_wb <=#Tp 1'b0;
else
if(TxRetrySync3)
TxRetry_wb <=#Tp 1'b1;
end
// Synchronizing TxAbort signal
eth_sync_clk1_clk2 syn7 (.clk1(WB_CLK_I), .clk2(MTxClk), .reset1(WB_RST_I), .reset2(WB_RST_I),
.set2(TxAbort), .sync_out(TxAbortSync3));
// Synchronized TxAbort_wb signal (synchronized to WISHBONE clock)
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
TxAbort_wb <=#Tp 1'b0;
else
if(TxStartFrm_wb)
TxAbort_wb <=#Tp 1'b0;
else
if(TxAbortSync3 & ~TxStartFrmRequest)
TxAbort_wb <=#Tp 1'b1;
end
// Reading of the next receive buffer descriptor starts after reception status is
// 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
always @ (negedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
RxBDReady <=#Tp 1'b0;
else
if(RxEn & RxBDRead)
RxBDReady <=#Tp BDDataOut[15];
else
if(RxStatusWrite)
RxBDReady <=#Tp 1'b0;
end
// Reading the Rx buffer descriptor
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
RxBDRead <=#Tp 1'b1;
else
if(StartRxBDRead)
RxBDRead <=#Tp 1'b1;
else
if(ResetRxBDRead)
RxBDRead <=#Tp 1'b0;
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
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
RxStatusWrite <=#Tp 1'b0;
else
if(StartRxStatusWrite)
RxStatusWrite <=#Tp 1'b1;
else
RxStatusWrite <=#Tp 1'b0;
end
// Forcing next descriptor on DMA channel 1 (Rx)
assign WB_ND_O[1] = RxStatusWrite;
// Latched status that a status write occured.
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
RxStatusWriteOccured <=#Tp 1'b0;
else
if(StartRxStatusWrite)
RxStatusWriteOccured <=#Tp 1'b1;
else
if(StartRxBDRead)
RxStatusWriteOccured <=#Tp 1'b0;
end
// Generation of the synchronized signal ShiftEnded that indicates end of reception
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 WB_RST_I)
begin
if(WB_RST_I)
LastByteIn <=#Tp 1'b0;
else
if(ShiftWillEnd & (&RxByteCnt))
LastByteIn <=#Tp 1'b0;
else
if(RxValid & RxBDReady & RxEndFrm & ~(&RxByteCnt))
LastByteIn <=#Tp 1'b1;
end
// Indicating that data reception will end
always @ (posedge MRxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
ShiftWillEnd <=#Tp 1'b0;
else
if(ShiftEnded)
ShiftWillEnd <=#Tp 1'b0;
else
if(LastByteIn & (&RxByteCnt) | RxValid & RxEndFrm & (&RxByteCnt))
ShiftWillEnd <=#Tp 1'b1;
end
// Receive byte counter
always @ (posedge MRxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
RxByteCnt <=#Tp 2'h0;
else
if(ShiftEnded)
RxByteCnt <=#Tp 2'h0;
else
if(RxValid & RxBDReady | LastByteIn)
RxByteCnt <=#Tp RxByteCnt + 1;
end
// Indicates how many bytes are valid within the last word
always @ (posedge MRxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
RxValidBytes <=#Tp 2'h1;
else
if(ShiftEnded)
RxValidBytes <=#Tp 2'h1;
else
if(RxValid & ~LastByteIn & ~RxStartFrm)
RxValidBytes <=#Tp RxValidBytes + 1;
end
// 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 WB_RST_I)
begin
if(WB_RST_I)
RxDataLatched1 <=#Tp 16'h0;
else
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h0)
RxDataLatched1[7:0] <=#Tp RxData;
else
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h1)
RxDataLatched1[15:8] <=#Tp RxData;
end
// Latching incoming data to buffer
always @ (posedge MRxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
RxDataLatched2 <=#Tp 32'h0;
else
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h2)
RxDataLatched2[23:0] <=#Tp {RxData,RxDataLatched1};
else
if(RxValid & RxBDReady & ~LastByteIn & RxByteCnt == 2'h3)
RxDataLatched2[31:24] <=#Tp RxData;
end
// Indicating start of the reception process
always @ (posedge MRxClk or posedge WB_RST_I)
begin
if(WB_RST_I)
StartShifting <=#Tp 1'b0;
else
if((RxValid & RxBDReady & ~RxStartFrm & (&RxByteCnt)) | (ShiftWillEnd & LastByteIn & (&RxByteCnt)))
StartShifting <=#Tp 1'b1;
else
StartShifting <=#Tp 1'b0;
end
// Synchronizing Rx start frame to the WISHBONE clock
assign StartRxStartFrmSync1 = RxStartFrm & RxBDReady;
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 WB_RST_I)
begin
if(WB_RST_I)
RxStartFrm_wb <=#Tp 1'b0;
else
if(RxStartFrmSync3 & ~RxStartFrm_wb)
RxStartFrm_wb <=#Tp 1'b1;
else
RxStartFrm_wb <=#Tp 1'b0;
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;
// Sync. stage 1
always @ (posedge StartShifting_wb or posedge ResetShifting_wb)
begin
if(ResetShifting_wb)
Shifting_wb_Sync1 <=#Tp 1'b0;
else
Shifting_wb_Sync1 <=#Tp 1'b1;
end
// Sync. stage 2
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
Shifting_wb_Sync2 <=#Tp 1'b0;
else
if(Shifting_wb_Sync1 & ~RxDataValid_wb)
Shifting_wb_Sync2 <=#Tp 1'b1;
else
Shifting_wb_Sync2 <=#Tp 1'b0;
end
// Generating synchronized signal that will latch data for writing to the WISHBONE
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
LatchNow_wb <=#Tp 1'b0;
else
if(Shifting_wb_Sync2 & ~RxDataValid_wb)
LatchNow_wb <=#Tp 1'b1;
else
LatchNow_wb <=#Tp 1'b0;
end
// Indicating that valid data is avaliable
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
RxDataValid_wb <=#Tp 1'b0;
else
if(LatchNow_wb & ~RxDataValid_wb)
RxDataValid_wb <=#Tp 1'b1;
else
if(RxDataValid_wb)
RxDataValid_wb <=#Tp 1'b0;
end
// Forcing next descriptor in the DMA (Channel 1 is used for rx)
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
WB_REQ_O_RX <=#Tp 1'b0;
else
if(LatchNow_wb & ~RxDataValid_wb & r_DmaEn)
WB_REQ_O_RX <=#Tp 1'b1;
else
if(DMACycleFinishedRx)
WB_REQ_O_RX <=#Tp 1'b0;
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
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
WbWriteError <=#Tp 1'b0;
else
if(LatchNow_wb & ~RxDataValid_wb)
begin
if(WB_REQ_O[1] & ~WB_ACK_I[1])
WbWriteError <=#Tp 1'b1;
end
else
if(RxStartFrm_wb)
WbWriteError <=#Tp 1'b0;
end
// Assembling data that will be written to the WISHBONE
always @ (posedge WB_CLK_I or posedge WB_RST_I)
begin
if(WB_RST_I)
RxData_wb <=#Tp 32'h0;
else
if(LatchNow_wb & ~RxDataValid_wb & ~ShiftWillEnd)
RxData_wb <=#Tp RxDataLatched2;
else
if(LatchNow_wb & ~RxDataValid_wb & ShiftWillEnd)
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
// Selecting the data for the WISHBONE
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
if(WB_RST_I)
RxEndFrm_wb <=#Tp 1'b0;
else
if(LatchNow_wb & ~RxDataValid_wb & ShiftWillEnd)
RxEndFrm_wb <=#Tp 1'b1;
else
if(StartRxStatusWrite)
RxEndFrm_wb <=#Tp 1'b0;
end
// Interrupts
assign TxB_IRQ = 1'b0;
assign TxE_IRQ = 1'b0;
assign RxB_IRQ = 1'b0;
assign RxF_IRQ = 1'b0;
assign Busy_IRQ = 1'b0;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -