📄 tb_eth_top.v
字号:
input ControlFrame;
reg Wrap;
reg [31:0] TempAddr;
reg [31:0] TempData;
reg [31:0] kk;
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 data to buffer
for(kk=0; kk<Length; kk=kk+4)
begin
TempAddr = `TX_BUF_BASE + TxBDIndex * 32'h600 + kk;
TempData = {kk[7:0], kk[7:0]+2'h1, kk[7:0]+2'h2, kk[7:0]+2'h3};
WishboneWriteData(TempAddr, TempData, 4'hf); // Writing Data to buffer that is pointed by the BD
end
// Writing buffer pointer
TempAddr = {22'h01, ((TxBDIndex*2'h2 + 1'b1)<<2)};
TempData = `TX_BUF_BASE + TxBDIndex * 32'h600; // 1536 bytes is reserved for one frame
WishboneWrite(TempData, TempAddr); // Writing Tx pointer
TempAddr = {22'h01, ((TxBDIndex*2'h2)<<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 == 6) // Only 4 buffer descriptors are used
// TxBDIndex = 0;
// else
TxBDIndex = TxBDIndex + 1;
WishboneWrite(TempData, TempAddr); // Writing status to TxBD
end
endtask
task SendPacketX;
input [15:0] Length;
input ControlFrame;
input [1:0] AddrOffset;
reg Wrap;
reg [31:0] TempAddr;
reg [31:0] TempData;
reg [31:0] kk;
reg [3:0] Select;
begin
Wrap = 1'b0;
case(AddrOffset)
2'h0 : Select = 4'hf;
2'h1 : Select = 4'h7;
2'h2 : Select = 4'h3;
2'h3 : Select = 4'h1;
endcase
// Writing data to buffer
for(kk=0; kk<Length+4; kk=kk+4) // Length+4 is because we might start up to 3 bytes later
begin
if(kk>0)
Select = 4'hf;
TempAddr = `TX_BUF_BASE + TxBDIndex * 32'h600 + kk;
TempData = {kk[7:0]+3'h1, kk[7:0]+3'h2, kk[7:0]+3'h3, kk[7:0]+3'h4};
WishboneWriteData(TempAddr, TempData, Select); // Writing Data to buffer that is pointed by the BD
end
// Writing buffer pointer
TempAddr = {22'h01, ((TxBDIndex*2'h2 + 1'b1)<<2)};
TempData = `TX_BUF_BASE + TxBDIndex * 32'h600 + AddrOffset; // 1536 bytes is reserved for one frame
WishboneWrite(TempData, TempAddr); // Writing Tx pointer
TempAddr = {22'h01, ((TxBDIndex*2'h2)<<2)};
TempData = {Length[15:0], 1'b1, 1'b1, Wrap, 3'h0, ControlFrame, 1'b0, TxBDIndex[7:0]}; // Ready, interrupt and Wrap = 1
#1;
if(Wrap)
TxBDIndex = 0;
else
TxBDIndex = TxBDIndex + 1;
WishboneWrite(TempData, TempAddr); // Writing status to TxBD
end
endtask
task send_packet;
input [47:0] dest_addr;
input [15:0] length;
reg [31:0] BD, ptr;
reg [31:0] i;
reg [2:0] increment;
reg [31:0] TempAddr;
reg [31:0] TempData;
reg [15:0] kk;
reg [3:0] Select;
begin
bd_status_addr = `TX_BD_BASE + g_last_txbd * 8;
mama
WishboneRead(bd_status_addr, BD); // Read BD
WishboneRead(bd_status_addr+4, ptr); // Read buffer pointer
case(ptr[1:0])
2'h0 : begin Select = 4'hf; increment = 3'h4 end
2'h1 : begin Select = 4'h7; increment = 3'h3 end
2'h2 : begin Select = 4'h3; increment = 3'h2 end
2'h3 : begin Select = 4'h1; increment = 3'h1 end
endcase
// Writing data to buffer
for(i=ptr; i<(length+ptr); i=i+increment) // (i=0; i<length; i=i+increment)
begin
if(i>ptr) // After first write all accesses are word accesses
begin Select = 4'hf; increment=3'h4; end
TempAddr = `TX_BUF_BASE + TxBDIndex * 32'h600 + kk;
TempData = {i[7:0]+3'h1, i[7:0]+3'h2, i[7:0]+3'h3, i[7:0]+3'h4};
mama
WishboneWriteData(TempAddr, TempData, Select); // Writing Data to buffer that is pointed by the BD
end
// Writing buffer pointer
TempAddr = {22'h01, ((TxBDIndex*2'h2 + 1'b1)<<2)};
TempData = `TX_BUF_BASE + TxBDIndex * 32'h600 + AddrOffset; // 1536 bytes is reserved for one frame
WishboneWrite(TempData, TempAddr); // Writing Tx pointer
TempAddr = {22'h01, ((TxBDIndex*2'h2)<<2)};
TempData = {length[15:0], 1'b1, 1'b1, Wrap, 3'h0, ControlFrame, 1'b0, TxBDIndex[7:0]}; // Ready, interrupt and Wrap = 1
#1;
if(Wrap)
TxBDIndex = 0;
else
TxBDIndex = TxBDIndex + 1;
WishboneWrite(TempData, TempAddr); // Writing status to TxBD
if(BD & 32'h2000) // Wrap bit set ?
g_last_txbd = 0;
else
g_last_txbd = g_last_txbd+1;
end
endtask // send_packet
task ReceivePacket; // Initializes RxBD and then generates traffic on the MRxD[3:0] signals.
input [15:0] LengthRx;
input RxControlFrame;
input [31:0] TransferType; //Broadcast,Unicast,Multicast
reg WrapRx;
reg [31:0] TempRxAddr;
// reg [31:0] TempRxData;
integer 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*2'h2 + 1'b1)<<2)};
TempRxData = `RX_BUF_BASE + RxBDIndex * 32'h600; // 1536 bytes is reserved for one frame
WishboneWrite(TempRxData, TempRxAddr); // Writing Rx pointer
TempRxAddr = {22'h01, ((tb_eth_top.ethtop.r_TxBDNum + RxBDIndex*2'h2)<<2)};
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 + 1;
abc=1;
WishboneWrite(TempRxData, TempRxAddr); // Writing status to RxBD
abc=0;
begin
#200;
if(RxControlFrame)
GetControlDataOnMRxD(LengthRx); // LengthRx = PAUSE timer value.
else
GetDataOnMRxD(LengthRx, TransferType); // LengthRx bytes is comming on MRxD[3:0] signals
end
end
endtask
task ReceivePacketX; // Initializes RxBD and then generates traffic on the MRxD[3:0] signals.
input [15:0] LengthRx;
input RxControlFrame;
input [31:0] TransferType; //Broadcast,Unicast,Multicast
input [1:0] AddrOffset;
reg WrapRx;
reg [31:0] TempRxAddr;
integer TempRxData;
reg abc;
begin
WrapRx = 1'b0;
TempRxAddr = {22'h01, ((tb_eth_top.ethtop.r_TxBDNum + RxBDIndex*2'h2 + 1'b1)<<2)};
TempRxData = `RX_BUF_BASE + RxBDIndex * 32'h600 + AddrOffset; // 1536 bytes is reserved for one frame
WishboneWrite(TempRxData, TempRxAddr); // Writing Rx pointer
TempRxAddr = {22'h01, ((tb_eth_top.ethtop.r_TxBDNum + RxBDIndex*2'h2)<<2)};
TempRxData = {16'h0, 1'b1, 1'b1, WrapRx, 5'h0, RxBDIndex[7:0]}; // Ready, interrupt and WrapRx = 1 or 0
#1;
RxBDIndex = RxBDIndex + 1;
abc=1;
WishboneWrite(TempRxData, TempRxAddr); // Writing status to RxBD
abc=0;
begin
#200;
if(RxControlFrame)
GetControlDataOnMRxD(LengthRx); // LengthRx = PAUSE timer value.
else
GetDataOnMRxD(LengthRx, TransferType); // LengthRx bytes is comming on MRxD[3:0] signals
end
end
endtask
task GetDataOnMRxD;
input [15:0] Len;
input [31:0] TransferType;
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);
if(TransferType == `UNICAST_XFR && tt == 1)
MRxD= 4'h0; // Unicast transfer
else if(TransferType == `BROADCAST_XFR && tt < 7)
MRxD = 4'hf;
else
MRxD=tt[3:0]; // Multicast transfer
@ (posedge MRxClk);
if(TransferType == `BROADCAST_XFR && tt < 7)
MRxD = 4'hf;
else
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
task InitializeMemory;
reg [9:0] mem_addr;
begin
LogEnable = 1'b0;
$display("\n\n(%0t) Initializing Memory...", $time);
for(mem_addr=0; mem_addr<=10'h0ff; mem_addr=mem_addr+1'b1)
WishboneWrite(32'h0, {22'h01, mem_addr<<2}); // Writing status to RxBD
LogEnable = 1'b1;
end
endtask
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -