计数器的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