Implemented PUSH instruction, fixed register addressing bug and a RET bug

This commit is contained in:
(Tim) Efthimis Kritikos 2023-02-24 07:32:27 +00:00
parent a189da249c
commit abee49d6c3
5 changed files with 58 additions and 27 deletions

View File

@ -273,7 +273,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
/* DEC - Register/Memory */ /* DEC - Register/Memory */
/* 1 1 1 1 1 1 1 W | MOD 0 0 1 R/M | < DISP LO> | < DISP HI> */ /* 1 1 1 1 1 1 1 W | MOD 0 0 1 R/M | < DISP LO> | < DISP HI> */
seq_addr_entry=`UCODE_NO_INSTRUCTION; seq_addr_entry=`UCODE_NO_INSTRUCTION;
has_operands=1; has_operands=0;
opcode_size=1; opcode_size=1;
`start_aligning_instruction `start_aligning_instruction
Wbit=CIR[8:8]; Wbit=CIR[8:8];
@ -414,7 +414,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
end end
next_state=`PROC_IF_STATE_ENTRY; next_state=`PROC_IF_STATE_ENTRY;
end end
11'b11101000_xxx:begin 11'b1110_1000_xxx:begin
/* CALL - Direct call within segment */ /* CALL - Direct call within segment */
/* 1 1 1 0 1 0 0 0 | IP-INC-LO | IP-INC-HI |*/ /* 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 PARAM2=2; //substract from sp
seq_addr_entry=`UCODE_CALL_ENTRY; seq_addr_entry=`UCODE_CALL_ENTRY;
end end
11'b11000011_xxx:begin 11'b1100_0011_xxx:begin
/* RET - Return from call within segment */ /* RET - Return from call within segment */
/* | 1 1 0 0 0 0 1 1 | */ /* | 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; has_operands=1;
Wbit=1; Wbit=1;
Sbit=0; Sbit=0;
PARAM2=2; PARAM1=2;
seq_addr_entry=`UCODE_RET_ENTRY; seq_addr_entry=`UCODE_RET_ENTRY;
end end
11'b1010101x_xxx:begin 11'b1010_101x_xxx:begin
/* STOS - Write byte/word to [DI] and increment accordingly */ /* STOS - Write byte/word to [DI] and increment accordingly */
/* | 1 0 1 0 1 0 1 W | */ /* | 1 0 1 0 1 0 1 W | */
`start_unaligning_instruction `start_unaligning_instruction
@ -457,6 +457,18 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
seq_addr_entry=`UCODE_STOS_ENTRY; seq_addr_entry=`UCODE_STOS_ENTRY;
PARAM2=(Wbit==1)?2:1; PARAM2=(Wbit==1)?2:1;
end 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 default:begin
`invalid_instruction `invalid_instruction
end 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'b101: ALU_1OP=`ALU_OP_ADD_SIGNED_B;
3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE; 3'b110: ALU_1OP=`ALU_OP_SUB_REVERSE;
endcase endcase
reg_read_port1_addr=ucode_data[25:22]; if(ucode_data[33:33]==0)
IN_MOD =ucode_data[28:26]; reg_read_port1_addr=ucode_data[25:22];
reg_read_port2_addr=ucode_data[32:29]; 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
end end

View File

@ -185,7 +185,7 @@ always @(negedge clock) begin
* be done by decode at the end*/ * be done by decode at the end*/
if (ucode_seq_addr==`UCODE_NO_INSTRUCTION) if (ucode_seq_addr==`UCODE_NO_INSTRUCTION)
unaligned_access=unaligning_instruction^unaligned_access; unaligned_access=unaligning_instruction^unaligned_access;
case(OUT_MOD) /*TODO: use RM*/ case(OUT_MOD)
3'b000, 3'b000,
3'b001, 3'b001,
3'b010 : begin 3'b010 : begin
@ -507,7 +507,7 @@ always @(posedge clock) begin
end end
end end
`PROC_EX_STATE_ENTRY:begin `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; state=`PROC_EX_STATE_EXIT;
end end
`PROC_MEMIO_WRITE:begin `PROC_MEMIO_WRITE:begin

View File

@ -32,11 +32,13 @@ input write_port1_we;
reg [15:0] registers [7:0]; reg [15:0] registers [7:0];
assign read_port1_data = ( read_port1_addr[3:3] ? registers[read_port1_addr[2:0]] : assign read_port1_data[15:8] = read_port1_addr[3:3] ? registers[read_port1_addr[2:0]][15:8] : 8'hz ;
( 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[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]] : assign read_port2_data[15:8] = read_port2_addr[3:3] ? registers[read_port2_addr[2:0]][15:8] : 8'hz ;
( 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[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 `ifdef DEBUG_REG_WRITES
string debug_name; string debug_name;

View File

@ -17,6 +17,13 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */ along with this program. If not, see <http://www.gnu.org/licenses/>. */
//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 //rr2: reg_read_port2_addr
// //
//imd: IN_MOD //imd: IN_MOD
@ -50,19 +57,24 @@
@000 0000_000_000__00__00_0000__00_000000 @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 // CALL
// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | // wbo|krs|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) @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 0000_011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP] @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 0000_011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC @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 // RET
// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | // wbo|krs|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) @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 0000_011_1100_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP @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 // STOS
// rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | // wbo|krs|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] @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 zzzz_011_1111_000_011__00__01_1111__00_000000 // ALU_1: DI ALU_2: PARAM2 (2) 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]

View File

@ -18,11 +18,12 @@
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 UCODE_ADDR_BITS 5 `define UCODE_ADDR_BITS 5
`define UCODE_DATA_BITS 33 `define UCODE_DATA_BITS 37
`define UCODE_SIZE 8 `define UCODE_SIZE 10
/* DEFINE ADDRESSES IN THE MICROCODE */ /* DEFINE ADDRESSES IN THE MICROCODE */
`define UCODE_NO_INSTRUCTION 5'b00000 `define UCODE_NO_INSTRUCTION 5'b00000
`define UCODE_CALL_ENTRY 5'b00001 `define UCODE_CALL_ENTRY 5'b00001
`define UCODE_RET_ENTRY 5'b00100 `define UCODE_RET_ENTRY 5'b00100
`define UCODE_STOS_ENTRY 5'b00110 `define UCODE_STOS_ENTRY 5'b00110
`define UCODE_PUSH_ENTRY 5'b01000