计数器的verilog同步问题
verilog sync issue with counter
我正在尝试创建一个 8 位并行到串行组件来发送数据和位数。
位号和传输的串行数据没有在正确的时间发送,
请看波形
module counter
(
input clk,rst,
input [7:0]data,
output reg [7:0]cnt,
output reg data_Tx
);
parameter lim = 7;
always @(posedge clk or negedge rst)
if (!rst)
begin
cnt <= 0;
data_Tx <= 1'b1;
end
else
begin
if (clk)
begin
if (cnt < lim)
begin
data_Tx <= data[cnt];
cnt <= cnt +1;
end
else
cnt <= 0;
end
end
endmodule
please see wave form here
我已经在波形(蓝色)上标记了应该传输的比特数,正如你所看到的,它们被移动了。
另外,在红色圆圈中,当从并行输入传输第一位时,data_Tx 需要为“0”,但由于第一行我是“1”,我该如何解决这个情况?
我应该使用状态机吗???
谢谢
您已陷入所有 HDL 初学者都会遇到的标准陷阱:您的信号在 之后 时钟边沿发生变化。花几个月的编码时间,处理这个问题就成了第二天性。
但在我处理之前:听从 Greg 的建议并从代码中删除 if (clk)
。
第一个简单的解决方案是将 data_Tx <= data[cnt];
移到时钟部分之外:
assign data_Tx = data[cnt];
但请注意,在重置后(当 cnt 为零时),data_Tx
位会反映您的 data[0]
位。所以不能保证它是 1。一旦将新值分配给 data
,它就会改变。
如果您想要同步 data_Tx
输出并希望 cnt
内联,您必须将 cnt
延迟一个时钟周期:
....
reg [2:0] early_cnt;
always @(posedge clk or negedge rst)
if (!rst)
begin
cnt <= 0;
early_cnt <= 8'h00;
data_Tx <= 1'b1;
end
else
begin
cnt <= early_cnt;
if (early_cnt < lim)
begin
data_Tx <= data[early_cnt];
early_cnt <= early_cnt + 8'h01;
end
else
early_cnt <= 0;
end
我正在尝试创建一个 8 位并行到串行组件来发送数据和位数。 位号和传输的串行数据没有在正确的时间发送, 请看波形
module counter
(
input clk,rst,
input [7:0]data,
output reg [7:0]cnt,
output reg data_Tx
);
parameter lim = 7;
always @(posedge clk or negedge rst)
if (!rst)
begin
cnt <= 0;
data_Tx <= 1'b1;
end
else
begin
if (clk)
begin
if (cnt < lim)
begin
data_Tx <= data[cnt];
cnt <= cnt +1;
end
else
cnt <= 0;
end
end
endmodule
please see wave form here
我已经在波形(蓝色)上标记了应该传输的比特数,正如你所看到的,它们被移动了。
另外,在红色圆圈中,当从并行输入传输第一位时,data_Tx 需要为“0”,但由于第一行我是“1”,我该如何解决这个情况?
我应该使用状态机吗???
谢谢
您已陷入所有 HDL 初学者都会遇到的标准陷阱:您的信号在 之后 时钟边沿发生变化。花几个月的编码时间,处理这个问题就成了第二天性。
但在我处理之前:听从 Greg 的建议并从代码中删除 if (clk)
。
第一个简单的解决方案是将 data_Tx <= data[cnt];
移到时钟部分之外:
assign data_Tx = data[cnt];
但请注意,在重置后(当 cnt 为零时),data_Tx
位会反映您的 data[0]
位。所以不能保证它是 1。一旦将新值分配给 data
,它就会改变。
如果您想要同步 data_Tx
输出并希望 cnt
内联,您必须将 cnt
延迟一个时钟周期:
....
reg [2:0] early_cnt;
always @(posedge clk or negedge rst)
if (!rst)
begin
cnt <= 0;
early_cnt <= 8'h00;
data_Tx <= 1'b1;
end
else
begin
cnt <= early_cnt;
if (early_cnt < lim)
begin
data_Tx <= data[early_cnt];
early_cnt <= early_cnt + 8'h01;
end
else
early_cnt <= 0;
end