我正在尝试在我的一个模块中实现data_valid信号。到目前为止,我想到了使用计数器的解决方案。同样,当我有一个有效的输入时,我将打开使能引脚以开始处理数据。
我实现的模块需要 5个时钟周期来产生有效的输出数据。这个想法是要计数到5个时钟周期,然后再将有效信号设置为高电平然后在提供有效数据后重置计数器。
以下是一个简短的示例版本,我想在1个周期后获取有效数据的地方要做的事情。但显然,它并不能很好地工作,我无法确切指出我缺少的地方东西。
示例代码:
module control_unit (
input [3:0] a,
input [3:0] b,
input [3:0] m,
input clk,
input enable,
input nreset,
output data_valid,
output [7:0] o
);
reg [7:0] r1;
reg [4:0] c;
reg count;
always @(posedge clk or negedge nreset)
begin
if (~nreset) count <= 1'b0;
else if (enable)
count <= count+1'b1;
else count = count;
end
assign data_valid = (count == 1'b1) ? 1'b1 : 1'b0;
always @(posedge clk)
begin
c <= a+b;
r1 <= c[3:0]*m;
end
assign o = r1;
endmodule
测试台代码:
`timescale 1ns/10ps
module tb_control_unit (
);
reg clk;
reg enable;
reg nreset;
wire data_valid;
reg[3:0] a,b,m;
wire [7:0] o;
control_unit control_unit_i (
.clk(clk),
.enable(enable),
.nreset(nreset),
.data_valid(data_valid),
.a(a),
.b(b),
.m(m),
.o(o)
);
parameter CLKPERIODE = 10;
initial clk = 1'b1;
always #(CLKPERIODE/2) clk = !clk;
initial enable = 1'b1;
initial begin
a = 4'b0001;
b = 4'b0001;
m = 4'b0010;
#10 nreset =1'b0;
//#20 nreset =1'b1;
#20 a = 4'b0010;
b = 4'b0010;
m = 4'b0001;
#100 $finish();
end
endmodule
请注意:代码的当前状态代表了根据我的初学者技能进行的多次试用的版本。
我面临的问题是,data_valid信号在前几个时钟周期内未正确提供任何输出,并且由于该原因,我的计数器不同步(可能是assign语句是许多原因之一?)>
总结起来,
问题:
我的概念有什么问题吗? 如何根据控制信号从一开始就保持正确的计数?
请记住,一天结束时我将进行综合,并且我的项目的条件是使用最少的面积。
那么,实现此条件的最佳方法是什么:“如果count == 5”,“ data_valid <= 1'b1”?
答案 0 :(得分:1)
首先,如Serge所说:为什么不给它重新设置?
第二:
想法是计数到5个时钟周期,然后将有效信号设置为高
但是您的比较者说:data_valid = (count == 1'b1) ...
为什么要与一个比较?
第三:
valid_input到达然后==> enable = 1,
但是您的代码却相反:有效是从enable派生的。
第四:count
仅是一位。您可以计数0,1就是这样。要计数到五个,您需要使其增大,至少3位。
第五:使用完计数器后不要将其放回原处。它一直在计数,因此它将翻转并重新开始,并且使用3位计数器,您将在每8个时钟周期获得data_valid
。
我建议您修复所有问题,然后重试。