0
\$\begingroup\$

I'm trying to complete an assignment using Verilog, the details aren't too important, except that it must be a combinatorial design. Unfortunately I'm running into what I assume is the hardware getting stuck in an infinite loop: the following signal(s) form a combinatorial loop:

the following signal(s) form a combinatorial loop: _n0112, GND_2_o_GND_2_o_mux_66_OUT<1>, mode[2]_GND_2_o_equal_75_o, mode<1>, ran0, mode[2]_GND_2_o_equal_75_o_mmx_out.

Here's my code(I know its messy and can be done better, I'm working on it):

module seven_seg(
input [3:0] a,
input [3:0] b,
input [3:0] c,
input [3:0] d,
input [1:0] mux,
output [6:0] out,
output an0,
output an1,
output an2,
output an3
);
 wire [6:0] x;
 wire [6:0] y;
 wire [6:0] i;
 wire [6:0] j;
 reg [2:0] mode = 3'b000;
 reg ran0;
 reg ran1;
 reg ran2;
 reg ran3;
parameter zero = 7'b1000000;
parameter one = 7'b1001111;
parameter two = 7'b0010010;
parameter three = 7'b0000110;
parameter four = 7'b1001100;
parameter five = 7'b0100100;
parameter six = 7'b0100000;
parameter seven = 7'b0011111;
parameter eight = 7'b0000000;
parameter nine = 7'b0000100;
parameter ten = 7'b0001000;
parameter eleven = 7'b0000000;
parameter twelve = 7'b0110001;
parameter thirteen= 7'b0000001;
parameter fourteen= 7'b0110000;
parameter fifteen = 7'b0111000;
assign c = 4'b0001;
assign d = 4'b0000;
assign x = (a == 4'b0000) ? zero :
(a == 4'b0001) ? one :
(a == 4'b0010) ? two :
(a == 4'b0011) ? three :
(a == 4'b0100) ? four :
(a == 4'b0101) ? five :
(a == 4'b0110) ? six :
(a == 4'b0111) ? seven : 
(a == 4'b1000) ? eight : 
(a == 4'b1001) ? nine : 
(a == 4'b1010) ? ten : 
(a == 4'b1011) ? eleven : 
(a == 4'b1100) ? twelve : 
(a == 4'b1101) ? thirteen : 
(a == 4'b1111) ? fourteen : fifteen;
assign y = (b == 4'b0000) ? zero :
(b == 4'b0001) ? one :
(b == 4'b0010) ? two :
(b == 4'b0011) ? three :
(b == 4'b0100) ? four :
(b == 4'b0101) ? five :
(b == 4'b0110) ? six :
(b == 4'b0111) ? seven : 
(b == 4'b1000) ? eight : 
(b == 4'b1001) ? nine : 
(b == 4'b1010) ? ten : 
(b == 4'b1011) ? eleven : 
(b == 4'b1100) ? twelve : 
(b == 4'b1101) ? thirteen : 
(b == 4'b1111) ? fourteen : fifteen;
always @(*)
begin
 if(mux == 2'b00)
 if(mode == 3'b000)
 mode = 3'b001;
 else if(mode == 3'b010)
 mode = 3'b011;
 else mode = 3'b000;
 else if(mux == 2'b01)
 mode = 3'b000;
 else if(mux == 2'b10)
 mode = 3'b010;
 else //if(mux == 2'b11)
 mode = 3'b100;
end
always @(*)
begin
 if(mode == 3'b000)
 begin
 ran0 = 0;
 ran1 = 1;
 ran2 = 1;
 ran3 = 1;
 end
 else if(mode == 3'b001)
 begin
 ran0 = 1;
 ran1 = 0;
 ran2 = 1;
 ran3 = 1;
 end
 else if(mode == 3'b010)
 begin
 ran0 = 1;
 ran1 = 1;
 ran2 = 0;
 ran3 = 1;
 end
 else if(mode == 3'b011)//011
 begin
 ran0 = 1;
 ran1 = 1;
 ran2 = 1;
 ran3 = 0;
 end
 else 
 begin
 ran0 = 0;
 ran1 = 0;
 ran2 = 0;
 ran3 = 1;
 end
end
assign an0 = ran0;
assign an1 = ran1;
assign an2 = ran2;
assign an3 = ran3;
assign out = x;
endmodule

So I think I understand the problem, it has to do with this block:

always @(mux)
begin
 if(mux == 2'b00)
 if(mode == 3'b000)
 mode = 3'b001;
 else if(mode == 3'b010)
 mode = 3'b011;
 else mode = 3'b000;
 else if(mux == 2'b01)
 mode = 3'b000;
 else if(mux == 2'b10)
 mode = 3'b010;
 else //if(mux == 2'b11)
 mode = 3'b100;
end

The synthesizer ends up putting 'mode' into the sensitivity list for some reason, and I believe that's why it ends up in a loop. I would appreciate some more insight as to what's going on here.

Thanks!

FSM

Voltage Spike
93k53 gold badges93 silver badges243 bronze badges
asked Jan 18, 2015 at 4:06
\$\endgroup\$
1
  • \$\begingroup\$ Some Verilog advice not related to your question: The ? : construct often infers an explicit 2:1 mux in synthesize. Therefor your code infers a 15 deep chain of 2:1 muxes. It is recommended to use case statement, allowing the synthesizer can choose the mux configuration (ex: one 16:1, or two 8:1 + one 2:1, five 4:1, etc). Also reg doesn't mean flop, if you declare output an0 as output reg an0 then you can assign an0 directly in your always block and omit the assign an0 = ran0 (which is just extra code, synthesis will not even treat the assign as a buffer). \$\endgroup\$ Commented Jan 18, 2015 at 17:48

2 Answers 2

2
\$\begingroup\$

Whether you put it the sensitivity list or not, the mode variable depends on the mode variable. See where I point it out below.

Pretend you are trying to make that hardware. How do you make that work? Remember there is not clock here, so you would have to create a combinatorial loop, right?

always @(mux)
begin
 if(mux == 2'b00)
 if(mode == 3'b000) <---- HERE
 mode = 3'b001;
 else if(mode == 3'b010) <----- HERE
 mode = 3'b011;
 else mode = 3'b000;
 else if(mux == 2'b01)
 mode = 3'b000;
 else if(mux == 2'b10)
 mode = 3'b010;
 else //if(mux == 2'b11)
 mode = 3'b100;
end

Walk through the design to understand what does this do in the situation where mux is starting at 2'b01 then goes to 2'b00? When mux = 2'b01, mode = 3'b000. Then when mux goes to 2'b00, it looks to see that mode is 3'b000, and changes mode to be 3'b001. Then it immediately sees that mux is 2'b00 and mode is 3'b001 and changes mode to 3'b000, then it sees that mux is 2'b00 and mode is 3'b000 and changes mode to 3'b001. This is a combinatorial loop.

As an aside, let me explain what the sensitivity list is exactly. Originally, verilog was designed as a modelling language. The sensitivity list was a way to tell the simulator dependencies. This helped to reduce unneeded processing by letting the simulator not look into the code for each always block to determine if it needed to run it.

However, today verilog is mostly used to infer logic, so the sensitivity list is really not as useful as it was. The synthesis tool will look at the code and determine that you forgot something. You can't trick it by not putting it in the list. It is a dependency according to your logic and the synthesis tool will treat it as such. It probably even helpfully gave you a warning that you forgot it.

answered Jan 18, 2015 at 4:10
\$\endgroup\$
5
  • \$\begingroup\$ I tried adding a lastMode reg and using that in the stead of the 'if(mode == 3'b000)' -> if(lastMode == 3'b000), but it's still not working properly. I don't understand why. \$\endgroup\$ Commented Jan 18, 2015 at 5:45
  • \$\begingroup\$ If last mode depends on mode without a clock delay, it is still a combinatorial loop. What do you want it to do when mux is 3'b000? \$\endgroup\$ Commented Jan 18, 2015 at 6:05
  • \$\begingroup\$ When mux is 2'b00, the next state depends on whether mux was 2'b01 or 2'b10. I'm just not sure of how to implement that without getting stuck in a loop. \$\endgroup\$ Commented Jan 18, 2015 at 21:59
  • \$\begingroup\$ Seems like you need to implement a latch with combinatorial logic. Please update your original question to show the state machine. Without that, it is very difficult to help. \$\endgroup\$ Commented Jan 18, 2015 at 22:47
  • \$\begingroup\$ Added it, hope it's not too messy. \$\endgroup\$ Commented Jan 18, 2015 at 23:47
0
\$\begingroup\$

Your code doesn't match your (incomplete) graph. Here is a table form that shows missing transitions explicitly.

Mode\Mux 2'b00 2'b01 2'b10 2'b11
3'b000 3'b001 3'b000 3'b010 3'b100
3'b001 3'b001 3'b000 3'b010 3'b100
3'b010 3'b011 3'b000 3'b010 3'b100
3'b011 3'b011 3'b000 3'b010 3'b100
3'b100 ? ? ? 3'b100

For example, you have Mode = 2'b00, Mux = 3'b011 going to 3'b000, which is where you have a combinatorial loop.

answered Jan 19, 2015 at 1:12
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.