|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
最近在写代码的时候发现一个很隐秘的组合逻辑环,一个不小心就会出现,应该是自己代码习惯的问题。代码见下方。刚好如下的两个模块fsm和fack形成了一个组合逻辑环“ack_i -> nstate -> req_o -> ack_i",用modelsim仿真一下代码会直接报错,用quartusII编译综合可以通过,但是会有警告表明产生了组合逻辑环。
仔细分析,产生这种情况的原因是,两个模块中都存在”input -> output 的组合逻辑“,如果这两个电路刚好匹配,就会形成组合逻辑环。但是如果是两个规模较大的模块,发现这种比较隐蔽的组合逻辑环感觉应该不是那么简单。
问题来了:是不是说每个模块里面最好将输入和输出用至少一级寄存器隔开比较安全?因为你不仔细分析不会知道其他人的代码是怎么写的,如果一旦产生了组合逻辑环,再次修改代码可能会导致比较复杂的改动(当然这里举例比较简单)。所以考虑安全性,最好采用这种方式。
请问,我的分析是不是正确的?上面讲的代码方式”每个模块里面最好将输入和输出用至少一级寄存器隔开比较安全“是不是应该采取?还是说”出现问题后再修改设计切断组合逻辑环“?谢谢!
代码如下:"fsm.v":
- `timescale 1ns/1ns
- module fsm(
- input clk
- ,input rst_n
- ,output req_o
- ,input ack_i
- ,output led_o
- );
-
- localparam F_IDLE = 2'd0,
- F_S0 = 2'd1,
- F_S1 = 2'd2;
-
- reg [1:0] cstate;
- reg [1:0] nstate;
-
- always @(posedge clk,negedge rst_n) begin
- if(!rst_n)
- cstate <= F_IDLE;
- else
- cstate <= nstate;
- end
-
- always @( * ) begin
- case(cstate)
- F_IDLE:
- nstate = F_S0;
-
- F_S0:
- if(ack_i)
- nstate = F_S1;
- else
- nstate = F_S0;
-
- F_S1:
- nstate = F_IDLE;
-
- default:
- nstate = F_IDLE;
-
- endcase
- end
-
- //assign req_o = (cstate == F_S0); //ok;
- assign req_o = (cstate == F_S0) && (nstate == F_S0); //error;
-
-
- assign led_o = (cstate == F_S1);
-
-
- endmodule
复制代码
"fack.v":
- `timescale 1ns/1ns
- module fack(
- input req_i
- ,output ack_o
- );
- assign ack_o = req_i;
-
- endmodule
复制代码
"top.v":
- `timescale 1ns/1ns
- module top(
- input clk
- ,input rst_n
- ,output led_o
- );
- fsm fsm(
- .clk (clk )
- ,.rst_n (rst_n)
- ,.req_o (req )
- ,.ack_i (ack )
- ,.led_o (led_o)
- );
-
- fack fack(
- .req_i (req )
- ,.ack_o (ack )
- );
-
- endmodule
复制代码 |
|