• 【深入浅出玩转FPGA学习11----Testbench书写技巧1】


    深入浅出玩转FPGA学习11----Testbench书写技巧1

    封装有用的子程序

    在C语言中,有经验的软件工程师一定会为经常使用的一段代码写一个子程序,然后通过不同的参数对其进行调用。这样做可以达到代码复用的效果,减少了不必要的重复劳动,也使得代码相对简捷一些。在Testbench中也可以使用task进行代码的封装,它能够和C语言的子函数一样被灵活调用。
    下面的例子给出一段很实用的封装子程序,也许在每个工程的测试脚本中都可以排上用场。

    // 封装一些做测试时有用的报告显示
    //包括任务error, warning, fatal, terminate
    module print_task();
    //显示warning报告,同时包含显示当前时间和警告内容(由用户输入)
    task warning;
    		input [80*8:1] msg;
    		begin
    				$write("WARNING at %t: %s", $time,msg);
    		end
    endtask
    //显示error 报告,同时包含显示当前时间和错误内容(由用户输入)
    task error;
    		input [80*8:1] msg;
    		begin
    				$write("-ERROR- at %t: %s", $time, msg);
    		end
    endtask
    //显示fatal报告,同时包含显示当前时间和致命内容(由用户输入)
    task fatal;
    		input [80*8:1] msg;
    		begin
    				$write(" *FATAL* at %t: %s", $time, msg);
    		terminate;
    		end
    endtask
    //显示warning 报告,同时包含显示当前时间和结束信息(该任务生成)
    task terminate;
    		begin
    				$write("Simulation completed\n");
    				$ finish;
    		end
    endtask
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    在使用封装子程序时,如下代码所示:

    //使用print_task.v,后面就可以调用其封装好的task了
    print_task print();
    ...
    initial begin
    if (...) print.error("Unexpected response\n"); //调用error任务
    ...
    print.terminate; //调用terminate任务
    end
    ...
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    关于变量的定义

    在编写Testbench时,关于变量的定义常犯的错误就是将一个定义好的全局变量应用到了两个不同的always块中(如EX1C),那么由于这两个always块独立并行的工作机制,很可能会导致意想不到的后果。

    EX1C:
    interger i;
    always begin
    		for(i=0; i<32; i=i+1) begin
    		end
    end
    always begin
    		for(i=0; i<32;i=i+1) begin
    				...
    	   end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    实际上,在Verilog中(编写Testbench时),如果在begin…end 之间定义了always的块名,那么可以如EX1C一样申明变量。这样两个always块里的变量i就互不相关,也就不会产生不可预料的结果了。

    EX2C:
    
    always begin
    		integer i;
    		for(i=0; i<32; i=i+1) begin
    		...
    		end
    end
    always
     begin: block_2
     		integer i;
    		for(i=0; i<32;i=i+1) begin
    				...
    	   end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    除此以外,在Verilog中的function和task也支持类似上面的局部变量定义。

    HDL的并行性

    为什么C不能取代Verilog和VHDL作为硬件描述语言?因为C缺少了硬件描述最基本的3个思想:连通性(connectivity)、时间性(Time)和并行性(Concurrency)。
    连通性是使用一个简单并相互连接的模块来描述设计的能力,原理图设计工具就是连通性完美的支持工具。
    时间性是表现设计状态演进的时间变化的能力,这个能力不同于衡量一个代码执行所用的时间。
    并行性是描述同时发生相互独立的行为的能力。

  • 相关阅读:
    HRNet高分辨率网络用于人体2D姿态评估
    【MySQL】查询语句
    中电金信:技术实践|Flink维度表关联方案解析
    Mockito Spies InjectMocks & 回调测试
    0成本LLM微调上手项目,⚡️一步一步使用colab训练法律LLM,基于microsoft/phi-1_5,包含lora微调,全参微调
    SpringBoot集成WebSocket--------Spring方式集成(一)
    flutter 运行ios模拟器报错
    链路ID通过MDC实现线程间传递
    计算机网络 静态路由及动态路由RIP
    万物皆可集成系列:低代码对接企企云实现数据集成
  • 原文地址:https://blog.csdn.net/qq_38617667/article/details/125952220