Added support to CMP for compare memory to opcode parameter, added support for both PROC_DE_LOAD_?_PARAM and PROC_MEMIO_READ at the same command and associated changes

This commit is contained in:
(Tim) Efthimis Kritikos 2023-02-24 02:18:48 +00:00
parent c4ac55d4c3
commit e684db8348
7 changed files with 72 additions and 48 deletions

View File

@ -34,6 +34,7 @@ always @ ( * ) begin
`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_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_SUB_REVERSE: {C_FLAG,OUT}=B-A;
`ALU_OP_AND: OUT=A&B; `ALU_OP_AND: OUT=A&B;
`ALU_OP_OR: OUT=A|B; `ALU_OP_OR: OUT=A|B;
`ALU_OP_XOR: OUT=A^B; `ALU_OP_XOR: OUT=A^B;
@ -47,6 +48,7 @@ always @ ( * ) begin
`ALU_OP_ADD: {C_FLAG,OUT[7:0]}=A[7:0]+B[7:0]; `ALU_OP_ADD: {C_FLAG,OUT[7:0]}=A[7:0]+B[7:0];
`ALU_OP_ADD_SIGNED_B: {C_FLAG,OUT[7:0]}=A[7:0]+SIGNED_8B; `ALU_OP_ADD_SIGNED_B: {C_FLAG,OUT[7:0]}=A[7:0]+SIGNED_8B;
`ALU_OP_SUB: {C_FLAG,OUT[7:0]}=A[7:0]-B[7:0]; `ALU_OP_SUB: {C_FLAG,OUT[7:0]}=A[7:0]-B[7:0];
`ALU_OP_SUB_REVERSE: {C_FLAG,OUT[7:0]}=B[7:0]-A[7:0];
`ALU_OP_AND: OUT=A&B; `ALU_OP_AND: OUT=A&B;
`ALU_OP_OR: OUT=A|B; `ALU_OP_OR: OUT=A|B;
`ALU_OP_XOR: OUT=A^B; `ALU_OP_XOR: OUT=A^B;

View File

@ -24,3 +24,4 @@
`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 `define ALU_OP_ADD_SIGNED_B 3'b101
`define ALU_OP_SUB_REVERSE 3'b110

View File

@ -138,20 +138,30 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
Sbit=CIR[9:9]; Sbit=CIR[9:9];
IN_MOD=CIR[7:6]; IN_MOD=CIR[7:6];
RM=CIR[2:0]; RM=CIR[2:0];
if(((Wbit==1)&&(Sbit==1))||Wbit==0)begin case({Sbit,Wbit})
`start_unaligning_instruction 2'b00,2'b11:begin
end else begin `start_unaligning_instruction
`invalid_instruction; end
end 2'b01:begin
`start_aligning_instruction
end
2'b10:begin
`invalid_instruction
end
endcase
in_alu1_sel1=2'b00;
OUT_MOD=3'b100;
ALU_1OP=`ALU_OP_SUB;
if(IN_MOD==2'b11)begin if(IN_MOD==2'b11)begin
in_alu1_sel1=2'b00; /*compare register with param*/
in_alu1_sel2=2'b01; in_alu1_sel2=2'b01;
reg_read_port2_addr={Wbit,RM}; reg_read_port2_addr={Wbit,RM};
OUT_MOD=3'b100;
ALU_1OP=`ALU_OP_SUB;
next_state=`PROC_DE_LOAD_8_PARAM; next_state=`PROC_DE_LOAD_8_PARAM;
end else begin end else begin
`invalid_instruction /*compare register indirect access
* with param */
in_alu1_sel2=2'b00;
next_state=`PROC_DE_LOAD_16_PARAM; /*will the call MEMIO_READ*/
end end
end end
11'b1011_0xxx_xxx : begin 11'b1011_0xxx_xxx : begin
@ -199,18 +209,19 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
IN_MOD=CIR[7:6]; IN_MOD=CIR[7:6];
RM=CIR[2:0]; RM=CIR[2:0];
Wbit=CIR[8:8]; Wbit=CIR[8:8];
in_alu1_sel2=2'b00; in_alu1_sel1=2'b00;
PARAM1=0;
if(CIR[9:9] == 1)begin if(CIR[9:9] == 1)begin
/* Mem/Reg to reg */ /* Mem/Reg to reg */
if(IN_MOD==2'b11)begin if(IN_MOD==2'b11)begin
/*Reg to Reg*/ /*Reg to Reg*/
in_alu1_sel1=2'b01; in_alu1_sel2=2'b01;
reg_read_port1_addr={Wbit,RM}; reg_read_port2_addr={Wbit,RM};
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
end else begin end else begin
/*Mem to Reg*/ /*Mem to Reg*/
in_alu1_sel1=2'b00; in_alu1_sel2=2'b00;
next_state=`RPOC_MEMIO_READ; next_state=`PROC_MEMIO_READ;
end end
OUT_MOD=3'b011; OUT_MOD=3'b011;
reg_write_addr={Wbit,CIR[5:3]}; reg_write_addr={Wbit,CIR[5:3]};
@ -218,22 +229,20 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
/* Reg to Mem/Reg */ /* Reg to Mem/Reg */
if(IN_MOD==2'b11)begin if(IN_MOD==2'b11)begin
/*Reg to Reg*/ /*Reg to Reg*/
in_alu1_sel1=2'b01; in_alu1_sel2=2'b01;
OUT_MOD=3'b011; OUT_MOD=3'b011;
reg_write_addr={Wbit,RM}; reg_write_addr={Wbit,RM};
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
end else begin end else begin
/*Reg to Mem*/ /*Reg to Mem*/
in_alu1_sel1=2'b00; in_alu1_sel2=2'b00;
reg_read_port1_addr={Wbit,CIR[5:3]};
OUT_MOD={1'b0,IN_MOD}; OUT_MOD={1'b0,IN_MOD};
next_state=`PROC_DE_LOAD_REG_TO_PARAM; next_state=`PROC_DE_LOAD_REG_TO_PARAM;
end end
reg_read_port1_addr={Wbit,CIR[5:3]}; reg_read_port2_addr={Wbit,CIR[5:3]};
end end
ALU_1OP=`ALU_OP_ADD; ALU_1OP=`ALU_OP_ADD;
PARAM2=0;
end end
11'b0100_xxxx_xxx:begin//DEC 11'b0100_xxxx_xxx:begin//DEC
/* DEC - Decrement Register */ /* DEC - Decrement Register */
@ -270,20 +279,20 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
Wbit=CIR[8:8]; Wbit=CIR[8:8];
IN_MOD=CIR[7:6]; IN_MOD=CIR[7:6];
RM=CIR[2:0]; RM=CIR[2:0];
in_alu1_sel1=(IN_MOD==2'b11)? 2'b01 : 2'b00; in_alu1_sel2=(IN_MOD==2'b11)? 2'b01 : 2'b00;
in_alu1_sel2=2'b00;/* number 1 */ in_alu1_sel1=2'b00;/* number 1 */
PARAM2=1; PARAM1=1;
OUT_MOD={1'b0,IN_MOD}; OUT_MOD={1'b0,IN_MOD};
/*in case IN_MOD=11 */ /*in case IN_MOD=11 */
reg_read_port1_addr={1'b0,RM}; reg_read_port2_addr={1'b0,RM};
reg_write_addr={1'b0,RM}; reg_write_addr={1'b0,RM};
ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB:`ALU_OP_ADD; ALU_1OP=(CIR[3:3]==1)?`ALU_OP_SUB_REVERSE:`ALU_OP_ADD;
if ( IN_MOD == 2'b11 ) if ( IN_MOD == 2'b11 )
next_state=`PROC_EX_STATE_ENTRY; next_state=`PROC_EX_STATE_ENTRY;
else else
next_state=`RPOC_MEMIO_READ; next_state=`PROC_MEMIO_READ;
end end
11'b1111_0100_xxx : begin 11'b1111_0100_xxx : begin
/* HLT - Halt */ /* HLT - Halt */
@ -449,7 +458,7 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
2'b00: next_state=`PROC_EX_STATE_ENTRY; 2'b00: next_state=`PROC_EX_STATE_ENTRY;
2'b01: next_state=`PROC_DE_LOAD_16_PARAM; 2'b01: next_state=`PROC_DE_LOAD_16_PARAM;
2'b10: next_state=`PROC_DE_LOAD_8_PARAM; 2'b10: next_state=`PROC_DE_LOAD_8_PARAM;
2'b11: next_state=`RPOC_MEMIO_READ; 2'b11: next_state=`PROC_MEMIO_READ;
endcase endcase
reg_write_addr=ucode_data[11:8 ]; reg_write_addr=ucode_data[11:8 ];
in_alu1_sel1 =ucode_data[13:12]; in_alu1_sel1 =ucode_data[13:12];
@ -464,9 +473,11 @@ always @( CIR or SIMPLE_MICRO or seq_addr_input ) begin
3'b011: ALU_1OP=`ALU_OP_OR; 3'b011: ALU_1OP=`ALU_OP_OR;
3'b100: ALU_1OP=`ALU_OP_XOR; 3'b100: ALU_1OP=`ALU_OP_XOR;
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;
endcase endcase
reg_read_port1_addr=ucode_data[25:22]; reg_read_port1_addr=ucode_data[25:22];
IN_MOD =ucode_data[28:26]; IN_MOD =ucode_data[28:26];
reg_read_port1_addr=ucode_data[32:29];
end end
end end

View File

@ -37,7 +37,7 @@
`define PROC_DE_LOAD_REG_TO_PARAM 6'b001100 `define PROC_DE_LOAD_REG_TO_PARAM 6'b001100
/*MEM/IO READ*/ /*MEM/IO READ*/
`define RPOC_MEMIO_READ 6'b010000 `define PROC_MEMIO_READ 6'b010000
`define PROC_MEMIO_READ_SETADDR 6'b010001 `define PROC_MEMIO_READ_SETADDR 6'b010001
`define PROC_MEMIO_GET_ALIGNED_DATA 6'b010010 /* :) */ `define PROC_MEMIO_GET_ALIGNED_DATA 6'b010010 /* :) */
`define PROC_MEMIO_GET_UNALIGNED_DATA 6'b010011 /* :( */ `define PROC_MEMIO_GET_UNALIGNED_DATA 6'b010011 /* :( */

View File

@ -249,7 +249,7 @@ always @(negedge clock) begin
else else
state=`PROC_NEXT_MICROCODE; state=`PROC_NEXT_MICROCODE;
end end
3'b110:begin /* Indirect write on SP */ 3'b110:begin /* SP Indirect write*/
reg_read_port1_addr=4'b1100; reg_read_port1_addr=4'b1100;
state=`PROC_MEMIO_WRITE; state=`PROC_MEMIO_WRITE;
end end
@ -374,7 +374,7 @@ always @(posedge clock) begin
end end
end end
`PROC_DE_LOAD_REG_TO_PARAM:begin `PROC_DE_LOAD_REG_TO_PARAM:begin
PARAM1=reg_read_port1_data; PARAM2=reg_read_port2_data;
state=`PROC_EX_STATE_ENTRY; state=`PROC_EX_STATE_ENTRY;
end end
`PROC_DE_LOAD_8_PARAM:begin `PROC_DE_LOAD_8_PARAM:begin
@ -407,11 +407,14 @@ always @(posedge clock) begin
if(unaligned_access==1)begin if(unaligned_access==1)begin
PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]}; PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]};
ProgCount=ProgCount+1; ProgCount=ProgCount+1;
state=`PROC_EX_STATE_ENTRY;
end else begin end else begin
PARAM1 = {external_data_bus[15:8],CIR[7:0]}; PARAM1 = {external_data_bus[15:8],CIR[7:0]};
state=`PROC_EX_STATE_ENTRY;
end end
case(IN_MOD)
3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state=`PROC_EX_STATE_ENTRY;
endcase
end else begin end else begin
ProgCount=ProgCount+1; ProgCount=ProgCount+1;
if(unaligned_access==1)begin if(unaligned_access==1)begin
@ -419,15 +422,21 @@ always @(posedge clock) begin
state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET; state=`PROC_DE_LOAD_16_EXTRA_FETCH_SET;
end else begin end else begin
PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]}; PARAM1 = {external_data_bus[7:0],external_data_bus[15:8]};
state=`PROC_EX_STATE_ENTRY; case(IN_MOD)
3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state=`PROC_EX_STATE_ENTRY;
endcase
end end
end end
end end
`PROC_DE_LOAD_16_EXTRA_FETCH:begin `PROC_DE_LOAD_16_EXTRA_FETCH:begin
PARAM1[15:8] = external_data_bus[15:8]; PARAM1[15:8] = external_data_bus[15:8];
state=`PROC_EX_STATE_ENTRY; case(IN_MOD)
3'b000,3'b001,3'b010: state=`PROC_MEMIO_READ;
default: state=`PROC_EX_STATE_ENTRY;
endcase
end end
`RPOC_MEMIO_READ:begin `PROC_MEMIO_READ:begin
/*Decode MOD R/M, read the data and place it to PARAM1*/ /*Decode MOD R/M, read the data and place it to PARAM1*/
case (IN_MOD) case (IN_MOD)
3'b000, 3'b000,
@ -475,7 +484,7 @@ always @(posedge clock) begin
`invalid_instruction; `invalid_instruction;
end end
end end
3'b110:begin /* Indirect write on SP */ 3'b110:begin /* SP Indirect read*/
reg_read_port1_addr=4'b1100; reg_read_port1_addr=4'b1100;
state=`PROC_MEMIO_READ_SETADDR; state=`PROC_MEMIO_READ_SETADDR;
end end
@ -486,11 +495,11 @@ always @(posedge clock) begin
end end
`PROC_MEMIO_GET_ALIGNED_DATA:begin `PROC_MEMIO_GET_ALIGNED_DATA:begin
PARAM1=(Wbit==1)? {external_data_bus[7:0],external_data_bus[15:8]} : {8'b00000000,external_data_bus[15:8]} ; PARAM2=(Wbit==1)? {external_data_bus[7:0],external_data_bus[15:8]} : {8'b00000000,external_data_bus[15:8]} ;
state=`PROC_EX_STATE_ENTRY; state=`PROC_EX_STATE_ENTRY;
end end
`PROC_MEMIO_GET_UNALIGNED_DATA:begin `PROC_MEMIO_GET_UNALIGNED_DATA:begin
PARAM1={8'b00000000,external_data_bus[7:0]}; PARAM2={8'b00000000,external_data_bus[7:0]};
if(Wbit==1) begin if(Wbit==1) begin
state=`PROC_MEMIO_GET_SECOND_BYTE; state=`PROC_MEMIO_GET_SECOND_BYTE;
end else begin end else begin
@ -534,7 +543,7 @@ always @(posedge clock) begin
data_bus_output_register={ALU_1O[15:8],BYTE_WRITE_TEMP_REG[7:0]}; data_bus_output_register={ALU_1O[15:8],BYTE_WRITE_TEMP_REG[7:0]};
end end
`PROC_MEMIO_GET_SECOND_BYTE1:begin `PROC_MEMIO_GET_SECOND_BYTE1:begin
PARAM1[15:8]=external_data_bus[15:8]; PARAM2[15:8]=external_data_bus[15:8];
state=`PROC_EX_STATE_ENTRY; state=`PROC_EX_STATE_ENTRY;
end end
`PROC_NEXT_MICROCODE:begin `PROC_NEXT_MICROCODE:begin

View File

@ -28,6 +28,7 @@
// 011:ALU_OP_OR // 011:ALU_OP_OR
// 100:ALU_OP_XOR // 100:ALU_OP_XOR
// 101:ALU_OP_ADD_SIGNED_B // 101:ALU_OP_ADD_SIGNED_B
// 110:ALU_OP_SUB_REVERSE
// //
//a1o: OUT_MOD. Handled in `PROC_EX_STATE_EXIT //a1o: OUT_MOD. Handled in `PROC_EX_STATE_EXIT
// //
@ -41,18 +42,18 @@
// 00: PROC_EX_STATE_ENTRY // 00: PROC_EX_STATE_ENTRY
// 01: PROC_DE_LOAD_16_PARAM // 01: PROC_DE_LOAD_16_PARAM
// 10: PROC_DE_LOAD_8_PARAM // 10: PROC_DE_LOAD_8_PARAM
// 11: RPOC_MEMIO_READ // 11: PROC_MEMIO_READ
// //
//Nxt M: Next microcode address //Nxt M: Next microcode address
@000 0000_000_000__00__00_0000__00_000000 @000 0000_000_000__00__00_0000__00_000000
// 28 25 21 18 15 13 11 7 5 0 // 32 28 25 21 18 15 13 11 7 5 0
// imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | // rr2 |imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@001 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 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 011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP] @002 0000_011_zzzz_000_110__10__11_zzzz__00_000011 // ALU_1: 0 ALU_2: PC ALU_OP:ADD ALU_out: [SP]
@003 011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC @003 0000_011_zzzz_000_101__10__00_zzzz__00_000000 // ALU_1: PARAM1 (arg) ALU_2: PC ALU_OP:ADD ALU_out: PC
// imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M | // rr2|imd|rr1 |a1f|a1o|a12|a11|rwa |nxs|Nxt M |
@004 110_zzzz_000_101__11__00_zzzz__11_000101 // ALU_1: PARAM1 ([SP]) ALU_2: 0 ALU_OP:ADD ALU_out: PC @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 011_1100_000_011__00__01_1100__00_000000 // ALU_1: SP ALU_2: PARAM2 (2) ALU_OP:ADD ALU_out: SP @005 0000_011_1100_000_011__01__00_1100__00_000000 // ALU_1: PARAM1 (2) ALU_2: SP ALU_OP:ADD ALU_out: SP

View File

@ -18,7 +18,7 @@
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 32 `define UCODE_DATA_BITS 33
`define UCODE_SIZE 6 `define UCODE_SIZE 6
/* DEFINE ADDRESSES IN THE MICROCODE */ /* DEFINE ADDRESSES IN THE MICROCODE */