📄 8080 cpu .v
字号:
wdatahold <= regfil[`reg_a]; // set write data
raddrhold <= pc+16'h1; // set read address
statesel <= `mac_sta; // perform sta
state <= `cpus_read;
pc <= pc + 16'h3; // next
end
6'b111010: begin // LDA
raddrhold <= pc+16'h1; // set read address
regd <= `reg_a; // set destination
statesel <= `mac_lda; // perform lda
state <= `cpus_read;
pc <= pc+16'h3; // next
end
6'b100010: begin // SHLD
wdatahold <= regfil[`reg_l]; // set write data
wdatahold2 <= regfil[`reg_h];
raddrhold <= pc+16'h1; // set read address
statesel <= `mac_shld; // perform SHLD
state <= `cpus_read;
pc <= pc+16'h3; // skip
end
6'b101010: begin // LHLD
raddrhold <= pc+16'h1; // set read address
statesel <= `mac_lhld; // perform LHLD
state <= `cpus_read;
pc <= pc+16'h3; // skip
end
// the illegal opcodes behave as NOPs
6'b001000, 6'b010000, 6'b011000, 6'b100000, 6'b101000,
6'b110000, 6'b110000: begin
state <= `cpus_fetchi; // fetch next instruction
pc <= pc+16'h1; // Next instruction byte
end
endcase
end
2'b01: begin // 01: MOV instruction
// Check its the halt instruction, which occupies the invalid
// "MOV M,M" instruction.
if (opcode == 8'b01110110) state <= `cpus_halt;
// Otherwise, the 01 prefix is single instruction format.
else begin
// Format 01DDDSSS
// Check memory source, use state if so
if (opcode[2:0] == `reg_m) begin
// place hl as address
raddrhold <= regfil[`reg_h]<<8|regfil[`reg_l];
regd <= opcode[5:3]; // set destination
statesel <= `mac_readbtoreg; // read byte to register
state <= `cpus_read;
// Check memory destination, use state if so
end else if (opcode[5:3] == `reg_m) begin
// place hl as address
waddrhold <= regfil[`reg_h]<<8|regfil[`reg_l];
wdatahold <= regfil[opcode[2:0]]; // place data to write
statesel <= `mac_writebyte; // write byte
state <= `cpus_write;
// otherwise simple register to register
end else begin
regfil[opcode[5:3]] <= regfil[opcode[2:0]];
state <= `cpus_fetchi; // Fetch next instruction
end
end
pc <= pc+16'h1; // Next instruction byte
end
2'b10: begin // 10: Reg or mem to accumulator ops
// 10 prefix is single instruction format
aluopra <= regfil[`reg_a]; // load as alu a
aluoprb <= regfil[opcode[2:0]]; // load as alu b
alusel <= opcode[5:3]; // set alu operation from instruction
alucin <= carry; // input carry
if (opcode[2:0] == `reg_m) begin
// set read address
raddrhold <= regfil[`reg_h]<<8|regfil[`reg_l];
statesel <= `mac_alum; // alu from m
state <= `cpus_read; // read byte
end else
state <= `cpus_alucb; // go to alu cycleback
pc <= pc+16'h1; // Next instruction byte
end
2'b11: begin // 11: jmp/call and others
case (opcode[5:0]) // decode these instructions
6'b000101, 6'b010101, 6'b100101, 6'b110101: begin // PUSH
waddrhold <= sp-16'h2; // write to stack
sp <= sp-16'h2; // pushdown stack
case (opcode[5:4]) // register set
2'b00: { wdatahold2, wdatahold } <=
{ regfil[`reg_b], regfil[`reg_c] };
2'b01: { wdatahold2, wdatahold } <=
{ regfil[`reg_d], regfil[`reg_e] };
2'b10: { wdatahold2, wdatahold } <=
{ regfil[`reg_h], regfil[`reg_l] };
2'b11: { wdatahold2, wdatahold } <=
{ regfil[`reg_a], sign, zero, 1'b0, auxcar,
1'b0, parity, 1'b1, carry };
endcase
statesel <= `mac_writedbyte; // write double byte
state <= `cpus_write;
pc <= pc+16'h1; // Next instruction byte
end
6'b000001, 6'b010001, 6'b100001, 6'b110001: begin // POP
popdes <= opcode[5:4]; // set destination
raddrhold <= sp; // read from stack
sp <= sp+16'h2; // pushup stack
statesel <= `mac_pop; // perform POP
state <= `cpus_read;
pc <= pc+16'h1; // Next instruction byte
end
6'b101011: begin // XCHG
regfil[`reg_d] <= regfil[`reg_h];
regfil[`reg_e] <= regfil[`reg_l];
regfil[`reg_h] <= regfil[`reg_d];
regfil[`reg_l] <= regfil[`reg_e];
state <= `cpus_fetchi; // Fetch next instruction
pc <= pc+16'h1; // Next instruction byte
end
6'b100011: begin // XTHL
raddrhold <= sp; // address SP for read
waddrhold <= sp; // address SP for write
wdatahold <= regfil[`reg_l]; // set data is HL
wdatahold2 <= regfil[`reg_h];
statesel <= `mac_xthl; // perform XTHL
state <= `cpus_read;
pc <= pc+16'h1; // Next instruction byte
end
6'b111001: begin // SPHL
sp <= { regfil[`reg_h], regfil[`reg_l] };
state <= `cpus_fetchi; // Fetch next instruction
pc <= pc+16'h1; // Next instruction byte
end
6'b000110, 6'b001110, 6'b010110, 6'b011110, 6'b100110,
6'b101110, 6'b110110,
6'b111110: begin // immediate arithmetic to accumulator
aluopra <= regfil[`reg_a]; // load as alu a
alusel <= opcode[5:3]; // set alu operation from instruction
alucin <= carry; // input carry
raddrhold <= pc+16'h1; // read at PC
statesel <= `mac_accimm; // finish accumulator immediate
state <= `cpus_read;
pc <= pc+16'h2; // skip immediate byte
end
6'b101001: begin // PCHL
state <= `cpus_fetchi; // Fetch next instruction
pc <= { regfil[`reg_h], regfil[`reg_l] };
end
6'b000011: begin // JMP
raddrhold <= pc+16'h1; // pick up jump address
statesel <= `mac_jmp; // finish JMP
state <= `cpus_read;
end
6'b000010, 6'b001010, 6'b010010, 6'b011010, 6'b100010,
6'b101010, 6'b110010, 6'b111010: begin // Jcc
raddrhold <= pc+16'h1; // pick up jump address
statesel <= `mac_jmp; // finish JMP
// choose continue or read according to condition
case (opcode[5:3]) // decode flag cases
3'b000: if (zero) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b001: if (!zero) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b010: if (carry) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b011: if (!carry) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b100: if (parity) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b101: if (!parity) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b110: if (sign) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b111: if (!sign) state <= `cpus_fetchi;
else state <= `cpus_read;
endcase
pc <= pc+16'h3; // advance after jump for false
end
6'b001101: begin // CALL
raddrhold <= pc+16'h1; // pick up call address
waddrhold <= sp-16'h2; // place address on stack
// if interrupt cycle, use current pc, else use address
// after call
if (intcyc) { wdatahold2, wdatahold } <= pc;
else { wdatahold2, wdatahold } <= pc+16'h3;
statesel <= `mac_call; // finish CALL
state <= `cpus_read;
end
6'b000100, 6'b001100, 6'b010100, 6'b011100, 6'b100100,
6'b101100, 6'b110100, 6'b111100: begin // Ccc
raddrhold <= pc+16'h1; // pick up call address
waddrhold <= sp-16'h2; // place address on stack
// of address after call
{ wdatahold2, wdatahold } <= pc + 16'h3;
statesel <= `mac_call; // finish CALL
// choose continue or read according to condition
case (opcode[5:3]) // decode flag cases
3'b000: if (zero) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b001: if (!zero) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b010: if (carry) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b011: if (!carry) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b100: if (parity) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b101: if (!parity) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b110: if (sign) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b111: if (!sign) state <= `cpus_fetchi;
else state <= `cpus_read;
endcase
pc <= pc+16'h3; // advance after jump for false
end
6'b001001: begin // RET
raddrhold <= sp; // read from stack
statesel <= `mac_ret; // finish RET
state <= `cpus_read;
end
6'b000000, 6'b001000, 6'b010000, 6'b011000, 6'b100000,
6'b101000, 6'b110000, 6'b111000: begin // Rcc
raddrhold <= sp; // read from stack
statesel <= `mac_ret; // finish JMP
// choose read or continue according to condition
case (opcode[5:3]) // decode flag cases
3'b000: if (zero) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b001: if (!zero) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b010: if (carry) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b011: if (!carry) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b100: if (parity) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b101: if (!parity) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b110: if (sign) state <= `cpus_fetchi;
else state <= `cpus_read;
3'b111: if (!sign) state <= `cpus_fetchi;
else state <= `cpus_read;
endcase
pc <= pc+16'h1; // Next instruction byte
end
6'b000111, 6'b001111, 6'b010111, 6'b011111, 6'b100111,
6'b101111, 6'b110111, 6'b111111: begin // RST
pc <= opcode & 8'b00111000; // place restart value in PC
waddrhold <= sp-16'h2; // place address on stack
// if interrupt cycle, use current pc, else use address
// after call
if (intcyc) { wdatahold2, wdatahold } <= pc;
else { wdatahold2, wdatahold } <= pc+16'h3;
{ wdatahold2, wdatahold } <= pc+16'h1; // of address after call
sp <= sp-16'h2; // pushdown stack CNS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -