From abee49d6c3c5787d2c73b4b24b87c87b33b3b539 Mon Sep 17 00:00:00 2001 From: "(Tim) Efthimis Kritikos" Date: Fri, 24 Feb 2023 07:32:27 +0000 Subject: [PATCH] Implemented PUSH instruction, fixed register addressing bug and a RET bug --- system/decoder.v | 32 ++++++++++++++++++++++++-------- system/processor.v | 4 ++-- system/registers.v | 10 ++++++---- system/ucode.txt | 34 +++++++++++++++++++++++----------- system/ucode_header.v | 5 +++-- 5 files changed, 58 insertions(+), 27 deletions(-) diff --git a/system/decoder.v b/system/decoder.v index 4659a81..a659c7c 100644 --- a/system/decoder.v +++ b/system/decoder.v @@ -273,7 +273,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin /* DEC - Register/Memory */ /* 1 1 1 1 1 1 1 W | MOD 0 0 1 R/M | < DISP LO> | < DISP HI> */ seq_addr_entry=`UCODE_NO_INSTRUCTION; - has_operands=1; + has_operands=0; opcode_size=1; `start_aligning_instruction Wbit=CIR[8:8]; @@ -414,7 +414,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin end next_state=`PROC_IF_STATE_ENTRY; end - 11'b11101000_xxx:begin + 11'b1110_1000_xxx:begin /* CALL - Direct call within segment */ /* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/ @@ -427,7 +427,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin PARAM2=2; //substract from sp seq_addr_entry=`UCODE_CALL_ENTRY; end - 11'b11000011_xxx:begin + 11'b1100_0011_xxx:begin /* RET - Return from call within segment */ /* | 1 1 0 0 0 0 1 1 | */ @@ -442,10 +442,10 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin has_operands=1; Wbit=1; Sbit=0; - PARAM2=2; + PARAM1=2; seq_addr_entry=`UCODE_RET_ENTRY; end - 11'b1010101x_xxx:begin + 11'b1010_101x_xxx:begin /* STOS - Write byte/word to [DI] and increment accordingly */ /* | 1 0 1 0 1 0 1 W | */ `start_unaligning_instruction @@ -457,6 +457,18 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin seq_addr_entry=`UCODE_STOS_ENTRY; PARAM2=(Wbit==1)?2:1; end + 11'b0101_0xxx_xxx:begin + /* PUSH - SP-=2; [SP]=REG */ + /* | 0 1 0 1 0 REG | */ + `start_unaligning_instruction + opcode_size=0; + has_operands=0; + Wbit=1; + Sbit=0; + PARAM2=2; + reg_read_port2_addr={1'b1,CIR[10:8]}; + seq_addr_entry=`UCODE_PUSH_ENTRY; + end default:begin `invalid_instruction end @@ -487,9 +499,13 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin 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_port2_addr=ucode_data[32:29]; + if(ucode_data[33:33]==0) + reg_read_port1_addr=ucode_data[25:22]; + IN_MOD=ucode_data[28:26]; + if(ucode_data[34:34]==0) + reg_read_port2_addr=ucode_data[32:29]; + if(ucode_data[36:36]==1) + Wbit=ucode_data[35:35]; end end diff --git a/system/processor.v b/system/processor.v index 3c17cb0..3282f75 100644 --- a/system/processor.v +++ b/system/processor.v @@ -185,7 +185,7 @@ always @(negedge clock) begin * be done by decode at the end*/ if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) unaligned_access=unaligning_instruction^unaligned_access; - case(OUT_MOD) /*TODO: use RM*/ + case(OUT_MOD) 3'b000, 3'b001, 3'b010 : begin @@ -507,7 +507,7 @@ always @(posedge clock) begin end end `PROC_EX_STATE_ENTRY:begin - FLAGS[7:0] = ALU_1FLAGS[7:0]; + FLAGS[7:0] = ALU_1FLAGS[7:0]; //TODO, we should probably move all the ...STATE_EXIT stuff here state=`PROC_EX_STATE_EXIT; end `PROC_MEMIO_WRITE:begin diff --git a/system/registers.v b/system/registers.v index d6d36cb..c527fc1 100644 --- a/system/registers.v +++ b/system/registers.v @@ -32,11 +32,13 @@ input write_port1_we; reg [15:0] registers [7:0]; -assign read_port1_data = ( read_port1_addr[3:3] ? registers[read_port1_addr[2:0]] : - ( read_port1_addr[2:2] ? {8'b0,registers[read_port1_addr[2:0]][15:8]} : {8'b0,registers[read_port1_addr[2:0]][7:0]} ) ); +assign read_port1_data[15:8] = read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][15:8] : 8'hz ; +assign read_port1_data[7:0] = ( read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][7:0] : + ( read_port1_addr[2:2] ? {8'b0,registers[read_port1_addr[1:0]][15:8]} : {8'b0,registers[read_port1_addr[1:0]][7:0]} ) ); -assign read_port2_data = ( read_port2_addr[3:3] ? registers[read_port2_addr[2:0]] : - ( read_port2_addr[2:2] ? {8'b0,registers[read_port2_addr[2:0]][15:8]} : {8'b0,registers[read_port2_addr[2:0]][7:0]} ) ); +assign read_port2_data[15:8] = read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][15:8] : 8'hz ; +assign read_port2_data[7:0] = ( read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][7:0] : + ( read_port2_addr[2:2] ? {8'b0,registers[read_port2_addr[1:0]][15:8]} : {8'b0,registers[read_port2_addr[1:0]][7:0]} ) ); `ifdef DEBUG_REG_WRITES string debug_name; diff --git a/system/ucode.txt b/system/ucode.txt index 9bb43da..c0984bc 100644 --- a/system/ucode.txt +++ b/system/ucode.txt @@ -17,6 +17,13 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +//wbo: Wbit overwrite, {VALUE,ENABLE}. ex 11 would force one, 10 wouldn't do anything +// +//krs: Keep registers, selects weather the register port 1 and/or 2 +// addresses is set on that microcoded instruction or kept as it +// was before allowing for registers to be parameterised. +// {Register_port2, Register_port1} +// //rr2: reg_read_port2_addr // //imd: IN_MOD @@ -50,19 +57,24 @@ @000 0000_000_000__00__00_0000__00_000000 -// 32 28 25 21 18 15 13 11 7 5 0 +// 36 34 32 28 25 21 18 15 13 11 7 5 0 // CALL -// 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 +// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | +@001 _00_00_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 _00_00_0000_011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP] +@003 _00_00_0000_011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC // RET -// 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 +// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | +@004 _00_00_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 _00_00_1100_011_0000_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP // STOS -// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | -@006 1000_011_zzzz_000_000__01__11_zzzz__00_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI] -@007 zzzz_011_1111_000_011__00__01_1111__00_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI +// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | +@006 _00_00_1000_011_zzzz_000_000__01__11_zzzz__00_000111 // ALU_1: 0 ALU_2: AX ALU_OP:ADD ALU_out: [DI] +@007 _11_00_zzzz_011_1111_000_011__00__01_1111__00_000000 // ALU_1: DI ALU_2: PARAM2 (2) ALU_OP:ADD ALU_OUT: DI + +// PUSH +// wbo|krs|rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | +@008 _00_10_0000_011_1100_001_011__00__01_1100__00_001001 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:SUB ALU_out: SP (also fetch the opcode argument to PARAM1) +@009 _00_10_0000_011_zzzz_000_110__01__11_zzzz__00_000000 // ALU_1: 0 ALU_2: REG ALU_OP:ADD ALU_out: [SP] diff --git a/system/ucode_header.v b/system/ucode_header.v index 5fe32d8..9c31d9e 100644 --- a/system/ucode_header.v +++ b/system/ucode_header.v @@ -18,11 +18,12 @@ along with this program. If not, see . */ `define UCODE_ADDR_BITS 5 -`define UCODE_DATA_BITS 33 -`define UCODE_SIZE 8 +`define UCODE_DATA_BITS 37 +`define UCODE_SIZE 10 /* DEFINE ADDRESSES IN THE MICROCODE */ `define UCODE_NO_INSTRUCTION 5'b00000 `define UCODE_CALL_ENTRY 5'b00001 `define UCODE_RET_ENTRY 5'b00100 `define UCODE_STOS_ENTRY 5'b00110 +`define UCODE_PUSH_ENTRY 5'b01000