📄 tb_ethernet.v
字号:
end// Generating mtx_clk clockinitialbegin mtx_clk=0;// #3 forever #20 mtx_clk = ~mtx_clk; // 2*20 ns -> 25 MHz #3 forever #200 mtx_clk = ~mtx_clk; // 2*200 ns -> 2.5 MHzend// Generating mrx_clk clockinitialbegin mrx_clk=0;// #16 forever #20 mrx_clk = ~mrx_clk; // 2*20 ns -> 25 MHz #16 forever #200 mrx_clk = ~mrx_clk; // 2*200 ns -> 2.5 MHzendreg [31:0] tmp;initialbegin wait(StartTB); // Start of testbench eth_host.wb_write(`ETH_MODER, 4'hf, 32'h0); // Reset OFF eth_host.wb_read(`ETH_MODER, 4'hf, tmp); eth_host.wb_write(32'hd0000000, 4'hf, `ETH_MODER_RXEN | `ETH_MODER_TXEN | `ETH_MODER_PRO | `ETH_MODER_CRCEN | `ETH_MODER_PAD); // Set MODER register eth_host.wb_read(32'hd0000000, 4'hf, tmp); initialize_txbd(3); initialize_rxbd(6); set_packet(16'h34, 8'h1); set_packet(16'h34, 8'h11); send_packet; set_packet(16'h34, 8'h21); set_packet(16'h34, 8'h31); send_packet; GetDataOnMRxD(100, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals repeat (100) @(posedge mrx_clk); // Waiting for TxEthMac to finish transmit GetDataOnMRxD(70, `BROADCAST_XFR); // LengthRx bytes is comming on MRxD[3:0] signals repeat (10000) @(posedge wb_clk_o); // Waiting for TxEthMac to finish transmit $display("\n\n End of simulation"); $stop;end 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 endendtask // initialize_txbdtask 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 endendtask // initialize_rxbdtask 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); endendtask // set_packettask 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); endendtask // send_packettask 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; endendtask // GetDataOnMRxDendmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -