dimavlo1 said:I try to design the 8085 microproceccor with VHDL. I have some ideas on this but I would like to know if i can find some help here. I am confused about how to design the instruction decoding and make it communicate with the other units such as register array and control unit.
module I8085(/*AUTOARG*/
// Outputs
RESETOUT, SOD, INTABAR, ADDR, S0, ALE, WRBAR, RDBAR, S1, IOMBAR, CLKOUT,
HLDA,
// Inouts
AD,
// Inputs
X1, SID, TRAP, RST75, RST65, RST55, INTR, READY, RESETINBAR, HOLD
);
input X1;
output RESETOUT, SOD;
input SID, TRAP, RST75, RST65, RST55, INTR;
output INTABAR;
output [7:0] ADDR;
output S0,ALE,WRBAR, RDBAR,S1,IOMBAR;
input READY, RESETINBAR;
output CLKOUT, HLDA;
input HOLD;
inout [7:0] AD;
reg [15:0] ADDRESS_OUT;
reg S0, S1,IOMBAR;
reg CLKOUT, HLDA;
reg ALE_pos, ALE_neg;
reg INTA_pos, INTA_neg;
reg oe;
reg [7:0] DO;
reg [3:0] TSTATES, TSTATES_nx;
reg [2:0] MCYCLE, MCYCLE_nx;
reg WR_MOD, HOLDFF, INTEFF;
reg RESETOUTFF ;
reg BIMC;
reg HLTAFF ;
reg Z, S, P, CY, AC ;
reg [7:0] ACC, // ACC is the accumulator
ACT, // ACT is the temp accumulator
TEMP,
IR, // instruction register
DBUF, // buffer the input data (ID)
//MAR, // outputs to address bus A(15 downto 8)
//MDR, // outputs to address/data bus AD(7 downto 0)
B, C, D, E, H, L, Z_reg, W_reg ;
reg [15:0] SP, PC;
parameter TRESET = 4'd0,
T1 = 4'd1,
T2 = 4'd2,
T3 = 4'd3,
T4 = 4'd4,
T5 = 4'd5,
T6 = 4'd6,
THOLD = 4'd9,
TWAIT = 4'd7,
THALT = 4'd8;
parameter M1 = 3'd1,
M2 = 3'd2,
M3 = 3'd3,
M4 = 3'd4,
M5 = 3'd5;
wire reset_delayed;
reg RD1, RD2, WR1;
reg FETCH_F_WZ;
reg IRBIT3, IRBIT0;
reg [2:0] DDD, SSS;
reg [1:0] DPAIR, IGROUP;
reg CC_TEST;
reg M75FF, M65FF, M55FF;
reg TRAPFF;
reg [2:0] PRIO_ENCODE, PRIO_ENCODE_nx;
reg RST75FF;
reg clear_rst75_ff;
reg clear_trap_ff;
reg CC6;
reg INA,INTA;
reg BIMCB;
reg [8:0] ALU_OUT;
reg [15:0] B16BCTR;
integer LAST_OP;
reg SOD_FF;
reg [7:0] temp_MOV;
reg [7:0] temp_D;
reg [7:0] temp_E;
reg END_INST_flag ;
reg common, common1, wrinm2, wrinm3, wrinm4, wrinm5;
reg DAD_inst;
reg [2:0] PIE;
reg clock_gate;
reg HOLD_sync, TRAP_sync, RST75_sync, RST65_sync, RST55_sync, INTR_sync, SID_sync;
reg HOLD_r, TRAP_r, RST75_r, RST65_r, RST55_r, INTR_r, SID_r;
reg RST75_delay, TRAP_delay;
assign ADDR = ADDRESS_OUT[15:8];
assign AD = (TSTATES == 1) ? ADDRESS_OUT[7:0] : (oe) ? DO : 8'bzzzzzzzz;
wire EI_ENABLE = (PRIO_ENCODE == 0) ? 1'b1 : 0;
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed) begin
MCYCLE <= 0;
RESETOUTFF <= 1'b0;
end else begin
RESETOUTFF <= 1'b1;
MCYCLE <= MCYCLE_nx;
end
always @(posedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin // clear the flip-flops
PC <= 0; // Program Counter
HLTAFF <= 1'b0;
WR_MOD <= 1'b0;
INTEFF <= 1'b0;
clear_rst75_ff <= 1'b0;
clear_trap_ff <= 1'b0;
M75FF <= 1'b1;
M65FF <= 1'b1;
M55FF <= 1'b1;
LAST_OP = 99;
FETCH_F_WZ <= 1'b0;
SOD_FF <= 1'b0;
END_INST_flag <= 1'b0;
IR <= 0;
DBUF <= 0;
ACC <= 0;
ACT <= 0;
CY <= 1'b0; // condition codes
P <= 1'b0;
AC <= 1'b0;
Z <= 1'b0;
S <= 1'b0;
ALE_pos <= 0;
end else begin // Begin processing on positive edge of clock
//CLKOUT <= 1'b0;
if (TSTATES_nx == 1)
ALE_pos <= 1'b1; else ALE_pos <= 1'b0;
// HW_INTR_PS
// interrupts are sampled during the second clock cycle before M1,T1
if (TSTATES_nx == 2)
END_INST_flag <= 1'b0;
if (TSTATES == THALT && PRIO_ENCODE != 7)
HLTAFF <= 1'b0;
if (TSTATES == T3)
WR_MOD <= 1'b0;
//-------------------------------------------------------------------------
if (MCYCLE_nx == 1 && (TSTATES_nx == 1 || TSTATES_nx == 2 || TSTATES_nx == 3)) begin
//--------------------------------------------------------//
// Common processing for all OP-CODES //
// MCYCLE = 1 //
// AND //
// TSTATES = 1, 2, or 3 //
// Instruction Fetch //
//--------------------------------------------------------//
case (TSTATES_nx)
// MCYCLE = 1, TSTATES = 1
1 : begin
if (FETCH_F_WZ) begin
ADDRESS_OUT <= {W_reg, Z_reg};
PC <= {W_reg, Z_reg};
end else
ADDRESS_OUT <= PC;
S1 <= 1'b1;
S0 <= 1'b1;
// Cf., interrupt acknowledge timing, p 2-13, MCS 80/85 user's manual
IOMBAR <= INTR_sync & (PRIO_ENCODE_nx == 4);
end
// MCYCLE = 1, TSTATES = 2
2 : begin
if (LAST_OP != 99) begin
//--------- Procedure OP_RUNIN_NEXT_INST; ----------
case (LAST_OP)
0 : ALU_OUT = ACT + TEMP; // ADD r
1 : ALU_OUT = ACT + TEMP + CY; // ADC r
2 : ALU_OUT = ACT - TEMP; // SUB r
3 : ALU_OUT = ACT - TEMP - CY; // SBB r
4 : ALU_OUT = ACT & TEMP;
5 : ALU_OUT = ACT ^ TEMP;
6 : ALU_OUT = ACT | TEMP;
7 : ALU_OUT = ACT - TEMP; // CMP
10,11,12,13 : CY <= ALU_OUT[8];
// 14 : ALU_OUT = TEMP; // DAA
// 15 : // CMA
// 16 : CY <= 1; // STC
// 17 : if (CY == 0) CY <= 1; else CY <= 0; // CMC
20 : ACC[7] <= SID_sync; // RIM
30 : if (ACC[6] == 1'b1) begin // SIM
SOD_FF <= ACC[7];
clear_rst75_ff <= 1'b0;
end
endcase // end of case LAST_OP
if ((LAST_OP <16) && (LAST_OP != 7)) ACC <= ALU_OUT;
// setup flags for condition codes Z,S,P,CY,AC
if (LAST_OP <10) begin
// SET_FLAGS;
if (ALU_OUT == 0) Z <= 1'b1; else Z <= 1'b0;
S <= ALU_OUT[7];
CY <= ALU_OUT[8];
P <= ^ALU_OUT[7:0];
end
case (LAST_OP)
0,1,2,3 : AC <= ALU_OUT[4] ^ TEMP[4] ^ ACT[4];
4 : begin
CY <= 1'b0;
AC <= 1'b1;
end
5,6 : begin
CY <= 1'b0;
AC <= 1'b0;
end
endcase // case (LAST_OP)
//------- end Procedure OP_RUNIN_NEXT_INST; --------------
end // if (LAST_OP != 99)
if ( FETCH_F_WZ )
FETCH_F_WZ <= 1'b0;
PC <= PC + 1; // increment Program Counter
//synthesis translate_off
$display ($time,,
"C%bZ%bM%bE%bI%b A=%h B=%h%h D=%h%h H=%h%h S=%h P=%h IR=%h",
CY, Z, S, P, AC,
ACC, B, C, D, E, H, L,
SP, PC, IR);
//synthesis translate_on
end // case: 2
// MCYCLE = 1, TSTATES = 3
3 : begin
LAST_OP = 99;
if (PRIO_ENCODE != 7/*HRSTTYPE > 0*/) begin
INTEFF <= 1'b0; // (DI) disable interrupts
IR <= 8'b00010000;
IGROUP <= 2'b00; // high order two bits select instruction group
DDD <= 3'b010; // bits 5 downto 3 select destination register
DPAIR <= 2'b01;
SSS <= 3'b000; // bits 2 downto 0 select source register
IRBIT0 <= 1'b0;
IRBIT3 <= 1'b0;
if (PRIO_ENCODE == 4) Z_reg <= {2'b00, AD[5:3], 3'b000};
if (PRIO_ENCODE == 0) begin
Z_reg <= 8'h24;
clear_trap_ff <= 1'b1;
end
if (PRIO_ENCODE == 1) begin
Z_reg <= 8'h3c;
clear_rst75_ff <= 1'b1;
end
if (PRIO_ENCODE == 2) Z_reg <= 8'h34;
if (PRIO_ENCODE == 3) Z_reg <= 8'h2c;
end else begin
DBUF <= AD; // DBUS_IN(DBUF);
IR <= AD;
TEMP <= AD;
// Decode the instruction register
IGROUP <= AD[7 : 6]; // high order two bits select instruction group
DDD <= AD[5 : 3]; // bits 5 downto 3 select destination register
DPAIR <= AD[5 : 4];
SSS <= AD[2 : 0]; // bits 2 downto 0 select source register
IRBIT0 <= AD[0];
IRBIT3 <= AD[3];
end
end // case: 3
endcase // case (TSTATES)
//=========================================================================
end else begin
// either (MCYCLE > 1) OR (MCYCLE = 1 AND TSTATES > 3)
//=========================================================================
//
// Instruction decode begins here. The high order two bits of the op-code, referred
// to as IGROUP, select the major function. Then, the third, fourth and fifth bits
// of the op-code, referred to as DDD, select the destination, and the rightmost
// three bits of the op-code, referred to as SSS, select the source. The DDD and SSS
// fields either further refine the functionality or select source and destination
// registers for the op-code.
//
case (IGROUP)
0 : begin // IGROUP = (0,0)
case (SSS)
0 : begin
case (DDD) // OP-CODE = 00 DDD 000 (SSS = 000)
0 : begin
END_INST_flag <= 1'b1; // NOP
//last_MC <= 3'b001;
end
2 : begin // HWRST 0001 0000
case (MCYCLE)
1 : begin
clear_rst75_ff <= 1'b0;
clear_trap_ff <= 1'b0;
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
4 : begin
W_reg <= 0;
SP <= SP - 1;
PC <= PC - 1;
//last_MC <= 3'b001;
end
//5 : SP <= SP - 1;
endcase // case (TSTATES_nx)
end
2 : begin
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
SP <= SP - 1;
DBUF <= PC[15:8];
DO <= PC[15:8];
WR_MOD <= 1'b1;
end
endcase // case (TSTATES_nx)
end // case: 2
3 : begin
case (TSTATES_nx)
2 : begin
DBUF <= PC[7:0];
DO <= PC[7:0];
WR_MOD <= 1'b1;
end
3 : begin
FETCH_F_WZ <= 1'b1;
END_INST_flag <= 1'b1;
end
endcase // case TSTATES
end // case: 3
endcase // case (MCYCLE)
end // case: 2
4 : begin // RIM
ACC[0] <= M55FF;
ACC[1] <= M65FF;
ACC[2] <= M75FF;
ACC[3] <= INTEFF;
ACC[4] <= RST55_sync;
ACC[5] <= RST65_sync;
ACC[6] <= RST75FF;
LAST_OP = 20;
END_INST_flag <= 1'b1;
end // case: 4
6 : begin // SIM
if (ACC[3]) begin
M55FF <= ACC[0];
M65FF <= ACC[1];
M75FF <= ACC[2];
end
if (ACC[4]) begin
clear_rst75_ff <= 1'b1;
LAST_OP = 30;
end
END_INST_flag <= 1'b1;
end // case: 6
1,3,5,7,8 : END_INST_flag <= 1'b1;
endcase // case (DDD)
end // case: 0
1 : begin // OP-CODE = 00 DDD 001 (SSS = 001)
case (IRBIT3) // instruction register, bit 3
1'b0 : begin // LXI (Load immediate register pair)
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 : begin
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2;
PC <= PC + 1'b1;
DBUF <= AD;
end
3 : begin
case (DPAIR)
0 : C <= AD/*DBUF*/;
1 : E <= AD/*DBUF*/;
2 : L <= AD/*DBUF*/;
3 : SP[7:0] <= AD/*DBUF*/;
endcase
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
end // case: 2
3 : begin
case (TSTATES_nx)
2 : begin // PC_READ_T2;
PC <= PC + 1'b1;
DBUF <= AD;
end
3 : begin
case (DPAIR)
0 : B <= AD/*DBUF*/;
1 : D <= AD/*DBUF*/;
2 : H <= AD/*DBUF*/;
3 : SP[15:8] <= AD/*DBUF*/;
endcase
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
//ADDRESS_OUT <= PC ;
end
endcase // case (TSTATES_nx)
end // case: 3
endcase // case (MCYCLE)
end // case: 1'b0
1'b1 : begin // DAD (Double add)
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : case (DPAIR)
0 : ACT <= C;
1 : ACT <= E;
2 : ACT <= L;
3 : ACT <= SP[7:0];
endcase // DPAIR
endcase
2 : begin
case (TSTATES_nx)
1 : begin
case (DPAIR)
0 : ACT <= B;
1 : ACT <= D;
2 : ACT <= H;
3 : ACT <= SP[15:8];
endcase // DPAIR
end
2 : ALU_OUT = ACT + L;
3 : begin
L <= ALU_OUT[7:0];
CY <= ALU_OUT[8];
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
end // case: 2
3 : begin
case (TSTATES_nx)
2 : ALU_OUT = ACT + H + CY;
3 : begin
H <= ALU_OUT[7:0];
CY <= ALU_OUT[8];
//MCYCLE <= 1;
END_INST_flag <= 1'b1;
end
endcase // TSTATES
end // case: 3
endcase // case (MCYCLE)
end // case: 1'b1
endcase // case (IRBIT3)
end // case: 1
2 : begin // op code = 00 DDD 010 (SSS = 010)
case (DDD)
0,2 : // STAX
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
if (DPAIR == 0) begin
ADDRESS_OUT[15:8] <= B ;
ADDRESS_OUT[7:0] <= C ;
end else begin
ADDRESS_OUT[15:8] <= D ;
ADDRESS_OUT[7:0] <= E ;
end
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end // case: 1
endcase
2 :
case (TSTATES_nx)
2 : // HL_READ_T2
DO <= ACC;
3 : begin
// MCYCLE <= 1;
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
1,3 : // LDAX
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
if (DPAIR == 0) begin
ADDRESS_OUT[15:8] <= B ;
ADDRESS_OUT[7:0] <= C ;
end else begin
ADDRESS_OUT[15:8] <= D ;
ADDRESS_OUT[7:0] <= E ;
end
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end // case: 1
endcase // case (TSTATES_nx)
2 :
case (TSTATES_nx)
2 : // HL_READ_T2
begin end
3 : begin
//MCYCLE <= 1;
ACC <= AD;
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
4,5 : // SHLD/LHLD
case (MCYCLE)
// 1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase // case (TSTATES_nx)
2 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2
PC <= PC + 1'b1;
end
3 : //MCYCLE <= 3;
Z_reg <= AD;
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
1 : begin // MEM_WZ_WRITE_T1
ADDRESS_OUT[15:8] <= W_reg ;
ADDRESS_OUT[7:0] <= Z_reg ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin // PC_READ_T2
PC <= PC + 1'b1;
end
3 : //MCYCLE <= 4;
W_reg <= AD;
endcase // case (TSTATES_nx)
4 :
case (TSTATES_nx)
1 : begin // MEM_WZ_WRITE_T1
ADDRESS_OUT[15:8] <= W_reg ;
ADDRESS_OUT[7:0] <= Z_reg ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin
WR_MOD <= 1'b1;
if (IRBIT3 == 1'b0)
DO <= L ;
B16BCTR[15:8] = W_reg;
B16BCTR[7:0] = Z_reg;
B16BCTR = B16BCTR + 1'b1;
end
3 : begin
if (IRBIT3 == 1'b1)
L <= AD;
W_reg <= B16BCTR[15:8];
Z_reg <= B16BCTR[7:0];
//MCYCLE <= 5;
end
endcase // case (TSTATES_nx)
5 :
case (TSTATES_nx)
2 : begin
WR_MOD <= 1'b1;
if (IRBIT3 == 1'b0)
DO <= H ;
end
3 : begin
if (IRBIT3 == 1'b1)
H <= AD;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
6,7 : // 6 = STA (store accumulator)
// 7 = LDA (load accumulator)
case (MCYCLE)
//1 : MCYCLE <= 2;
1 :case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2
PC <= PC + 1'b1;
end
3 : // MCYCLE <= 3;
Z_reg <= AD;
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
1 : begin // MEM_WZ_WRITE_T1
ADDRESS_OUT[15:8] <= W_reg ;
ADDRESS_OUT[7:0] <= Z_reg ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin // PC_READ_T2
PC <= PC + 1'b1;
end
3 : // MCYCLE <= 4;
W_reg <= AD;
endcase // case (TSTATES_nx)
4 :
case (TSTATES_nx)
2 : begin
if (IRBIT3 == 1'b0)
DO <= ACC ; // STA
WR_MOD <= 1'b1;
end
3 : begin
if (IRBIT3 == 1'b1)
ACC <= AD; // LDA
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
endcase // case (DDD)
end // case: 2
3 : // op code = 00 DDD 011 (SSS = 011)
case (TSTATES_nx)
4 : begin
case (DPAIR)
0 : begin
B16BCTR[15:8] = B;
B16BCTR[7:0] = C;
end
1 : begin
B16BCTR[15:8] = D;
B16BCTR[7:0] = E;
end
2 : begin
B16BCTR[15:8] = H;
B16BCTR[7:0] = L;
end
3 : B16BCTR = SP;
endcase // end of case DPAIR
// when IRBIT3 = 0, INX, when 1, DCX
if (IRBIT3 == 1'b0)
B16BCTR = B16BCTR + 1'b1;
else
B16BCTR = B16BCTR - 1'b1;
end // case: 4
5 :
case (DPAIR)
0 : begin
B <= B16BCTR[15:8];
C <= B16BCTR[7:0];
end
1 : begin
D <= B16BCTR[15:8];
E <= B16BCTR[7:0];
end
2 : begin
H <= B16BCTR[15:8];
L <= B16BCTR[7:0];
end
3 : SP <= B16BCTR;
endcase // case (DPAIR)
6 : END_INST_flag <= 1'b1;
endcase // case (TSTATES_nx)
4,5 : // op code = 00 DDD 10X (SSS = 10X)
if (DDD == 6) // memory access
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase // case (TSTATES_nx)
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin
end
3 : begin
if (IRBIT0 == 1'b0)
ALU_OUT = AD + 1;
else
ALU_OUT = AD - 1;
TEMP <= ALU_OUT[7:0];
if (ALU_OUT == 0)
Z <= 1'b1;
else
Z <= 1'b0;
S <= ALU_OUT[7];
P <= ^ALU_OUT[7:0];
AC <= ALU_OUT[4] ^ TEMP[4] ^ ACT[4];
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
2 : begin
DO <= TEMP ;
WR_MOD <= 1'b1;
end
3 : begin
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
else begin
case (MCYCLE)
1 : case(TSTATES_nx)
4 : begin
case (DDD)
0 : ALU_OUT[7:0] = B;
1 : ALU_OUT[7:0] = C;
2 : ALU_OUT[7:0] = D;
3 : ALU_OUT[7:0] = E;
4 : ALU_OUT[7:0] = H;
5 : ALU_OUT[7:0] = L;
7 : ALU_OUT[7:0] = ACC;
endcase
if (IRBIT0 == 1'b0)
ALU_OUT = ALU_OUT[7:0] + 1;
else
ALU_OUT = ALU_OUT[7:0] - 1;
case (DDD)
0 : B <= ALU_OUT[7:0];
1 : C <= ALU_OUT[7:0];
2 : D <= ALU_OUT[7:0];
3 : E <= ALU_OUT[7:0];
4 : H <= ALU_OUT[7:0];
5 : L <= ALU_OUT[7:0];
7 : ACC <= ALU_OUT[7:0];
endcase
if (ALU_OUT == 0)
Z <= 1'b1;
else
Z <= 1'b0;
S <= ALU_OUT[7];
P <= ^ALU_OUT[7:0];
AC <= ALU_OUT[4] ^ TEMP[4] ^ ACT[4];
END_INST_flag <= 1'b1;
end // case: 4
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // else: !if(DDD == 6)
6 : // MVI (SSS = 6)
if (DDD == 6) // move 2nd byte of inst. to Memory
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 : case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : // MCYCLE <= 3;
TEMP <= AD;
endcase // case (TSTATES_nx)
3 : case (TSTATES_nx)
2 : begin
DO <= TEMP ;
WR_MOD <= 1'b1;
end
3 : begin
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
else begin // move 2nd byte of inst. to designated register
case (MCYCLE)
//1 : MCYCLE <= 2;
1 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
2 : begin
PC <= PC + 1'b1;
DBUF <= AD;
end
3 : begin
//MCYCLE <= 1;
case (DDD)
0 : B <= AD/*DBUF*/;
1 : C <= AD/*DBUF*/;
2 : D <= AD/*DBUF*/;
3 : E <= AD/*DBUF*/;
4 : H <= AD/*DBUF*/;
5 : L <= AD/*DBUF*/;
7 : ACC <= AD/*DBUF*/;
endcase // end of case DDD
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // else: !if(DDD = 6)
7 : begin // (SSS = 7) ROTATE_ETC
LAST_OP = DDD + 10;
case (DDD)
0 : // RLC
ALU_OUT[7:0] = {ACC[6:0], ACC[7]};
1 : // RRC
ALU_OUT[7:0] = {ACC[0], ACC[7:1]};
2 : // RAL
ALU_OUT[8:0] = {ACC[7:0],CY};
3 : // RAR
ALU_OUT[7:0] = {CY, ACC[7:1]};
4 : begin // DAA
if (ACC[3:0] > 9) begin
ALU_OUT[7:0] = ACC + 6;
ALU_OUT[8] = 1'b1;
end else begin
ALU_OUT[7:0] = ACC;
ALU_OUT[8] = 1'b0;
end
if (ACC[7:4] > 9) begin
ALU_OUT[7:0] = ALU_OUT[7:0] + 96; // 96 = 6 x 00010000
ALU_OUT[8] = 1'b1;
end else
ALU_OUT[8] = 1'b0;
end
5 : ALU_OUT = ~ACC; // CMA
6 : CY <= 1'b1; // STC (Set Carry to 1)
7 : CY <= ~CY; // CMC (Complement Carry)
endcase
END_INST_flag <= 1'b1;
end // case: 7
endcase // case (SSS)
end // case: 0
1 : begin // IGROUP = (0,1) MOV, HLT op code = 01 DDD SSS (IR = 01)
if (SSS == 6) begin
if (DDD == 6) begin // HLT instruction
case (TSTATES_nx)
4 : begin
//MCYCLE <= 2;
HLTAFF <= 1'b1;
end
2 :
END_INST_flag <= 1'b1;
endcase // end of case TSTATES
end else begin // MOVM instruction (Move from Memory to Reg.)
case (TSTATES_nx)
1 : begin // MEM_HL_READ_T1
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : // HL_READ_T2
DBUF <= AD;
3 : begin
//MCYCLE <= 1;
END_INST_flag <= 1'b1;
case (DDD)
0 : B <= AD /*DBUF*/;
1 : C <= AD /*DBUF*/;
2 : D <= AD /*DBUF*/;
3 : E <= AD /*DBUF*/;
4 : H <= AD /*DBUF*/;
5 : L <= AD /*DBUF*/;
7 : ACC <= AD/*DBUF*/;
endcase // end of case DDD
end
//4 : MCYCLE <= 2;
endcase // case (TSTATES_nx)
end // else: !if(DDD = 6)
end else if (DDD == 6) begin // MOVM instruction (move from Reg. to Memory)
case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ; // MEM_HL_WRITE_T1
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin // WRITE_T2
WR_MOD <= 1'b1;
DO <= TEMP;
end
3 : begin
//MCYCLE <= 1;
END_INST_flag <= 1'b1;
end
4 : begin // SOURCE_REG
//MCYCLE <= 2;
case (SSS)
0 : TEMP <= B;
1 : TEMP <= C;
2 : TEMP <= D;
3 : TEMP <= E;
4 : TEMP <= H;
5 : TEMP <= L;
7 : TEMP <= ACC;
endcase // case SSS
end
endcase // case (TSTATES_nx)
end else begin// if ((DDD !=6) && (SSS !=6)) then (MOV r1,r2)
// this will be state 4, there is only one MCYCLE
case (SSS)
0 : temp_MOV = B;
1 : temp_MOV = C;
2 : temp_MOV = D;
3 : temp_MOV = E;
4 : temp_MOV = H;
5 : temp_MOV = L;
7 : temp_MOV = ACC;
endcase // case SSS
case (DDD)
0 : B <= temp_MOV;
1 : C <= temp_MOV;
2 : D <= temp_MOV;
3 : E <= temp_MOV;
4 : H <= temp_MOV;
5 : L <= temp_MOV;
7 : ACC <= temp_MOV;
endcase // end of case DDD
END_INST_flag <= 1'b1;
end // else: !if(DDD = 6)
end // case: 1
2 : begin // IGROUP = (1,0) op code = 10 DDD SSS (IR = 10) (ALU operations)
LAST_OP = DDD;
//
// The Group 2 instructions complete execution
// during state T2 of the next instruction.
// The DDD field is used to decode the operation.
if (SSS != 6) begin
case (SSS)
0 : TEMP <= B;
1 : TEMP <= C;
2 : TEMP <= D;
3 : TEMP <= E;
4 : TEMP <= H;
5 : TEMP <= L;
7 : TEMP <= ACC;
endcase // source_reg
ACT <= ACC;
END_INST_flag <= 1'b1;
end else begin // SSS = 6 => memory fetch
case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : DBUF <= AD;
3 : begin
TEMP <= AD/*DBUF*/;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
4 : begin
ACT <= ACC; // if TSTATES=4, then MCYCLE must be 1
//MCYCLE <= 2;
end
endcase // case (TSTATES_nx)
end // else: !if(SSS != 6)
end // case: 2
3 : begin // IGROUP = (1,1) op code = 11 DDD SSS (IR = 11)
case (SSS)
0 : begin // RC (Return Conditional)
case (MCYCLE)
1 : begin
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
4 : case (DDD)
0 : CC_TEST <= ~Z;
1 : CC_TEST <= Z;
2 : CC_TEST <= ~CY;
3 : CC_TEST <= CY;
4 : CC_TEST <= ~P;
5 : CC_TEST <= P;
6 : CC_TEST <= ~S;
7 : CC_TEST <= S;
endcase // DPAIR
6 :
if (CC_TEST == 1'b0)
END_INST_flag <= 1'b1;
//else
//MCYCLE <= 2;
endcase // case (TSTATES_nx)
end // case: 1
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : begin
PC[7:0] <= AD;
Z_reg <= AD;
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : begin
PC[15:8] <= AD;
W_reg <= AD;
END_INST_flag <= 1'b1;
FETCH_F_WZ <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 0
1 : begin // SSS = 1
case (IRBIT3)
1'b0 : begin // POP rp
// rp - register pair
// rp = 00: BC , rp = 01: DE , rp = 10: HL , rp = 11: PSW
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : begin
DBUF <= AD; // buffer the input data
case (MCYCLE)
2 : begin
//MCYCLE <= 3;
case (DPAIR)
0 : C <= AD/*DBUF*/;
1 : E <= AD/*DBUF*/;
2 : L <= AD/*DBUF*/;
3 : begin
CY <= AD[0] /*DBUF[0]*/;
P <= AD[2] /*DBUF[2]*/;
AC <= AD[4] /*DBUF[4]*/;
Z <= AD[6] /*DBUF[6]*/;
S <= AD[7] /*DBUF[7]*/;
end
endcase // case (DPAIR)
end // case: 2
3 : begin
//MCYCLE <= 1;
case (DPAIR)
0 : B <= AD/*DBUF*/;
1 : D <= AD/*DBUF*/;
2 : H <= AD/*DBUF*/;
3 : ACC <= AD/*DBUF*/;
endcase
END_INST_flag <= 1'b1;
end
endcase // case (MCYCLE)
end // case: 3
//4 : MCYCLE <= 2; // if TSTATES = 4, MCYCLE must be 1
endcase // case (TSTATES_nx)
end // case: 1'b0
1'b1 : begin
case (DPAIR)
0 : begin // RET
case (MCYCLE)
//1 : MCYCLE <= 2;
1 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : //MCYCLE <= 3;
PC[7:0] <= AD;
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : begin
PC[15:8] <= AD;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 0
// 1 : // NOOP
2 : begin // PCHL
case (TSTATES_nx)
4 : PC[15:8] <= H;
5 : begin
PC[7:0] <= L;
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
end
3 : begin // SPHL
case (TSTATES_nx)
4 : SP[15:8] <= H;
5 : begin
SP[7:0] <= L;
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
end
endcase // case (DPAIR)
end // case: 1'b1
endcase // case (IRBIT3)
end // case: 1
2 : begin // Conditional Jump
case (MCYCLE)
1 : begin // TSTATES = 4
case (DDD)
0 : CC_TEST <= ~Z;
1 : CC_TEST <= Z;
2 : CC_TEST <= ~CY;
3 : CC_TEST <= CY;
4 : CC_TEST <= ~P;
5 : CC_TEST <= P;
6 : CC_TEST <= ~S;
7 : CC_TEST <= S;
endcase
//MCYCLE <= 2;
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
endcase
end
2 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : begin//MCYCLE <= 3;
if (CC_TEST == 1'b0) begin
PC <= PC + 1'b1;
END_INST_flag <= 1'b1;
end
Z_reg <= AD; // Byte2 -> Z
end
endcase // TSTATES
3 :
case (TSTATES_nx)
2 : begin
PC <= PC + 1'b1;
end
3 : begin
W_reg <= AD; // Byte3 -> W
END_INST_flag <= 1'b1;
FETCH_F_WZ <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 2
3 : begin
case (DDD)
0 : begin // JMP
case (MCYCLE)
//1 : MCYCLE <= 2;
1 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
PC <= PC + 1'b1;
end
//3 : MCYCLE <= 3;
3 : Z_reg <= AD; // Byte2 -> Z
endcase // TSTATES
3 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : begin
W_reg <= AD; // Byte3 -> W
END_INST_flag <= 1'b1;
FETCH_F_WZ <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 0
//1 : NOOP;
2,3 : begin // IO_OUT/IO_IN
case (MCYCLE)
//1 : MCYCLE <= 2; // TSTATES = 4
1 : case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= {W_reg, Z_reg}/*PC*/ ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b1 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : begin// MCYCLE <= 3;
Z_reg <= AD; // Byte2 -> Z
W_reg <= AD; // Byte2 -> W
end
endcase // TSTATES
3 :
case (TSTATES_nx)
2 : begin
if (IRBIT3 == 1'b0) // OUT instruction
DO <= ACC ;
end
3 : begin
if (IRBIT3 == 1'b1) // IN instruction
ACC <= AD ;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 2,3
4 : begin // XTHL
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2
SP <= SP + 1'b1;
end
3 : //MCYCLE <= 3;
Z_reg <= AD;
endcase // TSTATES
3 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin end // PC_READ_T2
3 : //MCYCLE <= 4;
W_reg <= AD;
endcase // TSTATES
4 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin
WR_MOD <= 1'b1;
DO <= H ;
SP <= SP - 1;
end
//3 : MCYCLE <= 5;
endcase // TSTATES
5 :
case (TSTATES_nx)
2 : begin
WR_MOD <= 1'b1;
DO <= L ;
end
3 : begin
L <= Z_reg;
H <= W_reg;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 4
5 : begin // XCHG
temp_D = D;
temp_E = E;
D <= H;
E <= L;
H <= temp_D;
L <= temp_E;
END_INST_flag <= 1'b1;
end
6 : begin
INTEFF <= 1'b0; // (DI) disable interrupts
END_INST_flag <= 1'b1;
end
7 : begin
INTEFF <= 1'b1; // (EI) enable interrupts
END_INST_flag <= 1'b1;
end
endcase // case (DDD)
end // case: 3
4 : begin // CONDITIONAL CALL
case (MCYCLE)
1 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
4 : begin
case (DDD)
0 : CC_TEST <= ~Z;
1 : CC_TEST <= Z;
2 : CC_TEST <= ~CY;
3 : CC_TEST <= CY;
4 : CC_TEST <= ~P;
5 : CC_TEST <= P;
6 : CC_TEST <= ~S;
7 : CC_TEST <= S;
endcase // case (DDD)
end
5 : begin
//MCYCLE <= 2;
if (CC_TEST == 1'b1)
SP <= SP - 1'b1;
end
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
if (CC_TEST == 1'b1) begin
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
end
2 : begin // PC_READ_T2;
if (CC_TEST == 1'b1)
PC <= PC + 1;
else
PC <= PC + 2;
end
3 : begin
DBUF <= AD;
Z_reg <= AD/*DBUF*/;
if (CC_TEST == 1'b0)
END_INST_flag <= 1'b1;
//MCYCLE <= 3;
end
endcase
3 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // PC_READ_T2;
PC <= PC + 1;
end
3 : begin
DBUF <= AD;
W_reg <= AD/*DBUF*/;
//MCYCLE <= 4;
end
endcase
4 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
SP <= SP - 1;
DBUF <= PC[15:8];
DO <= PC[15:8];
WR_MOD <= 1'b1;
end
3 : begin // WRITE_T3;
//DO <= DBUF ;
//MCYCLE <= 5;
end
endcase
5 :
case (TSTATES_nx)
2 : begin
DBUF <= PC[7:0];
DO <= PC[7:0];
WR_MOD <= 1'b1;
end
3 : begin // WRITE_T3;
//DO <= DBUF ;
//MCYCLE <= 1;
END_INST_flag <= 1'b1;
if (CC_TEST == 1'b1) FETCH_F_WZ <= 1'b1; else FETCH_F_WZ <= 1'b0;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 4
5 : begin // IGROUP = 3, SSS = 5
case (IRBIT3)
1'b0 : begin // PUSH rp (register pair)
case (MCYCLE)
1 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
5 : SP <= SP - 1'b1; // Compared to 8080
6 : begin // 8085 uses an additional state, T6
//MCYCLE <= 2;
//ADDRESS_OUT <= SP ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // RP_PSW_SOURCE
case (DPAIR)
0 : DO <= B[7:0];
1 : DO <= D ;
2 : DO <= H ;
3 : DO <= ACC ;
endcase
SP <= SP - 1'b1;
WR_MOD <= 1'b1;
end
3 : begin
//MCYCLE <= 3;
//ADDRESS_OUT <= SP ;
end
endcase
3 :
case (TSTATES_nx)
2 : begin // RP_PSW_SOURCE(2)
case (DPAIR)
0 : DO <= C ;
1 : DO <= E ;
2 : DO <= L ;
3 : DO <= {S, Z, 1'b0, AC, 1'b0, P, 1'b0, CY};
endcase
WR_MOD <= 1'b1;
end
3 : begin
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
//ADDRESS_OUT <= PC ;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 1'b0
1'b1 : begin
case (DPAIR)
0 : begin // CALL
case (MCYCLE)
1 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
4 : SP <= SP - 1;
//5 : MCYCLE <= 2;
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2;
PC <= PC + 1;
end
3 : begin
DBUF <= AD;
Z_reg <= AD/*DBUF*/;
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // PC_READ_T2;
PC <= PC + 1'b1;
end
3 : begin
DBUF <= AD;
W_reg <= AD/*DBUF*/;
//MCYCLE <= 4;
end
endcase // case (TSTATES_nx)
4 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
SP <= SP - 1;
DBUF <= PC[15:8];
DO <= PC[15:8];
WR_MOD <= 1'b1;
end
3 : begin // WRITE_T3;
//DO <= DBUF ;
//MCYCLE <= 5;
end
endcase // case (TSTATES_nx)
5 :
case (TSTATES_nx)
2 : begin
DBUF <= PC[7:0];
DO <= PC[7:0];
WR_MOD <= 1'b1;
end
3 : begin // WRITE_T3;
//MCYCLE <= 1;
FETCH_F_WZ <= 1'b1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 0
// 1,2,3 : //NOOP;
endcase // case (DPAIR)
end // case: 1'b1
endcase // case (IRBIT3)
end // case: 5
6 : begin // SSS = 6 => memory fetch
LAST_OP = DDD;
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : begin
DBUF <= AD;
TEMP <= AD/*DBUF*/;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
4 : begin
ACT <= ACC; // if TSTATES=4, then MCYCLE must be 1
//MCYCLE <= 2;
end
endcase // case (TSTATES_nx)
end // case: 6
7 : begin // RST
case (MCYCLE)
1 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
4 : begin
W_reg <= 0;
SP <= SP - 1;
end
//6 : MCYCLE <= 2;
endcase // TSTATES
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // SP_READ_T2
SP <= SP - 1;
DO <= PC[15:8] ;
end
//3 : MCYCLE <= 3;
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
2 : begin // SP_READ_T2
DO <= PC[7:0];
Z_reg[7:6] <= 0;
Z_reg[5:3] <= TEMP[5:3];
Z_reg[2:0] <= 0;
end
3 : begin
END_INST_flag <= 1'b1;
FETCH_F_WZ <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 7
endcase // case (SSS)
end // case: 3
endcase // case (IGROUP)
end // else: !if(MCYCLE==1 && (TSTATES==0 || TSTATES==1 || TSTATES==2 || TSTATES==3))
end // else: !if(!RESETINBAR)
end // always @ (posedge X1 or negedge RESETINBAR)
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// Compute RDBAR/WRBAR signals
//-------------------------------------------------------------------------
always @(/*AS*/DDD or IGROUP or INA or SSS or common or common1) begin
if ((IGROUP == 3 && SSS == 7) // RST n FWW
|| (IGROUP == 0 && DDD == 2 && SSS == 0) //HWRST
|| (INA == 1'b1)
|| (IGROUP == 3 && SSS == 5
&& (DDD == 0 || DDD == 2 || DDD == 4 || DDD == 6))) // PUSH rp FWW
common = 1'b0;
else common = 1'b1;
if ((IGROUP == 3 && DDD == 1 && SSS == 5) // CALL FRRWW
|| (IGROUP == 3 && SSS == 4) // C??? FRRWW
|| (IGROUP == 3 && DDD == 4 && SSS == 3) // XTHL FRRWW
|| (IGROUP == 0 && DDD == 4 && SSS == 2)) // SHLD FRRWW
common1 = 1'b0;
else common1 = 1'b1;
if ((common == 1'b0)
|| (IGROUP == 1 && DDD == 6 && SSS != 6) // MOV M,REG FW
|| (IGROUP == 0 && DDD == 0 && SSS == 2) // STAX B FW
|| (IGROUP == 0 && DDD == 2 && SSS == 2)) // STAX D FW
wrinm2 = 1'b1;
else wrinm2 = 1'b0;
if (( common == 1'b0)
|| (IGROUP == 0 && DDD == 6 && (SSS == 4 || SSS == 5 || SSS == 6)) // MVI M/DCR M/INR M
|| (IGROUP == 3 && DDD == 2 && SSS == 3)) // OUT FRW
wrinm3 = 1'b1;
else wrinm3 = 1'b0;
if (( common1 == 1'b0)
||(IGROUP == 0 && DDD == 6 && SSS == 2)) // STA FRRW
wrinm4 = 1'b1;
else wrinm4 = 1'b0;
if (common1 == 1'b0)
wrinm5 = 1'b1;
else wrinm5 = 1'b0;
end // always @ (...
always @(negedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin
RD1 <= 1'b0;
RD2 <= 1'b0;
WR1 <= 1'b0;
CLKOUT <= 1'b0;
end else begin
if (TSTATES_nx == 2) begin
case (MCYCLE)
1 : begin
RD1 <= 1'b1;
RD2 <= 1'b0;
WR1 <= 1'b0;
end
2 : begin
RD1 <= 1'b0;
if (wrinm2 == 1'b0) RD2 <= 1'b1; else RD2 <= 1'b0;
if (wrinm2 == 1'b1) WR1 <= 1'b1; else WR1 <= 1'b0;
end
3 : begin
RD1 <= 1'b0;
if (wrinm3 == 1'b0) RD2 <= 1'b1; else RD2 <= 1'b0;
if (wrinm3 == 1'b1) WR1 <= 1'b1; else WR1 <= 1'b0;
end
4 : begin
RD1 <= 1'b0;
if ((IGROUP == 0 && DDD == 7 && SSS == 2) // LDA FRRR
|| (IGROUP == 0 && DDD == 5 && SSS == 2)) // LHLD FRRRR
RD2 <= 1'b1;
else
RD2 <= 1'b0;
if (wrinm4 == 1'b1)
WR1 <= 1'b1;
else
WR1 <= 1'b0;
end
5 : begin
RD1 <= 1'b0;
if (IGROUP == 0 && DDD == 5 && SSS == 2) // LHLD FRRRR
RD2 <= 1'b1; else RD2 <= 1'b0;
if (wrinm5 == 1'b1)
WR1 <= 1'b1; else WR1 <= 1'b0;
end
endcase // case (MCYCLE)
end else if (TSTATES_nx == 3) begin
RD1 <= 1'b0;
RD2 <= 1'b0;
WR1 <= 1'b0;
end
CLKOUT <= ~CLKOUT ;
end // else: !if(!RESETINBAR)
end // always @ (negedge X1)
reg RDBAR_pos, WRBAR_pos, RDBAR_neg, WRBAR_neg ;
always @ (posedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin
RDBAR_pos <= 1'b1;
WRBAR_pos <= 1'b1;
end else begin
RDBAR_pos <= BIMCB | INTA | ~(RD1 | RD2);
WRBAR_pos <= ~WR1 | ~DAD_inst;
end
end
always @ (negedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin
RDBAR_neg <= 1'b1;
WRBAR_neg <= 1'b1;
end else begin
RDBAR_neg <= RDBAR_pos;
WRBAR_neg <= WRBAR_pos;
end
end
assign RDBAR = RDBAR_pos & RDBAR_neg;
assign WRBAR = WRBAR_pos & WRBAR_neg;
always @(/*AS*/IGROUP or IRBIT3 or SSS)
if (IGROUP == 0 && SSS == 1 && IRBIT3 == 1'b1) // DAD
DAD_inst = 1'b0;
else
DAD_inst = 1'b1;
always @(/*AS*/DAD_inst or INA or MCYCLE) begin
if (MCYCLE == 1)
if (INA == 1'b1)
BIMCB = 1'b1;
else
BIMCB = 1'b0;
else // MCYCLE /= 1
if (DAD_inst == 1'b0)
BIMCB = 1'b1;
else
BIMCB = 1'b0;
end // always @ (...
always@(posedge X1 or negedge reset_delayed) begin
if (!reset_delayed)
oe <= 0;
else
case (MCYCLE)
1 : oe <= 0;
2 : if (TSTATES_nx == 2) oe <= wrinm2;
3 : if (TSTATES_nx == 2) oe <= wrinm3;
4 : if (TSTATES_nx == 2) oe <= wrinm4;
5 : if (TSTATES_nx == 2) oe <= wrinm5;
endcase // case (MCYCLE)
end // always@ (posedge X1 negedge RESETINBAR)
assign SOD = SOD_FF ;
assign RESETOUT = ~RESETOUTFF;
assign INTABAR = ~(INTA_pos | INTA_neg);
//-----------------------------------------------------------------------
// This next process computes the T-states (minor state) transitions.
//
// The order of the T-states (and their mapping into
// the gate-level state machine) are as follows
// TX, T1, T2, T3, T4, T5, T6, TW, THALT, TH
//
// M1, M2, M3, M4, M5
//-----------------------------------------------------------------------
reg [1:0] reset_sync;
always @(posedge X1 or negedge RESETINBAR)
if (!RESETINBAR)
reset_sync <= 2'b00;
else
reset_sync <= {reset_sync[0], 1'b1};
assign reset_delayed = reset_sync[1];
reg HOLDFF_nx, HLDA_nx;
always @(posedge X1)
if (!reset_delayed) begin
TSTATES <= TRESET;
HOLDFF <= 1'b0;
HLDA <= 1'b0;
end else begin
TSTATES <= TSTATES_nx;
HOLDFF <= HOLDFF_nx;
HLDA <= HLDA_nx;
end
always @(/*AS*/HLDA or HLTAFF or HOLDFF or HOLD_sync or IGROUP or IR
or IRBIT3 or MCYCLE or PRIO_ENCODE or READY or SSS or TSTATES
or WR_MOD or BIMC) begin
TSTATES_nx = TSTATES;
HOLDFF_nx = HOLDFF;
HLDA_nx = HLDA;
CC6 = 1'b0;
case (TSTATES)
TRESET : begin
TSTATES_nx = T1;
end
THOLD : begin
if (HOLD_sync != 1'b1) begin
if (HLTAFF == 1'b0)
TSTATES_nx = T1;
else
TSTATES_nx = THALT;
HOLDFF_nx = 1'b0;
HLDA_nx = 1'b0;
end
end
T1 : if (HLTAFF == 1'b1) TSTATES_nx = THALT; else TSTATES_nx = T2;
T2, TWAIT : begin
if ((SSS == 1) && (IRBIT3 == 1'b1) && (IGROUP == 0) // DAD inst.
&& ((MCYCLE == 2) || (MCYCLE == 3)))
BIMC = 1'b1;
else
BIMC = 1'b0;
if (READY == 1'b1 || BIMC == 1'b1) begin
TSTATES_nx = T3;
if (HOLD_sync == 1'b1)
HOLDFF_nx = 1'b1;
else
HOLDFF_nx = 1'b0;
end else
TSTATES_nx = TWAIT;
end
T3 : begin
if (HOLDFF == 1'b1)
if (WR_MOD == 1'b1)
HLDA_nx = 1'b1; // CK_PERIOD
else
HLDA_nx = 1'b0;
if (MCYCLE == 1)
TSTATES_nx = T4;
else if (HOLDFF == 1'b1)
TSTATES_nx = THOLD;
else
TSTATES_nx = T1;
end
// CC6 denotes those op-codes that require six clock cycles during the M1 machine cycle
T4 : begin
if ((IGROUP == 0 && SSS == 3) // INX/DCX instructions
|| (IGROUP == 3 && ( SSS ==0 || SSS == 4 || SSS == 5 || SSS == 7) )
|| (IR == 8'hE9 || IR == 8'hF9)) begin //PCHL SPHL
CC6 = 1'b1;
TSTATES_nx = T5;
if (HOLD_sync == 1'b1) begin
HOLDFF_nx = 1'b1;
HLDA_nx = 1'b1; // CK_PERIOD
end
end else if (HOLDFF == 1'b1) begin
TSTATES_nx = THOLD;
end else begin
TSTATES_nx = T1;
end
end // case: 4
T5 : TSTATES_nx = T6;
T6 : if (HOLDFF == 1'b1) TSTATES_nx = THOLD; else TSTATES_nx = T1;
THALT :
if (HOLD_sync == 1'b1) begin
TSTATES_nx = THOLD;
HOLDFF_nx = 1'b1;
end else if (PRIO_ENCODE != 7) begin
TSTATES_nx = T1;
end else
TSTATES_nx = THALT;
endcase // case (TSTATES)
end // always @ (...
//------------------------------------------------------
// Interrupt Processing
//------------------------------------------------------
wire TRAP_rise = ~TRAP_delay & TRAP_sync;
wire RST75_rise = ~RST75_delay & RST75_sync;
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed)
TRAPFF <= 0;
else if (clear_trap_ff)
TRAPFF <= 0;
else if (TRAP_rise)
TRAPFF <= 1;
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed)
RST75FF <= 0;
else
if (clear_rst75_ff)
RST75FF <= 0;
else if (RST75_rise)
RST75FF <= 1;
always @(/*AS*/INTEFF or INTR_sync or M55FF or M65FF or M75FF or RST55_sync
or RST65_sync or RST75FF or TRAPFF or TRAP_sync) begin
PIE = 3'b111;
if (TRAP_sync == 1'b1 && TRAPFF == 1'b1)
PIE = 3'b000;
else if (INTEFF == 1'b1)
if (M75FF == 1'b0 && RST75FF == 1'b1) PIE = 3'b001;
else if (M65FF == 1'b0 && RST65_sync == 1'b1) PIE = 3'b010;
else if (M55FF == 1'b0 && RST55_sync == 1'b1) PIE = 3'b011;
else if (INTR_sync == 1'b1) PIE = 3'b100;
end
always@(/*AS*/CC6 or MCYCLE or TSTATES) begin
if ( MCYCLE == 1)
if (CC6 == 1'b1)
if (TSTATES == 6)
clock_gate = 1'b1;
else
clock_gate = 1'b0;
else if (TSTATES == 4)
clock_gate = 1'b1;
else
clock_gate = 1'b0;
else
if (TSTATES == 3)
clock_gate = 1'b1;
else
clock_gate = 1'b0;
end
always @(/*AS*/PIE or PRIO_ENCODE or TSTATES or clock_gate) begin
PRIO_ENCODE_nx = PRIO_ENCODE;
if ((TSTATES == 8 || TSTATES == 9 // THALT or THOLD
|| clock_gate == 1'b1))
PRIO_ENCODE_nx = PIE;
end
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed ) begin
PRIO_ENCODE <= 7;
end else begin
PRIO_ENCODE <= PRIO_ENCODE_nx;
end // else: !if(!RESETINBAR )
always @(/*AS*/PRIO_ENCODE)
if (PRIO_ENCODE == 4) begin
INTA = 1'b1;
INA = ~&PRIO_ENCODE[1:0];
end else begin
INTA = 1'b0;
INA = 1'b0;
end
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed)
INTA_pos <= 1'b0;
else
if (TSTATES == 1)
INTA_pos <= INTA;
else
INTA_pos <= 1'b0;
always @(negedge X1 or negedge reset_delayed)
if (!reset_delayed) begin
ALE_neg <= 1'b0;
INTA_neg <= 1'b0;
end else begin
INTA_neg <= INTA_pos;
if (TSTATES == 1)
ALE_neg <= ALE_pos;
else
ALE_neg <= 0;
end
assign ALE = ALE_pos & ~ALE_neg;
always @(/*AS*/END_INST_flag or MCYCLE or TSTATES_nx) begin
MCYCLE_nx = MCYCLE;
if (TSTATES_nx == 1 && END_INST_flag == 1'b1)
MCYCLE_nx = 1;
else if (TSTATES_nx == 1)
MCYCLE_nx = MCYCLE + 1;
end
// Synchronize interrupt inputs
always @(posedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin
HOLD_sync <= 1'b0;
TRAP_sync <= 1'b0;
RST75_sync <= 1'b0;
RST65_sync <= 1'b0;
RST55_sync <= 1'b0;
INTR_sync <= 1'b0;
SID_sync <= 1'b0;
SID_r <= 1'b0;
HOLD_r <= 1'b0;
TRAP_r <= 1'b0;
RST75_r <= 1'b0;
RST65_r <= 1'b0;
RST55_r <= 1'b0;
INTR_r <= 1'b0;
end else begin // if (!RESETINBAR)
HOLD_sync <= HOLD_r;
TRAP_sync <= TRAP_r ;
RST75_sync <= RST75_r;
RST65_sync <= RST65_r;
RST55_sync <= RST55_r;
INTR_sync <= INTR_r;
SID_sync <= SID_r;
SID_r <= SID;
HOLD_r <= HOLD;
TRAP_r <= TRAP;
RST75_r <= RST75;
RST65_r <= RST65;
RST55_r <= RST55;
INTR_r <= INTR ;
end // else: !if(!RESETINBAR)
end // always @ (posedge X1 or negedge RESETINBAR)
always @(posedge X1) begin
RST75_delay <= RST75_sync;
TRAP_delay <= TRAP_sync;
end
endmodule // I8085
module I8085(/*AUTOARG*/
// Outputs
RESETOUT, SOD, INTABAR, ADDR, S0, ALE, WRBAR, RDBAR, S1, IOMBAR, CLKOUT,
HLDA,
// Inouts
AD,
// Inputs
X1, SID, TRAP, RST75, RST65, RST55, INTR, READY, RESETINBAR, HOLD
);
input X1;
output RESETOUT, SOD;
input SID, TRAP, RST75, RST65, RST55, INTR;
output INTABAR;
output [7:0] ADDR;
output S0,ALE,WRBAR, RDBAR,S1,IOMBAR;
input READY, RESETINBAR;
output CLKOUT, HLDA;
input HOLD;
inout [7:0] AD;
reg [15:0] ADDRESS_OUT;
reg S0, S1,IOMBAR;
reg CLKOUT, HLDA;
reg ALE_pos, ALE_neg;
reg INTA_pos, INTA_neg;
reg oe;
reg [7:0] DO;
reg [3:0] TSTATES, TSTATES_nx;
reg [2:0] MCYCLE, MCYCLE_nx;
reg WR_MOD, HOLDFF, INTEFF;
reg RESETOUTFF ;
reg BIMC;
reg HLTAFF ;
reg Z, S, P, CY, AC ;
reg [7:0] ACC, // ACC is the accumulator
ACT, // ACT is the temp accumulator
TEMP,
IR, // instruction register
B, C, D, E, H, L, Z_reg, W_reg ;
reg [15:0] SP, PC;
parameter TRESET = 4'd0,
T1 = 4'd1,
T2 = 4'd2,
T3 = 4'd3,
T4 = 4'd4,
T5 = 4'd5,
T6 = 4'd6,
THOLD = 4'd9,
TWAIT = 4'd7,
THALT = 4'd8;
parameter M1 = 3'd1,
M2 = 3'd2,
M3 = 3'd3,
M4 = 3'd4,
M5 = 3'd5;
wire reset_delayed;
reg RD1, RD2, WR1;
reg FETCH_F_WZ;
reg IRBIT3, IRBIT0;
reg [2:0] DDD, SSS;
reg [1:0] DPAIR, IGROUP;
reg CC_TEST;
reg M75FF, M65FF, M55FF;
reg TRAPFF;
reg [2:0] PRIO_ENCODE, PRIO_ENCODE_nx;
reg RST75FF;
reg clear_rst75_ff;
reg clear_trap_ff;
reg CC6;
reg INA,INTA;
reg BIMCB;
reg [8:0] ALU_OUT;
reg [15:0] B16BCTR;
integer LAST_OP;
reg SOD_FF;
reg [7:0] temp_MOV;
reg [7:0] temp_D;
reg [7:0] temp_E;
reg END_INST_flag ;
reg common, common1, wrinm2, wrinm3, wrinm4, wrinm5;
reg DAD_inst;
reg [2:0] PIE;
reg clock_gate;
reg HOLD_sync, TRAP_sync, RST75_sync, RST65_sync, RST55_sync, INTR_sync, SID_sync;
reg HOLD_r, TRAP_r, RST75_r, RST65_r, RST55_r, INTR_r, SID_r;
reg RST75_delay, TRAP_delay;
assign ADDR = ADDRESS_OUT[15:8];
assign AD = (TSTATES == 1) ? ADDRESS_OUT[7:0] : (oe) ? DO : 8'bzzzzzzzz;
wire EI_ENABLE = (PRIO_ENCODE == 0) ? 1'b1 : 0;
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed) begin
MCYCLE <= 0;
RESETOUTFF <= 1'b0;
end else begin
RESETOUTFF <= 1'b1;
MCYCLE <= MCYCLE_nx;
end
always @(posedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin // clear the flip-flops
PC <= 0; // Program Counter
HLTAFF <= 1'b0;
WR_MOD <= 1'b0;
INTEFF <= 1'b0;
clear_rst75_ff <= 1'b0;
clear_trap_ff <= 1'b0;
M75FF <= 1'b1;
M65FF <= 1'b1;
M55FF <= 1'b1;
LAST_OP = 99;
FETCH_F_WZ <= 1'b0;
SOD_FF <= 1'b0;
END_INST_flag <= 1'b0;
IR <= 0;
ACC <= 0;
ACT <= 0;
CY <= 1'b0; // condition codes
P <= 1'b0;
AC <= 1'b0;
Z <= 1'b0;
S <= 1'b0;
ALE_pos <= 0;
end else begin // Begin processing on positive edge of clock
//CLKOUT <= 1'b0;
if (TSTATES_nx == 1)
ALE_pos <= 1'b1; else ALE_pos <= 1'b0;
// HW_INTR_PS
// interrupts are sampled during the second clock cycle before M1,T1
if (TSTATES_nx == 2)
END_INST_flag <= 1'b0;
if (TSTATES == THALT && PRIO_ENCODE != 7)
HLTAFF <= 1'b0;
if (TSTATES == T3)
WR_MOD <= 1'b0;
//-------------------------------------------------------------------------
if (MCYCLE_nx == 1 && (TSTATES_nx == 1 || TSTATES_nx == 2 || TSTATES_nx == 3)) begin
//--------------------------------------------------------//
// Common processing for all OP-CODES //
// MCYCLE = 1 //
// AND //
// TSTATES = 1, 2, or 3 //
// Instruction Fetch //
//--------------------------------------------------------//
case (TSTATES_nx)
// MCYCLE = 1, TSTATES = 1
1 : begin
if (FETCH_F_WZ) begin
ADDRESS_OUT <= {W_reg, Z_reg};
PC <= {W_reg, Z_reg};
end else
ADDRESS_OUT <= PC;
S1 <= 1'b1;
S0 <= 1'b1;
// Cf., interrupt acknowledge timing, p 2-13, MCS 80/85 user's manual
IOMBAR <= INTR_sync & (PRIO_ENCODE_nx == 4);
end
// MCYCLE = 1, TSTATES = 2
2 : begin
if (LAST_OP != 99) begin
//--------- Procedure OP_RUNIN_NEXT_INST; ----------
case (LAST_OP)
0 : ALU_OUT = ACT + TEMP; // ADD r
1 : ALU_OUT = ACT + TEMP + CY; // ADC r
2 : ALU_OUT = ACT - TEMP; // SUB r
3 : ALU_OUT = ACT - TEMP - CY; // SBB r
4 : ALU_OUT = ACT & TEMP;
5 : ALU_OUT = ACT ^ TEMP;
6 : ALU_OUT = ACT | TEMP;
7 : ALU_OUT = ACT - TEMP; // CMP
10,11,12,13 : CY <= ALU_OUT[8];
// 14 : ALU_OUT = TEMP; // DAA
// 15 : // CMA
// 16 : CY <= 1; // STC
// 17 : if (CY == 0) CY <= 1; else CY <= 0; // CMC
20 : ACC[7] <= SID_sync; // RIM
30 : if (ACC[6] == 1'b1) begin // SIM
SOD_FF <= ACC[7];
clear_rst75_ff <= 1'b0;
end
endcase // end of case LAST_OP
if ((LAST_OP <16) && (LAST_OP != 7)) ACC <= ALU_OUT;
// setup flags for condition codes Z,S,P,CY,AC
if (LAST_OP <10) begin
// SET_FLAGS;
if (ALU_OUT == 0) Z <= 1'b1; else Z <= 1'b0;
S <= ALU_OUT[7];
CY <= ALU_OUT[8];
P <= ^ALU_OUT[7:0];
end
case (LAST_OP)
0,1,2,3 : AC <= ALU_OUT[4] ^ TEMP[4] ^ ACT[4];
4 : begin
CY <= 1'b0;
AC <= 1'b1;
end
5,6 : begin
CY <= 1'b0;
AC <= 1'b0;
end
endcase // case (LAST_OP)
//------- end Procedure OP_RUNIN_NEXT_INST; --------------
end // if (LAST_OP != 99)
if ( FETCH_F_WZ )
FETCH_F_WZ <= 1'b0;
PC <= PC + 1; // increment Program Counter
//synthesis translate_off
$display ($time,,
"C%bZ%bM%bE%bI%b A=%h B=%h%h D=%h%h H=%h%h S=%h P=%h IR=%h",
CY, Z, S, P, AC,
ACC, B, C, D, E, H, L,
SP, PC, IR);
//synthesis translate_on
end // case: 2
// MCYCLE = 1, TSTATES = 3
3 : begin
LAST_OP = 99;
if (PRIO_ENCODE != 7/*HRSTTYPE > 0*/) begin
INTEFF <= 1'b0; // (DI) disable interrupts
IR <= 8'b00010000;
IGROUP <= 2'b00; // high order two bits select instruction group
DDD <= 3'b010; // bits 5 downto 3 select destination register
DPAIR <= 2'b01;
SSS <= 3'b000; // bits 2 downto 0 select source register
IRBIT0 <= 1'b0;
IRBIT3 <= 1'b0;
if (PRIO_ENCODE == 4) Z_reg <= {2'b00, AD[5:3], 3'b000};
if (PRIO_ENCODE == 0) begin
Z_reg <= 8'h24;
clear_trap_ff <= 1'b1;
end
if (PRIO_ENCODE == 1) begin
Z_reg <= 8'h3c;
clear_rst75_ff <= 1'b1;
end
if (PRIO_ENCODE == 2) Z_reg <= 8'h34;
if (PRIO_ENCODE == 3) Z_reg <= 8'h2c;
end else begin
IR <= AD;
TEMP <= AD;
// Decode the instruction register
IGROUP <= AD[7 : 6]; // high order two bits select instruction group
DDD <= AD[5 : 3]; // bits 5 downto 3 select destination register
DPAIR <= AD[5 : 4];
SSS <= AD[2 : 0]; // bits 2 downto 0 select source register
IRBIT0 <= AD[0];
IRBIT3 <= AD[3];
end
end // case: 3
endcase // case (TSTATES)
//=========================================================================
end else begin
// either (MCYCLE > 1) OR (MCYCLE = 1 AND TSTATES > 3)
//=========================================================================
//
// Instruction decode begins here. The high order two bits of the op-code, referred
// to as IGROUP, select the major function. Then, the third, fourth and fifth bits
// of the op-code, referred to as DDD, select the destination, and the rightmost
// three bits of the op-code, referred to as SSS, select the source. The DDD and SSS
// fields either further refine the functionality or select source and destination
// registers for the op-code.
//
case (IGROUP)
0 : begin // IGROUP = (0,0)
case (SSS)
0 : begin
case (DDD) // OP-CODE = 00 DDD 000 (SSS = 000)
0 : begin
END_INST_flag <= 1'b1; // NOP
//last_MC <= 3'b001;
end
2 : begin // HWRST 0001 0000
case (MCYCLE)
1 : begin
clear_rst75_ff <= 1'b0;
clear_trap_ff <= 1'b0;
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
4 : begin
W_reg <= 0;
SP <= SP - 1;
PC <= PC - 1;
//last_MC <= 3'b001;
end
//5 : SP <= SP - 1;
endcase // case (TSTATES_nx)
end
2 : begin
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
SP <= SP - 1;
DO <= PC[15:8];
WR_MOD <= 1'b1;
end
endcase // case (TSTATES_nx)
end // case: 2
3 : begin
case (TSTATES_nx)
2 : begin
DO <= PC[7:0];
WR_MOD <= 1'b1;
end
3 : begin
FETCH_F_WZ <= 1'b1;
END_INST_flag <= 1'b1;
end
endcase // case TSTATES
end // case: 3
endcase // case (MCYCLE)
end // case: 2
4 : begin // RIM
ACC[0] <= M55FF;
ACC[1] <= M65FF;
ACC[2] <= M75FF;
ACC[3] <= INTEFF;
ACC[4] <= RST55_sync;
ACC[5] <= RST65_sync;
ACC[6] <= RST75FF;
LAST_OP = 20;
END_INST_flag <= 1'b1;
end // case: 4
6 : begin // SIM
if (ACC[3]) begin
M55FF <= ACC[0];
M65FF <= ACC[1];
M75FF <= ACC[2];
end
if (ACC[4]) begin
clear_rst75_ff <= 1'b1;
LAST_OP = 30;
end
END_INST_flag <= 1'b1;
end // case: 6
1,3,5,7,8 : END_INST_flag <= 1'b1;
endcase // case (DDD)
end // case: 0
1 : begin // OP-CODE = 00 DDD 001 (SSS = 001)
case (IRBIT3) // instruction register, bit 3
1'b0 : begin // LXI (Load immediate register pair)
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 : begin
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2;
PC <= PC + 1'b1;
end
3 : begin
case (DPAIR)
0 : C <= AD;
1 : E <= AD;
2 : L <= AD;
3 : SP[7:0] <= AD;
endcase
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
end // case: 2
3 : begin
case (TSTATES_nx)
2 : begin // PC_READ_T2;
PC <= PC + 1'b1;
end
3 : begin
case (DPAIR)
0 : B <= AD;
1 : D <= AD;
2 : H <= AD;
3 : SP[15:8] <= AD;
endcase
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
//ADDRESS_OUT <= PC ;
end
endcase // case (TSTATES_nx)
end // case: 3
endcase // case (MCYCLE)
end // case: 1'b0
1'b1 : begin // DAD (Double add)
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : case (DPAIR)
0 : ACT <= C;
1 : ACT <= E;
2 : ACT <= L;
3 : ACT <= SP[7:0];
endcase // DPAIR
endcase
2 : begin
case (TSTATES_nx)
1 : begin
case (DPAIR)
0 : ACT <= B;
1 : ACT <= D;
2 : ACT <= H;
3 : ACT <= SP[15:8];
endcase // DPAIR
end
2 : ALU_OUT = ACT + L;
3 : begin
L <= ALU_OUT[7:0];
CY <= ALU_OUT[8];
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
end // case: 2
3 : begin
case (TSTATES_nx)
2 : ALU_OUT = ACT + H + CY;
3 : begin
H <= ALU_OUT[7:0];
CY <= ALU_OUT[8];
//MCYCLE <= 1;
END_INST_flag <= 1'b1;
end
endcase // TSTATES
end // case: 3
endcase // case (MCYCLE)
end // case: 1'b1
endcase // case (IRBIT3)
end // case: 1
2 : begin // op code = 00 DDD 010 (SSS = 010)
case (DDD)
0,2 : // STAX
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
if (DPAIR == 0) begin
ADDRESS_OUT[15:8] <= B ;
ADDRESS_OUT[7:0] <= C ;
end else begin
ADDRESS_OUT[15:8] <= D ;
ADDRESS_OUT[7:0] <= E ;
end
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end // case: 1
endcase
2 :
case (TSTATES_nx)
2 : // HL_READ_T2
DO <= ACC;
3 : begin
// MCYCLE <= 1;
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
1,3 : // LDAX
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
if (DPAIR == 0) begin
ADDRESS_OUT[15:8] <= B ;
ADDRESS_OUT[7:0] <= C ;
end else begin
ADDRESS_OUT[15:8] <= D ;
ADDRESS_OUT[7:0] <= E ;
end
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end // case: 1
endcase // case (TSTATES_nx)
2 :
case (TSTATES_nx)
2 : // HL_READ_T2
begin end
3 : begin
//MCYCLE <= 1;
ACC <= AD;
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
4,5 : // SHLD/LHLD
case (MCYCLE)
// 1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase // case (TSTATES_nx)
2 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2
PC <= PC + 1'b1;
end
3 : //MCYCLE <= 3;
Z_reg <= AD;
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
1 : begin // MEM_WZ_WRITE_T1
ADDRESS_OUT[15:8] <= W_reg ;
ADDRESS_OUT[7:0] <= Z_reg ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin // PC_READ_T2
PC <= PC + 1'b1;
end
3 : //MCYCLE <= 4;
W_reg <= AD;
endcase // case (TSTATES_nx)
4 :
case (TSTATES_nx)
1 : begin // MEM_WZ_WRITE_T1
ADDRESS_OUT[15:8] <= W_reg ;
ADDRESS_OUT[7:0] <= Z_reg ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin
WR_MOD <= 1'b1;
if (IRBIT3 == 1'b0)
DO <= L ;
B16BCTR[15:8] = W_reg;
B16BCTR[7:0] = Z_reg;
B16BCTR = B16BCTR + 1'b1;
end
3 : begin
if (IRBIT3 == 1'b1)
L <= AD;
W_reg <= B16BCTR[15:8];
Z_reg <= B16BCTR[7:0];
//MCYCLE <= 5;
end
endcase // case (TSTATES_nx)
5 :
case (TSTATES_nx)
2 : begin
WR_MOD <= 1'b1;
if (IRBIT3 == 1'b0)
DO <= H ;
end
3 : begin
if (IRBIT3 == 1'b1)
H <= AD;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
6,7 : // 6 = STA (store accumulator)
// 7 = LDA (load accumulator)
case (MCYCLE)
//1 : MCYCLE <= 2;
1 :case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2
PC <= PC + 1'b1;
end
3 : // MCYCLE <= 3;
Z_reg <= AD;
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
1 : begin // MEM_WZ_WRITE_T1
ADDRESS_OUT[15:8] <= W_reg ;
ADDRESS_OUT[7:0] <= Z_reg ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin // PC_READ_T2
PC <= PC + 1'b1;
end
3 : // MCYCLE <= 4;
W_reg <= AD;
endcase // case (TSTATES_nx)
4 :
case (TSTATES_nx)
2 : begin
if (IRBIT3 == 1'b0)
DO <= ACC ; // STA
WR_MOD <= 1'b1;
end
3 : begin
if (IRBIT3 == 1'b1)
ACC <= AD; // LDA
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
endcase // case (DDD)
end // case: 2
3 : // op code = 00 DDD 011 (SSS = 011)
case (TSTATES_nx)
4 : begin
case (DPAIR)
0 : begin
B16BCTR[15:8] = B;
B16BCTR[7:0] = C;
end
1 : begin
B16BCTR[15:8] = D;
B16BCTR[7:0] = E;
end
2 : begin
B16BCTR[15:8] = H;
B16BCTR[7:0] = L;
end
3 : B16BCTR = SP;
endcase // end of case DPAIR
// when IRBIT3 = 0, INX, when 1, DCX
if (IRBIT3 == 1'b0)
B16BCTR = B16BCTR + 1'b1;
else
B16BCTR = B16BCTR - 1'b1;
end // case: 4
5 :
case (DPAIR)
0 : begin
B <= B16BCTR[15:8];
C <= B16BCTR[7:0];
end
1 : begin
D <= B16BCTR[15:8];
E <= B16BCTR[7:0];
end
2 : begin
H <= B16BCTR[15:8];
L <= B16BCTR[7:0];
end
3 : SP <= B16BCTR;
endcase // case (DPAIR)
6 : END_INST_flag <= 1'b1;
endcase // case (TSTATES_nx)
4,5 : // op code = 00 DDD 10X (SSS = 10X)
if (DDD == 6) // memory access
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase // case (TSTATES_nx)
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin
end
3 : begin
if (IRBIT0 == 1'b0)
ALU_OUT = AD + 1;
else
ALU_OUT = AD - 1;
TEMP <= ALU_OUT[7:0];
if (ALU_OUT == 0)
Z <= 1'b1;
else
Z <= 1'b0;
S <= ALU_OUT[7];
P <= ^ALU_OUT[7:0];
AC <= ALU_OUT[4] ^ TEMP[4] ^ ACT[4];
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
2 : begin
DO <= TEMP ;
WR_MOD <= 1'b1;
end
3 : begin
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
else begin
case (MCYCLE)
1 : case(TSTATES_nx)
4 : begin
case (DDD)
0 : ALU_OUT[7:0] = B;
1 : ALU_OUT[7:0] = C;
2 : ALU_OUT[7:0] = D;
3 : ALU_OUT[7:0] = E;
4 : ALU_OUT[7:0] = H;
5 : ALU_OUT[7:0] = L;
7 : ALU_OUT[7:0] = ACC;
endcase
if (IRBIT0 == 1'b0)
ALU_OUT = ALU_OUT[7:0] + 1;
else
ALU_OUT = ALU_OUT[7:0] - 1;
case (DDD)
0 : B <= ALU_OUT[7:0];
1 : C <= ALU_OUT[7:0];
2 : D <= ALU_OUT[7:0];
3 : E <= ALU_OUT[7:0];
4 : H <= ALU_OUT[7:0];
5 : L <= ALU_OUT[7:0];
7 : ACC <= ALU_OUT[7:0];
endcase
if (ALU_OUT == 0)
Z <= 1'b1;
else
Z <= 1'b0;
S <= ALU_OUT[7];
P <= ^ALU_OUT[7:0];
AC <= ALU_OUT[4] ^ TEMP[4] ^ ACT[4];
END_INST_flag <= 1'b1;
end // case: 4
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // else: !if(DDD == 6)
6 : // MVI (SSS = 6)
if (DDD == 6) // move 2nd byte of inst. to Memory
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 : case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : // MCYCLE <= 3;
TEMP <= AD;
endcase // case (TSTATES_nx)
3 : case (TSTATES_nx)
2 : begin
DO <= TEMP ;
WR_MOD <= 1'b1;
end
3 : begin
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
else begin // move 2nd byte of inst. to designated register
case (MCYCLE)
//1 : MCYCLE <= 2;
1 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
2 : begin
PC <= PC + 1'b1;
end
3 : begin
//MCYCLE <= 1;
case (DDD)
0 : B <= AD;
1 : C <= AD;
2 : D <= AD;
3 : E <= AD;
4 : H <= AD;
5 : L <= AD;
7 : ACC <= AD;
endcase // end of case DDD
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // else: !if(DDD = 6)
7 : begin // (SSS = 7) ROTATE_ETC
LAST_OP = DDD + 10;
case (DDD)
0 : // RLC
ALU_OUT[7:0] = {ACC[6:0], ACC[7]};
1 : // RRC
ALU_OUT[7:0] = {ACC[0], ACC[7:1]};
2 : // RAL
ALU_OUT[8:0] = {ACC[7:0],CY};
3 : // RAR
ALU_OUT[7:0] = {CY, ACC[7:1]};
4 : begin // DAA
if (ACC[3:0] > 9) begin
ALU_OUT[7:0] = ACC + 6;
ALU_OUT[8] = 1'b1;
end else begin
ALU_OUT[7:0] = ACC;
ALU_OUT[8] = 1'b0;
end
if (ACC[7:4] > 9) begin
ALU_OUT[7:0] = ALU_OUT[7:0] + 96; // 96 = 6 x 00010000
ALU_OUT[8] = 1'b1;
end else
ALU_OUT[8] = 1'b0;
end
5 : ALU_OUT = ~ACC; // CMA
6 : CY <= 1'b1; // STC (Set Carry to 1)
7 : CY <= ~CY; // CMC (Complement Carry)
endcase
END_INST_flag <= 1'b1;
end // case: 7
endcase // case (SSS)
end // case: 0
1 : begin // IGROUP = (0,1) MOV, HLT op code = 01 DDD SSS (IR = 01)
if (SSS == 6) begin
if (DDD == 6) begin // HLT instruction
case (TSTATES_nx)
4 : begin
//MCYCLE <= 2;
HLTAFF <= 1'b1;
end
2 :
END_INST_flag <= 1'b1;
endcase // end of case TSTATES
end else begin // MOVM instruction (Move from Memory to Reg.)
case (TSTATES_nx)
1 : begin // MEM_HL_READ_T1
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // HL_READ_T2
end
3 : begin
//MCYCLE <= 1;
END_INST_flag <= 1'b1;
case (DDD)
0 : B <= AD;
1 : C <= AD;
2 : D <= AD;
3 : E <= AD;
4 : H <= AD;
5 : L <= AD;
7 : ACC <= AD;
endcase // end of case DDD
end
//4 : MCYCLE <= 2;
endcase // case (TSTATES_nx)
end // else: !if(DDD = 6)
end else if (DDD == 6) begin // MOVM instruction (move from Reg. to Memory)
case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ; // MEM_HL_WRITE_T1
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin // WRITE_T2
WR_MOD <= 1'b1;
DO <= TEMP;
end
3 : begin
//MCYCLE <= 1;
END_INST_flag <= 1'b1;
end
4 : begin // SOURCE_REG
//MCYCLE <= 2;
case (SSS)
0 : TEMP <= B;
1 : TEMP <= C;
2 : TEMP <= D;
3 : TEMP <= E;
4 : TEMP <= H;
5 : TEMP <= L;
7 : TEMP <= ACC;
endcase // case SSS
end
endcase // case (TSTATES_nx)
end else begin// if ((DDD !=6) && (SSS !=6)) then (MOV r1,r2)
// this will be state 4, there is only one MCYCLE
case (SSS)
0 : temp_MOV = B;
1 : temp_MOV = C;
2 : temp_MOV = D;
3 : temp_MOV = E;
4 : temp_MOV = H;
5 : temp_MOV = L;
7 : temp_MOV = ACC;
endcase // case SSS
case (DDD)
0 : B <= temp_MOV;
1 : C <= temp_MOV;
2 : D <= temp_MOV;
3 : E <= temp_MOV;
4 : H <= temp_MOV;
5 : L <= temp_MOV;
7 : ACC <= temp_MOV;
endcase // end of case DDD
END_INST_flag <= 1'b1;
end // else: !if(DDD = 6)
end // case: 1
2 : begin // IGROUP = (1,0) op code = 10 DDD SSS (IR = 10) (ALU operations)
LAST_OP = DDD;
//
// The Group 2 instructions complete execution
// during state T2 of the next instruction.
// The DDD field is used to decode the operation.
if (SSS != 6) begin
case (SSS)
0 : TEMP <= B;
1 : TEMP <= C;
2 : TEMP <= D;
3 : TEMP <= E;
4 : TEMP <= H;
5 : TEMP <= L;
7 : TEMP <= ACC;
endcase // source_reg
ACT <= ACC;
END_INST_flag <= 1'b1;
end else begin // SSS = 6 => memory fetch
case (TSTATES_nx)
1 : begin
ADDRESS_OUT[15:8] <= H ;
ADDRESS_OUT[7:0] <= L ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin end
3 : begin
TEMP <= AD;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
4 : begin
ACT <= ACC; // if TSTATES=4, then MCYCLE must be 1
//MCYCLE <= 2;
end
endcase // case (TSTATES_nx)
end // else: !if(SSS != 6)
end // case: 2
3 : begin // IGROUP = (1,1) op code = 11 DDD SSS (IR = 11)
case (SSS)
0 : begin // RC (Return Conditional)
case (MCYCLE)
1 : begin
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
4 : case (DDD)
0 : CC_TEST <= ~Z;
1 : CC_TEST <= Z;
2 : CC_TEST <= ~CY;
3 : CC_TEST <= CY;
4 : CC_TEST <= ~P;
5 : CC_TEST <= P;
6 : CC_TEST <= ~S;
7 : CC_TEST <= S;
endcase // DPAIR
6 :
if (CC_TEST == 1'b0)
END_INST_flag <= 1'b1;
//else
//MCYCLE <= 2;
endcase // case (TSTATES_nx)
end // case: 1
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : begin
PC[7:0] <= AD;
Z_reg <= AD;
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : begin
PC[15:8] <= AD;
W_reg <= AD;
END_INST_flag <= 1'b1;
FETCH_F_WZ <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 0
1 : begin // SSS = 1
case (IRBIT3)
1'b0 : begin // POP rp
// rp - register pair
// rp = 00: BC , rp = 01: DE , rp = 10: HL , rp = 11: PSW
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : begin
case (MCYCLE)
2 : begin
//MCYCLE <= 3;
case (DPAIR)
0 : C <= AD;
1 : E <= AD;
2 : L <= AD;
3 : begin
CY <= AD[0];
P <= AD[2];
AC <= AD[4];
Z <= AD[6];
S <= AD[7];
end
endcase // case (DPAIR)
end // case: 2
3 : begin
//MCYCLE <= 1;
case (DPAIR)
0 : B <= AD;
1 : D <= AD;
2 : H <= AD;
3 : ACC <= AD;
endcase
END_INST_flag <= 1'b1;
end
endcase // case (MCYCLE)
end // case: 3
//4 : MCYCLE <= 2; // if TSTATES = 4, MCYCLE must be 1
endcase // case (TSTATES_nx)
end // case: 1'b0
1'b1 : begin
case (DPAIR)
0 : begin // RET
case (MCYCLE)
//1 : MCYCLE <= 2;
1 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : //MCYCLE <= 3;
PC[7:0] <= AD;
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
2 : begin // SP_READ_T2
SP <= SP + 1'b1;
end
3 : begin
PC[15:8] <= AD;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 0
// 1 : // NOOP
2 : begin // PCHL
case (TSTATES_nx)
4 : PC[15:8] <= H;
5 : begin
PC[7:0] <= L;
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
end
3 : begin // SPHL
case (TSTATES_nx)
4 : SP[15:8] <= H;
5 : begin
SP[7:0] <= L;
END_INST_flag <= 1'b1;
end
endcase // case (TSTATES_nx)
end
endcase // case (DPAIR)
end // case: 1'b1
endcase // case (IRBIT3)
end // case: 1
2 : begin // Conditional Jump
case (MCYCLE)
1 : begin // TSTATES = 4
case (DDD)
0 : CC_TEST <= ~Z;
1 : CC_TEST <= Z;
2 : CC_TEST <= ~CY;
3 : CC_TEST <= CY;
4 : CC_TEST <= ~P;
5 : CC_TEST <= P;
6 : CC_TEST <= ~S;
7 : CC_TEST <= S;
endcase
//MCYCLE <= 2;
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
endcase
end
2 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : begin//MCYCLE <= 3;
if (CC_TEST == 1'b0) begin
PC <= PC + 1'b1;
END_INST_flag <= 1'b1;
end
Z_reg <= AD; // Byte2 -> Z
end
endcase // TSTATES
3 :
case (TSTATES_nx)
2 : begin
PC <= PC + 1'b1;
end
3 : begin
W_reg <= AD; // Byte3 -> W
END_INST_flag <= 1'b1;
FETCH_F_WZ <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 2
3 : begin
case (DDD)
0 : begin // JMP
case (MCYCLE)
//1 : MCYCLE <= 2;
1 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
PC <= PC + 1'b1;
end
//3 : MCYCLE <= 3;
3 : Z_reg <= AD; // Byte2 -> Z
endcase // TSTATES
3 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : begin
W_reg <= AD; // Byte3 -> W
END_INST_flag <= 1'b1;
FETCH_F_WZ <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 0
//1 : NOOP;
2,3 : begin // IO_OUT/IO_IN
case (MCYCLE)
//1 : MCYCLE <= 2; // TSTATES = 4
1 : case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= PC ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= {W_reg, Z_reg}/*PC*/ ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b1 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : begin// MCYCLE <= 3;
Z_reg <= AD; // Byte2 -> Z
W_reg <= AD; // Byte2 -> W
end
endcase // TSTATES
3 :
case (TSTATES_nx)
2 : begin
if (IRBIT3 == 1'b0) // OUT instruction
DO <= ACC ;
end
3 : begin
if (IRBIT3 == 1'b1) // IN instruction
ACC <= AD ;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 2,3
4 : begin // XTHL
case (MCYCLE)
//1 : MCYCLE <= 2;
1 : case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2
SP <= SP + 1'b1;
end
3 : //MCYCLE <= 3;
Z_reg <= AD;
endcase // TSTATES
3 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin end // PC_READ_T2
3 : //MCYCLE <= 4;
W_reg <= AD;
endcase // TSTATES
4 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
IOMBAR <= 1'b0 ;
S1 <= 1'b0 ;
S0 <= 1'b1 ;
end
2 : begin
WR_MOD <= 1'b1;
DO <= H ;
SP <= SP - 1;
end
//3 : MCYCLE <= 5;
endcase // TSTATES
5 :
case (TSTATES_nx)
2 : begin
WR_MOD <= 1'b1;
DO <= L ;
end
3 : begin
L <= Z_reg;
H <= W_reg;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 4
5 : begin // XCHG
temp_D = D;
temp_E = E;
D <= H;
E <= L;
H <= temp_D;
L <= temp_E;
END_INST_flag <= 1'b1;
end
6 : begin
INTEFF <= 1'b0; // (DI) disable interrupts
END_INST_flag <= 1'b1;
end
7 : begin
INTEFF <= 1'b1; // (EI) enable interrupts
END_INST_flag <= 1'b1;
end
endcase // case (DDD)
end // case: 3
4 : begin // CONDITIONAL CALL
case (MCYCLE)
1 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
4 : begin
case (DDD)
0 : CC_TEST <= ~Z;
1 : CC_TEST <= Z;
2 : CC_TEST <= ~CY;
3 : CC_TEST <= CY;
4 : CC_TEST <= ~P;
5 : CC_TEST <= P;
6 : CC_TEST <= ~S;
7 : CC_TEST <= S;
endcase // case (DDD)
end
5 : begin
//MCYCLE <= 2;
if (CC_TEST == 1'b1)
SP <= SP - 1'b1;
end
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
if (CC_TEST == 1'b1) begin
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
end
2 : begin // PC_READ_T2;
if (CC_TEST == 1'b1)
PC <= PC + 1;
else
PC <= PC + 2;
end
3 : begin
Z_reg <= AD;
if (CC_TEST == 1'b0)
END_INST_flag <= 1'b1;
//MCYCLE <= 3;
end
endcase
3 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // PC_READ_T2;
PC <= PC + 1;
end
3 : begin
W_reg <= AD;
//MCYCLE <= 4;
end
endcase
4 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
SP <= SP - 1;
DO <= PC[15:8];
WR_MOD <= 1'b1;
end
3 : begin // WRITE_T3;
//MCYCLE <= 5;
end
endcase
5 :
case (TSTATES_nx)
2 : begin
DO <= PC[7:0];
WR_MOD <= 1'b1;
end
3 : begin // WRITE_T3;
//MCYCLE <= 1;
END_INST_flag <= 1'b1;
if (CC_TEST == 1'b1) FETCH_F_WZ <= 1'b1; else FETCH_F_WZ <= 1'b0;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 4
5 : begin // IGROUP = 3, SSS = 5
case (IRBIT3)
1'b0 : begin // PUSH rp (register pair)
case (MCYCLE)
1 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
5 : SP <= SP - 1'b1; // Compared to 8080
6 : begin // 8085 uses an additional state, T6
//MCYCLE <= 2;
//ADDRESS_OUT <= SP ;
end
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // RP_PSW_SOURCE
case (DPAIR)
0 : DO <= B[7:0];
1 : DO <= D ;
2 : DO <= H ;
3 : DO <= ACC ;
endcase
SP <= SP - 1'b1;
WR_MOD <= 1'b1;
end
3 : begin
//MCYCLE <= 3;
//ADDRESS_OUT <= SP ;
end
endcase
3 :
case (TSTATES_nx)
2 : begin // RP_PSW_SOURCE(2)
case (DPAIR)
0 : DO <= C ;
1 : DO <= E ;
2 : DO <= L ;
3 : DO <= {S, Z, 1'b0, AC, 1'b0, P, 1'b0, CY};
endcase
WR_MOD <= 1'b1;
end
3 : begin
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
//ADDRESS_OUT <= PC ;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 1'b0
1'b1 : begin
case (DPAIR)
0 : begin // CALL
case (MCYCLE)
1 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
4 : SP <= SP - 1;
//5 : MCYCLE <= 2;
endcase
2 :
case (TSTATES_nx)
1 : begin // MEM_PC_READ_T1;
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin // PC_READ_T2;
PC <= PC + 1;
end
3 : begin
Z_reg <= AD;
//MCYCLE <= 3;
end
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // PC_READ_T2;
PC <= PC + 1'b1;
end
3 : begin
W_reg <= AD;
//MCYCLE <= 4;
end
endcase // case (TSTATES_nx)
4 :
case (TSTATES_nx)
1 : begin // MEM_SP_WRITE_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b0 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin
SP <= SP - 1;
DO <= PC[15:8];
WR_MOD <= 1'b1;
end
3 : begin // WRITE_T3;
//MCYCLE <= 5;
end
endcase // case (TSTATES_nx)
5 :
case (TSTATES_nx)
2 : begin
DO <= PC[7:0];
WR_MOD <= 1'b1;
end
3 : begin // WRITE_T3;
//MCYCLE <= 1;
FETCH_F_WZ <= 1'b1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 0
// 1,2,3 : //NOOP;
endcase // case (DPAIR)
end // case: 1'b1
endcase // case (IRBIT3)
end // case: 5
6 : begin // SSS = 6 => memory fetch
LAST_OP = DDD;
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= PC ;
IOMBAR <= 1'b0 ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
end
2 : begin
PC <= PC + 1'b1;
end
3 : begin
TEMP <= AD;
END_INST_flag <= 1'b1;
//MCYCLE <= 1;
end
4 : begin
ACT <= ACC; // if TSTATES=4, then MCYCLE must be 1
//MCYCLE <= 2;
end
endcase // case (TSTATES_nx)
end // case: 6
7 : begin // RST
case (MCYCLE)
1 :
case (TSTATES_nx)
1 : begin // MEM_SP_READ_T1
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
4 : begin
W_reg <= 0;
SP <= SP - 1;
end
//6 : MCYCLE <= 2;
endcase // TSTATES
2 :
case (TSTATES_nx)
1 : begin
ADDRESS_OUT <= SP ;
S1 <= 1'b1 ;
S0 <= 1'b0 ;
IOMBAR <= 1'b0 ;
end
2 : begin // SP_READ_T2
SP <= SP - 1;
DO <= PC[15:8] ;
end
//3 : MCYCLE <= 3;
endcase // case (TSTATES_nx)
3 :
case (TSTATES_nx)
2 : begin // SP_READ_T2
DO <= PC[7:0];
Z_reg[7:6] <= 0;
Z_reg[5:3] <= TEMP[5:3];
Z_reg[2:0] <= 0;
end
3 : begin
END_INST_flag <= 1'b1;
FETCH_F_WZ <= 1'b1;
//MCYCLE <= 1;
end
endcase // case (TSTATES_nx)
endcase // case (MCYCLE)
end // case: 7
endcase // case (SSS)
end // case: 3
endcase // case (IGROUP)
end // else: !if(MCYCLE==1 && (TSTATES==0 || TSTATES==1 || TSTATES==2 || TSTATES==3))
end // else: !if(!RESETINBAR)
end // always @ (posedge X1 or negedge RESETINBAR)
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// Compute RDBAR/WRBAR signals
//-------------------------------------------------------------------------
always @(/*AS*/DDD or IGROUP or INA or SSS or common or common1) begin
if ((IGROUP == 3 && SSS == 7) // RST n FWW
|| (IGROUP == 0 && DDD == 2 && SSS == 0) //HWRST
|| (INA == 1'b1)
|| (IGROUP == 3 && SSS == 5
&& (DDD == 0 || DDD == 2 || DDD == 4 || DDD == 6))) // PUSH rp FWW
common = 1'b0;
else common = 1'b1;
if ((IGROUP == 3 && DDD == 1 && SSS == 5) // CALL FRRWW
|| (IGROUP == 3 && SSS == 4) // C??? FRRWW
|| (IGROUP == 3 && DDD == 4 && SSS == 3) // XTHL FRRWW
|| (IGROUP == 0 && DDD == 4 && SSS == 2)) // SHLD FRRWW
common1 = 1'b0;
else common1 = 1'b1;
if ((common == 1'b0)
|| (IGROUP == 1 && DDD == 6 && SSS != 6) // MOV M,REG FW
|| (IGROUP == 0 && DDD == 0 && SSS == 2) // STAX B FW
|| (IGROUP == 0 && DDD == 2 && SSS == 2)) // STAX D FW
wrinm2 = 1'b1;
else wrinm2 = 1'b0;
if (( common == 1'b0)
|| (IGROUP == 0 && DDD == 6 && (SSS == 4 || SSS == 5 || SSS == 6)) // MVI M/DCR M/INR M
|| (IGROUP == 3 && DDD == 2 && SSS == 3)) // OUT FRW
wrinm3 = 1'b1;
else wrinm3 = 1'b0;
if (( common1 == 1'b0)
||(IGROUP == 0 && DDD == 6 && SSS == 2)) // STA FRRW
wrinm4 = 1'b1;
else wrinm4 = 1'b0;
if (common1 == 1'b0)
wrinm5 = 1'b1;
else wrinm5 = 1'b0;
end // always @ (...
always @(negedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin
RD1 <= 1'b0;
RD2 <= 1'b0;
WR1 <= 1'b0;
CLKOUT <= 1'b0;
end else begin
if (TSTATES_nx == 2) begin
case (MCYCLE)
1 : begin
RD1 <= 1'b1;
RD2 <= 1'b0;
WR1 <= 1'b0;
end
2 : begin
RD1 <= 1'b0;
if (wrinm2 == 1'b0) RD2 <= 1'b1; else RD2 <= 1'b0;
if (wrinm2 == 1'b1) WR1 <= 1'b1; else WR1 <= 1'b0;
end
3 : begin
RD1 <= 1'b0;
if (wrinm3 == 1'b0) RD2 <= 1'b1; else RD2 <= 1'b0;
if (wrinm3 == 1'b1) WR1 <= 1'b1; else WR1 <= 1'b0;
end
4 : begin
RD1 <= 1'b0;
if ((IGROUP == 0 && DDD == 7 && SSS == 2) // LDA FRRR
|| (IGROUP == 0 && DDD == 5 && SSS == 2)) // LHLD FRRRR
RD2 <= 1'b1;
else
RD2 <= 1'b0;
if (wrinm4 == 1'b1)
WR1 <= 1'b1;
else
WR1 <= 1'b0;
end
5 : begin
RD1 <= 1'b0;
if (IGROUP == 0 && DDD == 5 && SSS == 2) // LHLD FRRRR
RD2 <= 1'b1; else RD2 <= 1'b0;
if (wrinm5 == 1'b1)
WR1 <= 1'b1; else WR1 <= 1'b0;
end
endcase // case (MCYCLE)
end else if (TSTATES_nx == 3) begin
RD1 <= 1'b0;
RD2 <= 1'b0;
WR1 <= 1'b0;
end
CLKOUT <= ~CLKOUT ;
end // else: !if(!RESETINBAR)
end // always @ (negedge X1)
reg RDBAR_pos, WRBAR_pos, RDBAR_neg, WRBAR_neg ;
always @ (posedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin
RDBAR_pos <= 1'b1;
WRBAR_pos <= 1'b1;
end else begin
RDBAR_pos <= BIMCB | INTA | ~(RD1 | RD2);
WRBAR_pos <= ~WR1 | ~DAD_inst;
end
end
always @ (negedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin
RDBAR_neg <= 1'b1;
WRBAR_neg <= 1'b1;
end else begin
RDBAR_neg <= RDBAR_pos;
WRBAR_neg <= WRBAR_pos;
end
end
assign RDBAR = RDBAR_pos & RDBAR_neg;
assign WRBAR = WRBAR_pos & WRBAR_neg;
always @(/*AS*/IGROUP or IRBIT3 or SSS)
if (IGROUP == 0 && SSS == 1 && IRBIT3 == 1'b1) // DAD
DAD_inst = 1'b0;
else
DAD_inst = 1'b1;
always @(/*AS*/DAD_inst or INA or MCYCLE) begin
if (MCYCLE == 1)
if (INA == 1'b1)
BIMCB = 1'b1;
else
BIMCB = 1'b0;
else // MCYCLE /= 1
if (DAD_inst == 1'b0)
BIMCB = 1'b1;
else
BIMCB = 1'b0;
end // always @ (...
always@(posedge X1 or negedge reset_delayed) begin
if (!reset_delayed)
oe <= 0;
else
case (MCYCLE)
1 : oe <= 0;
2 : if (TSTATES_nx == 2) oe <= wrinm2;
3 : if (TSTATES_nx == 2) oe <= wrinm3;
4 : if (TSTATES_nx == 2) oe <= wrinm4;
5 : if (TSTATES_nx == 2) oe <= wrinm5;
endcase // case (MCYCLE)
end // always@ (posedge X1 negedge RESETINBAR)
assign SOD = SOD_FF ;
assign RESETOUT = ~RESETOUTFF;
assign INTABAR = ~(INTA_pos | INTA_neg);
//-----------------------------------------------------------------------
// This next process computes the T-states (minor state) transitions.
//
// The order of the T-states (and their mapping into
// the gate-level state machine) are as follows
// TX, T1, T2, T3, T4, T5, T6, TW, THALT, TH
//
// M1, M2, M3, M4, M5
//-----------------------------------------------------------------------
reg [1:0] reset_sync;
always @(posedge X1 or negedge RESETINBAR)
if (!RESETINBAR)
reset_sync <= 2'b00;
else
reset_sync <= {reset_sync[0], 1'b1};
assign reset_delayed = reset_sync[1];
reg HOLDFF_nx, HLDA_nx;
always @(posedge X1)
if (!reset_delayed) begin
TSTATES <= TRESET;
HOLDFF <= 1'b0;
HLDA <= 1'b0;
end else begin
TSTATES <= TSTATES_nx;
HOLDFF <= HOLDFF_nx;
HLDA <= HLDA_nx;
end
always @(/*AS*/HLDA or HLTAFF or HOLDFF or HOLD_sync or IGROUP or IR
or IRBIT3 or MCYCLE or PRIO_ENCODE or READY or SSS or TSTATES
or WR_MOD or BIMC) begin
TSTATES_nx = TSTATES;
HOLDFF_nx = HOLDFF;
HLDA_nx = HLDA;
CC6 = 1'b0;
case (TSTATES)
TRESET : begin
TSTATES_nx = T1;
end
THOLD : begin
if (HOLD_sync != 1'b1) begin
if (HLTAFF == 1'b0)
TSTATES_nx = T1;
else
TSTATES_nx = THALT;
HOLDFF_nx = 1'b0;
HLDA_nx = 1'b0;
end
end
T1 : if (HLTAFF == 1'b1) TSTATES_nx = THALT; else TSTATES_nx = T2;
T2, TWAIT : begin
if ((SSS == 1) && (IRBIT3 == 1'b1) && (IGROUP == 0) // DAD inst.
&& ((MCYCLE == 2) || (MCYCLE == 3)))
BIMC = 1'b1;
else
BIMC = 1'b0;
if (READY == 1'b1 || BIMC == 1'b1) begin
TSTATES_nx = T3;
if (HOLD_sync == 1'b1)
HOLDFF_nx = 1'b1;
else
HOLDFF_nx = 1'b0;
end else
TSTATES_nx = TWAIT;
end
T3 : begin
if (HOLDFF == 1'b1)
if (WR_MOD == 1'b1)
HLDA_nx = 1'b1; // CK_PERIOD
else
HLDA_nx = 1'b0;
if (MCYCLE == 1)
TSTATES_nx = T4;
else if (HOLDFF == 1'b1)
TSTATES_nx = THOLD;
else
TSTATES_nx = T1;
end
// CC6 denotes those op-codes that require six clock cycles during the M1 machine cycle
T4 : begin
if ((IGROUP == 0 && SSS == 3) // INX/DCX instructions
|| (IGROUP == 3 && ( SSS ==0 || SSS == 4 || SSS == 5 || SSS == 7) )
|| (IR == 8'hE9 || IR == 8'hF9)) begin //PCHL SPHL
CC6 = 1'b1;
TSTATES_nx = T5;
if (HOLD_sync == 1'b1) begin
HOLDFF_nx = 1'b1;
HLDA_nx = 1'b1; // CK_PERIOD
end
end else if (HOLDFF == 1'b1) begin
TSTATES_nx = THOLD;
end else begin
TSTATES_nx = T1;
end
end // case: 4
T5 : TSTATES_nx = T6;
T6 : if (HOLDFF == 1'b1) TSTATES_nx = THOLD; else TSTATES_nx = T1;
THALT :
if (HOLD_sync == 1'b1) begin
TSTATES_nx = THOLD;
HOLDFF_nx = 1'b1;
end else if (PRIO_ENCODE != 7) begin
TSTATES_nx = T1;
end else
TSTATES_nx = THALT;
endcase // case (TSTATES)
end // always @ (...
//------------------------------------------------------
// Interrupt Processing
//------------------------------------------------------
wire TRAP_rise = ~TRAP_delay & TRAP_sync;
wire RST75_rise = ~RST75_delay & RST75_sync;
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed)
TRAPFF <= 0;
else if (clear_trap_ff)
TRAPFF <= 0;
else if (TRAP_rise)
TRAPFF <= 1;
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed)
RST75FF <= 0;
else
if (clear_rst75_ff)
RST75FF <= 0;
else if (RST75_rise)
RST75FF <= 1;
always @(/*AS*/INTEFF or INTR_sync or M55FF or M65FF or M75FF or RST55_sync
or RST65_sync or RST75FF or TRAPFF or TRAP_sync) begin
PIE = 3'b111;
if (TRAP_sync == 1'b1 && TRAPFF == 1'b1)
PIE = 3'b000;
else if (INTEFF == 1'b1)
if (M75FF == 1'b0 && RST75FF == 1'b1) PIE = 3'b001;
else if (M65FF == 1'b0 && RST65_sync == 1'b1) PIE = 3'b010;
else if (M55FF == 1'b0 && RST55_sync == 1'b1) PIE = 3'b011;
else if (INTR_sync == 1'b1) PIE = 3'b100;
end
always@(/*AS*/CC6 or MCYCLE or TSTATES) begin
if ( MCYCLE == 1)
if (CC6 == 1'b1)
if (TSTATES == 6)
clock_gate = 1'b1;
else
clock_gate = 1'b0;
else if (TSTATES == 4)
clock_gate = 1'b1;
else
clock_gate = 1'b0;
else
if (TSTATES == 3)
clock_gate = 1'b1;
else
clock_gate = 1'b0;
end
always @(/*AS*/PIE or PRIO_ENCODE or TSTATES or clock_gate) begin
PRIO_ENCODE_nx = PRIO_ENCODE;
if ((TSTATES == 8 || TSTATES == 9 // THALT or THOLD
|| clock_gate == 1'b1))
PRIO_ENCODE_nx = PIE;
end
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed ) begin
PRIO_ENCODE <= 7;
end else begin
PRIO_ENCODE <= PRIO_ENCODE_nx;
end // else: !if(!RESETINBAR )
always @(/*AS*/PRIO_ENCODE)
if (PRIO_ENCODE == 4) begin
INTA = 1'b1;
INA = ~&PRIO_ENCODE[1:0];
end else begin
INTA = 1'b0;
INA = 1'b0;
end
always @(posedge X1 or negedge reset_delayed)
if (!reset_delayed)
INTA_pos <= 1'b0;
else
if (TSTATES == 1)
INTA_pos <= INTA;
else
INTA_pos <= 1'b0;
always @(negedge X1 or negedge reset_delayed)
if (!reset_delayed) begin
ALE_neg <= 1'b0;
INTA_neg <= 1'b0;
end else begin
INTA_neg <= INTA_pos;
if (TSTATES == 1)
ALE_neg <= ALE_pos;
else
ALE_neg <= 0;
end
assign ALE = ALE_pos & ~ALE_neg;
always @(/*AS*/END_INST_flag or MCYCLE or TSTATES_nx) begin
MCYCLE_nx = MCYCLE;
if (TSTATES_nx == 1 && END_INST_flag == 1'b1)
MCYCLE_nx = 1;
else if (TSTATES_nx == 1)
MCYCLE_nx = MCYCLE + 1;
end
// Synchronize interrupt inputs
always @(posedge X1 or negedge reset_delayed) begin
if (!reset_delayed) begin
HOLD_sync <= 1'b0;
TRAP_sync <= 1'b0;
RST75_sync <= 1'b0;
RST65_sync <= 1'b0;
RST55_sync <= 1'b0;
INTR_sync <= 1'b0;
SID_sync <= 1'b0;
SID_r <= 1'b0;
HOLD_r <= 1'b0;
TRAP_r <= 1'b0;
RST75_r <= 1'b0;
RST65_r <= 1'b0;
RST55_r <= 1'b0;
INTR_r <= 1'b0;
end else begin // if (!RESETINBAR)
HOLD_sync <= HOLD_r;
TRAP_sync <= TRAP_r ;
RST75_sync <= RST75_r;
RST65_sync <= RST65_r;
RST55_sync <= RST55_r;
INTR_sync <= INTR_r;
SID_sync <= SID_r;
SID_r <= SID;
HOLD_r <= HOLD;
TRAP_r <= TRAP;
RST75_r <= RST75;
RST65_r <= RST65;
RST55_r <= RST55;
INTR_r <= INTR ;
end // else: !if(!RESETINBAR)
end // always @ (posedge X1 or negedge RESETINBAR)
always @(posedge X1) begin
RST75_delay <= RST75_sync;
TRAP_delay <= TRAP_sync;
end
endmodule // I8085
module ram85a(ale, ad, a, write, read, iomout);
reg [8:1] dflags;
initial dflags = 'b00000000;
// diag flags:
// 1 = trace read and writes
// 2 = dump ram after loading
inout[7:0] ad;
input[7:0] a;
input ale, write, read, iomout;
reg[7:0] ad_reg;
tri[7:0] ad = (read || iomout) ? 'bz : ad_reg;
parameter ramsize = 1<<16; //'h7A;
reg[7:0] ram[ramsize-1:0];
reg[15:0] address;
always @(negedge ale) begin
address = {a, ad};
if(dflags[1])
$display("Reading %h into ram address", address);
end
always @(negedge read) begin
if(dflags[1])
$display("Reading %h = ram[%h]", ram[address], address);
ad_reg = ram[address];
end
always @(negedge write) begin
if(!dflags[1])
$display("Writing ram[%h] = %h", address, ad);
ram[address] = ad;
end
reg [12*8:1] filename;
//define contents of RAM
initial begin
if ($value$plusargs("TESTNAME=%s", filename)) begin
$display("Loading memory from %s file",filename);
$readmemh(filename,ram);
end else
$readmemh("testmem0.dat",ram);
if(dflags[2])
printmem;
end
//print out the contents of the RAM
task printmem;
integer i;
reg[7:0] data;
begin
$write("dump of ram");
for(i = 0; i < ramsize; i = i + 1)
begin
data = ram[i];
if((i % 4) == 0) $write(" ");
if((i % 16) == 0) $write("\n%h: ", i);
$write("%h", data);
$write(" ");
end
$write("\n\n");
end
endtask
endmodule
module test();
reg clk;
reg reset_n;
wire [7:0] addr;
wire ale, write, read, iomout, CLOCK;
wire [7:0] ad;
reg trap, intr, rst75, rst65, rst55;
wire inta_n;
I8085 I8085 (.X1 (clk),
.RESETOUT (),
.SOD (),
.SID (1'b0),
.TRAP (trap),
.RST75 (rst75),
.RST65 (rst65),
.RST55 (rst55),
.INTR (intr),
.INTABAR (inta_n),
.ADDR (addr),
.S0 (),
.S1 (),
.ALE (ale),
.WRBAR (write),
.RDBAR (read),
.IOMBAR (iomout),
.READY (1'b1),
.RESETINBAR (reset_n),
.CLKOUT (CLOCK),
.HLDA (),
.HOLD (1'b0),
.AD (ad));
ram85a ram85a (.ale (ale),
.ad (ad),
.a (addr) ,
.write (write),
.read (read),
.iomout (iomout));
initial begin
clk = 0;
reset_n = 0;
intr = 0;
trap = 0;
rst75 = 0;
rst65 = 0;
rst55 = 0;
#1033 reset_n = 1;
//#400 intr = 1'b1;
//@(negedge inta_n) intr = 1'b0;
#413 rst75 = 1;
#15 rst75 = 0;
end
always #500 clk = ~clk;
assign ad = (inta_n) ? 'bz : 8'h18;
endmodule // test
00 // NOP
FB // EI
3E // MVI A,8
08 //
30 // SIM
31 // LXI SP
00 //
80 //
01 // LXI B,data16
12 //
34 //
02 // STAX B
03 // INX B
04 // INR B
05 // DCR B
06 // MVI B,data
55 //
3E // MVI A, AA
AA //
07 // RLC
21 // LXI H,data16
11 //
22 //
09 // DAD B
0A // LDAX B
0B // DCX B
0C // INR C
0D // DCR C
0E // MVI C,data
44 //
0F // RRC
11 // LXI D,data16
66 //
77 //
12 // STAX D
13 // INX D
14 // INR D
15 // DCR D
16 // MVI D,data
88 //
17 // RAL
19 // DAD D
1A // LDAX D
1B // DCX D
1C // INR E
1D // DCR E
1E // MVI E,data
33 //
1F // RAR
21 // LXI H,data16
CC //
DD //
22 // SHLD addr
00
10
23 // INX H
24 // INR H
25 // DCR H
26 // MVI H,data
EE //
27 // DAA
29 // DAD H
2A // LHLD data16
20 //
10 //
2B // DCX H
2C // INR L
2D // DCR L
2E // MVI L,data
43 //
2F // CMA
30 // SIM
31 // LXI SP,data16
00 //
80 //
32 // STA data
00 //
10 //
33 // INX SP
34 // INR M
35 // DCR M
36 // MVI M,data
66 //
37 // STC
39 // DAD SP
3A // LDA data
11 //
22 //
3B // DCX SP
3C // INR A
3D // DCR A
3E // MVI A,data
99 //
3F // CMC
40 // MOV B,B
41 // MOV B,C
42 // MOV B,D
43 // MOV B,E
44 // MOV B,H
45 // MOV B,L
46 // MOV B,M
47 // MOV B,A
48 // MOV C,B
49 // MOV C,C
4A // MOV C,D
4B // MOV C,E
4C // MOV C,H
4D // MOV C,L
4E // MOV C,M
4F // MOV C,A
50 // MOV D,B
51 // MOV D,C
52 // MOV D,D
53 // MOV D,E
54 // MOV D,H
55 // MOV D,L
56 // MOV D,M
57 // MOV D,A
58 // MOV E,B
59 // MOV E,C
5A // MOV E,D
5B // MOV E,E
5C // MOV E,H
5D // MOV E,L
5E // MOV E,M
5F // MOV E,A
60 // MOV H,B
61 // MOV H,C
62 // MOV H,D
63 // MOV H,E
64 // MOV H,H
65 // MOV H,L
66 // MOV H,M
67 // MOV H,A
68 // MOV L,B
69 // MOV L,C
6A // MOV L,D
6B // MOV L,E
6C // MOV L,H
6D // MOV L,L
6E // MOV L,M
6F // MOV L,A
70 // MOV M,B
71 // MOV M,C
72 // MOV M,D
73 // MOV M,E
74 // MOV M,H
75 // MOV M,L
76 // HLT
@5513 77
@8867 CA
@1020 AB CD
@CD43 99
@2211 33
@4d44 00
@4444 ab
@9999 cd
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?