OpenCores
URL https://opencores.org/ocsvn/socgen/socgen/trunk

Subversion Repositories socgen

[/] [socgen/] [trunk/] [Projects/] [opencores.org/] [Mos6502/] [ip/] [core/] [rtl/] [verilog/] [sequencer] - Rev 131

Compare with Previous | Blame | View Log


module `VARIANT`SEQUENCER

#(parameter VEC_TABLE = 8'hff,
  parameter STATE_SIZE=3
)

(

    input  wire            clk,         
    input  wire            reset,        
    input  wire            enable,
    input  wire            now_fetch_op,
    input  wire    [STATE_SIZE:0]   state,         // current and next state registers
    input  wire    [1:0]   cmd,         
    input  wire    [7:0]   vector,         
    input  wire    [1:0]   length,         
    input  wire    [7:0]   alu_a,     
    input  wire    [7:0]   alu_result,    // result from alu operation
    input  wire    [7:0]   alu_status,    // 
    input  wire    [7:0]   data_in,       // data that comes from the bus controller
    input  wire    [15:0]  prog_data16,       // data that comes from the bus controller
    input  wire    [7:0]   prog_data,
    input  wire    [7:0]   pg0_data,
    input  wire    [7:0]   index,         // selected index 

    input  wire    [1:0]   ins_type,
    input  wire    [2:0]   alu_op_a_sel,

    input  wire            implied,
    input  wire            immediate,  
    input  wire            relative,
    input  wire            absolute,
    input  wire            zero_page,
    input  wire            indirectx,
    input  wire            indirecty, 
    input  wire            stack,
    input  wire            jump_indirect,

    input  wire            brk,
    input  wire            rti,
    input  wire            rts,
    input  wire            jump,
    input  wire            jsr,
 
    input  wire            branch_inst, 


    output  reg            fetch_op,
    output  reg   [15:0]   prog_counter,            // program counter


    output  reg   [15:0]   address,       // system bus address
    output  reg            alu_enable,       
 
    output  reg    [7:0]   pg0_add,       
    output  reg            pg0_wr,       
    output  reg            pg0_rd,       


    output  reg   [7:0]    operand,        
    output  reg   [7:0]    imm_data,       
    output  reg            rd,        // read = 1
    output  reg            wr,        // write = 1
    output  reg    [7:0]   data_out,      // data that will be written somewhere else


    output  reg    [15:0]  offset,

    output  reg            stk_push,
    output  reg  [15:0]    stk_push_data,
    output  reg            stk_pull,
    input  wire  [15:0]    stk_pull_data      
);

   




  reg              stk_push_p;


   

 wire [15:0]   next_pc;             // a simple logic to add one to the PC
 wire  [8:0]   p_indexed;  
 
 assign next_pc              = prog_counter + 16'b0000000000000001;
 assign p_indexed            = prog_data +index;

   

always @ (posedge clk ) 
   if (reset)     stk_push              <= 1'b1;  
   else           stk_push              <= stk_push_p  || 
                                           (stack   &&   !enable &&   (state == `EXECUTE )  &&     (ins_type == `ins_type_write )) ||   
                                           (              enable &&   (state != `INT_1 )  &&     now_fetch_op &&   (cmd == `cmd_load_vec))  ;




   

   

always @ (posedge clk ) begin 
   if (reset) 
        begin
            stk_push_p      <=  1'b0;
           
        end 
   else if(!enable)
        begin
            stk_push_p      <=  1'b0;
        end
    else begin
            case (state)
                
                `EXECUTE: 
                    begin
                     if( jsr )  
                          begin
                          stk_push_p         <= 1'b1;
                          end            
                    end

                default: 
                  begin
                   stk_push_p      <=  1'b0;
                  end                    
            endcase
        end
    end






   

always @ (posedge clk ) begin 
   if (reset) 
        begin
            stk_pull        <=  1'b0;
           
        end 
   else if( enable)
        begin
            stk_pull        <=  1'b0;
        end
    else begin
            case (state)
                

                `EXECUTE: 
                    begin
                     if( rts || rti)  
                       begin
                       stk_pull               <= 1'b1;            
                       end
                     else
                     if( stack )  
                       begin
                        if(ins_type == `ins_type_read )
                         begin
                         stk_pull             <= 1'b1;            
                         end 
                       end

                    end

                default: 
                  begin
                   stk_pull        <=  1'b0;     
                  end                    
            endcase
        end
    end



   









   
always @ (posedge clk ) 
   begin 
   if (reset)                                      stk_push_data      <= 16'h0000;
   else 
   if((state ==  `AXE_1)  &&  jsr )                stk_push_data      <= prog_counter;
   else
   if((cmd == `cmd_load_vec) && now_fetch_op )     stk_push_data      <= prog_counter;
   else                                            stk_push_data      <= (alu_op_a_sel ==  `alu_op_a_psr)? {alu_status,alu_status}:{alu_a,alu_a};
   end




   
always @ (posedge clk ) 
   begin 
   if (reset) 
        begin
            prog_counter    <= 16'h0000;  
            alu_enable      <=  1'b0;
            pg0_add         <=  8'h00;
            pg0_wr          <=  1'b0;
            pg0_rd          <=  1'b0;
            fetch_op        <=  1'b0;
            operand         <=  8'h00;        
            imm_data        <=  8'h00;
            address         <= 16'h0000;
            rd          <=  1'b0;       
            wr          <=  1'b0;
            data_out        <=  8'h00;
            offset          <=  16'h0000;
        end // if (reset)
   else if(!enable)





           begin
            case (state)
                


                `EXECUTE: 
                    begin
                     if( jump || jsr || absolute)  
                       begin
                       prog_counter           <= next_pc;                         
                       end

                    end


              
                `AXE_1: 
                    begin

                     if( jump || jsr  )  
                       begin
                          prog_counter       <= {prog_data,address[7:0]};
                          end
                     else
                     if( absolute  )  
                       begin
                        address               <= {prog_data,8'h00}  + {7'b0000000,address[8:0]};
                        if((ins_type == `ins_type_read) || (ins_type == `ins_type_rmw))
                           begin
                           rd             <= 1'b1;                           
                           end
                          end                     

                       
                    end 





              
              
              default:
             begin
            prog_counter    <=  prog_counter;      
            pg0_add         <=  pg0_add;
            pg0_wr          <=  pg0_wr;
            pg0_rd          <=  pg0_rd;    
            alu_enable      <=  alu_enable;
            operand         <=  operand;
            imm_data        <=  imm_data;
            address         <=  address;
            rd          <=  rd;
            fetch_op        <=  fetch_op;
            wr          <=  wr;
            data_out        <=  data_out;
            offset          <=  offset;
        end
            endcase // case (state)
           end


              
    else begin
            case (state)
                
                `RESET: 
                    begin 
                     prog_counter             <=  {VEC_TABLE,vector}; 
                    end

                `FETCH_OP:
                    begin 
                     prog_counter             <= next_pc;
                    end

                `EXECUTE: 
                    begin
                       alu_enable             <= 1'b0;
                       wr                 <= 1'b0;
                       pg0_wr                 <= 1'b0;
                     if(immediate)  
                       begin
                       prog_counter           <= next_pc;                 
                       imm_data               <= prog_data;
                       alu_enable             <= 1'b1;
                       fetch_op               <= 1'b1;  
                       end          
                     else
                     if(zero_page  )  
                       begin
                       prog_counter           <= next_pc;                 
                       address                <= {8'h00,p_indexed[7:0]};
                       pg0_add                <= p_indexed[7:0];
                       alu_enable             <= 1'b1;
                       fetch_op               <= 1'b1;            
                       if((ins_type == `ins_type_read) || (ins_type == `ins_type_rmw))
                          begin
                          pg0_rd              <= 1'b1;
                          end
                       end
                     else
                     if( absolute || jump  || jsr || jump_indirect)  
                       begin
                       prog_counter           <= next_pc;                 
                       address                <= {7'b0000000,p_indexed};
                       pg0_add                <= p_indexed[7:0];          
                       end
                     else
                     if( relative )  
                       begin
                         fetch_op             <= 1'b1;  
                         alu_enable           <= 1'b1; 
                         if(branch_inst)
                         prog_counter         <= prog_counter + 1'b1 + { prog_data[7],prog_data[7],prog_data[7],prog_data[7], 
                                                 prog_data[7],prog_data[7],prog_data[7],prog_data[7],prog_data} ;
                         else
                         prog_counter         <= next_pc;                  
                       end          
                     else

                     if( rts || rti)  
                       begin
                       prog_counter           <= stk_pull_data;
                       end
                     else

                     if( stack )  
                       begin
                       prog_counter           <= next_pc;                         
                        if(ins_type == `ins_type_read )
                         begin
                         operand              <= stk_pull_data[7:0];                     
                         end 
                       end
                     else

                     if(indirectx  )  
                       begin
                       prog_counter           <= next_pc;                 
                       pg0_add                <= p_indexed[7:0];
                       pg0_rd                 <= 1'b1;
                       end 
                     else
                     if(indirecty  )  
                       begin
                       prog_counter           <= next_pc;                 
                       pg0_add                <= prog_data;
                       pg0_rd                 <= 1'b1;
                       end 
                     else
                      prog_counter            <= next_pc;                
                    end


              
                `EXE_1: 
                    begin
                     if(immediate )  
                       begin
                        fetch_op              <=  1'b0;  
                        prog_counter          <= next_pc;             
                        alu_enable            <= 1'b0;
                        end          
                     else
                     if(zero_page  )  
                       begin
                        fetch_op              <=  1'b0;    
                        prog_counter          <= next_pc;               
                        rd                <= 1'b0;
                        wr                <= 1'b0;
                        pg0_rd                <= 1'b0;
                        operand               <= data_in;
                        alu_enable            <= 1'b0;
                       if((ins_type == `ins_type_write ) || (ins_type == `ins_type_rmw ))
                          begin
                          pg0_wr              <= 1'b1;
                          data_out            <= alu_result;               
                          end                 
                        end          
                     else
                     if( relative )  
                       begin
                          fetch_op            <= 1'b0;  
                          alu_enable          <= 1'b0; 
                          prog_counter        <= next_pc;                  
                          end       
                     else
                     prog_counter            <= next_pc;             
                    end 



                `AXE_1: 
                    begin
                     if(absolute  )  
                       begin
                        fetch_op              <=  1'b1;    
                        prog_counter          <= prog_counter;           
                        alu_enable            <= 1'b1;
                        end          
                     else
                     if(  jump || jsr)  
                       begin
                          fetch_op           <=  1'b1;  
                          prog_counter       <= prog_counter;
                          end
                     else
                     if( jump_indirect )  
                          begin
                          prog_counter       <= next_pc;
                          address            <= {prog_data,address[7:0]};
                          end                                  
                     else            
                     prog_counter            <= next_pc;             
                    end 


              

              


                `AXE_2: 
                     begin
                     fetch_op          <= 1'b0;
                     prog_counter      <= next_pc;
                     rd            <= 1'b0;
                     pg0_rd            <= 1'b0;
                     operand           <= data_in;
                     alu_enable        <= 1'b0;  
                     if(absolute  )  
                       begin
                        if((ins_type == `ins_type_rmw ) || (ins_type == `ins_type_write ))
                           begin
                           wr       <= 1'b1;
                           data_out     <= alu_result;                                          
                           end                 
                       end                      
                     end
              

                      


                `IDX_1: 
                     begin
                     prog_counter     <= prog_counter;
                     address[7:0]     <= pg0_data;
                     pg0_add          <= pg0_add + 1'b1;
                     pg0_rd           <= 1'b1;
                     end


                `IDX_2: 
                     begin
                     prog_counter     <= prog_counter;
                     address[15:8]    <= pg0_data;
                     pg0_add          <= address[7:0];
                     alu_enable       <= 1'b1;
                     fetch_op         <= 1'b1;                          
                     if( ins_type == `ins_type_read)
                          begin
                          rd      <= 1'b1;
                          pg0_rd      <= 1'b1;
                          end
                     else
                     if(ins_type == `ins_type_write )
                          begin
                          wr       <= 1'b1;
                          pg0_rd       <= 1'b0;
                          data_out     <= alu_result;               
                          end                 
                     end

                `IDX_3: 
                     begin
                     fetch_op         <= 1'b0;    
                     prog_counter     <= next_pc;
                     alu_enable       <= 1'b0;
                     rd           <= 1'b0;
                     wr           <= 1'b0;
                     pg0_rd           <= 1'b0;
                     pg0_wr           <= 1'b0;
                        
                     end

                `IDY_1: 
                     begin
                     prog_counter    <= prog_counter;
                     address[8:0]    <= pg0_data + index;
                     pg0_add         <= pg0_add + 1'b1;
                     pg0_rd          <= 1'b1;
                     end


                `IDY_2: 
                     begin
                     prog_counter     <= prog_counter;
                     address[15:8]    <= pg0_data + {7'b0,address[8]} ;
                     pg0_add          <= address[7:0];
                     pg0_rd           <= 1'b0;
                     alu_enable       <= 1'b1;
                     fetch_op         <=  1'b1;                         
                     if( ins_type == `ins_type_read)
                          begin
                          rd      <= 1'b1;
                          pg0_rd      <= 1'b1;
                          end
                     else
                     if(ins_type == `ins_type_write )
                       begin
                          pg0_rd      <= 1'b0;
                          wr      <= 1'b1;
                          data_out    <= alu_result;               
                          end                 
                     end


                `IDY_3: 
                     begin
                     fetch_op         <=  1'b0;    
                     prog_counter     <= next_pc;
                     alu_enable       <= 1'b0;
                     rd           <= 1'b0;
                     wr           <= 1'b0;
                     pg0_rd           <= 1'b0;
                     pg0_wr           <= 1'b0;
                        
                     end



                `INT_1: 
                    begin
                    alu_enable               <= 1'b0;
                    if(cmd == `cmd_load_vec)
                       begin 
                       address               <=  16'h0000;
                       rd                <=  1'b0;
                       prog_counter          <=  {VEC_TABLE,vector}; 
                       end
                    else              
                       begin 
                       prog_counter          <=  prog_data16;
                       end
                    end

              
              
           
                `INT_2: 
                    begin 
                     address               <=  16'h0000;
                     rd                <=  1'b0;               
                     prog_counter          <=  prog_data16;
                    end



              
                `HALT: 
                    begin 
                    address                <= 16'h0000;
                    rd                 <= 1'b0;
                    wr                 <= 1'b0;
                    end
           
                default: 
                  begin
                    address                <= 16'h0000;
                    prog_counter           <= 16'h0000;
                    rd                 <= 1'b0;
                    wr                 <= 1'b0;
                end                    
            endcase
        end
    end






   


endmodule



Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.