⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tb_eth_top.v

📁 < FPGA数字电子系统设计与开发实例导航> 一书的代码
💻 V
📖 第 1 页 / 共 4 页
字号:
  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 + -