111 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Verilog
		
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Verilog
		
	
	
	
| module controller(
 | |
| 	input clk,
 | |
| 	input rst,
 | |
| 	input[3:0] opcode,
 | |
| 	output[11:0] out
 | |
| );
 | |
| 
 | |
| localparam SIG_HLT       = 11;
 | |
| localparam SIG_PC_INC    = 10;
 | |
| localparam SIG_PC_EN     = 9;
 | |
| localparam SIG_MEM_LOAD  = 8;
 | |
| localparam SIG_MEM_EN    = 7;
 | |
| localparam SIG_IR_LOAD   = 6;
 | |
| localparam SIG_IR_EN     = 5;
 | |
| localparam SIG_A_LOAD    = 4;
 | |
| localparam SIG_A_EN      = 3;
 | |
| localparam SIG_B_LOAD    = 2;
 | |
| localparam SIG_ADDER_SUB = 1;
 | |
| localparam SIG_ADDER_EN  = 0;
 | |
| 
 | |
| localparam OP_LDA = 4'b0000;
 | |
| localparam OP_ADD = 4'b0001;
 | |
| localparam OP_SUB = 4'b0010;
 | |
| localparam OP_HLT = 4'b1111;
 | |
| 
 | |
| reg[2:0]  stage;
 | |
| reg[11:0] ctrl_word;
 | |
| 
 | |
| always @(negedge clk, posedge rst) begin
 | |
| 	if (rst) begin
 | |
| 		stage <= 0;
 | |
| 	end else begin
 | |
| 		if (stage == 5) begin
 | |
| 			stage <= 0;
 | |
| 		end else begin
 | |
| 			stage <= stage + 1;
 | |
| 		end
 | |
| 	end
 | |
| end
 | |
| 
 | |
| always @(*) begin
 | |
| 	ctrl_word = 12'b0;
 | |
| 
 | |
| 	case (stage)
 | |
| 		0: begin
 | |
| 			ctrl_word[SIG_PC_EN] = 1;
 | |
| 			ctrl_word[SIG_MEM_LOAD] = 1;
 | |
| 		end
 | |
| 		1: begin
 | |
| 			ctrl_word[SIG_PC_INC] = 1;
 | |
| 		end
 | |
| 		2: begin
 | |
| 			ctrl_word[SIG_MEM_EN] = 1;
 | |
| 			ctrl_word[SIG_IR_LOAD] = 1;
 | |
| 		end
 | |
| 		3: begin
 | |
| 			case (opcode)
 | |
| 				OP_LDA: begin
 | |
| 					ctrl_word[SIG_IR_EN] = 1;
 | |
| 					ctrl_word[SIG_MEM_LOAD] = 1;
 | |
| 				end
 | |
| 				OP_ADD: begin
 | |
| 					ctrl_word[SIG_IR_EN] = 1;
 | |
| 					ctrl_word[SIG_MEM_LOAD] = 1;
 | |
| 				end
 | |
| 				OP_SUB: begin
 | |
| 					ctrl_word[SIG_IR_EN] = 1;
 | |
| 					ctrl_word[SIG_MEM_LOAD] = 1;
 | |
| 				end
 | |
| 				OP_HLT: begin
 | |
| 					ctrl_word[SIG_HLT] = 1;
 | |
| 				end
 | |
| 			endcase
 | |
| 		end
 | |
| 		4: begin
 | |
| 			case (opcode)
 | |
| 				OP_LDA: begin
 | |
| 					ctrl_word[SIG_MEM_EN] = 1;
 | |
| 					ctrl_word[SIG_A_LOAD] = 1;
 | |
| 				end
 | |
| 				OP_ADD: begin
 | |
| 					ctrl_word[SIG_MEM_EN] = 1;
 | |
| 					ctrl_word[SIG_B_LOAD] = 1;
 | |
| 				end
 | |
| 				OP_SUB: begin
 | |
| 					ctrl_word[SIG_MEM_EN] = 1;
 | |
| 					ctrl_word[SIG_B_LOAD] = 1;
 | |
| 				end
 | |
| 			endcase
 | |
| 		end
 | |
| 		5: begin
 | |
| 			case (opcode)
 | |
| 				OP_ADD: begin
 | |
| 					ctrl_word[SIG_ADDER_EN] = 1;
 | |
| 					ctrl_word[SIG_A_LOAD] = 1;
 | |
| 				end
 | |
| 				OP_SUB: begin
 | |
| 					ctrl_word[SIG_ADDER_SUB] = 1;
 | |
| 					ctrl_word[SIG_ADDER_EN] = 1;
 | |
| 					ctrl_word[SIG_A_LOAD] = 1;
 | |
| 				end
 | |
| 			endcase
 | |
| 		end
 | |
| 	endcase
 | |
| end
 | |
| 
 | |
| assign out = ctrl_word;
 | |
| 
 | |
| endmodule
 | |
| 
 |