diff --git a/system/alu.v b/system/alu.v index c4a4bdb..4abe1b4 100644 --- a/system/alu.v +++ b/system/alu.v @@ -34,6 +34,7 @@ always @ ( * ) begin `ALU_OP_ADD: {C_FLAG,OUT}=A+B; `ALU_OP_ADD_SIGNED_B: {C_FLAG,OUT}=A+SIGNED_B; `ALU_OP_SUB: {C_FLAG,OUT}=A-B; + `ALU_OP_SUB_REVERSE: {C_FLAG,OUT}=B-A; `ALU_OP_AND: OUT=A&B; `ALU_OP_OR: OUT=A|B; `ALU_OP_XOR: OUT=A^B; @@ -47,6 +48,7 @@ always @ ( * ) begin `ALU_OP_ADD: {C_FLAG,OUT[7:0]}=A[7:0]+B[7:0]; `ALU_OP_ADD_SIGNED_B: {C_FLAG,OUT[7:0]}=A[7:0]+SIGNED_8B; `ALU_OP_SUB: {C_FLAG,OUT[7:0]}=A[7:0]-B[7:0]; + `ALU_OP_SUB_REVERSE: {C_FLAG,OUT[7:0]}=B[7:0]-A[7:0]; `ALU_OP_AND: OUT=A&B; `ALU_OP_OR: OUT=A|B; `ALU_OP_XOR: OUT=A^B; diff --git a/system/alu_header.v b/system/alu_header.v index 0061d1a..07e4fcb 100644 --- a/system/alu_header.v +++ b/system/alu_header.v @@ -24,3 +24,4 @@ `define ALU_OP_OR 3'b011 `define ALU_OP_XOR 3'b100 `define ALU_OP_ADD_SIGNED_B 3'b101 +`define ALU_OP_SUB_REVERSE 3'b110 diff --git a/system/decoder.v b/system/decoder.v index 8ac7567..e66b3c2 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -138,20 +138,30 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin Sbit=CIR[9:9]; IN_MOD=CIR[7:6]; RM=CIR[2:0]; - if(((Wbit==1)&&(Sbit==1))||Wbit==0)begin - `start_unaligning_instruction - end else begin - `invalid_instruction; - end + case({Sbit,Wbit}) + 2'b00,2'b11:begin + `start_unaligning_instruction + end + 2'b01:begin + `start_aligning_instruction + end + 2'b10:begin + `invalid_instruction + end + endcase + in_alu1_sel1=2'b00; + OUT_MOD=3'b100; + ALU_1OP=`ALU_OP_SUB; if(IN_MOD==2'b11)begin - in_alu1_sel1=2'b00; + /*compare register with param*/ in_alu1_sel2=2'b01; reg_read_port2_addr={Wbit,RM}; - OUT_MOD=3'b100; - ALU_1OP=`ALU_OP_SUB; next_state=`PROC_DE_LOAD_8_PARAM; end else begin - `invalid_instruction + /*compare register indirect access + * with param */ + in_alu1_sel2=2'b00; + next_state=`PROC_DE_LOAD_16_PARAM; /*will the call MEMIO_READ*/ end end 11'b1011_0xxx_xxx : begin @@ -199,18 +209,19 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin IN_MOD=CIR[7:6]; RM=CIR[2:0]; Wbit=CIR[8:8]; - in_alu1_sel2=2'b00; + in_alu1_sel1=2'b00; + PARAM1=0; if(CIR[9:9] == 1)begin /* Mem/Reg to reg */ if(IN_MOD==2'b11)begin /*Reg to Reg*/ - in_alu1_sel1=2'b01; - reg_read_port1_addr={Wbit,RM}; + in_alu1_sel2=2'b01; + reg_read_port2_addr={Wbit,RM}; next_state=`PROC_EX_STATE_ENTRY; end else begin /*Mem to Reg*/ - in_alu1_sel1=2'b00; - next_state=`RPOC_MEMIO_READ; + in_alu1_sel2=2'b00; + next_state=`PROC_MEMIO_READ; end OUT_MOD=3'b011; reg_write_addr={Wbit,CIR[5:3]}; @@ -218,22 +229,20 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin /* Reg to Mem/Reg */ if(IN_MOD==2'b11)begin /*Reg to Reg*/ - in_alu1_sel1=2'b01; + in_alu1_sel2=2'b01; OUT_MOD=3'b011; reg_write_addr={Wbit,RM}; next_state=`PROC_EX_STATE_ENTRY; end else begin /*Reg to Mem*/ - in_alu1_sel1=2'b00; - reg_read_port1_addr={Wbit,CIR[5:3]}; + in_alu1_sel2=2'b00; OUT_MOD={1'b0,IN_MOD}; next_state=`PROC_DE_LOAD_REG_TO_PARAM; end - reg_read_port1_addr={Wbit,CIR[5:3]}; + reg_read_port2_addr={Wbit,CIR[5:3]}; end ALU_1OP=`ALU_OP_ADD; - PARAM2=0; end 11'b0100_xxxx_xxx:begin//DEC /* DEC - Decrement Register */ @@ -270,20 +279,20 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin Wbit=CIR[8:8]; IN_MOD=CIR[7:6]; RM=CIR[2:0]; - in_alu1_sel1=(IN_MOD==2'b11)? 2'b01 : 2'b00; - in_alu1_sel2=2'b00;/* number 1 */ - PARAM2=1; + in_alu1_sel2=(IN_MOD==2'b11)? 2'b01 : 2'b00; + in_alu1_sel1=2'b00;/* number 1 */ + PARAM1=1; OUT_MOD={1'b0,IN_MOD}; /*in case IN_MOD=11 */ - reg_read_port1_addr={1'b0,RM}; + reg_read_port2_addr={1'b0,RM}; reg_write_addr={1'b0,RM}; - ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB:`ALU_OP_ADD; + ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD; if ( IN_MOD == 2'b11 ) next_state=`PROC_EX_STATE_ENTRY; else - next_state=`RPOC_MEMIO_READ; + next_state=`PROC_MEMIO_READ; end 11'b1111_0100_xxx : begin /* HLT - Halt */ @@ -449,7 +458,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 2'b00: next_state=`PROC_EX_STATE_ENTRY; 2'b01: next_state=`PROC_DE_LOAD_16_PARAM; 2'b10: next_state=`PROC_DE_LOAD_8_PARAM; - 2'b11: next_state=`RPOC_MEMIO_READ; + 2'b11: next_state=`PROC_MEMIO_READ; endcase reg_write_addr=ucode_data[11:8 ]; in_alu1_sel1 =ucode_data[13:12]; @@ -464,9 +473,11 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 3'b011: ALU_1OP=`ALU_OP_OR; 3'b100: ALU_1OP=`ALU_OP_XOR; 3'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B; + 3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE; endcase reg_read_port1_addr=ucode_data[25:22]; IN_MOD =ucode_data[28:26]; + reg_read_port1_addr=ucode_data[32:29]; end end diff --git a/system/proc_state_def.v b/system/proc_state_def.v index 9fa542a..2839364 100644 --- a/system/proc_state_def.v +++ b/system/proc_state_def.v @@ -37,7 +37,7 @@ `define PROC_DE_LOAD_REG_TO_PARAM 6'b001100 /*MEM/IO READ*/ -`define RPOC_MEMIO_READ 6'b010000 +`define PROC_MEMIO_READ 6'b010000 `define PROC_MEMIO_READ_SETADDR 6'b010001 `define PROC_MEMIO_GET_ALIGNED_DATA 6'b010010 /* :) */ `define PROC_MEMIO_GET_UNALIGNED_DATA 6'b010011 /* :( */ diff --git a/system/processor.v b/system/processor.v index 3af933f..d44a880 100644 --- a/system/processor.v +++ b/system/processor.v @@ -249,7 +249,7 @@ always @(negedge clock) begin else state=`PROC_NEXT_MICROCODE; end - 3'b110:begin /* Indirect write on SP */ + 3'b110:begin /* SP Indirect write*/ reg_read_port1_addr=4'b1100; state=`PROC_MEMIO_WRITE; end @@ -374,7 +374,7 @@ always @(posedge clock) begin end end `PROC_DE_LOAD_REG_TO_PARAM:begin - PARAM1=reg_read_port1_data; + PARAM2=reg_read_port2_data; state=`PROC_EX_STATE_ENTRY; end `PROC_DE_LOAD_8_PARAM:begin @@ -407,11 +407,14 @@ always @(posedge clock) begin if(unaligned_access==1)begin PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]}; ProgCount=ProgCount+1; - state=`PROC_EX_STATE_ENTRY; end else begin PARAM1 = {external_data_bus[15:8],CIR[7:0]}; - state=`PROC_EX_STATE_ENTRY; end + case(IN_MOD) + 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; + default: state=`PROC_EX_STATE_ENTRY; + endcase + end else begin ProgCount=ProgCount+1; if(unaligned_access==1)begin @@ -419,15 +422,21 @@ always @(posedge clock) begin state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET; end else begin PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]}; - state=`PROC_EX_STATE_ENTRY; + case(IN_MOD) + 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; + default: state=`PROC_EX_STATE_ENTRY; + endcase end end end `PROC_DE_LOAD_16_EXTRA_FETCH:begin PARAM1[15:8] = external_data_bus[15:8]; - state=`PROC_EX_STATE_ENTRY; + case(IN_MOD) + 3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ; + default: state=`PROC_EX_STATE_ENTRY; + endcase end - `RPOC_MEMIO_READ:begin + `PROC_MEMIO_READ:begin /*Decode MOD R/M, read the data and place it to PARAM1*/ case (IN_MOD) 3'b000, @@ -475,7 +484,7 @@ always @(posedge clock) begin `invalid_instruction; end end - 3'b110:begin /* Indirect write on SP */ + 3'b110:begin /* SP Indirect read*/ reg_read_port1_addr=4'b1100; state=`PROC_MEMIO_READ_SETADDR; end @@ -486,11 +495,11 @@ always @(posedge clock) begin end `PROC_MEMIO_GET_ALIGNED_DATA:begin - PARAM1=(Wbit==1)? {external_data_bus[7:0],external_data_bus[15:8]} : {8'b00000000,external_data_bus[15:8]} ; + PARAM2=(Wbit==1)? {external_data_bus[7:0],external_data_bus[15:8]} : {8'b00000000,external_data_bus[15:8]} ; state=`PROC_EX_STATE_ENTRY; end `PROC_MEMIO_GET_UNALIGNED_DATA:begin - PARAM1={8'b00000000,external_data_bus[7:0]}; + PARAM2={8'b00000000,external_data_bus[7:0]}; if(Wbit==1) begin state=`PROC_MEMIO_GET_SECOND_BYTE; end else begin @@ -534,7 +543,7 @@ always @(posedge clock) begin data_bus_output_register={ALU_1O[15:8],BYTE_WRITE_TEMP_REG[7:0]}; end `PROC_MEMIO_GET_SECOND_BYTE1:begin - PARAM1[15:8]=external_data_bus[15:8]; + PARAM2[15:8]=external_data_bus[15:8]; state=`PROC_EX_STATE_ENTRY; end `PROC_NEXT_MICROCODE:begin diff --git a/system/ucode.txt b/system/ucode.txt index aa80c60..1bf4766 100644 --- a/system/ucode.txt +++ b/system/ucode.txt @@ -28,6 +28,7 @@ // 011:ALU_OP_OR // 100:ALU_OP_XOR // 101:ALU_OP_ADD_SIGNED_B +// 110:ALU_OP_SUB_REVERSE // //a1o: OUT_MOD. Handled in `PROC_EX_STATE_EXIT // @@ -41,18 +42,18 @@ // 00: PROC_EX_STATE_ENTRY // 01: PROC_DE_LOAD_16_PARAM // 10: PROC_DE_LOAD_8_PARAM -// 11: RPOC_MEMIO_READ +// 11: PROC_MEMIO_READ // //Nxt M: Next microcode address @000 0000_000_000__00__00_0000__00_000000 -// 28 25 21 18 15 13 11 7 5 0 -// imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | -@001 011_1100_001_011__00__01_1100__01_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1) -@002 011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP] -@003 011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC +// 32 28 25 21 18 15 13 11 7 5 0 +// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | +@001 0000_011_1100_001_011__00__01_1100__01_000010 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1) +@002 0000_011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP] +@003 0000_011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC -// imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | -@004 110_zzzz_000_101__11__00_zzzz__11_000101 // ALU_1: PARAM1 ([SP]) ALU_2: 0 ALU_OP:ADD ALU_out: PC -@005 011_1100_000_011__00__01_1100__00_000000 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:ADD ALU_out: SP +// rr2|imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | +@004 0000_110_zzzz_000_101__00__11_zzzz__11_000101 // ALU_1: 0 ALU_2: PARAM2 ([SP) ALU_OP:ADD ALU_out: PC (also read [SP] to PARAM2) +@005 0000_011_1100_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP diff --git a/system/ucode_header.v b/system/ucode_header.v index 1a53528..22b841c 100644 --- a/system/ucode_header.v +++ b/system/ucode_header.v @@ -18,7 +18,7 @@ along with this program. If not, see . */ `define UCODE_ADDR_BITS 5 -`define UCODE_DATA_BITS 32 +`define UCODE_DATA_BITS 33 `define UCODE_SIZE 6 /* DEFINE ADDRESSES IN THE MICROCODE */