在 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
并不是真正暗示有效的硬件结构。
在某种程度上,您在敏感列表中有两个姿势,一个没有被用于异步重置或设置。这意味着您已经创建了一个带有两个时钟输入的触发器。这种硬件结构根本不存在
除此之外使用数据信号(完成)作为时钟会导致合成时出现各种时序问题。将此设计想象成更大系统的一部分,并且您必须平衡所有时钟树,如果您不将数据和时钟分开,这将变得非常困难甚至几乎不可能。
我有 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
并不是真正暗示有效的硬件结构。
在某种程度上,您在敏感列表中有两个姿势,一个没有被用于异步重置或设置。这意味着您已经创建了一个带有两个时钟输入的触发器。这种硬件结构根本不存在
除此之外使用数据信号(完成)作为时钟会导致合成时出现各种时序问题。将此设计想象成更大系统的一部分,并且您必须平衡所有时钟树,如果您不将数据和时钟分开,这将变得非常困难甚至几乎不可能。