verilog always@(posedge)在uart中失败

verilog always@(posedge)在uart中失败,verilog,Verilog,我正在学习verilog,我想有些东西我不能总是理解,而且总是(@posedge-clk,…) 下面是一段通过uart发送位的代码。它在合成上失败了。 错误是 “的逻辑与已知FF或闩锁模板不匹配。当前软件版本不支持用于描述寄存器或闩锁的描述样式。” (和3个其他错误,以及) 如果我将always@(…)更改为always@*,则在下一步(“实现设计”)中会失败,因为东西没有连接 在我的书中,他们实现了一个fsmd,状态为always(posedge clk),其他逻辑为always@*,但我不明

我正在学习verilog,我想有些东西我不能总是理解,而且总是(@posedge-clk,…)

下面是一段通过uart发送位的代码。它在合成上失败了。 错误是 “的逻辑与已知FF或闩锁模板不匹配。当前软件版本不支持用于描述寄存器或闩锁的描述样式。” (和3个其他错误,以及) 如果我将always@(…)更改为always@*,则在下一步(“实现设计”)中会失败,因为东西没有连接

在我的书中,他们实现了一个fsmd,状态为always(posedge clk),其他逻辑为always@*,但我不明白为什么这不起作用

在另一个论坛上,我读到错误可能来自过于复杂的条件。但我也简化了一些事情(不是在这里编写代码,而是基本上删除了case(state)和ifs,使其具有带?:或二进制条件的单行赋值,但它也不起作用)

我以前在我编写的其他代码中也看到过这个错误,但我没有深入了解它的本质,因此如果您能帮助我理解一般问题(将uart作为一个具体示例的支持),我将非常高兴。 谢谢 托马斯

注意:我在使用xilinx spartan 3e初学者工具包和xilinx ise 14.4

module UART_out #(parameter [3:0] NUM_BITS = 8)
(
input wire baud_clk,
input wire send_tick,
input wire[NUM_BITS-1:0] data_in,
output wire tx,
output wire debug_done
);
localparam
        IDLE = 0,
        TRANSMIT = 1;
reg[NUM_BITS:0] bits_to_send;
reg state;
reg out_bit;
reg[4:0] cnt;

always @(posedge baud_clk, posedge send_tick)
begin
    case (state)
    IDLE:
        if (send_tick)
        begin
            bits_to_send <= {data_in, 0};
            state <= TRANSMIT;
            cnt <= 0;
        end
    TRANSMIT:
        begin
            if (cnt < NUM_BITS)
                cnt <= cnt + 1;
            else
                state <= IDLE;
            bits_to_send <= {1, bits_to_send[NUM_BITS:1]};
            out_bit <= bits_to_send[0];
        end
    endcase
end

assign tx = (state == IDLE ? 1 : out_bit);
assign debug_done = (state == IDLE);    
endmodule
模块UART_out#(参数[3:0]NUM_BITS=8)
(
输入线波特率时钟,
输入线发送勾号,
输入线[NUM_BITS-1:0]数据_in,
输出线tx,
输出线调试完成
);
局部参数
怠速=0,
传输=1;
reg[NUM_BITS:0]要发送的位;
注册州;
reg out_位;
reg[4:0]cnt;
始终@(posedge波特率时钟、posedge发送时钟)
开始
案件(州)
闲置:
如果(发送勾号)
开始
位发送错误:

The logic for does not match a known FF or Latch template. The description style you are using to describe a register or latch is not supported in the current software release.
指的是合成工具没有任何与您的描述匹配的硬件单元可供使用

您想要什么硬件:

always @(posedge baud_clk, posedge send_tick)
看起来您需要一个带启用信号的触发器。启用信号(发送勾号)应为1个时钟周期宽。然后用于选择时钟边缘上的逻辑路径。不是作为一个替代触发器

我认为这就是你真正需要的:

always @(posedge baud_clk) begin
  case (state)
    IDLE:
      if (send_tick) begin
        //...
      end
     //...
   endcase
end
如果
send_tick
来自另一个时钟域,则需要进行一些时钟域交叉,将其转换为
baud_clk
上的时钟宽脉冲

您可能会对具有多个触发器的块感到困惑,它们通常是clk和reset。通常为重置(初始化)条件添加
nedge reset\n
posedge reset

如果添加重置:

always @(posedge baud_clk or negedge reset_n) begin
  if (~reset_n) begin
    //reset conditions
    state <= IDLE;
    //...
  end
  else begin
    // Standard logic
  end
end
始终@(posedge波特率时钟或negedge复位)开始
如果(~reset\n)开始
//重置条件
状态