在 2 always 块中更改 reg 值的提示是什么?

What is the tip for change the value of a reg in 2 always block?

我有 2 个 always 块和一个 finish_bcd 线信号,以便仅检测转换是否完成。 转换后,我想把它放在 0 但它在另一个 always 块中...

wire finish_bcd;

bin2bcd BinTBcd (
 .binary(data),
 .thousands(w1),
 .hundreds(w2),
 .tens(w3),
 .ones(w4),
 .finish(finish_bcd)  //################ line 53
);

always @(posedge finish or posedge finish_bcd) begin
    if (finish_bcd == 1) begin
        case(enable)
            5'b00000: enable <= 5'b00001; //send the thousands
            5'b00001: enable <= 5'b00010; //send the hundreds
            5'b00010: enable <= 5'b00100; //send the tens
            5'b00100: enable <= 5'b01000; //send the ones
            5'b01000: enable <= 5'b10000; //send a ";"
            5'b10000: enable <= 5'b00000; // Everything is sent, I would like to do 'finish_bcd = 0;' here, at the end of the process in this always block.
            default: enable <= 5'b00000;
        endcase 
    end
end

bin2bcd 模块是:

module bin2bcd (
    input [10:0] binary,
    output reg [3:0] thousands,
    output reg [3:0] hundreds,
    output reg [3:0] tens,
    output reg [3:0] ones,
    output reg finish);

integer i;

always @(binary) begin
    // set 100's, 10's, and 1's to zero
   thousands = 4'b0;
   hundreds = 4'b0;
   tens = 4'b0;
   ones = 4'b0;

   for (i=10; i>=0; i=i-1) begin
       // add 3 to columns >= 5
       if (thousands >= 5)
           thousands = thousands + 3;         
       if (hundreds >= 5)
           hundreds = hundreds + 3;
       if (tens >= 5)
           tens = tens + 3;
       if (ones >= 5)
           ones = ones + 3;
        // shift left one
       thousands = thousands << 1;
       thousands[0] = hundreds[3];
       hundreds = hundreds << 1;
       hundreds[0] = tens[3];
       tens = tens << 1;
       tens[0] = ones[3];
       ones = ones << 1;
       ones[0] = binary[i];
   end

     finish <= 1;  //############ line to detect when the conversion is done

end
endmodule

另一个问题:为什么我不能只更改顶部模块中的 "reg finish_bcd;"?

我遇到了这个错误line 53 Reference to scalar reg 'finish_bcd' is not a legal net lvalue

我将为 Xilinx FPGA 综合此代码。

编辑:

我有一个二进制字,我想通过串行通信发送它然后我将这个二进制(11 位)转换为 BCD 以便发送 ASCII 码。 我想每次 "binary" 更改时发送。 finish_bcd用于检测转换何时完成,以便开始发送数据。 always @(posedge finish or posedge finish_bcd) begin 块用于更改状态(为了发送数千然后数百等...

然后,binary改变,转换完成,finish_bcd = 1,它开始发送数据(数千等...)每个发送的结束用[=18=检测] 一切都在模拟中工作,但由于 finish_bcd 不会变为 0,因此当它发送所有数字时,它会停止。我需要在最后重置 finish_bcd 以检测新的 binary 更改并开始发送新值。

谢谢。

always @*是组合,这个需要零时间模拟。对于状态机,您需要使用时钟并暗示状态触发器。

组合逻辑不能保持状态,因此它本身对状态机没有好处。 Moore FSM 中经常使用组合部分来将状态解码为输出(基于状态)。

bin2bcd 模块是组合的,因为没有使用时钟或触发器来使它花费超过 1 个时钟周期,这意味着它需要 0 个时钟周期。您已经使用了 for 循环,您可能指的是需要执行多少次循环,for 循环指定 10。但这是组合的,因此您暗示并行硬件负载,仅仅因为它是 verilog 中的循环并不意味着它重用比较器。如果你想最小化硬件并用 10 个时钟周期来计算结果,你需要构建一个状态机来控制和排序它。

第 2 部分

posedge finish or posedge finish_bcd 并不是真正暗示有效的硬件结构。

在某种程度上,您在敏感列表中有两个姿势,一个没有被用于异步重置或设置。这意味着您已经创建了一个带有两个时钟输入的触发器。这种硬件结构根本不存在

除此之外使用数据信号(完成)作为时钟会导致合成时出现各种时序问题。将此设计想象成更大系统的一部分,并且您必须平衡所有时钟树,如果您不将数据和时钟分开,这将变得非常困难甚至几乎不可能。