diff --git a/cpu/alu.v b/cpu/alu.v index b3ceb85..e2af38e 100644 --- a/cpu/alu.v +++ b/cpu/alu.v @@ -21,6 +21,8 @@ module ALU(input [15:0]A,input [15:0]B, input oe,output reg [15:0]OUT,input [`ALU_OP_BITS-1:0]op,output wire [7:0]FLAGS,input Wbit); reg C_FLAG; +wire signed [15:0]SIGNED_B; +assign SIGNED_B=B; assign FLAGS={(Wbit==1)?OUT[15:15]:OUT[7:7],(Wbit==1) ? (OUT[15:0]=='h0000) : (OUT[7:0]=='h00),5'b00000,C_FLAG}; @@ -28,6 +30,7 @@ always @ ( * ) begin if(Wbit==1)begin case (op) `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_AND: OUT=A&B; `ALU_OP_OR: OUT=A|B; diff --git a/cpu/alu_header.v b/cpu/alu_header.v index 07bee16..0061d1a 100644 --- a/cpu/alu_header.v +++ b/cpu/alu_header.v @@ -18,8 +18,9 @@ along with this program. If not, see . */ `define ALU_OP_BITS 3 -`define ALU_OP_ADD 3'b000 -`define ALU_OP_SUB 3'b001 -`define ALU_OP_AND 3'b010 -`define ALU_OP_OR 3'b011 -`define ALU_OP_XOR 3'b100 +`define ALU_OP_ADD 3'b000 +`define ALU_OP_SUB 3'b001 +`define ALU_OP_AND 3'b010 +`define ALU_OP_OR 3'b011 +`define ALU_OP_XOR 3'b100 +`define ALU_OP_ADD_SIGNED_B 3'b101 diff --git a/cpu/processor.v b/cpu/processor.v index 0268145..96f8a98 100644 --- a/cpu/processor.v +++ b/cpu/processor.v @@ -514,59 +514,87 @@ always @(posedge clock) begin 6'b011110, 6'b011111:begin /* Conditional relative jumps */ - /* Jump on Zero */ + /* JE/JZ - Jump on Zero */ /* 0 1 1 1 0 1 0 0 | IP-INC8 |*/ - /* Jump on Sign */ + /* JS - Jump on Sign */ /* 0 1 1 1 1 0 0 0 | IP-INC8 |*/ - /* Jump on not Sign */ + /* JNS -Jump on not Sign */ /* 0 1 1 1 1 0 0 1 | IP-INC8 |*/ /* .... */ `start_aligning_instruction Wbit=1; in1_sel=2'b10; in2_sel=2'b00; - PARAM2={8'b00000000,CIR[7:0]}; + PARAM2={{8{CIR[7:7]}},CIR[7:0]}; ALU_1OE=0; - ALU_1OP=`ALU_OP_ADD; + ALU_1OP=`ALU_OP_ADD_SIGNED_B; out_sel=3'b101; - if(CIR[7:7]==1) begin - `invalid_instruction; // We don't do singed add 8bit to unsigned 16bit - end else begin - case(CIR[11:9]) - 4'b000: begin - /* Jump on (not) Overflow */ - if(FLAGS[11:11]==CIR[8:8]) - state=`PROC_IF_STATE_ENTRY; - else begin - state=`PROC_EX_STATE_ENTRY; - end + case(CIR[11:9]) + 4'b000: begin + /* Jump on (not) Overflow */ + if(FLAGS[11:11]==CIR[8:8]) + state=`PROC_IF_STATE_ENTRY; + else begin + state=`PROC_EX_STATE_ENTRY; end - 4'b010: begin - /* Jump on (not) Zero */ - if(FLAGS[6:6]==CIR[8:8]) - state=`PROC_IF_STATE_ENTRY; - else - state=`PROC_EX_STATE_ENTRY; - end - 4'b100: begin - /* Jump on (not) Sign */ - if(FLAGS[7:7]==CIR[8:8]) - state=`PROC_IF_STATE_ENTRY; - else - state=`PROC_EX_STATE_ENTRY; - end - 4'b101: begin - /* Jump on (not) Parity */ - if(FLAGS[2:2]==CIR[8:8]) - state=`PROC_IF_STATE_ENTRY; - else - state=`PROC_EX_STATE_ENTRY; - end - default:begin - `invalid_instruction; /*We don't support that condition*/ - end - endcase - end + end + 4'b010: begin + /* Jump on (not) Zero */ + if(FLAGS[6:6]==CIR[8:8]) + state=`PROC_IF_STATE_ENTRY; + else + state=`PROC_EX_STATE_ENTRY; + end + 4'b100: begin + /* Jump on (not) Sign */ + if(FLAGS[7:7]==CIR[8:8]) + state=`PROC_IF_STATE_ENTRY; + else + state=`PROC_EX_STATE_ENTRY; + end + 4'b101: begin + /* Jump on (not) Parity */ + if(FLAGS[2:2]==CIR[8:8]) + state=`PROC_IF_STATE_ENTRY; + else + state=`PROC_EX_STATE_ENTRY; + end + default:begin + `invalid_instruction; /*We don't support that condition*/ + end + endcase + end + 6'b111010:begin + /* JMP,CALL */ + case(CIR[9:8]) + 2'b00: begin + /* CALL - Call direct within segment */ + /* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/ + `invalid_instruction + end + 2'b01: begin + /* JMP - Uncoditional Jump direct within segment */ + /* 1 1 1 0 1 0 0 1 | IP-INC-LO | IP-INC-HI |*/ + `invalid_instruction + end + 2'b10: begin + /* JMP - Unconditional jump direct intersegment */ + /* 0 0 0 0 0 0 0 0 | IP-LO | IP-HI | CS-LO | CS-HI | */ + `invalid_instruction + end + 2'b11: begin + /* JMP - Unconditional jump direct within segment (short) */ + /* | 1 1 1 0 1 0 0 1 | IP-INC-LO | */ + Wbit=1; + in1_sel=2'b10; + in2_sel=2'b00; + PARAM2={{8{CIR[7:7]}},CIR[7:0]}; + ALU_1OE=0; + ALU_1OP=`ALU_OP_ADD_SIGNED_B; + out_sel=3'b101; + state=`PROC_EX_STATE_ENTRY; + end + endcase end default:begin `invalid_instruction