📄 tb_eth_top.v
字号:
else
$write("\nWrite to RxBD (Data: 0x%x, RxBD Addr: 0x%0x)", Data, Address);
else
$write("\nWB write ?????????????? Data: 0x%x Addr: 0x%0x", 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;
reg [31:0] Data;
integer ii;
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;
for(ii=0; (ii<20 & ~WB_ACK_O); ii=ii+1) // Response on the WISHBONE is limited to 20 WB_CLK_I cycles
begin
@ (posedge WB_CLK_I);
Data = WB_DAT_O;
end
if(ii==20)
begin
$display("\nERROR: Task WishboneRead(Address=0x%0h): Too late or no appeariance of the WB_ACK_O signal, (Time=%0t)",
Address, $time);
#50 $stop;
end
@ (posedge WB_CLK_I);
if(~Address[11] & ~Address[10])
$write("\nRead from register (Data: 0x%x, Reg. Addr: 0x%0x)", Data, Address);
else
if(~Address[11] & Address[10])
if(Address[9:2] < tb_eth_top.ethtop.r_TxBDNum)
begin
$write("\nRead from TxBD (Data: 0x%x, TxBD Addr: 0x%0x)", Data, Address);
end
else
$write("\nRead from RxBD (Data: 0x%x, RxBD Addr: 0x%0x)", Data, Address);
else
$write("\nWB read ????????? Data: 0x%x Addr: 0x%0x", Data, 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 == 3) // Only 4 buffer descriptors are used
Wrap = 1'b1;
else
Wrap = 1'b0;
TempAddr = {22'h01, (TxBDIndex<<2)};
TempData = {Length[15:0], 1'b1, 1'b0, Wrap, 3'h0, ControlFrame, 1'b0, TxBDIndex[7:0]}; // Ready and Wrap = 1
#1;
if(TxBDIndex == 3) // Only 4 buffer descriptors are used
TxBDIndex = 0;
else
TxBDIndex = TxBDIndex + 1;
fork
begin
WishboneWrite(TempData, TempAddr); // Writing status to TxBD
end
begin
if(~ControlFrame)
WaitingForTxDMARequest(4'h1, Length); // Delay, DMALength
end
join
end
endtask
task ReceivePacket; // Initializes RxBD and then generates traffic on the MRxD[3:0] signals.
input [15:0] LengthRx;
input RxControlFrame;
reg WrapRx;
reg [31:0] TempRxAddr;
reg [31:0] TempRxData;
reg abc;
begin
if(RxBDIndex == 3) // Only 4 buffer descriptors are used
WrapRx = 1'b1;
else
WrapRx = 1'b0;
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
#1;
if(RxBDIndex == 3) // Only 4 buffer descriptors are used
RxBDIndex = 0;
else
RxBDIndex = RxBDIndex + 1;
abc=1;
WishboneWrite(TempRxData, TempRxAddr); // Writing status to RxBD
abc=0;
fork
begin
#200;
if(RxControlFrame)
GetControlDataOnMRxD(LengthRx); // LengthRx = PAUSE timer value.
else
GetDataOnMRxD(LengthRx); // LengthRx bytes is comming on MRxD[3:0] signals
end
begin
if(RxControlFrame)
WaitingForRxDMARequest(4'h1, 16'h40); // Delay, DMALength = 64 bytes.
else
WaitingForRxDMARequest(4'h1, LengthRx); // Delay, DMALength
end
join
end
endtask
task WaitingForTxDMARequest;
input [3:0] Delay;
input [15:0] DMALength;
integer pp;
reg [7:0]a, b, c, d;
for(pp=0; pp*4<DMALength; pp=pp+1)
begin
a = 4*pp[7:0]+3;
b = 4*pp[7:0]+2;
c = 4*pp[7:0]+1;
d = 4*pp[7:0] ;
@ (posedge WB_REQ_O[0]);
repeat(Delay) @(posedge WB_CLK_I);
wait (~WishboneBusy);
WishboneBusy = 1;
#1;
WB_DAT_I = {a, b, c, d};
// WB_ADR_I = {20'h20, pp[11:0]};
WB_ADR_I = {22'h02, pp[9:0]};
$display("task WaitingForTxDMARequest: pp=%0d, WB_ADR_I=0x%0h, WB_DAT_I=0x%0h", pp, WB_ADR_I, WB_DAT_I);
WB_WE_I = 1'b1;
WB_CYC_I = 1'b1;
WB_STB_I = 1'b1;
WB_SEL_I = 4'hf;
WB_ACK_I[0] = 1'b1;
@ (posedge WB_CLK_I);
#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;
WB_ACK_I[0] = 1'b0;
#5 WishboneBusy = 0;
end
endtask
task WaitingForRxDMARequest;
input [3:0] Delay;
input [15:0] DMALengthRx;
integer rr;
for(rr=0; rr*4<DMALengthRx; rr=rr+1)
begin
@ (posedge WB_REQ_O[1]);
repeat(Delay) @(posedge WB_CLK_I);
wait (~WishboneBusy);
WishboneBusy = 1;
#1;
// WB_ADR_I = {20'h20, rr[11:0]};
WB_ADR_I = {22'h02, rr[9:0]};
$display("task WaitingForRxDMARequest: rr=%0d, WB_ADR_I=0x%0h, WB_DAT_O=0x%0h", rr, WB_ADR_I, WB_DAT_O);
WB_WE_I = 1'b1;
WB_CYC_I = 1'b1;
WB_STB_I = 1'b1;
WB_SEL_I = 4'hf;
WB_ACK_I[1] = 1'b1;
@ (posedge WB_CLK_I);
#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;
WB_ACK_I[1] = 1'b0;
#5 WishboneBusy = 0;
end
endtask
task GetDataOnMRxD;
input [15:0] Len;
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=0; tt<Len; tt=tt+1)
begin
@ (posedge MRxClk);
MRxD=tt[3:0];
@ (posedge MRxClk);
MRxD=tt[7:4];
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
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -