📄 tests.v
字号:
$display("\n\nGetting descriptor ...");send_setup( 8'h12, // Function Address 8'h80, // Request Type GET_DESCRIPTOR, // Request 16'h0301, // wValue,字符串描述符,索引值为1,看看这个返回的到底是什么!! 16'h0, // wIndex 16'd010 // wLength,长度为10字节 );data_in( 8'h12, // Function Address 8'd010 // Expected payload size );// Status OKdata_out( 8'h12, // Function Address 8'h0 // Expected payload size );$display("\n\nGetting descriptor ...");send_setup( 8'h12, // Function Address 8'h80, // Request Type GET_DESCRIPTOR, // Request 16'h0302, // wValue,字符串描述符,索引值为2 16'h0, // wIndex 16'd08 // wLength,长度为8字节 );data_in( 8'h12, // Function Address 8'd08 // Expected payload size );// Status OKdata_out( 8'h12, // Function Address 8'h0 // Expected payload size );$display("\n\nGetting descriptor ...");send_setup( 8'h12, // Function Address 8'h80, // Request Type GET_DESCRIPTOR, // Request 16'h0303, // wValue,字符串描述符,索引值为3 16'h0, // wIndex 16'd016 // wLength,长度为16字节 );data_in( 8'h12, // Function Address 8'd010 // Expected payload size );// Status OKdata_out( 8'h12, // Function Address 8'h0 // Expected payload size );$display("\n\nGetting descriptor ...");send_setup( 8'h12, // Function Address 8'h80, // Request Type GET_DESCRIPTOR, // Request 16'h0203, // wValue,配置描述符,索引值为3,索引值可能是个偏移量或指针的概念 16'h0, // wIndex 16'd053 // wLength,长度为53字节 );data_in( 8'h12, // Function Address 8'd053 // Expected payload size );// Status OKdata_out( 8'h12, // Function Address 8'h0 // Expected payload size );show_errors;//这是个任务,注意它的用法$display("*****************************************************");$display("*** Test DONE ... ***");$display("*****************************************************\n\n");endendtasktask in0;//整个任务都是在对端点1进行测试,这点务必铭记在心,端点1是是什么端点的?我记不得了 //`ISO | `IN | 14'd0256 max packet size256字节reg [6:0] my_fa;integer quick, n, m, rlen,fc;reg [7:0] fd;integer pack_cnt, pack_cnt_max;reg [7:0] x;reg [3:0] pid;reg [3:0] expect_pid;reg [31:0] data;reg pid_cnt;begin$display("\n\n");$display("*****************************************************");$display("*** IN ep test 0 ***");$display("*****************************************************\n");send_sof(11'h000 ); // Send SOFpack_sz_max = 64;//这是在top中定义的,可以算个全局变量了,指端点能发送的最大包长度pack_cnt_max = 4;//这个的含义是什么?好象没什么特别的含义,就是测4次的意思pid_cnt = 0;my_fa = 7'h12;//给定设备地址for(pack_sz=0;pack_sz<pack_sz_max;pack_sz=pack_sz+1)//应该是测试各种可能的长度:从0长到64长begin$display("PL size: %0d", pack_sz);for(pack_cnt=0;pack_cnt<pack_cnt_max;pack_cnt=pack_cnt+1)//可以做四次,是什么呢 begin // Fill Buffer,将pack_sz规定数量的字节的待传数据写入端点1的fifo中 buffer1_last = 0;//初始化指针 for(fc=0;fc<pack_sz;fc=fc+1) begin #2; while(ep1_f_full) @(posedge clk);//如果fifo暂时没有地方让设备写数据,就等待 #1; //x = fc[7:0]; x = $random;//随机产生要传输的数据 ep1_f_din = x; buffer0[fc] = x;//备份要传输的数据 ep1_f_we = 1; @(posedge clk);//写使能持续一个时钟周期 #1; ep1_f_we = 0; @(posedge clk); end #1; ep1_f_we = 0; @(posedge clk); // Send Data,因为fifo中有货了,下面准备发送给主机了 repeat(1) @(posedge clk); send_sof(11'h000 ); // Send SOF,为什么又要发送这个??419行已经发送过了 repeat(1) @(posedge clk); send_token( my_fa, // Function Address 1, // Logical Endpoint Number `USBF_T_PID_IN // PID,in pid,主机向设备要数据 ); repeat(1) @(posedge clk); recv_packet(pid,rlen);//要了后就准备接收吧 if(pid_cnt) expect_pid = 4'hb;//data1,这里在搞data0与data1的事, else expect_pid = 4'h3;//data0 expect_pid = 4'h3;//这句这么写,岂不破坏了上面470,471做的工作?正是,因为是同步传输,一直用data0!!!! if(pid !== expect_pid) begin $display("ERROR: PID mismatch. Expected: %h, Got: %h (%t)", expect_pid, pid, $time); error_cnt = error_cnt + 1; end pid_cnt = ~pid_cnt;//其实就是奇偶变 if(rlen != pack_sz) begin $display("ERROR: Size mismatch. Expected: %d, Got: %d (%t)", pack_sz, rlen, $time); error_cnt = error_cnt + 1; end repeat(4) @(posedge clk);// send_token( my_fa, // Function Address,同步传输测试是不需要握手信号的!!// 1, // Logical Endpoint Number// `USBF_T_PID_ACK // PID,收到数据了,发ack信号// );// repeat(5) @(posedge clk); // Verify Data,检测主机收到的数据和原始的数据相比,如果是0长的数据,就跳过这里 for(fc=0;fc<pack_sz;fc=fc+1) begin x = buffer0[fc];//好象原始数据存在buffer0里了 if( (buffer1[fc] !== x) | ( (^buffer1[fc] ^ ^x) === 1'hx) )//后一个条件是干什么的?竟然有个x!! begin $display("ERROR: Data (%0d) mismatch. Expected: %h, Got: %h (%t)", fc, buffer1[fc], x, $time); error_cnt = error_cnt + 1; end end endrepeat(50) @(posedge clk);//等待50个时钟上升沿后结束,然后重新回到427再来endshow_errors;$display("*****************************************************");$display("*** Test DONE ... ***");$display("*****************************************************\n\n");endendtasktask out0;//这里在对端点4进行输出测试,接收来自主机的数据,端点4,`BULK | `OUT | 14'd064reg [6:0] my_fa;reg [31:0] data;integer len, n, no_pack, pl_sz;integer no_pack_max, pl_sz_max;reg pid;reg [7:0] x;begin$display("\n\n");$display("*****************************************************");$display("*** OUT ep test 0 ***");$display("*****************************************************\n");no_pack_max = 4; // Number Of packets to transferpl_sz_max = 128; // Payload Size,是有效载荷no_pack = 4; // Number Of packets to transferpl_sz = 0;my_fa = 7'h12;for(pl_sz=0;pl_sz<pl_sz_max;pl_sz=pl_sz+4)//数据包的有效载荷从0开始,到128,步长为4,分别进行测试beginpid = 0;$display("PL size: %0d", pl_sz);//我知道了,pl就是payload的意思for(n=0;n<4096;n=n+1) //buffer1[n] = $random; buffer1[n] = n;//主机端的buffer,现在里面装的是4096个字节的待传数据buffer1_last = 0;//清零,为了让571行的任务使用fork //注意fork-join是并行结构,这里为什么要用这个结构,这不是分明在为难我吗!!!for(no_pack=0;no_pack<no_pack_max;no_pack=no_pack+1) // Send no_pack Out packets送出去4个包 begin repeat(1) @(posedge clk); send_sof(11'h000 ); // Send SOF,为什么每次帧号都是0? repeat(1) @(posedge clk); send_token( my_fa, // Function Address 4, // Logical Endpoint Number `USBF_T_PID_OUT // PID,通知设备有数据要送出 ); repeat(1) @(posedge clk); if(pid==0) send_data(`USBF_T_PID_DATA0, pl_sz, 1);//不管设备的反映,数据送出去了 else send_data(`USBF_T_PID_DATA1, pl_sz, 1);//这里有一个疑问:如果pl_sz>64怎么办了?因为它比端点 //一次能接收的字节数还大! pid = ~pid;//data0,data1的标志 // Wait for ACK utmi_recv_pack(len);//等设备说话 if(8'hd2 !== txmem[0])//如果设备没有给ack信号 begin $display("ERROR: ACK mismatch. Expected: %h, Got: %h (%t)", 8'hd2, txmem[0], $time); error_cnt = error_cnt + 1; end repeat(1) @(posedge clk); end begin repeat(10) @(posedge clk2);//注意,这里等待了10个clk2的上升沿!!!!!!!!!!!!!!!!!!!!! for(n=0;n<(no_pack_max*pl_sz);n=n+1) // Compare Buffers,每个包的大小为pl_sz,一共四个包 begin #4;//这个4为了什么?为什么是4 ep4_f_re = 0; repeat(1) @(posedge clk2);//又是clk2,小心,弄清楚clk2是干什么的,与clk1一样 while(ep4_f_empty) begin ep4_f_re = 0; repeat(2) @(posedge clk2); end #2;//这个2为了什么?为什么是2 if(buffer1[n] !== ep4_f_dout)//如果要传的数据和收到的数据不同 begin $display("ERROR: DATA mismatch. Expected: %h, Got: %h (%t)", buffer1[n], ep4_f_dout, $time); error_cnt = error_cnt + 1; end ep4_f_re = 1; @(posedge clk2);//又过了一个clk2 end #1;//这个1是为了什么,我发誓一定要搞清楚!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ep4_f_re = 0; @(posedge clk2); endjoinrepeat(1) @(posedge clk);endshow_errors;$display("*****************************************************");$display("*** Test DONE ... ***");$display("*****************************************************\n\n");endendtask
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -