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

📄 tb_ethernet_with_cop.v

📁 用Verilog实现的以太网接口
💻 V
📖 第 1 页 / 共 2 页
字号:

  repeat (10000) @(posedge wb_clk_o);   // Waiting for TxEthMac to finish transmit

/*
  GetDataOnMRxD(113, `UNICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals

  repeat (10000) @(posedge wb_clk_o);   // Waiting for TxEthMac to finish transmit

  GetDataOnMRxD(500, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals

  repeat (1000) @(posedge mrx_clk);   // Waiting for TxEthMac to finish transmit


  GetDataOnMRxD(1200, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals


  GetDataOnMRxD(1000, `UNICAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals

  repeat (10000) @(posedge wb_clk_o);   // Waiting for TxEthMac to finish transmit
  
*/
  // Reading and printing interrupts
  eth_host.wb_read(`ETH_INT, 4'hf, tmp);
  $display("Print irq = 0x%0x", tmp);
  
  //Clearing all interrupts
  eth_host.wb_write(`ETH_INT, 4'hf, 32'h60);

  // Reading and printing interrupts
  eth_host.wb_read(`ETH_INT, 4'hf, tmp);
  $display("Print irq = 0x%0x", tmp);

  $display("\n\n End of simulation");
  $stop;



end
  

`ifdef ETH_WISHBONE_B3

integer single_cnt_tx, burst_cnt_tx, burst_cnt;
integer single_cnt_rx, burst_cnt_rx;

initial
begin
single_cnt_tx=0; burst_cnt_tx=0; burst_cnt=0;
single_cnt_rx=0; burst_cnt_rx=0;
end

// Single and burst cycle watcher
always @ (posedge wb_clk_o)
begin
  if(eth_ma_wb_ack_i) begin
    if(eth_ma_wb_cyc_o & eth_ma_wb_we_o & eth_ma_wb_cti_o==3'b000) begin
      if(burst_cnt!==0)
        $display("(%0t)(%m) ERROR !!!  burst_cnt should be 0 because this is a single access", $time);
      else
        single_cnt_rx=single_cnt_rx+1;
    end
    else if(eth_ma_wb_cyc_o & !eth_ma_wb_we_o & eth_ma_wb_cti_o==3'b000) begin
      if(burst_cnt!==0)
        $display("(%0t)(%m) ERROR !!!  burst_cnt should be 0 because this is a single access", $time);
      else
        single_cnt_tx=single_cnt_tx+1;
    end
    else if(eth_ma_wb_cyc_o & eth_ma_wb_cti_o==3'b010) begin // burst in progress
      burst_cnt=burst_cnt+1;
    end
    else if(eth_ma_wb_cyc_o & eth_ma_wb_we_o & eth_ma_wb_cti_o==3'b111 & burst_cnt==(`ETH_BURST_LENGTH-1)) begin
      burst_cnt_rx=burst_cnt_rx+1;
      burst_cnt=0;
    end
    else if(eth_ma_wb_cyc_o & !eth_ma_wb_we_o & eth_ma_wb_cti_o==3'b111 & burst_cnt==(`ETH_BURST_LENGTH-1)) begin
      burst_cnt_tx=burst_cnt_tx+1;
      burst_cnt=0;
    end
    else
      $display("(%0t)(%m) ERROR !!!  Unknown cycle type or sequence", $time);
  end
end
`endif  // ETH_WISHBONE_B3



task initialize_txbd;
  input [6:0] txbd_num;
  
  integer i;
  integer bd_status_addr, buf_addr, bd_ptr_addr;
  
  for(i=0; i<txbd_num; i=i+1) begin
    buf_addr = `TX_BUF_BASE + i * 32'h600;
    bd_status_addr = `TX_BD_BASE + i * 8;
    bd_ptr_addr = bd_status_addr + 4; 
    
    // Initializing BD - status
    if(i==txbd_num-1)
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h00007800);    // last BD: + WRAP
    else
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h00005800);    // IRQ + PAD + CRC

    eth_host.wb_write(bd_ptr_addr, 4'hf, buf_addr);             // Initializing BD - pointer
  end
endtask // initialize_txbd


task initialize_rxbd;
  input [6:0] rxbd_num;
  
  integer i;
  integer bd_status_addr, buf_addr, bd_ptr_addr;
  
  for(i=0; i<rxbd_num; i=i+1) begin
    buf_addr = `RX_BUF_BASE + i * 32'h600;
    bd_status_addr = `RX_BD_BASE + i * 8;
    bd_ptr_addr = bd_status_addr + 4; 
    
    // Initializing BD - status
    if(i==rxbd_num-1)
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h0000e000);    // last BD: + WRAP
    else
      eth_host.wb_write(bd_status_addr, 4'hf, 32'h0000c000);    // IRQ + PAD + CRC

    eth_host.wb_write(bd_ptr_addr, 4'hf, buf_addr);             // Initializing BD - pointer
  end
endtask // initialize_rxbd


task set_packet;
  input  [15:0] len;
  input   [7:0] start_data;

  integer i, sd;
  integer bd_status_addr, bd_ptr_addr, buffer, bd;
  
  begin
    sd = start_data;
    bd_status_addr = `TX_BD_BASE + packet_ready_cnt * 8;
    bd_ptr_addr = bd_status_addr + 4; 
    
    // Reading BD + buffer pointer
    eth_host.wb_read(bd_status_addr, 4'hf, bd);
    eth_host.wb_read(bd_ptr_addr, 4'hf, buffer);

    while(bd & `ETH_TX_BD_READY) begin  // Buffer is ready. Don't touch !!!
      repeat(100) @(posedge wb_clk_o);
      i=i+1;
      eth_host.wb_read(bd_status_addr, 4'hf, bd);
      if(i>1000)  begin
        $display("(%0t)(%m)Waiting for TxBD ready to clear timeout", $time);
        $stop;
      end
    end

    // First write might not be word allign.
    if(buffer[1:0]==1)  begin
      eth_host.wb_write(buffer-1, 4'h7, {8'h0, sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2});
      sd=sd+3;
      i=3;
    end
    else if(buffer[1:0]==2)  begin
      eth_host.wb_write(buffer-2, 4'h3, {16'h0, sd[7:0], sd[7:0]+3'h1});
      sd=sd+2;
      i=2;
    end      
    else if(buffer[1:0]==3)  begin
      eth_host.wb_write(buffer-3, 4'h1, {24'h0, sd[7:0]});
      sd=sd+1;
      i=1;
    end
    else
      i=0;


    for(i=i; i<len-4; i=i+4) begin   // Last 0-3 bytes are not written
      eth_host.wb_write(buffer+i, 4'hf, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, sd[7:0]+3'h3});
      sd=sd+4;
    end
    
    
    // Last word
    if(len-i==3)
      eth_host.wb_write(buffer+i, 4'he, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, 8'h0});
    else if(len-i==2)
      eth_host.wb_write(buffer+i, 4'hc, {sd[7:0], sd[7:0]+3'h1, 16'h0});
    else if(len-i==1)
      eth_host.wb_write(buffer+i, 4'h8, {sd[7:0], 24'h0});
    else if(len-i==4)
      eth_host.wb_write(buffer+i, 4'hf, {sd[7:0], sd[7:0]+3'h1, sd[7:0]+3'h2, sd[7:0]+3'h3});
    else
      $display("(%0t)(%m) ERROR", $time);
    

    // Checking WRAP bit
    if(bd & `ETH_TX_BD_WRAP)
      packet_ready_cnt = 0;
    else
      packet_ready_cnt = packet_ready_cnt+1;

    // Writing len to bd
    bd = bd | (len<<16);
    eth_host.wb_write(bd_status_addr, 4'hf, bd);
    
  end
endtask // set_packet


task send_packet;

  integer bd_status_addr, bd_ptr_addr, buffer, bd;
  
  begin
    bd_status_addr = `TX_BD_BASE + send_packet_cnt * 8;
    bd_ptr_addr = bd_status_addr + 4; 
    
    // Reading BD + buffer pointer
    eth_host.wb_read(bd_status_addr, 4'hf, bd);
    eth_host.wb_read(bd_ptr_addr, 4'hf, buffer);

    if(bd & `ETH_TX_BD_WRAP)
      send_packet_cnt=0;
    else
      send_packet_cnt=send_packet_cnt+1;

    // Setting ETH_TX_BD_READY bit
    bd = bd | `ETH_TX_BD_READY;
    eth_host.wb_write(bd_status_addr, 4'hf, bd);
  end


endtask // send_packet


task GetDataOnMRxD;
  input [15:0] Len;
  input [31:0] TransferType;
  integer tt;

  begin
    @ (posedge mrx_clk);
    #1MRxDV=1'b1;
    
    for(tt=0; tt<15; tt=tt+1)
      begin
        MRxD=4'h5;              // preamble
        @ (posedge mrx_clk);
        #1;
      end

    MRxD=4'hd;                // SFD
    
    for(tt=1; tt<(Len+1); tt=tt+1)
      begin
        @ (posedge mrx_clk);
        #1;
  	    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 mrx_clk);
	      #1;
	      if(TransferType == `BROADCAST_XFR && tt < 7)
	        MRxD = 4'hf;
	      else
          MRxD=tt[7:4];
      end

    @ (posedge mrx_clk);
    #1;
    MRxDV=1'b0;
  end
endtask // GetDataOnMRxD


endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -