📄 tb_ethernet_with_cop.v
字号:
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 + -