control_unit.v

来自「这是我同学在上海交大实习的时候做的一个单片机的verilog代码实现」· Verilog 代码 · 共 334 行

V
334
字号
module Control_Unit (
  Load_R0, Load_R1, 
  Load_R2, Load_R3, 
  Load_PC, Inc_PC, 
  Sel_Bus_1_Mux, Sel_Bus_2_Mux,
  Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, 
  Load_Carrier, 
  write, instruction, zero, Carrier_flag, clk, rst);
 
  parameter word_size = 16, op_size = 4, state_size = 4;
  parameter address_size = 8;
  parameter src_size = 2, dest_size = 2, Sel1_size = 3, Sel2_size = 2;
  // State Codes
  parameter S_idle = 0, S_fet1 = 1, S_fet2 = 2, S_dec = 3;
  parameter  S_ex1 = 4, S_rd1 = 5;  
  parameter S_wr1 = 6, S_br1 = 7, S_halt = 8, S_brz = 11;  
  parameter S_lw = 9, S_rw =10, S_cmp = 12;
  // Opcodes
  parameter NOP = 0, ADD = 1, SUB = 2, ID_WR = 3, DCC = 4;
  parameter RD  = 5, WR =  6,  BR =  7, BRZ = 8, ADDC = 9, ID_RD = 10;  
  parameter shift = 11, ACC = 12, BRC = 13, compare = 14, LD = 15;
  // Source and Destination Codes  
  parameter R0 = 0, R1 = 1, R2 = 2, R3 = 3;  

  output Load_R0, Load_R1, Load_R2, Load_R3;
  output Load_PC, Inc_PC;
  output [Sel1_size-1:0] Sel_Bus_1_Mux;
  output Load_IR, Load_Add_R;
  output Load_Reg_Y, Load_Reg_Z, Load_Carrier;
  output [Sel2_size-1: 0] Sel_Bus_2_Mux;
  output write;
  input [word_size-1: 0] instruction;
  input zero, Carrier_flag;
  input clk, rst;
 
  reg [state_size-1: 0] state, next_state;
  reg Load_R0, Load_R1, Load_R2, Load_R3, Load_PC, Inc_PC;
  reg Load_IR, Load_Add_R, Load_Reg_Y;
  reg Sel_ALU, Sel_Bus_1, Sel_Mem;
  reg Sel_R0, Sel_R1, Sel_R2, Sel_R3, Sel_PC, Sel_Ins;
  reg Load_Reg_Z, Load_Carrier, write;
  reg err_flag;

  wire [op_size-1:0] opcode = instruction [15:12];
  wire [src_size-1: 0] src = instruction [11:10];
  wire [dest_size-1:0] dest = instruction [9:8];
  wire [7:0] address = instruction [7:0];
 
  // Mux selectors
  assign  Sel_Bus_1_Mux[Sel1_size-1:0] = Sel_R0 ? 0:
				                             Sel_R1 ? 1:
				                             Sel_R2 ? 2:
				                             Sel_R3 ? 3:
				                             Sel_PC ? 4: 
				                            Sel_Ins ? 5 : 3'bx;  // 3-bits, sized number

  assign  Sel_Bus_2_Mux[Sel2_size-1:0] = Sel_ALU ? 0:
				                             Sel_Bus_1 ? 1:
				                             Sel_Mem ? 2: 2'bx;

  always @ (posedge clk or negedge rst) 
  begin: State_transitions
    if (rst == 0) 
       state <= S_idle; 
    else 
       state <= next_state; 
  end

  always @ (state or opcode or zero) 
  begin: Output_and_next_state 
    Sel_R0 = 0; 	Sel_R1 = 0;     	Sel_R2 = 0;    	Sel_R3 = 0;     	Sel_PC = 0; Sel_Ins = 0;
    Load_R0 = 0; 	Load_R1 = 0; 	Load_R2 = 0; 	Load_R3 = 0;	Load_PC = 0;

    Load_IR = 0;	Load_Add_R = 0;	Load_Reg_Y = 0;	Load_Reg_Z = 0; Load_Carrier = 0;
    Inc_PC = 0; 
    Sel_Bus_1 = 0; 
    Sel_ALU = 0; 
    Sel_Mem = 0; 
    write = 0; 
    err_flag = 0;	// Used for de-bug in simulation		
    next_state = state;

    case  (state)//״̬
    S_idle:		next_state = S_fet1;      
    S_fet1:		begin       	  	  	
             next_state = S_fet2; 
      	  	  	Sel_PC = 1;
  	  	  		 Sel_Bus_1 = 1;
 	  	   		 Load_Add_R = 1; 
    				 end
  	 S_fet2:		begin 		
             next_state = S_dec; 
             Sel_Mem = 1;
  	  	  		 Load_IR = 1; 
  	  	  		 Inc_PC = 1;
    				 end

  	 S_dec:  	case  (opcode) 
      		 		  NOP: next_state = S_fet1;
		  		  ADD, SUB, ADDC,LD, shift: 
		  		  begin
 		    		    next_state = S_ex1;
		    		    Sel_Bus_1 = 1;
		    		    Load_Reg_Y = 1;
		     		   case  (src)
		      		         R0: 		Sel_R0 = 1; 
		      		         R1: 		Sel_R1 = 1; 
		      		         R2: 		Sel_R2 = 1;
		      		         R3: 		Sel_R3 = 1; 
		      		         default : 	err_flag = 1;
		    		     endcase   
               end 
                
               compare:
                begin
                    next_state = S_cmp;
                    Sel_Bus_1 = 1;
		    		        Load_Reg_Y = 1;
		    		        case  (src)
		      		         R0: 		Sel_R0 = 1; 
		      		         R1: 		Sel_R1 = 1; 
		      		         R2: 		Sel_R2 = 1;
		      		         R3: 		Sel_R3 = 1; 
		      		         default : 	err_flag = 1;
		    		        endcase   

                end
                
                ACC,DCC: 
                begin
		               next_state=S_fet1;
						   case  (dest)
			      	       R0: begin Sel_R0 = 1; Load_R0 = 1; end			      
   				           R1: begin Sel_R1 = 1; Load_R1 = 1; end
			      	       R2: begin Sel_R2 = 1; Load_R2 = 1; end			      
 			      	       R3: begin Sel_R3 = 1; Load_R3 = 1; end 
			      	     default : 	err_flag = 1;
			    	       endcase
		               Sel_ALU =1;
                 end

			 	/*  NOT: begin
			    	    next_state = S_fet1;
			    	    Load_Reg_Z = 1;
			    	    Sel_Bus_1 = 1; 
			    	    Sel_ALU = 1; 
		 	     	    case  (src)
			      	      R0: 		Sel_R0 = 1;			      
      				          R1: 		Sel_R1 = 1;
			      	      R2: 		Sel_R2 = 1;			      
 			      	      R3: 		Sel_R3 = 1; 
			      	      default : 	err_flag = 1;
			    	    endcase   
  			     	    case  (dest)
			      	      R0: 		Load_R0 = 1; 
			      	      R1: 		Load_R1 = 1;			      
      				          R2: 		Load_R2 = 1;
			      	      R3: 		Load_R3 = 1;			      
      				      default: 	err_flag = 1;
			    	    endcase   
                 end  NOT */
  				  
               RD: begin
			    	     next_state = S_rd1;
			    	     Sel_Ins = 1; Sel_Bus_1 = 1; Load_Add_R = 1; 
                   end // RD

			  	   WR: begin
			    	     next_state = S_wr1;
			    	     Sel_Ins = 1; Sel_Bus_1 = 1; Load_Add_R = 1; 
                   end  // WR

               ID_RD: 
               begin
					      next_state=S_lw;
						   case  (src)
		      		           R0: 		Sel_R0 = 1; 
		      		           R1: 		Sel_R1 = 1; 
		      		           R2: 		Sel_R2 = 1;
		      		           R3: 		Sel_R3 = 1; 
		      		           default : 	err_flag = 1;
		    		         endcase  
				         Sel_Bus_1=1;
							Load_Add_R=1;
					 end
					 ID_WR: 
					 begin
			            next_state=S_rw;
						   case  (dest)
		      		           R0: 		Sel_R0 = 1; 
		      		           R1: 		Sel_R1 = 1; 
		      		           R2: 		Sel_R2 = 1;
		      		           R3: 		Sel_R3 = 1; 
		      		           default : 	err_flag = 1;
		    		         endcase  
							Sel_Bus_1=1;
							Load_Add_R=1;
					end
          
  
			  	   BR: begin 
			    	     next_state = S_br1;  
                   Sel_Ins = 1; Sel_Bus_1 = 1; Load_Add_R = 1; 
			    	     end  // BR
	
  				   BRZ:begin
  				       next_state=S_brz;
                   case  (dest)
			      	     R0: 		Sel_R0 = 1;			      
   				         R1: 		Sel_R1 = 1;
			      	     R2: 		Sel_R2 = 1;			      
 			      	     R3: 		Sel_R3 = 1; 
			      	     default : 	err_flag = 1;
			          endcase
                    Load_Reg_Z= 1; 
  				      end
              BRC: 
              begin
               if(Carrier_flag==1)
				   begin
					     next_state = S_br1; 
                    Sel_Ins = 1; 
                    Sel_Bus_1 = 1; 
                    Load_Add_R = 1;
				   end
					else 
						  next_state= S_fet1; 
					end  
                  
        		  		  default : next_state = S_halt;
				endcase  // (opcode)
				
				

	  S_ex1:		begin 
  			  	  next_state = S_fet1;
			  	  Load_Reg_Z = 1;
			  	  Sel_ALU = 1; 
			  	  Load_Carrier = 1;
		 	   	 case  (dest)
  	    		    	    R0: begin Sel_R0 = 1; Load_R0 = 1; end
			    	    R1: begin Sel_R1 = 1; Load_R1 = 1; end
			    	    R2: begin Sel_R2 = 1; Load_R2 = 1; end
			    	    R3: begin Sel_R3 = 1; Load_R3 = 1; end
			    	    default : err_flag = 1; 
			   	  endcase 
				end 

	  S_rd1:		begin 
              next_state = S_fet1;
			  	  Sel_Mem = 1;
              case (dest)
                  R0:Load_R0 = 1;
                  R1:Load_R1 = 1;
                  R2:Load_R2 = 1;
                  R3:Load_R3 = 1;
                  default:err_flag = 1;
              endcase
				end

	 S_wr1: 		begin
			  	  next_state = S_fet1;
              write = 1;
              case (src)
                  R0:Sel_R0 = 1;
                  R1:Sel_R1 = 1;
                  R2:Sel_R2 = 1;
                  R3:Sel_R3 = 1;
                  default:err_flag = 1;
              endcase
				end 

    S_brz: begin
                if (zero == 1) 
                begin
			    	    next_state = S_br1; 
                  Sel_Ins = 1; Sel_Bus_1 = 1; Load_Add_R = 1; 
			    	  end // BRZ
			  	    else 
			  	    begin 
                      next_state = S_fet1; 
                  end
                
            end
            
	 S_br1:		begin 
    	      	next_state = S_fet1;  
    	      	Sel_Mem = 1;
    	      	Load_PC = 1;
    	      	end
    	      	
   	S_lw:   begin
						next_state=S_fet1;
					   Sel_Mem=1;
						 case  (dest)
  	    		    	          R0:  Load_R0 = 1; 
			    	          R1:  Load_R1 = 1; 
			    	           R2:  Load_R2 = 1; 
			    	           R3:  Load_R3 = 1; 
			    	  default : err_flag = 1; 
			   	      endcase  
	         end
					
	 S_rw:    begin
						 next_state=S_fet1;
						 case  (src)
 			    	        R0: 		Sel_R0 = 1;		 	    
  				          R1: 		Sel_R1 = 1;		 	    
   				          R2: 		Sel_R2 = 1; 		 	    
   				          R3: 		Sel_R3 = 1;			    
  				          default : 	err_flag = 1;
		             endcase
						 write=1;
					end
					
	 S_cmp: begin
					    next_state=S_fet1;
					    Load_Carrier = 1;
						 case  (dest)
 			    	         R0: 		Sel_R0 = 1;		 	    
  				           R1: 		Sel_R1 = 1;		 	    
   				           R2: 		Sel_R2 = 1; 		 	    
   				           R3: 		Sel_R3 = 1;			    
  				           default : 	err_flag = 1;
		             endcase
            end
    	      	
    	   //   	S_br2:		begin next_state = S_fet1; Sel_Mem = 1; Load_PC = 1; end
	  S_halt:  		next_state = S_halt;
	  default:		next_state = S_idle;
    endcase    
  end
endmodule

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?