在 HDL 中实现时序逻辑和组合逻辑

Implementing between sequential and combinational logic in HDL

我正在开始 HDL,尤其是 Verilog 领域。

我发现有两种方法可以实现'sequential logic'和'combinational logic',想实现小数运算,但无法在组合逻辑和时序逻辑之间做出决定。

我知道时序逻辑有内存,它通常用于关键的时序路径,而不是像连线这样的组合逻辑。

让我来看我的例子。

reg [ 9:0] x; 

always@(clk)
#5    x = ~x;

wire [39:0] x_ext = {x,30b'0};
wire [39:0] x_fract;
assign x_fract = (x>>29) - (x>>27) + (x>>24) + (x>>21) - (x>>19) - (x>>15) + (x>>10) + (x>>9) - (x>>5) + (x>>2) - (x>>1) ;

像上面的代码一样,我可以实现简单的组合逻辑,但我很困惑我是否需要实现顺序逻辑?

使用时序逻辑至少有 2 个原因:1) 逻辑相关和 2) 硬件相关。

第一个仅取决于您的设计需求,可用于实现存储器、同步逻辑的不同部分或打破组合循环。在你的小例子中,逻辑上不需要这样的操作。

第二个是由于现代硬件中的电气延迟。你可以想象一个逻辑图。电信号走不同的路径并且在路径上具有不同的延迟。因此,正确的电气答案将在最长路径确定后确定。与此同时,输出信号只会抖动,消耗功率。所以,你需要知道安定下来需要多长时间。在那之前,您希望将旧值保留在输出中,并且仅在结果准备就绪时更新它们。为了保持功率并使逻辑顺利工作,您需要将设计分解成更小的组合部分,并将它们的执行与某个时钟同步。

由于您在设计中使用了很多 addition/subtraction,您的逻辑对于真正的硬件来说可能太大而无法作为单个块执行。综合流程工具会告诉你。

有一种方法可以拆分示例。

reg x_part1[39:0], x_part2[39:0], ...;
always @(posedge clk) x_part1 <= (x>>29) - (x>>27);
always @(posedge clk) x_part2 <= (x>>24) + (x>>21);
...
always @(posedge clk) x_comb <=  x_part1 + x_part2 + ...;
assign x_fract = x_comb;

上述代码中,如果'x'发生变化,相应的结果会延迟一个时钟周期出现。

您可能需要进一步拆分它或使用不同的模式。或者它可能只是按原样工作。在任何情况下,像 always @(posedge clk) x_comb <= ..; assign x_fract = x_comb;

这样的输出是个好主意