OpenCores
URL https://opencores.org/ocsvn/2d_game_console/2d_game_console/trunk

Subversion Repositories 2d_game_console

[/] [2d_game_console/] [trunk/] [Processor_ModelSim/] [Processor_Controller.v] - Rev 2

Compare with Previous | Blame | View Log

module Processor_Controller(
 
ram_grant,
instruction,
clock,
reset,
 
isr_addr,
int_req,
 
v_sync,
sleep,
 
ram_q,
 
add_overflow,
add_result,	
sub_overflow,
sub_result,	
mult_result,
divide_quotient,
divide_remain,
compare_aeb,
compare_agb,
compare_alb,
 
int_ack,
rom_addr,
opcode,
reg_a_num,
reg_b_num,
reg_c_num,
imm,
rflags_index,
const_bool,
 
sprite_level,
sprite_id,
sprite_x,
sprite_y,
sprite_color,
 
ram_addr,
ram_data,
ram_wren,
ram_req,
 
reg_c_val,
reg_b_val,
reg_a_val,
 
current_state,
next_state,
program_counter,
registers,
rflags,
v_sync_flag,
stack_pointer,
pc_stack,
pc_stack_val,
int_program_counter,
int_rflags
 
);
 
 
input	[15:0]	ram_q;
input	[15:0]	isr_addr;
input [31:0]	instruction;
 
input wire signed	[15:0]	add_result;
input wire signed	[15:0]	sub_result;
input wire signed	[31:0]	mult_result;
input wire signed	[15:0]	divide_quotient;
input	wire signed [15:0]	divide_remain;
 
input		ram_grant;
input		add_overflow;
input		sub_overflow;
input		compare_aeb;
input		compare_agb;
input		compare_alb;
input		int_req;
 
input		sleep;
input		v_sync;
 
input 	clock;
input 	reset;
 
output				v_sync_flag;
output				const_bool;
output	[2:0]		rflags_index;
output	[4:0]		reg_a_num;
output	[4:0]		reg_b_num;
output	[4:0]		reg_c_num;
output	[5:0]		opcode;
output	[15:0]	imm;
 
output reg	[15:0]	reg_a_val;
output reg	[15:0]	reg_b_val;
output reg	[15:0]	reg_c_val;
 
output reg	[15:0]	ram_addr;
output reg	[15:0]	ram_data;
output reg				ram_wren;
output reg				ram_req;
 
output reg				int_ack;
output reg	[15:0]	int_program_counter;
output reg	[7:0]		int_rflags;
 
output reg	[15:0]	rom_addr;
output reg	[15:0]	program_counter;
output reg	[511:0]	registers;
output reg	[7:0]		rflags;
 
output reg	[2:0]		stack_pointer;
output reg	[127:0]	pc_stack;
output reg	[15:0]	pc_stack_val;
 
output reg	[5:0]		sprite_level;
output reg	[383:0]	sprite_id;
output reg	[639:0]	sprite_x;
output reg	[639:0]	sprite_y;
output reg	[1023:0]	sprite_color;
 
assign	opcode			=	instruction[31:26];
assign	reg_a_num		=	instruction[25:21];
assign	reg_b_num		=	instruction[20:16];
assign	reg_c_num		=	instruction[15:11];
assign	imm				=	instruction[15:0];
assign	const_bool		=	instruction[17];
assign	rflags_index	=	instruction[20:18];
 
 
// Number of Interrupt Service Routines
parameter code_start_addr = 16'd4;
 
// INSTRUCTIONS OPERATION CODE
// Data Transfer Instructions
parameter opcode_lw						= 6'b001001;
parameter opcode_sw						= 6'b001010;
parameter opcode_limm					= 6'b001100;
// Arithmetic Instructions
parameter opcode_add						= 6'b010001;
parameter opcode_sub						= 6'b010010;
parameter opcode_mul						= 6'b010100;
parameter opcode_div						= 6'b010101;
// Logical Instructions
parameter opcode_and						= 6'b100001;
parameter opcode_or						= 6'b100010;
parameter opcode_cmp						= 6'b100100;
parameter opcode_not						= 6'b100101;
// Control Transfer Instructions (Immediate)
parameter opcode_jmp						= 6'b101001;
parameter opcode_brfl					= 6'b101010;
parameter opcode_call					= 6'b101011;
parameter opcode_ret						= 6'b101100;
parameter opcode_iret					= 6'b101101;
parameter opcode_nop						= 6'b101110;
// Control Transfer Instructions (Register)
parameter opcode_jr						= 6'b011001;
parameter opcode_brflr 					= 6'b011010;
parameter opcode_callr					= 6'b011011;
// Graphical instructions
parameter opcode_sprite_id				= 6'b110001;
parameter opcode_sprite_color			= 6'b110010;
parameter opcode_sprite_pos			= 6'b110100;
parameter opcode_wait_vsync			= 6'b110111;
 
 
/*########################################################################*/
/*#################  Video vertical sync edge-detection  #################*/
/*########################################################################*/
 
reg   v_sync_delay;
 
always @ (posedge clock)
begin
	v_sync_delay <= v_sync;
end
 
assign v_sync_flag = ~v_sync & v_sync_delay;
 
/*########################################################################*/
/*########################################################################*/
 
 
/*########################################################################*/
/*########################  FINITE STATE MACHINE  ########################*/
/*########################  PROCESSOR CONTROLLER  ########################*/
/*########################################################################*/
 
output reg	[5:0]		current_state;
output reg	[5:0]		next_state;
 
// States
parameter	Reset						= 6'b000000;	// Reset						= 0
parameter	Wait_Program_Mem_1	= 6'b000001;	// Wait_Program_Mem_1	= 1
parameter	Decode_Instruction	= 6'b000010;	// Decode_Instruction	= 2
parameter	Wait_Operation			= 6'b000011;	// Wait_Operation			= 3
parameter	Wait_DIV_1				= 6'b000100;	// Wait_DIV_1				= 4
parameter	Wait_DIV_2				= 6'b000101;	// Wait_DIV_2				= 5
parameter	Wait_DIV_3				= 6'b000110;	// Wait_DIV_3				= 6
parameter	Wait_DIV_4				= 6'b000111;	// Wait_DIV_4				= 7
parameter	ADD						= 6'b001000;	// ADD						= 8
parameter	SUB						= 6'b001001;	// SUB						= 9
parameter	MUL						= 6'b001010;	// MUL						= 10
parameter	DIV						= 6'b001011;	// DIV						= 11
parameter	AND						= 6'b001100;	// AND						= 12
parameter	OR							= 6'b001101;	// OR							= 13
parameter	CMP						= 6'b001110;	// CMP						= 14
parameter	NOT						= 6'b001111;	// NOT						= 15
parameter	SPRITE_ID				= 6'b010000;	// SPRITE_ID				= 16
parameter	SPRITE_COLOR			= 6'b010001;	// SPRITE_COLOR			= 17
parameter	SPRITE_POS				= 6'b010010;	// SPRITE_POS				= 18
parameter	LIMM						= 6'b010011;	// LIMM						= 19
parameter	LW_Begin					= 6'b010100;	// LW_Begin					= 20
parameter	LW_Wait_1				= 6'b010101;	// LW_Wait_1				= 21
parameter	LW_Wait_2				= 6'b010110;	// LW_Wait_2				= 22
parameter	LW_End					= 6'b010111;	// LW_End					= 23
parameter	SW_Begin					= 6'b011000;	// SW_Begin					= 24
parameter	SW_End					= 6'b011001;	// SW_End					= 25
parameter	JMP						= 6'b011010;	// JMP						= 26
 
parameter	JR							= 6'b011011;	// JR							= 27
parameter	BRFL						= 6'b011100;	// BRFL						= 28
parameter	BRFLR						= 6'b011101;	// BRFL						= 29
 
parameter	NOP						= 6'b011110;	// NOP						= 30
 
parameter	CALL						= 6'b011111;	// CALL						= 31
parameter	CALLR						= 6'b100000;	// CALLR						= 32
parameter	RET						= 6'b100001;	// RET						= 33
parameter	WAIT_VSYNC				= 6'b100010;	// WAIT_VSYNC				= 34
 
parameter	Inc_Program_Counter	= 6'b100011;	// Inc_Program_Counter	= 35
 
 
parameter	Int_Req_Wait			= 6'b100100;	// Int_Req_Wait			= 36
 
parameter	Interrupt				= 6'b100101;	// Interrupt				= 37
parameter	IRET						= 6'b100110;	// IRET						= 38
 
 
 
// Next State Decoder
always @ (*)
begin
	case (current_state)
 
		// State 0
		Reset:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
		// State 1
		Wait_Program_Mem_1:
		begin
			if (sleep)
				next_state = Wait_Program_Mem_1;
			else if (int_req)
				next_state = Int_Req_Wait;
			else
				next_state = Decode_Instruction;
		end
 
		// State 2
		Decode_Instruction:
		begin
			next_state = Wait_Operation;
		end
 
		// State 3
		Wait_Operation:
		begin
 
			case (opcode)
 
				opcode_add:
				begin
					next_state = ADD;
				end
 
				opcode_sub:
				begin
					next_state = SUB;
				end
 
				opcode_mul:
				begin
					next_state = MUL;
				end
 
				opcode_div:
				begin
					next_state = Wait_DIV_1;
				end
 
				opcode_and:
				begin
					next_state = AND;
				end
 
				opcode_or:
				begin
					next_state = OR;
				end
 
				opcode_cmp:
				begin
					next_state = CMP;
				end
 
				opcode_not:
				begin
					next_state = NOT;
				end
 
				opcode_sprite_id:
				begin
					next_state = SPRITE_ID;
				end
 
				opcode_sprite_color:
				begin
					next_state = SPRITE_COLOR;
				end
 
				opcode_sprite_pos:
				begin
					next_state = SPRITE_POS;
				end
 
				opcode_limm:
				begin
					next_state = LIMM;
				end
 
				opcode_lw:
				begin
					next_state = LW_Begin;
				end
 
				opcode_sw:
				begin
					next_state = SW_Begin;
				end
 
				opcode_jmp:
				begin
					next_state = JMP;
				end
 
 
 
 
				opcode_jr:
				begin
					next_state = JR;
				end
 
				opcode_brfl:
				begin
					if (rflags[rflags_index] == const_bool)
						next_state = BRFL;
					else
						next_state = Inc_Program_Counter;
				end
 
				opcode_brflr:
				begin
					if (rflags[rflags_index] == const_bool)
						next_state = BRFLR;
					else
						next_state = Inc_Program_Counter;
				end
 
				opcode_nop:
				begin
					next_state = NOP;
				end
 
				opcode_call:
				begin
					next_state = CALL;
				end
 
				opcode_callr:
				begin
					next_state = CALLR;
				end
 
				opcode_ret:
				begin
					next_state = RET;
				end
 
				opcode_wait_vsync:
				begin
					next_state = WAIT_VSYNC;
				end
 
				opcode_iret:
				begin
					next_state = IRET;
				end
 
 
 
 
				default:
				begin
					next_state = Reset;
				end
 
			endcase
 
 
		end		
 
		// State 4
		Wait_DIV_1:
		begin
			next_state = Wait_DIV_2;
		end
 
		// State 5
		Wait_DIV_2:
		begin
			next_state = Wait_DIV_3;
		end
 
		// State 6
		Wait_DIV_3:
		begin
			next_state = Wait_DIV_4;
		end
 
		// State 7
		Wait_DIV_4:
		begin
			next_state = DIV;
		end
 
		// State 8
		ADD:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 9
		SUB:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 10
		MUL:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 11
		DIV:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 12
		AND:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 13
		OR:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 14
		CMP:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 15
		NOT:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 16
		SPRITE_ID:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 17
		SPRITE_COLOR:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 18
		SPRITE_POS:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 19
		LIMM:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 20
		LW_Begin:
		begin
			if (ram_grant)
				next_state = LW_Wait_1;
			else
				next_state = LW_Begin;
		end
 
		// State 21
		LW_Wait_1:
		begin
			next_state = LW_Wait_2;
		end
 
		// State 22
		LW_Wait_2:
		begin
			next_state = LW_End;
		end
 
		// State 23
		LW_End:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 24
		SW_Begin:
		begin
			if (ram_grant)
				next_state = SW_End;
			else
				next_state = SW_Begin;
		end
 
		// State 25
		SW_End:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 26
		JMP:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
 
 
 
 
		// State 27
		JR:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
		// State 28
		BRFL:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
		// State 29
		BRFLR:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
		// State 30
		NOP:
		begin
			next_state = Inc_Program_Counter;
		end
 
		// State 31
		CALL:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
		// State 32
		CALLR:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
		// State 33
		RET:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
		// State 34
		WAIT_VSYNC:
		begin
			if (v_sync_flag)
				next_state = Inc_Program_Counter;
			else
				next_state = WAIT_VSYNC;
		end
 
 
 
		// State 35
		Inc_Program_Counter:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
 
		// State 36
		Int_Req_Wait:
		begin
			if (!int_req)
				next_state = Interrupt;
			else
				next_state = Int_Req_Wait;
		end
 
 
		// State 37
		Interrupt:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
 
		// State 38
		IRET:
		begin
			next_state = Wait_Program_Mem_1;
		end
 
 
		default:
		begin
			next_state = Reset;
		end
 
	endcase
 
end
 
 
// Output Decoder
always @ (*)
begin
 
	// Default Assignments
 
	pc_stack_val = pc_stack[16*stack_pointer +: 16];
	reg_a_val = registers[16*reg_a_num +: 16];
	reg_b_val = registers[16*reg_b_num +: 16];
	reg_c_val = registers[16*reg_c_num +: 16];
	sprite_level = registers[16*reg_a_num +: 6];
	rom_addr = program_counter;
	ram_wren = 0;
	ram_req = 0;
 
	case (current_state)
 
		// State 0
		Reset:
		begin
 
		end
 
		// State 1
		Wait_Program_Mem_1:
		begin
 
		end
 
		// State 2
		Decode_Instruction:
		begin
 
		end
 
		// State 3
		Wait_Operation:
		begin
 
		end
 
		// State 4
		Wait_DIV_1:
		begin
 
		end
 
		// State 5
		Wait_DIV_2:
		begin
 
		end
 
		// State 6
		Wait_DIV_3:
		begin
 
		end
 
		// State 7
		Wait_DIV_4:
		begin
 
		end
 
		// State 8
		ADD:
		begin
 
		end
 
		// State 9
		SUB:
		begin
 
		end
 
		// State 10
		MUL:
		begin
 
		end
 
		// State 11
		DIV:
		begin
 
		end
 
		// State 12
		AND:
		begin
 
		end
 
		// State 13
		OR:
		begin
 
		end
 
		// State 14
		CMP:
		begin
 
		end
 
		// State 15
		NOT:
		begin
 
		end
 
		// State 16
		SPRITE_ID:
		begin
 
		end
 
		// State 17
		SPRITE_COLOR:
		begin
 
		end
 
		// State 18
		SPRITE_POS:
		begin
 
		end
 
		// State 19
		LIMM:
		begin
 
		end
 
		// State 20
		LW_Begin:
		begin
			ram_req = 1;
		end
 
		// State 21
		LW_Wait_1:
		begin
			ram_req = 1;
		end
 
		// State 22
		LW_Wait_2:
		begin
			ram_req = 1;
		end
 
		// State 23
		LW_End:
		begin
			ram_req = 1;
		end
 
		// State 24
		SW_Begin:
		begin
			ram_wren = 1;
			ram_req = 1;
		end
 
		// State 25
		SW_End:
		begin
			ram_wren = 1;
			ram_req = 1;
		end
 
		// State 26
		JMP:
		begin
 
		end
 
 
 
 
 
		// State 27
		JR:
		begin
 
		end
 
		// State 28
		BRFL:
		begin
 
		end
 
		// State 29
		BRFLR:
		begin
 
		end
 
		// State 30
		NOP:
		begin
 
		end
 
		// State 31
		CALL:
		begin
 
		end
 
		// State 32
		CALLR:
		begin
 
		end
 
		// State 33
		RET:
		begin
 
		end
 
		// State 34
		WAIT_VSYNC:
		begin
 
		end
 
 
		// State 35
		Inc_Program_Counter:
		begin
 
		end
 
 
		// State 36
		Int_Req_Wait:
		begin
 
		end
 
 
		// State 37
		Interrupt:
		begin
 
		end
 
 
		// State 38
		IRET:
		begin
 
		end
 
 
		default:
		begin
 
		end
 
	endcase
end
 
 
// State Register and Reset Logic
always @ (posedge clock)
begin
 
	if (reset)
	begin
		current_state	<= Reset;
 
		program_counter <= code_start_addr;
		stack_pointer <= 3'b000;
		rflags <= 8'b00000000;
		int_ack <= 0;
 
	end
 
	else
	begin
		current_state	<=	next_state;
 
 
		// State: ADD
		if (next_state == ADD)
		begin
			if (add_overflow)
			begin
				rflags[6] <= 1;	//RFlags[overflow] = 1
				registers[16*reg_a_num +: 16] <= 16'b1111111111111111;
			end
 
			else
			begin
				rflags[6] <= 0;	//RFlags[overflow] = 0
				registers[16*reg_a_num +: 16] <= add_result;
			end
		end
 
 
		// State: SUB
		if (next_state == SUB)
		begin
			if (sub_overflow)
			begin
				rflags[6] <= 1;	//RFlags[overflow] = 1
				registers[16*reg_a_num +: 16] <= 16'b1111111111111111;
			end
 
			else
			begin
				rflags[6] <= 0;	//RFlags[overflow] = 0
				registers[16*reg_a_num +: 16] <= sub_result;
			end
		end
 
 
		// State: MUL
		if (next_state == MUL)
		begin
			if ( (mult_result > 32'sd32767) || (mult_result < -32'sd32768) )
			begin
				rflags[6] <= 1;	//RFlags[overflow] = 1
				registers[16*reg_a_num +: 16] <= 16'b1111111111111111;
			end
 
			else
			begin
				rflags[6] <= 0;	//RFlags[overflow] = 0
				registers[16*reg_a_num +: 16] <= mult_result[15:0];
			end
		end
 
 
		// State: DIV
		if (next_state == DIV)
		begin
 
			if (reg_b_val == 16'd0)
			begin
				rflags[0] <= 1;	//RFlags[error] = 1
				rflags[6] <= 0;	//RFlags[overflow] = 0
				registers[16*reg_a_num +: 16] <= 16'b1111111111111111;
			end
 
			else
			begin
				rflags[0] <= 0;	//RFlags[error] = 0
 
				if ( (reg_a_val == 16'b1000000000000000) && (reg_b_val == 16'b1111111111111111) )
				begin
					rflags[6] <= 1;	//RFlags[overflow] = 1
					registers[16*reg_a_num +: 16] <= 16'b1111111111111111;
				end
 
				else
				begin
					rflags[6] <= 0;	//RFlags[overflow] = 0
					registers[16*reg_a_num +: 16] <= divide_quotient;
				end
			end
		end
 
 
		// State: AND
		if (next_state == AND)
			registers[16*reg_a_num +: 16] <= reg_a_val & reg_b_val;
 
 
		// State: OR
		if (next_state == OR)
			registers[16*reg_a_num +: 16] <= reg_a_val | reg_b_val;
 
 
		// State: CMP
		if (next_state == CMP)
		begin
			rflags[3] <= compare_alb;	//RFlags[below]
			rflags[4] <= compare_aeb;	//RFlags[equal]
			rflags[5] <= compare_agb;	//RFlags[above]
		end
 
 
		// State: NOT
		if (next_state == NOT)
			registers[16*reg_a_num +: 16] <= ~ reg_a_val;
 
 
		// State: SPRITE_ID
		if (next_state == SPRITE_ID)
			sprite_id[6*sprite_level +: 6] <= reg_b_val[5:0];
 
 
		// State: SPRITE_COLOR
		if (next_state == SPRITE_COLOR)
			sprite_color[16*sprite_level +: 16] <= reg_b_val;
 
 
		// State: SPRITE_POS
		if (next_state == SPRITE_POS)
		begin
			sprite_x[10*sprite_level +: 10] <= reg_c_val[9:0];
			sprite_y[10*sprite_level +: 10] <= reg_b_val[9:0];
		end
 
 
		// State: LIMM
		if (next_state == LIMM)
			registers[16*reg_a_num +: 16] <= imm;
 
 
		// State: LW_Begin
		if (next_state == LW_Begin)
		begin
			ram_addr <= reg_b_val + imm;
		end
 
 
		// State: LW_End
		if (next_state == LW_End)
			registers[16*reg_a_num +: 16] <= ram_q;
 
 
		// State: SW_Begin
		if (next_state == SW_Begin)
		begin
			ram_addr <= reg_b_val + imm;
			ram_data <= reg_a_val;
		end
 
 
		// State: JMP
		if (next_state == JMP)
			program_counter <= imm;
 
 
 
 
 
		// State: JR
		if (next_state == JR)
			program_counter <= reg_a_val;
 
 
		// State: BRFL
		if (next_state == BRFL)
		begin
			program_counter <= imm;
		end
 
 
		// State: BRFLR
		if (next_state == BRFLR)
		begin
			program_counter <= reg_a_val;
		end
 
 
		// State: CALL
		if (next_state == CALL)
		begin
			pc_stack[16*stack_pointer +: 16] <= program_counter + 1'b1;
			program_counter <= imm;
			stack_pointer <= stack_pointer + 1'b1;
		end
 
 
		// State: CALLR
		if (next_state == CALLR)
		begin
			pc_stack[16*stack_pointer +: 16] <= program_counter + 1'b1;
			program_counter <= reg_a_val;
			stack_pointer <= stack_pointer + 1'b1;
		end
 
 
		// State: RET
		if (next_state == RET)
		begin
			program_counter <= pc_stack[16*(stack_pointer - 1) +: 16];
			stack_pointer <= stack_pointer - 1'b1;
		end
 
 
 
 
		// State: Inc_Program_Counter
		if (next_state == Inc_Program_Counter)
		begin
			program_counter <= program_counter + 1'b1;
		end
 
 
		// State: Int_Req_Wait
		if (next_state == Int_Req_Wait)
		begin
			int_ack <= 1;
		end
 
 
		// State: Interrupt
		if (next_state == Interrupt)
		begin
			int_rflags <= rflags;
			int_program_counter <= program_counter;
			program_counter <= isr_addr;
		end
 
		// State: IRET
		if (next_state == IRET)
		begin
			int_ack <= 0;
			rflags <= int_rflags;
			program_counter <= int_program_counter;
		end
 
 
 
	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.