0

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
  • 75,799
  • 36
  • 80
  • 208
  • 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). – Greg Jan 18 '15 at 17:48

2 Answers2

2

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.

caveman
  • 1,959
  • 11
  • 12
  • 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. – user3474353 Jan 18 '15 at 05:45
  • 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? – caveman Jan 18 '15 at 06:05
  • 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. – user3474353 Jan 18 '15 at 21:59
  • 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. – caveman Jan 18 '15 at 22:47
  • Added it, hope it's not too messy. – user3474353 Jan 18 '15 at 23:47
0

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.

caveman
  • 1,959
  • 11
  • 12