Added unconditional jumps and support for signed addition

This commit is contained in:
(Tim) Efthimis Kritikos 2023-02-14 14:48:35 +00:00
parent 037f6dd7da
commit f97f4625e6
3 changed files with 79 additions and 47 deletions

View File

@ -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); 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; 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}; 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 if(Wbit==1)begin
case (op) case (op)
`ALU_OP_ADD: {C_FLAG,OUT}=A+B; `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: {C_FLAG,OUT}=A-B;
`ALU_OP_AND: OUT=A&B; `ALU_OP_AND: OUT=A&B;
`ALU_OP_OR: OUT=A|B; `ALU_OP_OR: OUT=A|B;

View File

@ -18,8 +18,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
`define ALU_OP_BITS 3 `define ALU_OP_BITS 3
`define ALU_OP_ADD 3'b000 `define ALU_OP_ADD 3'b000
`define ALU_OP_SUB 3'b001 `define ALU_OP_SUB 3'b001
`define ALU_OP_AND 3'b010 `define ALU_OP_AND 3'b010
`define ALU_OP_OR 3'b011 `define ALU_OP_OR 3'b011
`define ALU_OP_XOR 3'b100 `define ALU_OP_XOR 3'b100
`define ALU_OP_ADD_SIGNED_B 3'b101

View File

@ -514,59 +514,87 @@ always @(posedge clock) begin
6'b011110, 6'b011110,
6'b011111:begin 6'b011111:begin
/* Conditional relative jumps */ /* Conditional relative jumps */
/* Jump on Zero */ /* JE/JZ - Jump on Zero */
/* 0 1 1 1 0 1 0 0 | IP-INC8 |*/ /* 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 |*/ /* 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 |*/ /* 0 1 1 1 1 0 0 1 | IP-INC8 |*/
/* .... */ /* .... */
`start_aligning_instruction `start_aligning_instruction
Wbit=1; Wbit=1;
in1_sel=2'b10; in1_sel=2'b10;
in2_sel=2'b00; in2_sel=2'b00;
PARAM2={8'b00000000,CIR[7:0]}; PARAM2={{8{CIR[7:7]}},CIR[7:0]};
ALU_1OE=0; ALU_1OE=0;
ALU_1OP=`ALU_OP_ADD; ALU_1OP=`ALU_OP_ADD_SIGNED_B;
out_sel=3'b101; out_sel=3'b101;
if(CIR[7:7]==1) begin case(CIR[11:9])
`invalid_instruction; // We don't do singed add 8bit to unsigned 16bit 4'b000: begin
end else begin /* Jump on (not) Overflow */
case(CIR[11:9]) if(FLAGS[11:11]==CIR[8:8])
4'b000: begin state=`PROC_IF_STATE_ENTRY;
/* Jump on (not) Overflow */ else begin
if(FLAGS[11:11]==CIR[8:8]) state=`PROC_EX_STATE_ENTRY;
state=`PROC_IF_STATE_ENTRY;
else begin
state=`PROC_EX_STATE_ENTRY;
end
end end
4'b010: begin end
/* Jump on (not) Zero */ 4'b010: begin
if(FLAGS[6:6]==CIR[8:8]) /* Jump on (not) Zero */
state=`PROC_IF_STATE_ENTRY; if(FLAGS[6:6]==CIR[8:8])
else state=`PROC_IF_STATE_ENTRY;
state=`PROC_EX_STATE_ENTRY; else
end state=`PROC_EX_STATE_ENTRY;
4'b100: begin end
/* Jump on (not) Sign */ 4'b100: begin
if(FLAGS[7:7]==CIR[8:8]) /* Jump on (not) Sign */
state=`PROC_IF_STATE_ENTRY; if(FLAGS[7:7]==CIR[8:8])
else state=`PROC_IF_STATE_ENTRY;
state=`PROC_EX_STATE_ENTRY; else
end state=`PROC_EX_STATE_ENTRY;
4'b101: begin end
/* Jump on (not) Parity */ 4'b101: begin
if(FLAGS[2:2]==CIR[8:8]) /* Jump on (not) Parity */
state=`PROC_IF_STATE_ENTRY; if(FLAGS[2:2]==CIR[8:8])
else state=`PROC_IF_STATE_ENTRY;
state=`PROC_EX_STATE_ENTRY; else
end state=`PROC_EX_STATE_ENTRY;
default:begin end
`invalid_instruction; /*We don't support that condition*/ default:begin
end `invalid_instruction; /*We don't support that condition*/
endcase end
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 end
default:begin default:begin
`invalid_instruction `invalid_instruction