System verilog 如何通过阻塞分配获得闩锁?
我的问题强调结构元素的修改System verilog 如何通过阻塞分配获得闩锁?,system-verilog,vivado,System Verilog,Vivado,我的问题强调结构元素的修改 struct packed { logic word; logic [31:0] test; } a; logic [32:0] a_input; logic a_ff; always_latch begin if (enable) begin a = a_input; // map the bus `a_input` to the struct `a` a.test = a.test[1:0];
struct packed {
logic word;
logic [31:0] test;
} a;
logic [32:0] a_input;
logic a_ff;
always_latch begin
if (enable) begin
a = a_input; // map the bus `a_input` to the struct `a`
a.test = a.test[1:0]; // change the `test` child
end
end
和启用
是同一时钟上的触发器(然后可以在物理硬件中的不同时刻到达锁存器)a_输入
是a
a\u输入的修改梳状/锁存版本
a.test
,a\u input
不是结构,那么我就不能使用a\u input.test
。然后,代码很好地描述了我想要做的事情
我怎样才能拿到门闩?
编辑:我可以混合使用始终梳
、始终梳
和分配
struct packed {
logic word;
logic [31:0] test;
} a, a_comb;
logic [32:0] a_input;
logic a_ff;
always_ff @(posedge clk)
if (enable) begin
a_ff <= a_comb;
end
always_comb begin
a_comb = a_input; // map the bus `a_input` to the struct `a_comb`
a_comb.test = a_comb.test[1:0]; // change the `test` child
end
assign a = (enable)? a_comb: a_ff;
我想将该逻辑转换为闩锁而不是FF。我在vivado中尝试了这段代码,它能够将其合成为LDCE闩锁
module latch (
input logic a_input,enable,
output logic a
);
always_latch if(enable) a = a_input;
endmodule
锁存器实际上是一个电平敏感寄存器,而不是边缘敏感寄存器。未显示enable的驱动程序,因此Vivado可能会将其驱动为0。举个简单的例子,如果你正在尝试制作一个闩锁,下面的方法应该可以做到
always@(enable) begin
a = enable ? a_input : a;
end
通常,我们倾向于避免闩锁,但如果您死心塌地地想要制作闩锁,您可以先从灵敏度列表中删除
posedge clk
,然后将其更改为*
。这意味着,在信号发生任何变化时,你都会得到块的重新评估。如果enable是从某个源驱动的,而不是优化到恒定的0状态,因为它是一个未驱动的信号,那么enable将在高电平时控制a_ff项的加载,然后在低电平时保持该值,这一事实应该被视为一个闩锁。首先确保一个简单的闩锁将合成为闩锁。如果没有,那么这是一个单独的问题,你需要弄清楚;检查您的合成器版本和目标设备
always_latch
if (enable)
a <= a_input;
始终\u闩锁
如果(启用)
a那和我解释的不一样。您的always\u latch
中只有一个赋值,阻塞或非阻塞对代码没有任何影响。为了将其视为非锁存,vivado应优化掉“启用”信号。所以,我想我们需要更多关于如何评估的信息。另外,在锁存器中使用非阻塞分配。如果它不是作为锁存器合成,它合成的目的是什么?仅供参考。测试[31:2]
将始终合成为常数。它不会对合成产生影响,但会对锁存重新开始非阻塞分配(减少RTL模拟中出现争用情况的机会)。它被合成为具有无限环回的LUT。更改为非阻塞,导线被定义为未连接。您的答案与使用Verilog2001而不是SV的罗摩奎师那美达的答案完全相同。第二行(struct的element amend)没有出现在您的示例中,这正是困扰我的问题。问题是如何让它在一个带有阻塞分配的always_闩锁中工作。我相信你的方法会起作用(而且可能更好),但我仍然很好奇为什么OP的原始代码不起作用。
always_latch
if (enable)
a <= a_input;
always_comb begin
a_comb = a_input;
a_comb.test = a_comb.test[1:0];
end
always_latch
if (enable)
a <= a_comb;
always_latch
if (enable)
a_lat <= a_input;
always_comb begin
a = a_lat;
a.test = a.test[1:0];
end
always_latch
if (enable)
a <= a_input & 32'h100000003;