第1个回答 2021-03-31
先说结论,可以用,但是分时候,不会用的时候别乱用。
你老师说的计数器xx,可能是让你写计数器的时候别用for循环,软硬件编程思维的不同。写一个计数器表示一段延时,软件编程的思维肯定的是用for循环,软件的执行是顺序执行,也就是一直处于这个循环中,直到不满足循环计数条件而跳出循环。
而硬件中的计数器实现直接就是一组D触发器,根据计数器的使能,加上在时钟边沿触发变化,再加上一个清零端(还可以加置位端)。软件和硬件这两个可以说,完全不是一个东西。
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt <= 3'd0;
else if(cnt_clear)
cnt <= 3'd0;
else if(cnt_en)
cnt <= cnt + 1'd1;
end
如果我想实现软件思维的delay一段时间怎么做,直接用上面的计数器做一个flag
assign flag = cnt == 3'd3;
当cnt == 3‘d3时,我输出一个flag,表示我这段延时的标志。
i的变化不跟时钟走吗?
在Verilog中使用for循环的功能就是,把同一块电路复制多份,完全起不到计数的作用,所以这个i的意思是复制多少份你这段代码实现的电路,和时钟没有任何关系。主要是为了提高编码效率。
这个配图的功能就是把这块电路,复制stages_num份,然后每个clk下,执行的内容操作是相同的。所以能实现在复位时刻,把整个寄存器都赋值为0,然后复位释放执行其他操作。(这个图为题主提供)
题主提供图
什么时候用
可以用,那么什么时候用,代码设计有规律的时候,可以配合generate for,合理使用generate+for循环可以提高编码效率,同样的赋值语句需要赋值多次。这个generate语句里面可以是任何有运算。
generate
genvar i;
for(i = 0;i < 16;i = i + 1)
begin: neg_data
assign neg_data_out[i*DATA_WIDTH +:DATA_WIDTH] =
-data_in[i*DATA_WIDTH +:DATA_WIDTH]
end
endgenerate
同一个模块需要实例化多次也可以,比如这里有一个运算需要调用16个乘法器,如果把乘法器IP模块实例化16份,那岂不是要写很长的代码,所以用generate+for可以极大的提高编码效率。
第2个回答 2010-11-06
begin
clk = 0;
forever #10 clk = !clk;
end
这样可以产生一个周期信号
这是Modelsim给的例test bench中给的方案(tcount.v),在modelsim中可以正常运行。
在quartus中仿真count.v(原module),把tcount.v在test bench中调用,仿真时可以正常通过。但如果单独仿真tcount.v,会报和你一样的错误。
这个错误按字面意思是“与非恒定循环条件循环必须终止在250次迭代”,具体原因我也不知道
第3个回答 2021-03-31
先说结论,可以用,但是分时候,不会用的时候别乱用。
你老师说的计数器xx,可能是让你写计数器的时候别用for循环,软硬件编程思维的不同。写一个计数器表示一段延时,软件编程的思维肯定的是用for循环,软件的执行是顺序执行,也就是一直处于这个循环中,直到不满足循环计数条件而跳出循环。
而硬件中的计数器实现直接就是一组D触发器,根据计数器的使能,加上在时钟边沿触发变化,再加上一个清零端(还可以加置位端)。软件和硬件这两个可以说,完全不是一个东西。
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt <= 3'd0;
else if(cnt_clear)
cnt <= 3'd0;
else if(cnt_en)
cnt <= cnt + 1'd1;
end
如果我想实现软件思维的delay一段时间怎么做,直接用上面的计数器做一个flag
assign flag = cnt == 3'd3;
当cnt == 3‘d3时,我输出一个flag,表示我这段延时的标志。
i的变化不跟时钟走吗?
在Verilog中使用for循环的功能就是,把同一块电路复制多份,完全起不到计数的作用,所以这个i的意思是复制多少份你这段代码实现的电路,和时钟没有任何关系。主要是为了提高编码效率。
这个配图的功能就是把这块电路,复制stages_num份,然后每个clk下,执行的内容操作是相同的。所以能实现在复位时刻,把整个寄存器都赋值为0,然后复位释放执行其他操作。(这个图为题主提供)
题主提供图
什么时候用
可以用,那么什么时候用,代码设计有规律的时候,可以配合generate for,合理使用generate+for循环可以提高编码效率,同样的赋值语句需要赋值多次。这个generate语句里面可以是任何有运算。
generate
genvar i;
for(i = 0;i < 16;i = i + 1)
begin: neg_data
assign neg_data_out[i*DATA_WIDTH +:DATA_WIDTH] =
-data_in[i*DATA_WIDTH +:DATA_WIDTH]
end
endgenerate
同一个模块需要实例化多次也可以,比如这里有一个运算需要调用16个乘法器,如果把乘法器IP模块实例化16份,那岂不是要写很长的代码,所以用generate+for可以极大的提高编码效率。
generate
genvar i;
for(i = 0;i < 16;i = i + 1)
begin: mult_12x12
DW02_mult #(
.A_WIDTH(12),
.B_WIDTH(12)
) u_DW02_mult0(
.A(mult_a[i*12 +:12]),
.B(mult_b[i*12 +:12]),
.TC(1’b0),
.PRODUCT(product[i*24 +:24])
);
end
endgenerate
当然这样写debug会有一些困扰,不容易找到信号对应位宽数据。不过Verdi会显示每一个generate块,选中对应的块,加进去的波形就会是对应的bit信号。
第4个回答 推荐于2017-10-09
如果想输出周期为20个
时间单位的方波,格式如下:
forever
begin
#0 clk=0;
#10 clk=1;
#10 clk=0;
end
或者
always #10 clk=~clk
希望我的回答能解决您的问题!本回答被提问者采纳