数字电路设计之堆栈的verilog实现

2019-04-14 18:57发布

表面上使用verilog实现POP和PUSH十分简单,实际上这里面还是有点学问的。如果是简单的堆栈实现可以这样做: 这里我就不把整个模块写出来,用for循环复位之类的我也没有写出来,主要是感受栈在verilog的实现,忽略那些细节。其实以下的做法是有问题的,因为在时序电路中,一般都是用非阻塞的,不然的话时序会很混乱的。
input wire pop;                           //输入出栈有效信号 input wire push;                         //输入入栈有效信号 input wire [31:0]push_data;      //要入栈的数据 output reg [31:0]pop_data;       //要输出的出栈数据
reg   [31:0]stack[255:0];           //用寄存器文件实现了堆栈 reg   [7:0]sp;                             //用来记录栈的位置 reg   overflow;                           //这个是数据溢出报错的,为1的时候就算报错 reg  no_data;                            //这个是没有数据在栈中的时候却想取数据
always@(posedge clk)   begin        if(pop&&!push)  begin                if(!sp)  begin                       no_data     = 0;                       pop_data  =stack[sp];                       sp              = sp - 1;
               end        
               else begin                      no_data     =1;//到了0的位置,不能再往下
               end
      end       else       if(push&&!pop)  begin             if(sp<255)  begin                       overflow    = 0;                       stack[sp]  = push_data;                       sp              = sp + 1;
               end        
               else begin                      overflow     =1;//栈的位置已经到了255,不能在堆栈
               end
      end       else;
end
底下的是我实现ARM contex m0处理器的时候对于POP和PUSH的处理,因为ARM的是有一个reglist,所以这里对于POP和PUSH没有那么简单,使用了一个count作为POP和PUSH顺序的值。以下的做法有点问题,得不到正确答案,应该改成时序逻辑的非阻塞。那么sp就要根据一些条件给出赋值了。稍微修改即可。
if(wb_is_PUSH)
                begin
                 if(pop_push[0]&&count==0) 
                   begin
                      if(sp < 255)
                       begin
                        sp              = sp +1;
                        stack[sp]   = gr[0];
                        overflow    = 0;                        
                       end
                   else
                       overflow  = 1;
                    end
                    else
                    if(pop_push[1]&&count==1)  
                    begin
                       if(sp < 255)
                        begin
                        sp            = sp +1;
                        stack[sp]  = gr[1];
                        overflow   = 0;                        
                        end
                        else
                        overflow  = 1;
                    end
                    else
                    if(pop_push[2]&&count==2)  
                    begin
                       if(sp < 255)
                        begin
                        sp             = sp +1;
                        stack[sp]   = gr[2];
                        overflow    = 0;                        
                        end
                        else
                        overflow    = 1;
                    end
                    else
                    if(pop_push[3]&&count==3)  
                    begin
                       if(sp < 255)
                        begin
                        sp              = sp +1;
                        stack[sp]   = gr[3];
                        overflow    = 0;                        
                        end
                        else
                        overflow   = 1;
                     end
                    else
                    if(pop_push[4]&&count==4)  
                    begin
                       if(sp < 255)
                        begin
                        sp           = sp +1;
                        stack[sp] = gr[4];
                        overflow  = 0;                        
                        end
                   else
                        overflow  = 1;
                    end
                    else
                    if(pop_push[5]&&count==5)  
                    begin
                        if(sp < 255)
                         begin
                         sp            = sp +1;
                         stack[sp]  = gr[5];
                         overflow   = 0;                        
                         end
                         else
                         overflow  = 1;
                    end
                    else
                    if(pop_push[6]&&count==6)  
                    begin
                        if(sp < 255)
                         begin
                         sp              = sp +1;
                         stack[sp]   = gr[6];
                         overflow    = 0;                        
                         end
                         else
                         overflow <= 1;
                     end
                     else
                     if(pop_push[7]&&count==7)  
                     begin
                        if(sp < 255)
                         begin
                         sp           = sp +1;
                         stack[sp] = gr[7];
                         overflow  = 0;                        
                         end
                         else
                         overflow  = 1;
                      end
                      else
                      if(pop_push[8]&&count==8)  
                      begin
                         if(sp < 255)
                          begin
                          sp            = sp +1;
                          stack[sp]  = {16'b0,pop_push[24:9]};
                          overflow  = 0;                        
                          end
                          else
                          overflow  = 1;
                       end
                       else
                          overflow = 0;
                end
                else
                if (wb_is_POP)
                    begin
                         if(pop_push[0]&&count==0)
                              begin
                                 gr[0]  = stack[sp[2:0]];
                                  if(sp == 0)
                                       begin
                                        below  = 1;
                                        sp       = 0;
                                        end
                                    else
                                       begin
                                       below  = 0;
                                        sp       = sp -1;
                                       end
                                end
                          else
                          if(pop_push[1]&&count==1)
                              begin
                                   gr[1]  = stack[sp];
                                    if(sp == 0)
                                       begin
                                        below = 1;
                                        sp      = 0;
                                        end
                                    else
                                       begin
                                       below = 0;
                                        sp    = sp -1;
                                       end
                                end
                            else
                           if(pop_push[2]&&count==2)
                              begin
                                   gr[2] = stack[sp];
                                    if(sp == 0)
                                       begin
                                        below = 1;
                                        sp       = 0;
                                        end
                                    else
                                       begin
                                       below = 0;
                                        sp     = sp -1;
                                       end
                                end
                            else
                           if(pop_push[3]&&count==3)
                              begin
                                   gr[3]  = stack[sp];
                                    if(sp == 0)
                                       begin
                                        below  = 1;
                                        sp       = 0;
                                        end
                                    else
                                       begin
                                       below = 0;
                                        sp    = sp -1;
                                       end
                                end
                            else
                           if(pop_push[4]&&count==4)
                              begin
                                   gr[4] = stack[sp];
                                    if(sp == 0)
                                       begin
                                        below = 1;
                                        sp      = 0;
                                        end
                                    else
                                       begin
                                       below = 0;
                                        sp    = sp -1;
                                       end
                                end
                            else
                           if(pop_push[5]&&count==5)
                              begin
                                   gr[5]  = stack[sp];
                                    if(sp == 0)
                                       begin
                                        below = 1;
                                        sp      = 0;
                                        end
                                    else
                                       begin
                                       below = 0;
                                        sp      = sp -1;
                                       end
                                end
                            else
                           if(pop_push[6]&&count==6)
                              begin
                                   gr[6]  = stack[sp];
                                    if(sp == 0)
                                       begin
                                        below = 1;
                                        sp      = 0;
                                        end
                                    else
                                       begin
                                       below  = 0;
                                        sp       = sp -1;
                                       end
                                end
                            else
                           if(pop_push[7]&&count==7)
                              begin
                                   gr[7]  = stack[sp];
                                    if(sp == 0)
                                       begin
                                        below = 1;
                                        sp      = 0;
                                        end
                                    else
                                       begin
                                       below = 0;
                                        sp     = sp -1;
                                       end
                                end
                            else
                           if(pop_push[8]&&count==8)
                              begin
                                    if(sp == 0)
                                       begin
                                        below = 1;
                                        sp      = 0;
                                        end
                                    else
                                       begin
                                       below = 0;
                                        sp    = sp -1;
                                       end
                                end
                            else;
                     end
                else;
            end
下面是技术控制器的verilog实现: always@(posedge clock) begin
    if(!reset)
        count <= 0;
    else
     if(count == 8)
       count <= 0;
    else
     if(wb_is_POP || wb_is_PUSH)
       count <= count + 1;     
    else;        
end
最后修改如下,已经仿真通过: //****************************************************************************************************************************************************
reg [3:0]count;
integer i;//进行初始化,将整块栈进行一个初始化
reg overflow;//用来表示栈已经满了,无法再加入东西,无法进行PUSH操作的时候会为一
reg below;   //这个是用来当栈的指针已经指向栈底也就是sp=0的时候再进行POP操作那么就会报错,此时below为1.
//_____________________________________________________________________WB 写回_________________________________________________________________________
always@(posedge clock)  //在这里把写回寄存器的序号在这一级得到而不是在取操作数的时候得到,是为了平均每一级的时间,加快运行速度。不过后来考虑到在去操作数的时候
//各个操作数是并行去操作数.在权衡之下,选择在取指的时候得出目的寄存器的序列号。这样节约了寄存器,又不会降低速度。
//为此得多付出几个寄存器。而且传递整条指令也是为了之后如果架构有改动的话,也便于从指令中得到消息。在判断该指令是什么指令的时候没有直接用指令而是传递寄存器的方式,这是减少逻辑判断。
        if(!reset)
            begin
            gr[7] <= 32'b0;
            gr[6] <= 32'b0;
            gr[5] <= 32'b0;
            gr[4] <= 32'b0;
            gr[3] <= 32'b0;
            gr[2] <= 32'b0;
            gr[1] <= 32'b0;
            gr[0] <= 32'b0;
            for(i = 0;i<63;i=i+1)
            stack[i] <= 0;
            overflow <= 0;  
            below    <= 0;
            sp       <= 0;
            //count    <= 0;            
            end
        else if (state == `exec)
            begin
                if (wb_is_AND  ||wb_is_EOR  ||wb_is_LSL0 ||wb_is_LSR0 ||wb_is_ASR0 ||wb_is_ADC  ||wb_is_SBC  ||wb_is_ROR  ||wb_is_NEG  ||
                    wb_is_ORR  ||wb_is_MUL  ||wb_is_BIC  ||wb_is_MVN  ||wb_is_ADD0 ||wb_is_ADD1 ||wb_is_SUB0 ||wb_is_LDR0 ||wb_is_LDR1 ||
                    wb_is_LDR2 ||wb_is_LDR3 ||wb_is_LDRB0||wb_is_LDRB1||wb_is_LDRH0||wb_is_LDRH1||wb_is_LDRSB||wb_is_LDRSH||wb_is_ADD2 ||
                    wb_is_ADD3 ||wb_is_ADD4 ||wb_is_ADD5 ||wb_is_SUB1 ||wb_is_SUB2 ||wb_is_SUB3 ||wb_is_MOV0 ||wb_is_MOV1 ||wb_is_LSL1 ||
                    wb_is_LSR1 ||wb_is_ASR1)
                     gr[wb_rd] <= reg_C1;
                else
                if(wb_is_PUSH)
                begin
                    //if(count == 8)
                    //    count = 0;
                    //else
                    //    count = count + 1;
                    if((pop_push[0]==1)&&(count==0))  //count = count + 1   
                    begin
                    if(sp < 63) begin
                    sp         <= sp +1;
                    stack[sp]  <= gr[0];
                    overflow   <= 0;                        
                    end
                    else
                       overflow <= 1;
                    end
                    else
                    if((pop_push[1])&&(count==1))  
                    begin
                        if(sp < 63)
                        begin
                        sp        <= sp +1;
                        stack[sp] <= gr[1];
                        overflow  <= 0;                        
                        end
                        else
                        overflow  <= 1;
                    end
                    else
                    if(pop_push[2]&&(count==2))  
                    begin
                       if(sp < 63)
                        begin
                        sp        <= sp +1;
                        stack[sp] <= gr[2];
                        overflow  <= 0;                        
                        end
                        else
                        overflow <= 1;
                    end
                    else
                    if(pop_push[3]&&(count==3))  
                    begin
                        if(sp < 63)
                        begin
                        sp        <= sp +1;
                        stack[sp] <= gr[3];
                        overflow  <= 0;                        
                        end
                        else
                        overflow  <= 1;
                    end
                    else
                    if(pop_push[4]&&(count==4))  
                    begin
                       if(sp < 63)
                        begin
                        sp        <= sp +1;
                        stack[sp] <= gr[4];
                        overflow  <= 0;                        
                        end
                        else
                        overflow  <= 1;
                    end
                    else
                    if(pop_push[5]&&(count==5))  
                    begin
                        if(sp < 63)
                        begin
                        sp        <= sp +1;
                        stack[sp] <= gr[5];
                        overflow  <= 0;                        
                        end
                    else
                        overflow  = 1;
                    end
                    else
                    if(pop_push[6]&&(count==6))  
                    begin
                         if(sp < 63)
                         begin
                         sp        <= sp +1;
                         stack[sp] <= gr[6];
                         overflow  <= 0;                        
                         end
                         else
                         overflow  <= 1;
                    end
                    else
                    if(pop_push[7]&&(count==7))  
                    begin
                        if(sp < 63)
                        begin
                        sp        <= sp +1;
                        stack[sp] <= gr[7];
                        overflow  <= 0;                        
                        end
                        else
                        overflow  <= 1;
                    end
                    else
                    if(pop_push[8]&&count==9)  
                    begin
                         if(sp < 63)
                         begin
                         sp        <= sp +1;
                         stack[sp] <= {16'b0,pop_push[24:9]};
                         overflow  <= 0;                        
                         end
                         else
                         overflow <= 1;
                    end
                    else
                     begin
                         overflow <= 0;
                         sp       <= sp;
                    end
                end
                else
                if (wb_is_POP)
                    begin
                         if(pop_push[0]&&count==0)
                             begin
                                 gr[0] <= stack[sp[2:0]];
                                 if(sp == 0)
                                 begin
                                 below <= 1;
                                 sp    <= 0;
                                 end
                                 else
                                 begin
                                 below <= 0;
                                 sp    <= sp -1;
                                 end
                            end
                          else
                          if(pop_push[1]&&count==1)
                              begin
                                   gr[1] = stack[sp];
                                   if(sp == 0)
                                   begin
                                   below <= 1;
                                   sp    <= 0;
                                   end
                                   else
                                   begin
                                   below <= 0;
                                   sp    <= sp -1;
                                   end
                              end
                          else
                          if(pop_push[2]&&count==2)
                              begin
                                  gr[2] <= stack[sp];
                                  if(sp == 0)
                                  begin
                                  below <= 1;
                                  sp    <= 0;
                                  end
                                  else
                                  begin
                                  below <= 0;
                                  sp    <= sp -1;
                                  end
                              end
                           else
                           if(pop_push[3]&&count==3)
                              begin
                                   gr[3] <= stack[sp];
                                   if(sp == 0)
                                   begin
                                   below <= 1;
                                   sp    <= 0;
                                   end
                                   else
                                   begin
                                   below <= 0;
                                   sp    <= sp -1;
                                   end
                              end
                           else
                           if(pop_push[4]&&count==4)
                              begin
                                   gr[4] <= stack[sp];
                                   if(sp == 0)
                                   begin
                                   below <= 1;
                                   sp    <= 0;
                                   end
                                   else
                                   begin
                                   below <= 0;
                                   sp    <= sp -1;
                                   end
                              end
                           else
                           if(pop_push[5]&&count==5)
                              begin
                                   gr[5] <= stack[sp];
                                   if(sp == 0)
                                   begin
                                   below <= 1;
                                   sp    <= 0;
                                   end
                                   else
                                   begin
                                   below <= 0;
                                   sp    <= sp -1;
                                   end
                               end
                           else
                           if(pop_push[6]&&count==6)
                              begin
                                    gr[6] <= stack[sp];
                                    if(sp == 0)
                                    begin
                                    below <= 1;
                                    sp    <= 0;
                                    end
                                    else
                                    begin
                                    below <= 0;
                                    sp    <= sp -1;
                                    end
                              end
                           else
                           if(pop_push[7]&&count==7)
                              begin
                                   gr[7] <= stack[sp];
                                   if(sp == 0)
                                   begin
                                   below <= 1;
                                   sp    <= 0;
                                   end
                                   else
                                   begin
                                   below <= 0;
                                   sp    <= sp -1;
                                   end
                              end
                           else
                           if(pop_push[8]&&count==8)
                              begin
                                    if(sp == 0)
                                    begin
                                    below <= 1;
                                    sp    <= 0;
                                    end
                                    else
                                    begin
                                    below <= 0;
                                    sp    <= sp -1;
                                    end
                              end
                           else
                           ;
                     end
                else;
            end
        else;
//***************************************************************************************************************************************************


//________________________________________________________控制器:用于POP,PUSH__________________________________________________________________________
//因为在有reglist的时候,POP这些操作有一个sp标志位置,但是因为得到的数据要进行堆栈的时候是并发进行的,那么就会很混乱,甚至得不到正确的结果,所以在这里使用一个时钟分频来计算这里我用
//了简单的实现,这个做起来就比较复杂,如果把系统时钟拿来分频做的话就比较简单
always@(posedge clock) begin
    if(!reset)
        count <= 0;
    else
     if(count == 8)
       count <= 0;
    else
     if(wb_is_POP || wb_is_PUSH)
       count <= count + 1;     
    else;        
end
//***************************************************************************************************************************************************