Implemented a CMP instruction and the some of the flags

This commit is contained in:
(Tim) Efthimis Kritikos 2023-02-12 01:05:39 +00:00
parent 0901af23db
commit c684348e38
2 changed files with 76 additions and 12 deletions

View File

@ -1,8 +1,10 @@
`include "alu_header.v"
module ALU(input [15:0]A,input [15:0]B, input oe,output reg [15:0]OUT,input [`ALU_OP_BITS-1:0]op);
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;
assign FLAGS={(Wbit==1)?OUT[15:15]:OUT[7:7],(Wbit==1) ? (OUT[15:0]=='h0000) : (OUT[7:0]=='h00),5'b00000,C_FLAG};
always @ ( * ) begin
case (op)
`ALU_OP_ADD: {C_FLAG,OUT}=A+B;

View File

@ -27,6 +27,30 @@ 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)
//
// P - Parity flag : is set if result has even parity
//
// A - Auxiliary flag : carry out from the low nibble to the high nibble or
// an equiv borrow. Used by decimal arithmetic instructions
//
// Z - Zero flag : Set when result of Operation is zero
//
// S - Sign flag : set if the high order bit of the result is 1. aka the sign
// of the result
//
// T - Trap flag : Set the cpu into single step mode where it generates an
// interrupt after each instruction
//
// I - Interrupt flag : 0: interrupts are masked
//
// D - Direction flag : 1: string instructions decrement 0: they increment
//
// O - Overflow flag : set on arythmetic overflow
// Execution units
reg [1:0] in1_sel;
@ -84,7 +108,8 @@ wire [15:0] ALU_1B;
wire [15:0] ALU_1O;
reg [`ALU_OP_BITS-1:0]ALU_1OP;
reg ALU_1OE;
ALU ALU(ALU_1A,ALU_1B,ALU_1OE,ALU_1O,ALU_1OP);
wire [7:0] ALU_FLAGS;
ALU ALU(ALU_1A,ALU_1B,ALU_1OE,ALU_1O,ALU_1OP,ALU_FLAGS,Wbit);
/*** Processor stages ***/
@ -109,15 +134,19 @@ always @(negedge clock) begin
state=`PROC_DE_STATE_ENTRY;
end
`PROC_EX_STATE_EXIT:begin
case(out_sel)
2'b11:begin
reg_write_we=0;
state=`PROC_IF_STATE_ENTRY;
end
default:begin
`invalid_instruction
end
endcase
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
end
`PROC_DE_LOAD_16_EXTRA_FETCH_SET:begin
external_address_bus = ProgCount;
@ -136,6 +165,7 @@ always @(posedge clock) begin
end
`PROC_IF_STATE_ENTRY:begin
ERROR=0;
Suppress_ALU_Output=0;
external_address_bus <= ProgCount;
read <= 0;
write <= 1;
@ -176,7 +206,8 @@ always @(posedge clock) begin
if(CIR[8:8]==1)
state=`PROC_DE_LOAD_16_PARAM;
else begin
`invalid_instruction /*do 8bit loads*/
PARAM1[7:0]=CIR[7:0];
state=`PROC_EX_STATE_ENTRY;
end
end else begin
`invalid_instruction
@ -353,6 +384,36 @@ always @(posedge clock) begin
endcase
end
6'b001111 : begin
if ( CIR[9:9] == 0 ) begin
/* CMP - Compare Immediate with accumulator */
/* 0 0 1 1 1 1 0 W | DATA | DATA if W |*/
/* */
/* NOTE: 8086 doc doesn't show the third byte but the */
/* W flag and my assembler seem to disagree */
Wbit=CIR[8:8];
if(Wbit)
`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;
ALU_1OE=0;
ALU_1OP=`ALU_OP_SUB;
if(CIR[8:8]==1)
state=`PROC_DE_LOAD_16_PARAM;
else begin
PARAM1[7:0]=CIR[7:0];
state=`PROC_EX_STATE_ENTRY;
end
end else begin
`invalid_instruction
end
end
default:begin
`invalid_instruction
end
@ -436,6 +497,7 @@ always @(posedge clock) begin
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