1. 程式人生 > >FPGA設計千兆乙太網MAC(3)——資料快取及位寬轉換模組設計與驗證

FPGA設計千兆乙太網MAC(3)——資料快取及位寬轉換模組設計與驗證

  1 `timescale 1ns / 1ps
  2 
  3 module tx_buffer_tb( );
  4 
  5 parameter USER_CLK_CYC = 10,
  6           ETH_CLK_CYC = 8,
  7           RST_TIM = 3;
  8           
  9 parameter SIM_TIM = 10_000;
 10 
 11 reg user_clk;
 12 reg rst_n;
 13 reg [32-1:0] din;
 14 reg din_vld,din_sop,din_eop;
 15 reg [2-1:0] din_mod;
16 wire rdy; 17 reg eth_tx_clk; 18 wire [8-1:0] dout; 19 wire dout_sop,dout_eop,dout_vld; 20 reg [8-1:0] dout_buf [0:1024-1]; 21 reg [16-1:0] len [0:100-1]; 22 reg [2-1:0] mod [0:100-1]; 23 reg err_flag = 0; 24 25 tx_buffer#(.DATA_W(32))//位寬不能改動 26 dut 27 ( 28 29 //全域性訊號 30 .rst_n (rst_n) ,//
保證拉低三個時鐘週期,否則FIF可能不會正確復位 31 .user_clk (user_clk) , 32 .din (din) , 33 .din_vld (din_vld) , 34 .din_sop (din_sop) , 35 .din_eop (din_eop) , 36 .din_mod (din_mod) , 37 .rdy (rdy) , 38 .eth_tx_clk (eth_tx_clk) , 39 .dout (dout) , 40 .dout_sop (dout_sop) ,
41 .dout_eop (dout_eop) , 42 .dout_vld (dout_vld) 43 ); 44 45 /***********************************時鐘******************************************/ 46 initial begin 47 user_clk = 1; 48 forever #(USER_CLK_CYC/2) user_clk = ~user_clk; 49 end 50 51 initial begin 52 eth_tx_clk = 1; 53 forever #(ETH_CLK_CYC/2) eth_tx_clk = ~eth_tx_clk; 54 end 55 /***********************************復位邏輯******************************************/ 56 initial begin 57 rst_n = 1; 58 #1; 59 rst_n = 0; 60 #(RST_TIM*USER_CLK_CYC); 61 rst_n = 1; 62 end 63 64 /***********************************輸入激勵******************************************/ 65 integer gen_time = 0; 66 initial begin 67 #1; 68 packet_initial; 69 #(RST_TIM*USER_CLK_CYC); 70 packet_gen(20,2); 71 #(USER_CLK_CYC*10); 72 packet_gen(30,1); 73 end 74 75 /***********************************輸出快取與檢測******************************************/ 76 integer j = 0; 77 integer chk_time = 0; 78 initial begin 79 forever begin 80 @(posedge eth_tx_clk) 81 if(dout_vld)begin 82 if(dout_sop)begin 83 dout_buf[0] = dout; 84 j = 1; 85 end 86 else if(dout_eop)begin 87 dout_buf[j] = dout; 88 j = j+1; 89 packet_check; 90 end 91 else begin 92 dout_buf[j] = dout; 93 j = j+1; 94 end 95 end 96 end 97 end 98 99 /***********************************score board******************************************/ 100 integer fid; 101 initial begin 102 fid = $fopen("test.txt"); 103 $fdisplay(fid," Start testing \n"); 104 #SIM_TIM; 105 if(err_flag) 106 $fdisplay(fid,"Check is failed\n"); 107 else 108 $fdisplay(fid,"Check is successful\n"); 109 $fdisplay(fid," Testing is finished \n"); 110 $fclose(fid); 111 $stop; 112 end 113 114 /***********************************子任務******************************************/ 115 //包生成子任務 116 task packet_gen; 117 input [16-1:0] length; 118 input [2-1:0] invalid_byte; 119 integer i; 120 begin 121 len[gen_time] = length; 122 mod[gen_time] = invalid_byte; 123 124 for(i = 1;i<=length;i=i+1)begin 125 if(rdy == 1)begin 126 din_vld = 1; 127 if(i==1) 128 din_sop = 1; 129 else if(i == length)begin 130 din_eop = 1; 131 din_mod = invalid_byte; 132 end 133 else begin 134 din_sop = 0; 135 din_eop = 0; 136 din_mod = 0; 137 end 138 din = i ; 139 end 140 141 else begin 142 din_sop = din_sop; 143 din_eop = din_eop; 144 din_vld = 0; 145 din_mod = din_mod; 146 din = din; 147 i = i - 1; 148 end 149 150 #(USER_CLK_CYC*1); 151 end 152 packet_initial; 153 gen_time = gen_time + 1; 154 end 155 endtask 156 157 task packet_initial; 158 begin 159 din_sop = 0; 160 din_eop = 0; 161 din_vld = 0; 162 din = 0; 163 din_mod = 0; 164 end 165 endtask 166 167 //包檢測子任務 168 task packet_check; 169 integer k; 170 integer num,packet_len; 171 begin 172 num = 1; 173 $fdisplay(fid,"%dth:Packet checking...\n",chk_time); 174 packet_len = 4*len[chk_time]-mod[chk_time]; 175 if(j != packet_len)begin 176 $fdisplay(fid,"Length of the packet is wrong.\n"); 177 err_flag = 1; 178 disable packet_check; 179 end 180 181 for(k=0;k<packet_len;k=k+1)begin 182 if(k%4 == 3)begin 183 if(dout_buf[k] != num)begin 184 $fdisplay(fid,"Data of the packet is wrong!\n"); 185 err_flag = 1; 186 end 187 num = num+1; 188 end 189 else if(dout_buf[k] != 0)begin 190 $fdisplay(fid,"Data of the packet is wrong,it should be zero!\n"); 191 err_flag = 1; 192 end 193 end 194 chk_time = chk_time + 1; 195 end 196 endtask 197 198 endmodule