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

📄 tb_eth_top.v

📁 该文件包含以太网IP核的相关代码
💻 V
📖 第 1 页 / 共 2 页
字号:
        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 + -