Add SAP-3
This commit is contained in:
		
							parent
							
								
									eb7cc9dc79
								
							
						
					
					
						commit
						3c0263fc05
					
				| 
						 | 
				
			
			@ -1,9 +1,13 @@
 | 
			
		|||
# FPGA Computer
 | 
			
		||||
 | 
			
		||||
8-bit computer modeled after the SAP-1 from the book [Digital Computer
 | 
			
		||||
8-bit computer modeled after the Simple-As-Possible computers from the book [Digital Computer
 | 
			
		||||
Electronics](https://www.goodreads.com/book/show/942643.Digital_Computer_Electronics) by Malvino and
 | 
			
		||||
Brown.
 | 
			
		||||
 | 
			
		||||
The SAP-3 is the final iteration of the computer and shares an instruction set with the Intel
 | 
			
		||||
8080/8085, minus a few instructions.
 | 
			
		||||
 | 
			
		||||
* [Blog post about the SAP-1.](https://austinmorlan.com/posts/fpga_computer_sap1/)
 | 
			
		||||
* [Blog post about the SAP-2.](https://austinmorlan.com/posts/fpga_computer_sap2/)
 | 
			
		||||
* [Blog post about the SAP-3.](https://austinmorlan.com/posts/fpga_computer_sap3/)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										40
									
								
								build.sh
								
								
								
								
							
							
						
						
									
										40
									
								
								build.sh
								
								
								
								
							| 
						 | 
				
			
			@ -35,6 +35,17 @@ SAP2_MODULES="
 | 
			
		|||
SAP2_TOP=$SRC_DIR/sap2/top.v
 | 
			
		||||
SAP2_TB=$SRC_DIR/sap2/top_tb.v
 | 
			
		||||
 | 
			
		||||
SAP3_MODULES="
 | 
			
		||||
	$SRC_DIR/sap3/alu.v
 | 
			
		||||
	$SRC_DIR/sap3/clock.v
 | 
			
		||||
	$SRC_DIR/sap3/controller.v
 | 
			
		||||
	$SRC_DIR/sap3/ir.v
 | 
			
		||||
	$SRC_DIR/sap3/memory.v
 | 
			
		||||
	$SRC_DIR/sap3/reg_file.v"
 | 
			
		||||
 | 
			
		||||
SAP3_TOP=$SRC_DIR/sap3/top.v
 | 
			
		||||
SAP3_TB=$SRC_DIR/sap3/top_tb.v
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if [ -z "$COMMAND" ]; then
 | 
			
		||||
	mkdir -p $BUILD_DIR/sap1
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +65,15 @@ if [ -z "$COMMAND" ]; then
 | 
			
		|||
	$BIN_DIR/icepack hardware.asc hardware.bin
 | 
			
		||||
 | 
			
		||||
	popd > /dev/null
 | 
			
		||||
 | 
			
		||||
	mkdir -p $BUILD_DIR/sap3
 | 
			
		||||
	pushd $BUILD_DIR/sap3 > /dev/null
 | 
			
		||||
 | 
			
		||||
	$BIN_DIR/yosys -p "synth_ice40 -json hardware.json" $SAP3_MODULES $SAP3_TOP
 | 
			
		||||
	$BIN_DIR/nextpnr-ice40 --lp8k --package cm81 --json hardware.json --asc hardware.asc --pcf $SRC_DIR/pins.pcf -q
 | 
			
		||||
	$BIN_DIR/icepack hardware.asc hardware.bin
 | 
			
		||||
 | 
			
		||||
	popd > /dev/null
 | 
			
		||||
elif [ "$COMMAND" == "init" ]; then
 | 
			
		||||
	virtualenv .env
 | 
			
		||||
	source .env/bin/activate
 | 
			
		||||
| 
						 | 
				
			
			@ -70,13 +90,14 @@ elif [ "$COMMAND" == "program" ]; then
 | 
			
		|||
		exit 1
 | 
			
		||||
	elif [ "$VERSION" == "sap1" ]; then
 | 
			
		||||
		pushd $BUILD_DIR/sap1 > /dev/null
 | 
			
		||||
		sudo tinyprog -p hardware.bin
 | 
			
		||||
		popd > /dev/null
 | 
			
		||||
	elif [ "$VERSION" == "sap2" ]; then
 | 
			
		||||
		pushd $BUILD_DIR/sap2 > /dev/null
 | 
			
		||||
		sudo tinyprog -p hardware.bin
 | 
			
		||||
		popd > /dev/null
 | 
			
		||||
	elif [ "$VERSION" == "sap3" ]; then
 | 
			
		||||
		pushd $BUILD_DIR/sap3 > /dev/null
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	sudo tinyprog -p hardware.bin
 | 
			
		||||
	popd > /dev/null
 | 
			
		||||
elif [ "$COMMAND" == "sim" ]; then
 | 
			
		||||
	if [ -z "$VERSION" ]; then
 | 
			
		||||
		echo "sim needs a version"
 | 
			
		||||
| 
						 | 
				
			
			@ -101,8 +122,17 @@ elif [ "$COMMAND" == "sim" ]; then
 | 
			
		|||
		popd  > /dev/null
 | 
			
		||||
 | 
			
		||||
		gtkwave $BUILD_DIR/sap2/top_tb.vcd $BUILD_DIR/sap2/top_tb.gtkw
 | 
			
		||||
	fi
 | 
			
		||||
	elif [ "$VERSION" == "sap3" ]; then
 | 
			
		||||
		mkdir -p $BUILD_DIR/sap3
 | 
			
		||||
 | 
			
		||||
		pushd $SRC_DIR/sap3 > /dev/null
 | 
			
		||||
		$BIN_DIR/iverilog -o $BUILD_DIR/sap3/top_tb $SAP3_MODULES $SAP3_TB
 | 
			
		||||
		$BIN_DIR/vvp $BUILD_DIR/sap3/top_tb
 | 
			
		||||
		mv top_tb.vcd $BUILD_DIR/sap3
 | 
			
		||||
		popd  > /dev/null
 | 
			
		||||
 | 
			
		||||
		gtkwave $BUILD_DIR/sap3/top_tb.vcd $BUILD_DIR/sap3/top_tb.gtkw
 | 
			
		||||
	fi
 | 
			
		||||
else
 | 
			
		||||
	echo "Invalid arguments"
 | 
			
		||||
fi
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,173 @@
 | 
			
		|||
module alu(
 | 
			
		||||
	input clk,
 | 
			
		||||
	input rst,
 | 
			
		||||
	input cs,
 | 
			
		||||
	input flags_we,
 | 
			
		||||
	input a_we,
 | 
			
		||||
	input a_store,
 | 
			
		||||
	input a_restore,
 | 
			
		||||
	input tmp_we,
 | 
			
		||||
	input[4:0] op,
 | 
			
		||||
	input[7:0] bus,
 | 
			
		||||
	output[7:0] flags,
 | 
			
		||||
	output[7:0] out
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
reg carry;
 | 
			
		||||
 | 
			
		||||
wire flg_c;
 | 
			
		||||
wire flg_z;
 | 
			
		||||
wire flg_p;
 | 
			
		||||
wire flg_s;
 | 
			
		||||
 | 
			
		||||
reg[7:0] acc;
 | 
			
		||||
reg[7:0] flg;
 | 
			
		||||
reg[7:0] act;    // Internal
 | 
			
		||||
reg[7:0] tmp;    // Internal
 | 
			
		||||
 | 
			
		||||
localparam FLG_Z = 0;
 | 
			
		||||
localparam FLG_C = 1;
 | 
			
		||||
localparam FLG_P = 2;
 | 
			
		||||
localparam FLG_S = 3;
 | 
			
		||||
 | 
			
		||||
localparam OP_ADD = 5'b00000;
 | 
			
		||||
localparam OP_ADC = 5'b00001;
 | 
			
		||||
localparam OP_SUB = 5'b00010;
 | 
			
		||||
localparam OP_SBB = 5'b00011;
 | 
			
		||||
localparam OP_ANA = 5'b00100;
 | 
			
		||||
localparam OP_XRA = 5'b00101;
 | 
			
		||||
localparam OP_ORA = 5'b00110;
 | 
			
		||||
localparam OP_CMP = 5'b00111;
 | 
			
		||||
localparam OP_RLC = 5'b01000;
 | 
			
		||||
localparam OP_RRC = 5'b01001;
 | 
			
		||||
localparam OP_RAL = 5'b01010;
 | 
			
		||||
localparam OP_RAR = 5'b01011;
 | 
			
		||||
localparam OP_DAA = 5'b01100; // Unsupported
 | 
			
		||||
localparam OP_CMA = 5'b01101;
 | 
			
		||||
localparam OP_STC = 5'b01110;
 | 
			
		||||
localparam OP_CMC = 5'b01111;
 | 
			
		||||
localparam OP_INR = 5'b10000;
 | 
			
		||||
localparam OP_DCR = 5'b10001;
 | 
			
		||||
 | 
			
		||||
assign flg_c = (carry == 1'b1);
 | 
			
		||||
assign flg_z = (acc[7:0] == 8'b0);
 | 
			
		||||
assign flg_s = acc[7];
 | 
			
		||||
assign flg_p = ~^acc[7:0];
 | 
			
		||||
 | 
			
		||||
always @(posedge clk, posedge rst) begin
 | 
			
		||||
	if (rst) begin
 | 
			
		||||
		acc <= 8'b0;
 | 
			
		||||
		act <= 8'b0;
 | 
			
		||||
		tmp <= 8'b0;
 | 
			
		||||
		carry <= 1'b0;
 | 
			
		||||
	end else begin
 | 
			
		||||
		if (a_we) begin
 | 
			
		||||
			acc <= bus;
 | 
			
		||||
		end else if (a_restore) begin
 | 
			
		||||
			acc <= act;
 | 
			
		||||
		end else if (cs) begin
 | 
			
		||||
			case (op)
 | 
			
		||||
				OP_ADD: begin
 | 
			
		||||
					{carry, acc} <= acc + tmp;
 | 
			
		||||
				end
 | 
			
		||||
				OP_ADC: begin
 | 
			
		||||
					{carry, acc} <= acc + tmp + flg[FLG_C];
 | 
			
		||||
				end
 | 
			
		||||
				OP_SUB:	begin
 | 
			
		||||
					{carry, acc} <= acc - tmp;
 | 
			
		||||
				end
 | 
			
		||||
				OP_SBB:	begin
 | 
			
		||||
					{carry, acc} <= acc - tmp - flg[FLG_C];
 | 
			
		||||
				end
 | 
			
		||||
				OP_ANA: begin
 | 
			
		||||
					{carry, acc} <= acc & tmp;
 | 
			
		||||
				end
 | 
			
		||||
				OP_XRA: begin
 | 
			
		||||
					{carry, acc} <= acc ^ tmp;
 | 
			
		||||
				end
 | 
			
		||||
				OP_ORA: begin
 | 
			
		||||
					{carry, acc} <= acc | tmp;
 | 
			
		||||
				end
 | 
			
		||||
				OP_CMP: begin
 | 
			
		||||
					act <= acc - tmp;
 | 
			
		||||
				end
 | 
			
		||||
				OP_RLC: begin
 | 
			
		||||
					carry <= acc[7];
 | 
			
		||||
					acc <= acc << 1;
 | 
			
		||||
				end
 | 
			
		||||
				OP_RRC: begin
 | 
			
		||||
					carry <= acc[0];
 | 
			
		||||
					acc <= acc >> 1;
 | 
			
		||||
				end
 | 
			
		||||
				OP_RAL: begin
 | 
			
		||||
					carry <= acc[7];
 | 
			
		||||
					acc <= (acc << 1 | {7'b0, flg[FLG_C]});
 | 
			
		||||
				end
 | 
			
		||||
				OP_RAR: begin
 | 
			
		||||
					carry <= acc[0];
 | 
			
		||||
					acc <= (acc >> 1 | {flg[FLG_C], 7'b0});
 | 
			
		||||
				end
 | 
			
		||||
				OP_CMA: begin
 | 
			
		||||
					acc <= ~acc;
 | 
			
		||||
				end
 | 
			
		||||
				OP_STC: begin
 | 
			
		||||
					carry <= 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
				OP_CMC: begin
 | 
			
		||||
					carry <= ~flg[FLG_C];
 | 
			
		||||
				end
 | 
			
		||||
				OP_INR: begin
 | 
			
		||||
					acc <= acc + 1;
 | 
			
		||||
				end
 | 
			
		||||
				OP_DCR: begin
 | 
			
		||||
					acc <= acc - 1;
 | 
			
		||||
				end
 | 
			
		||||
			endcase
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if (a_store)
 | 
			
		||||
			act <= acc;
 | 
			
		||||
 | 
			
		||||
		if (tmp_we)
 | 
			
		||||
			tmp <= bus;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @(negedge clk, posedge rst) begin
 | 
			
		||||
	if (rst) begin
 | 
			
		||||
		flg <= 8'b0;
 | 
			
		||||
	end else if (flags_we) begin
 | 
			
		||||
		flg <= bus;
 | 
			
		||||
	end else begin
 | 
			
		||||
		if (cs) begin
 | 
			
		||||
			case (op)
 | 
			
		||||
				OP_ADD, OP_ADC, OP_SUB, OP_SBB, OP_ANA, OP_XRA, OP_ORA: begin
 | 
			
		||||
					flg[FLG_C] <= flg_c;
 | 
			
		||||
					flg[FLG_Z] <= flg_z;
 | 
			
		||||
					flg[FLG_S] <= flg_s;
 | 
			
		||||
					flg[FLG_P] <= flg_p;
 | 
			
		||||
				end
 | 
			
		||||
 | 
			
		||||
				OP_CMP: begin
 | 
			
		||||
					flg[FLG_Z] <= (act == 8'b0);
 | 
			
		||||
				end
 | 
			
		||||
 | 
			
		||||
				OP_INR, OP_DCR: begin
 | 
			
		||||
					flg[FLG_Z] <= flg_z;
 | 
			
		||||
					flg[FLG_S] <= flg_s;
 | 
			
		||||
					flg[FLG_P] <= flg_p;
 | 
			
		||||
				end
 | 
			
		||||
 | 
			
		||||
				OP_RLC, OP_RRC, OP_RAL, OP_RAR, OP_STC, OP_CMC: begin
 | 
			
		||||
					flg[FLG_C] <= flg_c;
 | 
			
		||||
				end
 | 
			
		||||
			endcase
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
assign flags = flg;
 | 
			
		||||
assign out = acc;
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
module clock(
 | 
			
		||||
	input hlt,
 | 
			
		||||
	input clk_in,
 | 
			
		||||
	output clk_out);
 | 
			
		||||
 | 
			
		||||
assign clk_out = (hlt) ? 1'b0 : clk_in;
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,928 @@
 | 
			
		|||
module controller(
 | 
			
		||||
	input clk,
 | 
			
		||||
	input rst,
 | 
			
		||||
	input[7:0] opcode,
 | 
			
		||||
	input[7:0] flags,
 | 
			
		||||
	output[32:0] out
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
localparam DISPLAY       = 32;
 | 
			
		||||
localparam HLT           = 31;
 | 
			
		||||
localparam ALU_CS        = 30;
 | 
			
		||||
localparam ALU_FLAGS_WE  = 29;
 | 
			
		||||
localparam ALU_A_WE      = 28;
 | 
			
		||||
localparam ALU_A_STORE   = 27;
 | 
			
		||||
localparam ALU_A_RESTORE = 26;
 | 
			
		||||
localparam ALU_TMP_WE    = 25;
 | 
			
		||||
localparam ALU_OP4       = 24;
 | 
			
		||||
localparam ALU_OP0       = 20;
 | 
			
		||||
localparam ALU_OE        = 19;
 | 
			
		||||
localparam ALU_FLAGS_OE  = 18;
 | 
			
		||||
localparam REG_RD_SEL4   = 17;
 | 
			
		||||
localparam REG_RD_SEL0   = 13;
 | 
			
		||||
localparam REG_WR_SEL4   = 12;
 | 
			
		||||
localparam REG_WR_SEL0   = 8;
 | 
			
		||||
localparam REG_EXT1      = 7;
 | 
			
		||||
localparam REG_EXT0      = 6;
 | 
			
		||||
localparam REG_OE        = 5;
 | 
			
		||||
localparam REG_WE        = 4;
 | 
			
		||||
localparam MEM_WE        = 3;
 | 
			
		||||
localparam MEM_MAR_WE    = 2;
 | 
			
		||||
localparam MEM_OE        = 1;
 | 
			
		||||
localparam IR_WE         = 0;
 | 
			
		||||
 | 
			
		||||
localparam REG_INC   = 2'b01;
 | 
			
		||||
localparam REG_DEC   = 2'b10;
 | 
			
		||||
localparam REG_INC2  = 2'b11;
 | 
			
		||||
 | 
			
		||||
localparam REG_BC    = 5'b10000;
 | 
			
		||||
localparam REG_BC_B  = 5'b00000;
 | 
			
		||||
localparam REG_BC_C  = 5'b00001;
 | 
			
		||||
 | 
			
		||||
localparam REG_DE    = 5'b10010;
 | 
			
		||||
localparam REG_DE_D  = 5'b00010;
 | 
			
		||||
localparam REG_DE_E  = 5'b00011;
 | 
			
		||||
 | 
			
		||||
localparam REG_HL    = 5'b10100;
 | 
			
		||||
localparam REG_HL_H  = 5'b00100;
 | 
			
		||||
localparam REG_HL_L  = 5'b00101;
 | 
			
		||||
 | 
			
		||||
localparam REG_WZ    = 5'b10110;
 | 
			
		||||
localparam REG_WZ_W  = 5'b00110;
 | 
			
		||||
localparam REG_WZ_Z  = 5'b00111;
 | 
			
		||||
 | 
			
		||||
localparam REG_PC    = 5'b11000;
 | 
			
		||||
localparam REG_PC_P  = 5'b01000;
 | 
			
		||||
localparam REG_PC_C  = 5'b01001;
 | 
			
		||||
 | 
			
		||||
localparam REG_SP    = 5'b11010;
 | 
			
		||||
localparam REG_SP_S  = 5'b01010;
 | 
			
		||||
localparam REG_SP_P  = 5'b01011;
 | 
			
		||||
 | 
			
		||||
reg[32:0] ctrl_word;
 | 
			
		||||
reg[3:0] stage;
 | 
			
		||||
reg stage_rst;
 | 
			
		||||
 | 
			
		||||
assign out = ctrl_word;
 | 
			
		||||
 | 
			
		||||
always @(negedge clk, posedge rst) begin
 | 
			
		||||
	if (rst) begin
 | 
			
		||||
		stage <= 0;
 | 
			
		||||
	end else begin
 | 
			
		||||
		if (stage_rst) begin
 | 
			
		||||
			stage <= 0;
 | 
			
		||||
		end else begin
 | 
			
		||||
			stage <= stage + 1;
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @(*) begin
 | 
			
		||||
	ctrl_word = 0;
 | 
			
		||||
	stage_rst = 0;
 | 
			
		||||
 | 
			
		||||
	if (stage == 0) begin
 | 
			
		||||
		ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
		ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
		ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
	end else if (stage == 1) begin
 | 
			
		||||
		ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
		ctrl_word[IR_WE] = 1'b1;
 | 
			
		||||
	end else if (stage == 2) begin
 | 
			
		||||
		ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
		ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
	end else begin
 | 
			
		||||
		casez (opcode)
 | 
			
		||||
			// NOP
 | 
			
		||||
			8'o000: begin
 | 
			
		||||
				stage_rst = 1'b1;
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// HLT
 | 
			
		||||
			8'o166: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[HLT] = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// MOV Rd, M
 | 
			
		||||
			// opcode[5:3] - Rd
 | 
			
		||||
			8'o1?6: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					if (opcode[5:3] == 3'b111) begin
 | 
			
		||||
						ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
 | 
			
		||||
						ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// MOV M, Rs
 | 
			
		||||
			// opcode[2:0] - Rs
 | 
			
		||||
			8'o16?: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					if (opcode[2:0] == 3'b111) begin
 | 
			
		||||
						ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// MOV Rd, Rs
 | 
			
		||||
			// opcode[5:3] - Rd
 | 
			
		||||
			// opcode[2:0] - Rs
 | 
			
		||||
			8'o1??: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					if (opcode[2:0] == 3'b111) begin
 | 
			
		||||
						ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					if (opcode[5:3] == 3'b111) begin
 | 
			
		||||
						ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
 | 
			
		||||
						ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// INX, DCX
 | 
			
		||||
			// opcode[5:4] - 16-bit Register
 | 
			
		||||
			// opcode[3]   - Dec(1) / Inc (0)
 | 
			
		||||
			8'o0?3: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					if (opcode[5:4] == 2'b11)
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					else
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b10, opcode[5:4], 1'b0};
 | 
			
		||||
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = {opcode[3], ~opcode[3]};
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// INR/DCR M
 | 
			
		||||
			// opcode[5:3] - Rs
 | 
			
		||||
			// opcode[0]   - INR (0), DCR (1)
 | 
			
		||||
			8'o064: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_A_STORE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OP4:ALU_OP0] = {4'b1000, opcode[0]};
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_A_RESTORE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// INR/DCR Rs
 | 
			
		||||
			// opcode[5:3] - Rs
 | 
			
		||||
			// opcode[0]   - INR (0), DCR (1)
 | 
			
		||||
			8'o0?4, 8'o0?5: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					if (opcode[5:3] == 3'b111) begin
 | 
			
		||||
						ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
						ctrl_word[ALU_OP4:ALU_OP0] = 5'b10000;
 | 
			
		||||
						stage_rst = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:3]};
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
						ctrl_word[ALU_A_STORE] = 1'b1;
 | 
			
		||||
						ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OP4:ALU_OP0] = {4'b1000, opcode[0]};
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_A_RESTORE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// Arithmetic/Logic Set 0 (M)
 | 
			
		||||
			// opcode[5:3] - ALU Op
 | 
			
		||||
			8'o2?6: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_TMP_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// Arithmetic/Logic Set 0
 | 
			
		||||
			// opcode[2:0] - Rs
 | 
			
		||||
			// opcode[5:3] - ALU Op
 | 
			
		||||
			8'o2??: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					if (opcode[2:0] == 3'b111) begin
 | 
			
		||||
						ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
						ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
 | 
			
		||||
						stage_rst = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[2:0]};
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[ALU_TMP_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// Arithmetic/Logic Set 1
 | 
			
		||||
			// opcode[5:3] - ALU Op
 | 
			
		||||
			8'o0?7: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OP4:ALU_OP0] = {2'b01, opcode[5:3]};
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// Arithmetic/Logic Immediate
 | 
			
		||||
			// opcode[5:3] - ALU Op
 | 
			
		||||
			8'o3?6: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_TMP_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OP4:ALU_OP0] = {2'b0, opcode[5:3]};
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// MVI M, d8
 | 
			
		||||
			8'o066: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, REG_WZ_W};
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, REG_WZ_W};
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// MVI Rd, d8
 | 
			
		||||
			// opcode[5:3] - Rd
 | 
			
		||||
			8'o0?6: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					if (opcode[5:3] == 3'b111) begin
 | 
			
		||||
						ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:3]};
 | 
			
		||||
						ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// LXI
 | 
			
		||||
			// opcode[5:4] - Extended Register
 | 
			
		||||
			8'o001, 8'o021, 8'o041, 8'o061: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					if (opcode[5:4] == 2'b11)
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					else
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b10, opcode[5:4], 1'b0};
 | 
			
		||||
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 9) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// LDA/STA a16
 | 
			
		||||
			// opcode[3]: STA (0) / LDA (1)
 | 
			
		||||
			8'o062, 8'o072: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 9) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 10) begin
 | 
			
		||||
					if (opcode[3] == 0) begin
 | 
			
		||||
						ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// STAX/LDAX Rs
 | 
			
		||||
			// opcode[5:4] - Rs
 | 
			
		||||
			// opcode[3]   - STAX (0) / LDAX (1)
 | 
			
		||||
			8'o002, 8'o012, 8'o022, 8'o032: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					if (opcode[3] == 1'b0) begin
 | 
			
		||||
						ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// SHLD, LHLD
 | 
			
		||||
			// opcode[3] - SHLD (0) / LHLD (1)
 | 
			
		||||
			8'o042, 8'o052: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 9) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 10) begin
 | 
			
		||||
					if (opcode[3] == 1'b0) begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_H;
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL_H;
 | 
			
		||||
						ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
				end else if (stage == 11) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 12) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 13) begin
 | 
			
		||||
					if (opcode[3] == 1'b0) begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_L;
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL_L;
 | 
			
		||||
						ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// DAD
 | 
			
		||||
			// opcode[5:4] - Extended Register
 | 
			
		||||
			8'o011, 8'o031, 8'o051, 8'o071: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_L;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_A_STORE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					if (opcode[5:4] == 2'b11) begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP_P;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_TMP_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OP4:ALU_OP0] = 5'b00000; // Add
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_HL_H;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					if (opcode[5:4] == 2'b11) begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP_S;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_TMP_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 9) begin
 | 
			
		||||
					ctrl_word[ALU_CS] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OP4:ALU_OP0] = 5'b00001; // Add w/ Carry
 | 
			
		||||
				end else if (stage == 10) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[ALU_A_RESTORE] = 1'b1;
 | 
			
		||||
				end else if (stage == 11) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_HL;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// JMP
 | 
			
		||||
			8'o303: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// Jump Conditional
 | 
			
		||||
			// opcode[5:4] - flag
 | 
			
		||||
			// opcode[3]   - set (1) / unset (0)
 | 
			
		||||
			8'o3?2: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					if (flags[opcode[5:4]] != opcode[3]) begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
						ctrl_word[REG_EXT1:REG_EXT0] = REG_INC2;
 | 
			
		||||
						stage_rst = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// Call Conditional
 | 
			
		||||
			// opcode[5:4] - flag
 | 
			
		||||
			// opcode[3]   - set (1) / unset (0)
 | 
			
		||||
			8'o3?4: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					if (flags[opcode[5:4]] != opcode[3]) begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
						ctrl_word[REG_EXT1:REG_EXT0] = REG_INC2;
 | 
			
		||||
						stage_rst = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 9) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
 | 
			
		||||
				end else if (stage == 10) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 11) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_C;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 12) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
 | 
			
		||||
				end else if (stage == 13) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 14) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_P;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 15) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// CALL
 | 
			
		||||
			8'o315: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 9) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
 | 
			
		||||
				end else if (stage == 10) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 11) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_C;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 12) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
 | 
			
		||||
				end else if (stage == 13) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 14) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_PC_P;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 15) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// Return Conditional
 | 
			
		||||
			// opcode[5:4] - flag
 | 
			
		||||
			// opcode[3]   - set (1) / unset (0)
 | 
			
		||||
			8'o3?0: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					if (flags[opcode[5:4]] != opcode[3]) begin
 | 
			
		||||
						stage_rst = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
						ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 9) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// RET
 | 
			
		||||
			8'o311: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_W;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_WZ_Z;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 9) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_WZ;
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// PUSH Rs
 | 
			
		||||
			// opcode[5:4] - Extended Register
 | 
			
		||||
			8'o3?5: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					if (opcode[5:4] == 2'b11) begin // PSW
 | 
			
		||||
						ctrl_word[ALU_OE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b0};
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_DEC;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					if (opcode[5:4] == 2'b11) begin // PSW
 | 
			
		||||
						ctrl_word[ALU_FLAGS_OE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = {2'b0, opcode[5:4], 1'b1};
 | 
			
		||||
						ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[MEM_WE] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// POP Rs
 | 
			
		||||
			// opcode[5:4] - Extended Register
 | 
			
		||||
			8'o301, 8'o321, 8'o341, 8'o361: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 4) begin
 | 
			
		||||
					if (opcode[5:4] == 2'b11) begin // PSW
 | 
			
		||||
						ctrl_word[ALU_FLAGS_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:4], 1'b1};
 | 
			
		||||
						ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 5) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
				end else if (stage == 6) begin
 | 
			
		||||
					ctrl_word[REG_RD_SEL4:REG_RD_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_OE] = 1'b1;
 | 
			
		||||
					ctrl_word[MEM_MAR_WE] = 1'b1;
 | 
			
		||||
				end else if (stage == 7) begin
 | 
			
		||||
					if (opcode[5:4] == 2'b11) begin // PSW
 | 
			
		||||
						ctrl_word[ALU_A_WE] = 1'b1;
 | 
			
		||||
					end else begin
 | 
			
		||||
						ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = {2'b0, opcode[5:4], 1'b0};
 | 
			
		||||
						ctrl_word[REG_WE] = 1'b1;
 | 
			
		||||
					end
 | 
			
		||||
 | 
			
		||||
					ctrl_word[MEM_OE] = 1'b1;
 | 
			
		||||
				end else if (stage == 8) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_SP;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			// OUT
 | 
			
		||||
			8'o323: begin
 | 
			
		||||
				if (stage == 3) begin
 | 
			
		||||
					ctrl_word[REG_WR_SEL4:REG_WR_SEL0] = REG_PC;
 | 
			
		||||
					ctrl_word[REG_EXT1:REG_EXT0] = REG_INC;
 | 
			
		||||
					ctrl_word[DISPLAY] = 1'b1;
 | 
			
		||||
					stage_rst = 1'b1;
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		endcase
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
module ir(
 | 
			
		||||
	input clk,
 | 
			
		||||
	input rst,
 | 
			
		||||
	input we,
 | 
			
		||||
	input[7:0] bus,
 | 
			
		||||
	output[7:0] out
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
reg[7:0] ir;
 | 
			
		||||
 | 
			
		||||
always @(posedge clk, posedge rst) begin
 | 
			
		||||
	if (rst) begin
 | 
			
		||||
		ir <= 8'b0;
 | 
			
		||||
	end else if (we) begin
 | 
			
		||||
		ir <= bus;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
assign out = ir;
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
module memory(
 | 
			
		||||
	input clk,
 | 
			
		||||
	input rst,
 | 
			
		||||
	input mar_we,
 | 
			
		||||
	input ram_we,
 | 
			
		||||
	input[15:0] bus,
 | 
			
		||||
	output[7:0] out
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
initial begin
 | 
			
		||||
	$readmemh("program.bin", ram);
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
reg[15:0] mar;
 | 
			
		||||
reg[7:0]  ram[0:255];
 | 
			
		||||
 | 
			
		||||
always @(posedge clk, posedge rst) begin
 | 
			
		||||
	if (rst)
 | 
			
		||||
		mar <= 16'b0;
 | 
			
		||||
	else if (mar_we)
 | 
			
		||||
		mar <= bus;
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @(posedge clk) begin
 | 
			
		||||
	if (ram_we)
 | 
			
		||||
		ram[mar] <= bus[7:0];
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
assign out = ram[mar];
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
31 f0 00 3e 01 06 00 d3
 | 
			
		||||
ff 4f 78 fe 01 79 ca 17
 | 
			
		||||
00 c2 20 00 c3 07 00 1f
 | 
			
		||||
fe 01 cc 29 00 c3 07 00
 | 
			
		||||
17 fe 80 cc 2c 00 c3 07
 | 
			
		||||
00 06 00 c9 06 01 c9 76
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
00 00 00 00 00 00 00 00
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
module reg_file(
 | 
			
		||||
	input clk,
 | 
			
		||||
	input rst,
 | 
			
		||||
	input[4:0] rd_sel,
 | 
			
		||||
	input[4:0] wr_sel,
 | 
			
		||||
	input[1:0] ext,
 | 
			
		||||
	input we,
 | 
			
		||||
	input[15:0] data_in,
 | 
			
		||||
	output[15:0] data_out
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
// 8-bit
 | 
			
		||||
//           0      1
 | 
			
		||||
// 0000_  [  B  ][  C  ]
 | 
			
		||||
// 0001_  [  D  ][  E  ]
 | 
			
		||||
// 0010_  [  H  ][  L  ]
 | 
			
		||||
// 0011_  [  W  ][  Z  ]
 | 
			
		||||
// 0100_  [  P  ][  C  ]
 | 
			
		||||
// 0101_  [  S  ][  P  ]
 | 
			
		||||
 | 
			
		||||
// 16-bit (ext)
 | 
			
		||||
//                 
 | 
			
		||||
// 10000  [     BC     ]
 | 
			
		||||
// 10010  [     DE     ]
 | 
			
		||||
// 10100  [     HL     ]
 | 
			
		||||
// 10110  [     WZ     ]
 | 
			
		||||
// 11000  [     PC     ]
 | 
			
		||||
// 11010  [     SP     ]
 | 
			
		||||
reg[7:0] data[0:11];
 | 
			
		||||
 | 
			
		||||
reg[15:0] data_out;
 | 
			
		||||
wire wr_ext = wr_sel[4];
 | 
			
		||||
wire rd_ext = rd_sel[4];
 | 
			
		||||
wire[3:0] wr_dst = wr_sel[3:0];
 | 
			
		||||
wire[3:0] rd_src = rd_sel[3:0];
 | 
			
		||||
 | 
			
		||||
localparam EXT_INC  = 2'b01;
 | 
			
		||||
localparam EXT_DEC  = 2'b10;
 | 
			
		||||
localparam EXT_INC2 = 2'b11;
 | 
			
		||||
 | 
			
		||||
always @(posedge clk, posedge rst) begin
 | 
			
		||||
	if (rst) begin
 | 
			
		||||
		data[0] <= 8'b0; data[1] <= 8'b0; data[2] <= 8'b0; data[3] <= 8'b0; data[4] <= 8'b0;
 | 
			
		||||
		data[5] <= 8'b0; data[6] <= 8'b0; data[7] <= 8'b0; data[8] <= 8'b0; data[9] <= 8'b0;
 | 
			
		||||
		data[10] <= 8'b0; data[11] <= 8'b0;
 | 
			
		||||
	end else begin
 | 
			
		||||
		if (ext == EXT_INC) begin
 | 
			
		||||
			{data[wr_dst], data[wr_dst+1]} <= {data[wr_dst], data[wr_dst+1]} + 1;
 | 
			
		||||
		end else if (ext == EXT_INC2) begin
 | 
			
		||||
			{data[wr_dst], data[wr_dst+1]} <= {data[wr_dst], data[wr_dst+1]} + 2;
 | 
			
		||||
		end else if (ext == EXT_DEC) begin
 | 
			
		||||
			{data[wr_dst], data[wr_dst+1]} <= {data[wr_dst], data[wr_dst+1]} - 1;
 | 
			
		||||
		end else if (we) begin
 | 
			
		||||
			if (wr_ext) begin
 | 
			
		||||
				{data[wr_dst], data[wr_dst+1]} <= data_in;
 | 
			
		||||
			end else begin
 | 
			
		||||
				data[wr_dst] <= data_in[7:0];
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
always @(*) begin
 | 
			
		||||
	if (rd_ext) begin
 | 
			
		||||
		data_out = {data[rd_src], data[rd_src+1]};
 | 
			
		||||
	end else begin
 | 
			
		||||
		data_out = {8'b0, data[rd_src]};
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,153 @@
 | 
			
		|||
module top(
 | 
			
		||||
	input CLK,
 | 
			
		||||
	input PIN_24,
 | 
			
		||||
	output PIN_4,
 | 
			
		||||
	output PIN_5,
 | 
			
		||||
	output PIN_6,
 | 
			
		||||
	output PIN_7,
 | 
			
		||||
	output PIN_8,
 | 
			
		||||
	output PIN_9,
 | 
			
		||||
	output PIN_10,
 | 
			
		||||
	output PIN_11,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
assign rst = PIN_24;
 | 
			
		||||
assign {PIN_4, PIN_5, PIN_6, PIN_7, PIN_8, PIN_9, PIN_10, PIN_11} = out;
 | 
			
		||||
 | 
			
		||||
reg[7:0] out;
 | 
			
		||||
always @(posedge clk, posedge rst) begin
 | 
			
		||||
	if (rst) begin
 | 
			
		||||
		out = 8'b0;
 | 
			
		||||
	end else if (display) begin
 | 
			
		||||
		out = alu_out;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
reg[18:0] bus;
 | 
			
		||||
 | 
			
		||||
always @(*) begin
 | 
			
		||||
	bus = 16'b0;
 | 
			
		||||
 | 
			
		||||
	if (reg_oe)
 | 
			
		||||
		bus = reg_out;
 | 
			
		||||
	else if (mem_oe)
 | 
			
		||||
		bus = {8'b0, mem_out};
 | 
			
		||||
	else if (alu_oe)
 | 
			
		||||
		bus = {8'b0, alu_out};
 | 
			
		||||
	else if (alu_flags_oe)
 | 
			
		||||
		bus = {8'b0, alu_flags};
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
reg[23:0] clk_slow;
 | 
			
		||||
always @(posedge CLK) begin
 | 
			
		||||
	clk_slow <= clk_slow + 1;
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
wire rst;
 | 
			
		||||
wire hlt;
 | 
			
		||||
wire clk;
 | 
			
		||||
clock clock(
 | 
			
		||||
	.hlt(hlt),
 | 
			
		||||
	.clk_in(clk_slow[14]),
 | 
			
		||||
	.clk_out(clk)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire[4:0] reg_rd_sel;
 | 
			
		||||
wire[4:0] reg_wr_sel;
 | 
			
		||||
wire[1:0] reg_ext;
 | 
			
		||||
wire reg_oe;
 | 
			
		||||
wire reg_we;
 | 
			
		||||
wire[15:0] reg_out;
 | 
			
		||||
reg_file reg_file(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.rd_sel(reg_rd_sel),
 | 
			
		||||
	.wr_sel(reg_wr_sel),
 | 
			
		||||
	.ext(reg_ext),
 | 
			
		||||
	.we(reg_we),
 | 
			
		||||
	.data_in(bus),
 | 
			
		||||
	.data_out(reg_out)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire mem_mar_we;
 | 
			
		||||
wire mem_ram_we;
 | 
			
		||||
wire mem_oe;
 | 
			
		||||
wire[7:0] mem_out;
 | 
			
		||||
memory memory(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.mar_we(mem_mar_we),
 | 
			
		||||
	.ram_we(mem_ram_we),
 | 
			
		||||
	.bus(bus),
 | 
			
		||||
	.out(mem_out)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire ir_we;
 | 
			
		||||
wire[7:0] ir_out;
 | 
			
		||||
ir ir(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.we(ir_we),
 | 
			
		||||
	.bus(bus[7:0]),
 | 
			
		||||
	.out(ir_out)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire alu_cs;
 | 
			
		||||
wire alu_flags_we;
 | 
			
		||||
wire alu_a_we;
 | 
			
		||||
wire alu_a_store;
 | 
			
		||||
wire alu_a_restore;
 | 
			
		||||
wire alu_tmp_we;
 | 
			
		||||
wire alu_oe;
 | 
			
		||||
wire alu_flags_oe;
 | 
			
		||||
wire[4:0] alu_op;
 | 
			
		||||
wire[7:0] alu_flags;
 | 
			
		||||
wire[7:0] alu_out;
 | 
			
		||||
alu alu(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.cs(alu_cs),
 | 
			
		||||
	.flags_we(alu_flags_we),
 | 
			
		||||
	.a_we(alu_a_we),
 | 
			
		||||
	.a_store(alu_a_store),
 | 
			
		||||
	.a_restore(alu_a_restore),
 | 
			
		||||
	.tmp_we(alu_tmp_we),
 | 
			
		||||
	.op(alu_op),
 | 
			
		||||
	.bus(bus[7:0]),
 | 
			
		||||
	.flags(alu_flags),
 | 
			
		||||
	.out(alu_out)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire display;
 | 
			
		||||
controller controller(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.opcode(ir_out),
 | 
			
		||||
	.flags(alu_flags),
 | 
			
		||||
	.out({
 | 
			
		||||
		display,
 | 
			
		||||
		hlt,
 | 
			
		||||
		alu_cs,
 | 
			
		||||
		alu_flags_we,
 | 
			
		||||
		alu_a_we,
 | 
			
		||||
		alu_a_store,
 | 
			
		||||
		alu_a_restore,
 | 
			
		||||
		alu_tmp_we,
 | 
			
		||||
		alu_op,
 | 
			
		||||
		alu_oe,
 | 
			
		||||
		alu_flags_oe,
 | 
			
		||||
		reg_rd_sel,
 | 
			
		||||
		reg_wr_sel,
 | 
			
		||||
		reg_ext,
 | 
			
		||||
		reg_oe,
 | 
			
		||||
		reg_we,
 | 
			
		||||
		mem_ram_we,
 | 
			
		||||
		mem_mar_we,
 | 
			
		||||
		mem_oe,
 | 
			
		||||
		ir_we
 | 
			
		||||
		})
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,154 @@
 | 
			
		|||
module top_tb();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
initial begin
 | 
			
		||||
	$dumpfile("top_tb.vcd");
 | 
			
		||||
	$dumpvars(0, top_tb);
 | 
			
		||||
	for (i = 0; i < 12; i++) begin
 | 
			
		||||
		$dumpvars(0, reg_file.data[i]);
 | 
			
		||||
	end
 | 
			
		||||
	for (i = 230; i < 256; i++) begin
 | 
			
		||||
		$dumpvars(0, memory.ram[i]);
 | 
			
		||||
	end
 | 
			
		||||
	rst = 1;
 | 
			
		||||
	#1 rst = 0;
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
reg clk_in = 0;
 | 
			
		||||
integer i;
 | 
			
		||||
initial begin
 | 
			
		||||
	for (i = 0; i < 8096; i++) begin
 | 
			
		||||
		#1 clk_in = ~clk_in;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
reg[7:0] out;
 | 
			
		||||
always @(posedge clk, posedge rst) begin
 | 
			
		||||
	if (rst) begin
 | 
			
		||||
		out = 8'b0;
 | 
			
		||||
	end else if (display) begin
 | 
			
		||||
		out = alu_out;
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
reg[15:0] bus;
 | 
			
		||||
 | 
			
		||||
always @(*) begin
 | 
			
		||||
	bus = 16'b0;
 | 
			
		||||
 | 
			
		||||
	if (reg_oe)
 | 
			
		||||
		bus = reg_out;
 | 
			
		||||
	else if (mem_oe)
 | 
			
		||||
		bus = {8'b0, mem_out};
 | 
			
		||||
	else if (alu_oe)
 | 
			
		||||
		bus = {8'b0, alu_out};
 | 
			
		||||
	else if (alu_flags_oe)
 | 
			
		||||
		bus = {8'b0, alu_flags};
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
reg rst;
 | 
			
		||||
wire hlt;
 | 
			
		||||
wire clk;
 | 
			
		||||
clock clock(
 | 
			
		||||
	.hlt(hlt),
 | 
			
		||||
	.clk_in(clk_in),
 | 
			
		||||
	.clk_out(clk)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire[4:0] reg_rd_sel;
 | 
			
		||||
wire[4:0] reg_wr_sel;
 | 
			
		||||
wire[1:0] reg_ext;
 | 
			
		||||
wire reg_oe;
 | 
			
		||||
wire reg_we;
 | 
			
		||||
wire[15:0] reg_out;
 | 
			
		||||
reg_file reg_file(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.rd_sel(reg_rd_sel),
 | 
			
		||||
	.wr_sel(reg_wr_sel),
 | 
			
		||||
	.ext(reg_ext),
 | 
			
		||||
	.we(reg_we),
 | 
			
		||||
	.data_in(bus),
 | 
			
		||||
	.data_out(reg_out)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire mem_mar_we;
 | 
			
		||||
wire mem_ram_we;
 | 
			
		||||
wire mem_oe;
 | 
			
		||||
wire[7:0] mem_out;
 | 
			
		||||
memory memory(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.mar_we(mem_mar_we),
 | 
			
		||||
	.ram_we(mem_ram_we),
 | 
			
		||||
	.bus(bus),
 | 
			
		||||
	.out(mem_out)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire ir_we;
 | 
			
		||||
wire[7:0] ir_out;
 | 
			
		||||
ir ir(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.we(ir_we),
 | 
			
		||||
	.bus(bus[7:0]),
 | 
			
		||||
	.out(ir_out)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
wire alu_cs;
 | 
			
		||||
wire alu_flags_we;
 | 
			
		||||
wire alu_a_we;
 | 
			
		||||
wire alu_a_store;
 | 
			
		||||
wire alu_a_restore;
 | 
			
		||||
wire alu_tmp_we;
 | 
			
		||||
wire alu_oe;
 | 
			
		||||
wire alu_flags_oe;
 | 
			
		||||
wire[4:0] alu_op;
 | 
			
		||||
wire[7:0] alu_flags;
 | 
			
		||||
wire[7:0] alu_out;
 | 
			
		||||
alu alu(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.cs(alu_cs),
 | 
			
		||||
	.flags_we(alu_flags_we),
 | 
			
		||||
	.a_we(alu_a_we),
 | 
			
		||||
	.a_store(alu_a_store),
 | 
			
		||||
	.a_restore(alu_a_restore),
 | 
			
		||||
	.tmp_we(alu_tmp_we),
 | 
			
		||||
	.op(alu_op),
 | 
			
		||||
	.bus(bus[7:0]),
 | 
			
		||||
	.flags(alu_flags),
 | 
			
		||||
	.out(alu_out)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
controller controller(
 | 
			
		||||
	.clk(clk),
 | 
			
		||||
	.rst(rst),
 | 
			
		||||
	.opcode(ir_out),
 | 
			
		||||
	.flags(alu_flags),
 | 
			
		||||
	.out({
 | 
			
		||||
		display,
 | 
			
		||||
		hlt,
 | 
			
		||||
		alu_cs,
 | 
			
		||||
		alu_flags_we,
 | 
			
		||||
		alu_a_we,
 | 
			
		||||
		alu_a_store,
 | 
			
		||||
		alu_a_restore,
 | 
			
		||||
		alu_tmp_we,
 | 
			
		||||
		alu_op,
 | 
			
		||||
		alu_oe,
 | 
			
		||||
		alu_flags_oe,
 | 
			
		||||
		reg_rd_sel,
 | 
			
		||||
		reg_wr_sel,
 | 
			
		||||
		reg_ext,
 | 
			
		||||
		reg_oe,
 | 
			
		||||
		reg_we,
 | 
			
		||||
		mem_ram_we,
 | 
			
		||||
		mem_mar_we,
 | 
			
		||||
		mem_oe,
 | 
			
		||||
		ir_we
 | 
			
		||||
		})
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue