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输入的修改梳状/锁存版本
Vivado不会将其合成为闩锁

我只想更改
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;