不考虑混合阻塞和非阻塞问题以及16位输入的第一位

时间:2018-05-03 08:45:56

标签: verilog fsm

这是我的完整代码。输入'h'是16个数据位和符号位。在这些数据位中要识别一些特定的模式。因此,每个数据位都被带入FSM并检查该特定模式。

现在,这里有两个问题:

第一个问题是从不考虑第一个数据位。

第二个问题是变量'i'被分配了阻塞和非阻塞(没有代码似乎不起作用)。有人可以帮忙解决这个问题。

 module formatting(x,h,sign,y0,y1,y2,y3,out1,out2,out3,out4,out5,
 ft1,ft2,ft3,ft4,ft5,bit1,bit2,bit3,bit4,bit5);

 input [16:0]x;
 input [0:16]h;
 output sign;
 output [15:0]y0,y1,y2,y3;
 output reg [1:0]out1,out2,out3,out4,out5;
 output reg [3:0]ft1,ft2,ft3,ft4,ft5;
 output reg  bit1,bit2,bit3,bit4,bit5;

 wire [15:0]x1;
 reg inp;
 integer i=0;
 reg [2:0]s=3'b0;
 reg [2:0]st=3'b0;
 reg [3:0]ft=4'b0;
 reg [2:0]cnt=3'b0;
 reg [1:0]out;

 assign  sign=(x[0]^h[16]);
 assign  x1=x[16:1];
 assign  y0=((x1>>3)+(x1>>1)+(x1>>2));
 assign  y1=(x1>>1);
 assign  y2=((x1>>1)+(x1>>3));
 assign  y3=((x1>>2)+(x1>>1));

 always@(i,h,inp) 
   begin
if(i<16) 
    begin
        inp<=h[i+1];
        i<=i+1;//non-blocking assignment of variable'i'
   case(s)
   3'b000:if(inp == 1'b1)
            begin
               if(i<=13)
                 begin
                   s=3'b001;
                   st=st+1'b1;
                   ft=i;

                 end        
               else if(i==14)
                 begin
                   s=3'b100;
                   st=st+1'b1;
                   ft=i;

                 end  
               else if(i==15)
                 begin
                   s=3'b000;
                   st=st+1'b1;
                   ft=i;
                   out=2'b01;
                   cnt=cnt+1'b1;

                 end  
             end    
          else 
                begin
                   s=3'b000;

                end    

   3'b001: if(inp == 1'b0)
            begin
               s=3'b010;

            end
          else
            begin
              s=3'b011;
            end                       

   3'b010:if(inp == 1'b1)
             begin
               s=3'b000;
               out=2'b10;
               cnt=cnt+1'b1;
             end
           else
             begin
             s=3'b000;
             out=2'b01;
             cnt=cnt+1'b1;
             end    

   3'b011:if(inp == 1'b1)
             begin
               s=3'b000;
               out=2'b00;
               cnt=cnt+1'b1;
             end 
           else  
             begin
              s=3'b000;
              out=2'b11;
              cnt=cnt+1'b1;
             end
   3'b100:if(inp == 1'b1)
              begin
               s=3'b000;
               out=2'b11;
               cnt=cnt+1'b1;
              end   
          else
              begin
               s=3'b000;
               out=2'b01;
               cnt=cnt+1'b1;
              end

    default:begin
                 s=3'b000;
                 out=2'bxx;
              end 
     endcase

     case(cnt)
             3'b001:begin
                      out1=out;
                      bit1=1'b1;
                    end 
             3'b010:begin
                     out2=out;
                     bit2=1'b1;
                    end 
             3'b011:begin
                      out3=out;
                      bit3=1'b1;
                    end
             3'b100:begin
                      out4=out;
                      bit4=1'b1;
                    end
             3'b101:begin
                      out5=out;
                      bit5=1'b1;
                    end 
             default:begin
                       out1=2'b00;bit1=1'b0;
                       out2=2'b00;bit2=1'b0;
                       out3=2'b00;bit3=1'b0;
                       out4=2'b00;bit4=1'b0;
                       out5=2'b00;bit5=1'b0;
                     end                                                                              
           endcase

            case(st)
             3'b001:begin 
                      ft1=ft;
                    end  
             3'b010:begin 
                      ft2=ft;
                    end  
             3'b011:begin 
                      ft3=ft;
                    end  
             3'b100:begin
                      ft4=ft;
                    end  
             3'b101:begin
                      ft5=ft;
                    end     
             default:begin
                       ft1=4'b0000;
                       ft2=4'b0000;
                       ft3=4'b0000;
                       ft4=4'b0000;
                       ft5=4'b0000;
                     end
           endcase
   end 
    else
     begin
       i=0;//blocking assignment of variable'i'
       st=3'b000;
       cnt=3'b000;
       ft=4'b0000;
       s=3'b000;
     end        
  end    
  endmodule

1 个答案:

答案 0 :(得分:1)

您正在接受FSM。在HDL中,FSM是一段代码/硬件,它通过使用时钟的许多状态来推动。您的代码没有时钟,因此不是FSM

这也会导致阻塞和非阻塞分配混乱。在时钟部分中,您只使用非阻塞分配。在组合部分中,您只使用阻止分配。

我担心你必须认真地重新编写代码,思考每个步骤(时钟)需要做什么。还要添加重置信号。这将设置一切开始的初始状态。

现在也优选使用always (*)always_comb。危险在于您忘记了灵敏度列表中的变量,然后您的模拟将与硬件不匹配。

没有时钟,你必须使用单个for循环编写整个部分:

for (i=0; i<16; i=i+1)
begin
   // All logic expressed as a function of i
end

我预见到问题,因为你也有案件。 HDL就像它说的硬件描述语言一样。最后,你有一个必须完成所有处理的硬件。因此,综合工具必须知道它必须使用编译时间已知值生成的所有硬件。