Verilog中calc任务输出传入clk_gen后为0?求原因分析
问题分析与解答
核心问题:变量类型不匹配导致数据截断
你的代码存在变量类型不兼容的关键问题,这直接导致clk_gen输出ton=0, toff=0,下面逐个解答你的疑问:
1. 为何不是ton=24, toff=16?
calc任务的输出参数ton、toff是real类型,计算结果确实为24和16,但你在initial块里声明的接收变量:
reg ton; reg toff;
是1位宽度的reg类型(Verilog中未指定宽度的reg默认是1位)。当把real类型的24(二进制11000)、16(二进制10000)赋值给1位reg时,只会保留二进制最低位(即0),所以传给clk_gen的实际值就是0,自然无法得到24和16。
2. 为何不是ton=x, toff=x?
reg变量默认初始值是x,但你在initial块里先调用了calc任务,已经对ton、toff完成赋值(即使类型不匹配),变量被覆盖为0,而非保持初始的x。
3. 为何结果是ton=0, toff=0?
结合两点原因:
- 1位reg仅能存储0或1,24和16的二进制最低位都是0,赋值后变量值为0;
clk_gen中使用%0b(二进制格式符)打印real类型变量,属于格式不匹配,会加剧输出异常,但核心原因还是类型不匹配导致传入的值本身就是0。
修正后的代码
保证变量类型一致,将接收ton、toff的变量改为real类型,同时修正clk_gen的打印格式符:
`timescale 1ns / 1ps module newm(); reg clk=0; real period = 40; reg clk2 =0; always #5 clk2 = ~ clk2; // 通过calc任务计算ton和toff task calc(input real dutycycle,input real period,output real ton,output real toff); ton = dutycycle * period; toff = (1-dutycycle) * period ; $monitor("values inside calc, ton = %0d ,toff = %0d",ton,toff); endtask // 在clk_gen中使用ton和toff task clk_gen(input real ton,input real toff); $monitor("values inside clk_gen ,ton = %0d ,toff = %0d",ton,toff); @(posedge clk2); forever begin clk =1; #ton; clk= 0; #toff; end endtask // 运行代码 real ton; // 改为real类型 real toff; initial begin calc(0.6,period,ton,toff); clk_gen(ton,toff); end initial begin #200; $finish(); end endmodule
内容的提问来源于stack exchange,提问作者Sharathraj M
相关产品推荐
相关产品推荐

