From 16e02e0788c9083baceedee0b1123a72f2ed4d7c Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Mon, 13 Feb 2023 10:36:37 +0000 Subject: [PATCH] Added conditional jump support! --- cpu/Makefile | 2 +- cpu/processor.v | 157 +++++++++++++++++++++++++++++++++--------------- cpu/xt2 | 0 3 files changed, 111 insertions(+), 48 deletions(-) delete mode 100644 cpu/xt2 diff --git a/cpu/Makefile b/cpu/Makefile index 0c9f5e1..f980d99 100644 --- a/cpu/Makefile +++ b/cpu/Makefile @@ -32,7 +32,7 @@ ${VVP} : ${SOURCES} ${INCLUDES} .PHONY: disas disas: brainfuck.bin - objdump -D -b binary -m i8086 $^ + objdump -D -b binary -m i8086 $^ | less .PHONY: clean clean: diff --git a/cpu/processor.v b/cpu/processor.v index cfb5ebe..899e8dc 100644 --- a/cpu/processor.v +++ b/cpu/processor.v @@ -27,7 +27,6 @@ reg unaligned_access; reg [1:0]IN_MOD; reg [2:0]IN_RM; reg Wbit; -reg Suppress_ALU_Output; reg [15:0]FLAGS; /* . . . . O D I T S Z . A . P . C */ // C - Carry flag : carry out or borrow into the high order bit (8bit/16bit) @@ -55,7 +54,8 @@ reg [15:0]FLAGS; // Execution units reg [1:0] in1_sel; reg [1:0] in2_sel; -reg [1:0] out_sel; +/* out_sel : { EXTRA_FUNCTIONS_BIT[0:0], MOD_OR_EXTRA_FUNCTION[1:0] } */ +reg [2:0] out_sel; /*** RESET LOGIC ***/ always @(negedge reset) begin @@ -90,7 +90,7 @@ register_file register_file(reg_write_addr,reg_write_data,reg_write_we,reg_read_ mux4 #(.WIDTH(16)) MUX16_1A( PARAM1, reg_read_data, - 16'b0, + {ProgCount[14:0],unaligned_access}, /*THATS NOT ALL OF ADDR Bus, is that irrelevant with segmentation??*/ 16'b0, in1_sel, ALU_1A); @@ -98,7 +98,7 @@ mux4 #(.WIDTH(16)) MUX16_1A( mux4 #(.WIDTH(16)) MUX16_1B( PARAM2, reg_read_data, - 16'b0, + {ProgCount[14:0],unaligned_access}, /*THATS NOT ALL OF ADDR Bus, is that irrelevant with segmentation??*/ 16'b0, in2_sel, ALU_1B); @@ -134,19 +134,23 @@ always @(negedge clock) begin state=`PROC_DE_STATE_ENTRY; end `PROC_EX_STATE_EXIT:begin - if(Suppress_ALU_Output==0)begin - case(out_sel) - 2'b11:begin - reg_write_we=0; - state=`PROC_IF_STATE_ENTRY; - end - default:begin - `invalid_instruction - end - endcase - end else begin - state=`PROC_IF_STATE_ENTRY; - end + case(out_sel) + 3'b011:begin + reg_write_we=0; + state=`PROC_IF_STATE_ENTRY; + end + 3'b101:begin + ProgCount=ALU_1O[15:1]; + unaligned_access=ALU_1O[0:0]; + state=`PROC_IF_STATE_ENTRY; + end + 3'b100:begin + state=`PROC_IF_STATE_ENTRY; + end + default:begin + `invalid_instruction + end + endcase end `PROC_DE_LOAD_16_EXTRA_FETCH_SET:begin external_address_bus = ProgCount; @@ -165,7 +169,7 @@ always @(posedge clock) begin end `PROC_IF_STATE_ENTRY:begin ERROR=0; - Suppress_ALU_Output=0; + $display("Fetched instruction at %04x",{ProgCount[18:0],unaligned_access}); external_address_bus <= ProgCount; read <= 0; write <= 1; @@ -197,7 +201,7 @@ always @(posedge clock) begin IN_MOD=2'b11; in1_sel=2'b00; in2_sel=2'b01; - out_sel=2'b11; + out_sel=3'b011; reg_read_addr={CIR[8:8],3'b000}; reg_write_addr={CIR[8:8],3'b000}; reg_read_oe=0; @@ -224,7 +228,7 @@ always @(posedge clock) begin IN_MOD=2'b11; in1_sel=2'b00; in2_sel=2'b01; - out_sel=CIR[7:6]; + out_sel={1'b0,CIR[7:6]}; reg_read_addr={CIR[8:8],CIR[2:0]}; reg_write_addr={CIR[8:8],CIR[2:0]}; reg_read_oe=0; @@ -254,7 +258,7 @@ always @(posedge clock) begin IN_MOD=2'b11; in1_sel=2'b00; in2_sel=2'b00; - out_sel=2'b11; + out_sel=3'b011; reg_write_addr={1'b0,CIR[10:8]}; PARAM1[7:0]=CIR[7:0]; PARAM2=0; @@ -273,7 +277,7 @@ always @(posedge clock) begin IN_MOD=2'b11; in1_sel=2'b00; in2_sel=2'b00; - out_sel=2'b11; + out_sel=3'b011; reg_write_addr={1'b1,CIR[10:8]}; ALU_1OE=0; ALU_1OP=`ALU_OP_ADD; @@ -298,7 +302,7 @@ always @(posedge clock) begin in1_sel=2'b00; end in2_sel=2'b00; - out_sel=2'b11; + out_sel=3'b011; reg_write_addr={CIR[8:8],CIR[5:3]}; end else begin `invalid_instruction @@ -325,7 +329,7 @@ always @(posedge clock) begin Wbit=1; in1_sel=2'b01; in2_sel=2'b00; - out_sel=2'b11; + out_sel=3'b011; IN_MOD=2'b11; PARAM2=1; reg_read_addr={1'b1,CIR[10:8]}; @@ -350,7 +354,7 @@ always @(posedge clock) begin IN_MOD=CIR[7:6]; in1_sel=2'b00;/* number 1 */ in2_sel=(CIR[7:6]==2'b11)? 2'b01 : 2'b00; - out_sel=CIR[7:6]; + out_sel={1'b0,CIR[7:6]}; PARAM1=1; reg_read_addr={1'b0,CIR[2:0]}; reg_write_addr={1'b0,CIR[2:0]}; @@ -399,12 +403,12 @@ always @(posedge clock) begin `start_unaligning_instruction else `start_aligning_instruction - Suppress_ALU_Output=1; IN_MOD=2'b11; in1_sel=2'b00; in2_sel=2'b01; reg_read_addr={CIR[8:8],3'b000}; reg_read_oe=0; + out_sel=3'b100; ALU_1OE=0; ALU_1OP=`ALU_OP_SUB; if(CIR[8:8]==1) @@ -417,6 +421,65 @@ always @(posedge clock) begin `invalid_instruction end end + 6'b011100, + 6'b011101, + 6'b011110, + 6'b011111:begin + /* Conditional relative jumps */ + /* Jump on Zero */ + /* 0 1 1 1 0 1 0 0 | IP-INC8 |*/ + /* Jump on Sign */ + /* 0 1 1 1 1 0 0 0 | IP-INC8 |*/ + /* 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]}; + ALU_1OE=0; + ALU_1OP=`ALU_OP_ADD; + 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 + 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 default:begin `invalid_instruction end @@ -483,28 +546,28 @@ always @(posedge clock) begin if(IN_MOD!=2'b00)begin /*Actually check if 01 and add the 8bits or if 10 add the 16bits ....*/ `invalid_instruction; - end + end - end - `PROC_MEMIO_GET_ALIGNED_DATA:begin - PARAM1=(Wbit==1)? external_data_bus : {8'b00000000,external_data_bus[15:8]} ; - state=`PROC_EX_STATE_ENTRY; - end - `PROC_MEMIO_GET_UNALIGNED_DATA:begin - if(Wbit==1) begin - `invalid_instruction //easy to implement, get the other byte from the next address - end else begin - PARAM1={8'b00000000,external_data_bus[7:0]}; - state=`PROC_EX_STATE_ENTRY; - end - end - `PROC_EX_STATE_ENTRY:begin - reg_write_data=ALU_1O; - FLAGS[7:0] = ALU_FLAGS[7:0]; - state=`PROC_EX_STATE_EXIT; - ERROR=0; - end - endcase + end + `PROC_MEMIO_GET_ALIGNED_DATA:begin + PARAM1=(Wbit==1)? external_data_bus : {8'b00000000,external_data_bus[15:8]} ; + state=`PROC_EX_STATE_ENTRY; + end + `PROC_MEMIO_GET_UNALIGNED_DATA:begin + if(Wbit==1) begin + `invalid_instruction //easy to implement, get the other byte from the next address + end else begin + PARAM1={8'b00000000,external_data_bus[7:0]}; + state=`PROC_EX_STATE_ENTRY; + end + end + `PROC_EX_STATE_ENTRY:begin + reg_write_data=ALU_1O; + FLAGS[7:0] = ALU_FLAGS[7:0]; + state=`PROC_EX_STATE_EXIT; + ERROR=0; + end + endcase end diff --git a/cpu/xt2 b/cpu/xt2 deleted file mode 100644 index e69de29..0000000