verilog 通过function 递归, 数据拓展

此博客展示了使用Verilog HDL编写的模块和函数,用于处理和转换数据。主要内容包括定义参数NBYTES,创建reg类型的变量tb_stream和realstream,以及一个packet变量。通过initial begin块初始化数据,将packet的每个字节复制到tb_stream中。然后调用getrealstream函数,该函数接收一个stream和字节数,并返回一个经过处理的realstream。在函数内部,遍历stream并根据nbytes填充realstream,其余位置填充0。博客着重于理解Verilog中的数据操作和自定义函数的使用。

module test();

 

  parameter NBYTES      = 4   ;

 

  reg [511:0] tb_stream       ;

  reg [511 : 0] realstream    ;

  reg [31  : 0]        packet ;

 

  initial begin

数字电路设计中,下列哪种手段无法消除竞争冒险现象(d)a.    加滤波电容,消除毛刺b.    增加冗余项消除逻辑冒险c.    增加选通信号,避开毛刺d.    降低时钟频率解析:在同步电路中,降低时钟频率可以让寄存器采集数据的时候更容易满足setup check,也就更容易避开毛刺。因为假定时序路径延时不变,频率降低使时钟沿后移,setup time不变的情况下给了更多的timing margin使毛刺恢复。但与前3个选项相比,这不是从根本上消除毛刺,该毛刺信号还是会被电路传递,只不过降低了setup违例的风险。而在异步电路中,不论时钟频率是多少,毛刺都有被下游寄存器采集的风险。 2. 异步时钟数据采样的方法错误的是(d)a.    单bit高频时钟脉冲展宽后给低频时钟进行采样b.    握手信号后再采样c.    使用fifo隔离进行多bit的采样d.    高频时钟直接采样低频时钟的多bit数据 解析:多bit数据存在各bit到达采样点的时刻不同的问题,直接采样可能会采集到错误的数据。要通过握手或者fifo或者格雷码转换单bit等方式进行多bit数据传输。 3. 以下不能对多bit的数据总线的时钟异步处理的是:(c)a.    Dmux synchronizerb.    Gray-codec.    寄存器同步d.    AFIFO解析:同上一题,多bit数据总线不能直接用寄存器同步方式进行异步处理。 4. 一个4bit位宽的有符号数a=4’b1001取绝对值后的值为abs(a)=4’b0110(错误) 5. 对于两个位宽相同的无符号数a和b, a>b和a<b两个比较器面积是一样的(正确) 6. 组合逻辑电路的特点是输出信号只是该时刻输入信号的函数,它是无记忆功能的。时序逻辑电路的特点是任何时刻产生的稳定输出信号不仅与该时刻输入信号有关,而且与它过去的状态有关(正确) 7. 高的功能覆盖率意味着高的代码覆盖率(错误)解析:功能覆盖率和代码覆盖率没有直接的关系。功能覆盖率主要表征测试点关注信号的翻转情况。代码覆盖率包括了:信号翻转覆盖率,条件覆盖率和代码行覆盖率。可以想象一个极端场景:DUT是一个CPU,测试点只观察CPU里的加法器。加法器测全了,功能覆盖率高了,但是代码只测了冰山一角。如果反过来表达,高的代码覆盖率也同样不意味着高的功能覆盖率。假设DUT是一个8bit无符号加法器,测试两个向量:a=b=8’b1111_1111,和a=b=8’b0理论上就能基本将代码覆盖率打满,但是这只是所有操作数组合的其中两个,很明显功能覆盖率不可能高。 8. 为了发现逻辑缺陷,要想到什么测什么,一定要遍历所有可能(错误)解析:头脑风暴挖掘测试点是必须的,但是要保证测试点是符合规格说明和约束的,并且是可能会发生的场景。 9. 在verilog中,关于函数,不正确的是(无)a.    函数可以调用其他函数b.    函数只能返回一个值c.    函数必须至少带有一个输入d.    不能包含任何时延或时延控制解析:这个题目a,b,c,d都是正确的。 10. 在systemverilog中,任务task可以调用函数function(正确) 11. 下面哪个语句是可以综合的(c)   a. initial过程块   b. forever 循环语句   c. for循环语句   d. fork join解析:for循环语句多用在多bit信号的同类型操作或者递归操作上。可以放在组合逻辑always块中,或者与generate结合使用。Initial, forever和fork join主要用在验证环境的进程控制上。 12. 同步时序电路和异步时序电路比较,其差异在于后者(c)a. 没有触发器b. 没有稳定状态c. 没有统一的时钟脉冲控制d. 输出只与内部状态有关解析:异步时序电路是一种没有全局时钟的设计,所以c是正确的。异步时序电路有多种设计方式,有的设计方式会使用到触发器。并且是有稳定状态的。输出与内部状态和输入都有关系。因此a,b,d都错误。 13. 在模块实例化语句中,悬空端口可通过将端口表达式表示为空白指定为悬空。模块的输入端悬空值为(d)a. 0b. xc. 1d. z解析:模块输入不允许有悬空值。悬空则没有驱动,为高阻态z。 14. 下列电路中属于时序逻辑电路的是(b)a.    译码器b.    计数器c.    编码器d.    数据选择器解析:一般来说计数器每个周期统计一次进行累加,需要依赖于前一个周期的状态。其他三种基本电路都是组合逻辑,不需要依赖于过去的状态。 15. 以下说法错误的有(a)a. 为了避免wire信号出现x态,最好是在声明时,赋初始值0b. 一个模块例化多次,可以使用generatefor循环减少代码c. 模块例化时,需要将端口显式列出,即使某个端口未连接信号d. 循环表达式的循环次数必须为常数解析:如果声明时将wire信号先赋初始值0,而后使用assign语句,相当于多驱动电路,很明显是错的。只有在组合逻辑的always块中可以先将输出信号赋初始值0。 16. 某个状态下,不关心某个寄存器的输出值,那么将其设计为输出0,可以降低功耗(错误)解析:比起设计为输出0,降低功耗更好的做法是保持寄存器原值。因为功耗来自于信号toggle,如果在上一状态寄存器输出为1,下一状态下输出为0,即便0不使用,也产生了0到1的跳变,同样会有功耗,既然不关心,还不如保持输出为1。 17. 高频时钟域的数据总线(每时钟周期都变化)传递给低频时钟域,哪种同步方式正确?(b)a.    使用握手信号进行同步b.    使用异步fifoc.    使用同步fifod.    使用打2拍进行同步解析:c和d很明显错误。多bit数据不能使用打两拍同步。这道题的难点在于a选项。一般而言握手信号可以用于高频时钟域到低频时钟域的同步,但是为了保证数据不被漏采,从高频到低频握手信号valid_tx需要做信号宽度拓展,至少拓展为1.5个周期的rx时钟,因此相应的数据data_tx也要保持多个n个tx周期不变,n=1.5*clk_rx/clk_tx。这与题目条件数据总线每周期都变化相矛盾。因此只有b是正确的。 18. 同步电路设计中出现setup time不满足,不可以采用下面哪种措施解决(d)a.    减小信号延迟b.    Pipelinec.    降低时钟频率d.    增加时钟频率解析:setup time是由于时序路径延迟td+tsetup > tclk,而增加时钟频率则减小tclk,保持前两项不变,相当于恶化了setup time的满足。 19. 编写verilog程序时,变量的定义不可与关键字冲突(正确) 20. 关于亚稳态描述正确的是(d)a. 异步逻辑不会产生亚稳态b. 采用格雷码能消除亚稳态c. 亚稳态不会传递,所以不会导致相关逻辑处于不确定态d. 在时钟有效延的时候外部数据未稳定,导致触发器不能判断数据电平的状态
最新发布
10-25
<think>好的,我现在需要回答用户关于Verilogfunction和task在递归操作及静态存储方面的区别的问题。首先,我需要回忆一下Verilog的基本知识,尤其是关于function和task的特性,以及它们的存储机制。 根据用户提供的引用资料,Verilog早期的版本中,function和task都是静态存储的,也就是说无论调用多少次,它们都使用同一个内存地址,无法保存每次调用的独立数据。这会影响递归操作,因为递归需要每次调用都有自己的存储空间来保存参数和局部变量。然而,SystemVerilog引入了动态生命期的支持,允许递归调用,但用户的问题可能集中在传统Verilog的情况。 接下来,我需要比较function和task的不同之处。根据引用[3],函数不能包含延迟、事件或时序控制语句,而任务可以。此外,函数必须有至少一个输入,返回一个值,而任务可以有多个输入输出,不返回值。这些特性会影响它们在递归中的使用可能性。 关于递归,传统Verilog的静态存储意味着每次调用function或task时,它们的局部变量会被覆盖,无法正确保存递归层次的数据,所以递归无法正常工作。而SystemVerilog可能通过自动或动态存储解决了这个问题,但用户的问题可能更关注传统Verilog的情况。 现在需要将这些信息结构化,分点说明function和task在递归和存储上的区别,并引用提供的资料作为支持。需要确保使用正确的中文术语,并遵循用户给出的格式要求,比如行内数学表达式使用$...$,独立公式用$$...$$,不过这个问题可能不涉及数学公式,所以可能不需要使用。但需要检查是否有必要的地方加入。 另外,用户要求生成相关问题,我需要考虑与Verilogfunction和task相关的其他问题,比如使用场景、优化方法、与SystemVerilog的区别等。 最后,确保回答中引用的部分正确标注引用标记,如[^1]、[^2]、[^3],并且在末尾列出相关参考文献。同时,结构要清晰,分点回答,帮助用户逐步理解。</think>关于Verilog中$function$和$task$在递归操作及静态存储的区别,以下从五个维度对比分析: ### 一、静态存储特性 1. **Verilog默认存储机制** Verilog中所有$function$和$task$默认采用**静态存储**,无论被调用多少次,其内部变量始终共享同一物理内存地址。这意味着: - 递归调用时,前一次调用的变量值会被后一次覆盖 - 无法实现真正的递归操作(如阶乘计算) ```verilog function automatic integer factorial; // SystemVerilog需加automatic修饰 input integer n; begin if(n <= 1) factorial = 1; else factorial = n * factorial(n-1); end endfunction ``` ### 二、递归支持差异 | 特性 | $function$ | $task$ | |-----------------|---------------------------------------------------------------------------|------------------------------------------------------------------------------| | **递归可行性** | 传统Verilog不可行,SystemVerilog需声明为`automatic` | 传统Verilog完全不可行 | | **变量独立性** | 静态存储导致多级调用互相干扰 | 同左 | | **应用场景** | 纯组合逻辑计算 | 包含时序控制的操作 | ### 三、参数传递机制 1. **$function$参数规则** - 至少需要1个输入参数 - 通过返回值传递结果 - 示例:`function [7:0] sum(input [3:0] a, b);` 2. **$task$参数规则** - 可包含输入/输出/双向参数 - 通过输出参数传递多个结果 - 示例:`task read_mem(output [31:0] data, input [15:0] addr);` ### 四、时序控制能力 $$ \text{时序控制支持度} = \begin{cases} \text{禁用} & \text{在} function \text{中} \\ \text{允许} & \text{在} task \text{中} \end{cases} $$ - $function$禁止包含`#delay`、`@(posedge clk)`等时序控制语句 - $task$可完整支持时序控制语句,常用于仿真场景 ### 五、SystemVerilog扩展 SystemVerilog通过`automatic`修饰符实现动态存储: ```systemverilog task automatic recursive_task; input [31:0] depth; begin if(depth > 0) recursive_task(depth-1); end endtask ``` 此时每次调用都会创建独立存储空间,支持递归操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lhwcake

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值