verilog 开关控制数码管显示 出现竞争冒险怎么办

8个开关对应8位二进制 4个输出数码管输出计算后的DDS频率数值 仿真输出结果没有问题 但在最后生成比特流的时候提示用于显示的segment出现竞争冒险

输入switch一定计算后对应的16位二进制

    always@(posedge clk_A_10kHz)
    begin
    Intermediate_value1 = a*256;
    Intermediate_value2 = Intermediate_value1/b;
    Frequency_Theoretical_medium = Intermediate_value2*switch;
    Frequency_Theoretical = Frequency_Theoretical_medium[23:8];
    end

16位二进制转4个8421BCD num3 num2 num1 num0对应这四位

    always@(Frequency_Theoretical) 
    begin
    for(i=15;i>=0;i=i-1)
      begin
       if(num3>=5)
        num3=num3+3;
       if(num2>=5)
        num2=num2+3;
       if(num1>=5)
        num1=num1+3;
       if(num0>=5)
        num0=num0+3;
        
       num3=num3<<1;
       num3[0]=num2[3];
       
       num2=num2<<1;
       num2[0]=num1[3];
       
       num1=num1<<1;
       num1[0]=num0[3];
       
       num0=num0<<1;
       num0[0]=Frequency_Theoretical[i];
      end
end

**将num对应到segment显示 这里所有segment就出现了竞争冒险 **

  always@(posedge clk_A_10kHz)
    begin
      case(num3)
      0:segment3<=7'b1111110;
      1:segment3<=7'b0110000;
      2:segment3<=7'b1101101;
      3:segment3<=7'b1111001;
      4:segment3<=7'b0110011;
      5:segment3<=7'b1011011;
      6:segment3<=7'b1011111;
      7:segment3<=7'b1110000;
      8:segment3<=7'b1111111;
      9:segment3<=7'b1111011;
      default:segment3<=7'b1111110;
      endcase
      
      case(num2)
      0:segment2<=7'b1111110;
      1:segment2<=7'b0110000;
      2:segment2<=7'b1101101;
      3:segment2<=7'b1111001;
      4:segment2<=7'b0110011;
      5:segment2<=7'b1011011;
      6:segment2<=7'b1011111;
      7:segment2<=7'b1110000;
      8:segment2<=7'b1111111;
      9:segment2<=7'b1111011;
      default:segment2<=7'b1111110;
      endcase
      
      
      case(num1)
      0:segment1<=7'b1111110;
      1:segment1<=7'b0110000;
      2:segment1<=7'b1101101;
      3:segment1<=7'b1111001;
      4:segment1<=7'b0110011;
      5:segment1<=7'b1011011;
      6:segment1<=7'b1011111;
      7:segment1<=7'b1110000;
      8:segment1<=7'b1111111;
      9:segment1<=7'b1111011;
      default:segment1<=7'b1111110;
      endcase
      
      
      case(num0)
      0:segment0<=7'b1111110;
      1:segment0<=7'b0110000;
      2:segment0<=7'b1101101;
      3:segment0<=7'b1111001;
      4:segment0<=7'b0110011;
      5:segment0<=7'b1011011;
      6:segment0<=7'b1011111;
      7:segment0<=7'b1110000;
      8:segment0<=7'b1111111;
      9:segment0<=7'b1111011;
      default:segment0<=7'b1111110;
      endcase
      end
      
  always@(posedge clk_A_10kHz)
      begin
      sel<=sel+1;
      case(sel)
      0:dis_seg<={4'b1000,segment3[6:0]};
      1:dis_seg<={4'b0100,segment2[6:0]};
      2:dis_seg<={4'b0010,segment1[6:0]};
      3:dis_seg<={4'b0001,segment0[6:0]};
      default:dis_seg<=11'b0000_1111110;
      endcase
      
    end


初学者刚学一周verilog 各种组合逻辑 时钟逻辑弄不清 愿见谅


    always@(Frequency_Theoretical) 
    begin
    for(i=15;i>=0;i=i-1)
      begin
       if(num3>=5)
        num3=num3+3;
       if(num2>=5)
        num2=num2+3;
       if(num1>=5)
        num1=num1+3;
       if(num0>=5)
        num0=num0+3;
       num3=num3<<1;
       num3[0]=num2[3];
       num2=num2<<1;
       num2[0]=num1[3];
       num1=num1<<1;
       num1[0]=num0[3];
       num0=num0<<1;
       num0[0]=Frequency_Theoretical[i];
      end
end
 

不判断你的逻辑是否正确。
单说这段组合逻辑代码编写是否规范。
在组合逻辑中 if 一定要与 else 配对使用,否则会编译出锁存器来,会使你的代码逻辑变得非常难理解。
比如:
if(x==5)
y=a;
else
y=0;
这是正确的写法,假如没有else
if(x==5)
y=a;
这么写,编译器会把这段代码编译成
if(x==5)
y=a;
else
y=y; //y 被锁存了
你的代码中就是这种写法,就产生了锁存器(latch)逻辑。

说实话,你这段代码没看懂,按我的理解应该是将 Frequency_Theoretical 转成 4 个 8421BCD码 num3,num2,num1,num0
可以这样写

always@(Frequency_Theoretical) 
begin
    num0 = Frequency_Theoretical%10;
    num1 = (Frequency_Theoretical/10)%10;
    num2 = (Frequency_Theoretical/100)%10;
    num3 = Frequency_Theoretical/1000;
end