📄 8080 cpu .v
字号:
statesel <= `mac_writedbyte; // finish RST
state <= `cpus_write; // write to stack
end
6'b111011: begin // EI
eienb <= 1'b1; // set delayed interrupt enable
state <= `cpus_fetchi; // Fetch next instruction
pc <= pc+16'h1; // Next instruction byte
end
6'b110011: begin // DI
ei <= 1'b0;
state <= `cpus_fetchi; // Fetch next instruction
pc <= pc+16'h1; // Next instruction byte
end
6'b011011: begin // IN p
`ifndef NOIO
// perform input
raddrhold <= pc+1; // pick up byte I/O address
statesel <= `mac_in; // finish IN
state <= `cpus_read;
pc <= pc+16'h2; // advance over byte
`else
// ignore instruction
state <= `cpus_fetchi; // fetch next instruction
pc <= pc+16'h1; // Next instruction byte
`endif
end
6'b010011: begin // OUT p
`ifndef NOIO
// perform output
raddrhold <= pc+1; // pick up byte I/O address
statesel <= `mac_out; // finish OUT
state <= `cpus_read;
pc <= pc+16'h2; // advance over byte
`else
// ignore instruction
state <= `cpus_fetchi; // fetch next instruction
pc <= pc+16'h1; // Next instruction byte
`endif
end
// the illegal opcodes behave as NOPs
6'b001011, 6'b011001, 6'b011101, 6'b101101,
6'b111101: begin
state <= `cpus_fetchi; // fetch next instruction
pc <= pc+16'h1; // Next instruction byte
end
endcase
end
endcase
end
// Follow states. These state handlers implement the following cycles past
// M1, or primary fetch state.
//
// single byte write, writes wdatahold to the waddrhold address
//
`cpus_write: begin
addr <= waddrhold; // place address on output
waddrhold <= waddrhold + 1'b1; // next address
datao <= wdatahold; // set data to output
wdatahold <= wdatahold2; // next data
dataeno <= 1; // enable output data
state <= `cpus_write2; // next state
end
`cpus_write2: begin // continue write #2
writemem <= 1; // enable write memory data
state <= `cpus_write3; // idle one cycle for write
end
`cpus_write3: begin // continue write #3
`ifndef NOWAIT
if (!waitr)
`endif
begin // no wait selected, otherwise cycle
writemem <= 0; // disable write memory data
state <= `cpus_write4; // idle hold time
end
end
`cpus_write4: begin // continue write #4
dataeno <= 0; // disable output data
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
//
// single byte read, reads rdatahold from the raddrhold address
//
`cpus_read: begin
addr <= raddrhold; // place address on output
raddrhold <= raddrhold + 16'h1; // next address
if (intcyc) inta <= 1; // activate interrupt acknowledge
else readmem <= 1; // activate memory read
state <= `cpus_read2; // next state
end
`cpus_read2: begin // continue read #2
// wait one cycle
state <= `cpus_read3; // next state
end
`cpus_read3: begin // continue read #3
`ifndef NOWAIT
if (!waitr)
`endif
begin // no wait selected, otherwise cycle
rdatahold2 <= rdatahold; // shift data
rdatahold <= data; // read new data
readmem <= 0; // deactivate instruction memory read
inta <= 0; // deactivate interrupt acknowledge
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
end
`cpus_pop: begin // finish POP instruction
case (popdes) // register set
2'b00: { regfil[`reg_b], regfil[`reg_c] } <=
{ rdatahold, rdatahold2 };
2'b01: { regfil[`reg_d], regfil[`reg_e] } <=
{ rdatahold, rdatahold2 };
2'b10: { regfil[`reg_h], regfil[`reg_l] } <=
{ rdatahold, rdatahold2 };
2'b11: begin
regfil[`reg_a] <= rdatahold;
sign <= ((rdatahold2 >> 7)& 1'b1) ? 1'b1:1'b0;
zero <= ((rdatahold2 >> 6)& 1'b1) ? 1'b1:1'b0;
auxcar <= ((rdatahold2 >> 4)& 1'b1) ? 1'b1:1'b0;
parity <= ((rdatahold2 >> 2)& 1'b1) ? 1'b1:1'b0;
carry <= ((rdatahold2 >> 0)& 1'b1) ? 1'b1:1'b0;
end
endcase
state <= `cpus_fetchi; // Fetch next instruction
end
`cpus_jmp: begin // jump address
state <= `cpus_fetchi; // and return to instruction fetch
pc <= { rdatahold, rdatahold2 };
end
`cpus_call: begin // call address
sp <= sp-16'h2; // pushdown stack
state <= `cpus_fetchi; // and return to instruction fetch
pc <= { rdatahold, rdatahold2 };
end
`cpus_ret: begin // return from call
sp <= sp+16'h2; // pushup stack
state <= `cpus_fetchi; // and return to instruction fetch
pc <= { rdatahold, rdatahold2 };
end
`ifndef NOIO // if I/O instructions are to be included
`cpus_in: begin // input single byte to A
addr <= rdatahold; // place I/O address on address lines
readio <= 1; // set read I/O
state <= `cpus_in2; // continue
end
`cpus_in2: begin // input single byte to A #2
// wait one cycle
state <= `cpus_in3; // continue
end
`cpus_in3: begin // input single byte to A #3
`ifndef NOWAIT
if (!waitr)
`endif
begin // no wait selected, otherwise cycle
regfil[`reg_a] <= data; // place input data
readio <= 0; // clear read I/O
state <= `cpus_fetchi; // Fetch next instruction
end
end
`cpus_out: begin // output single byte from A
addr <= rdatahold; // place address on output
datao <= regfil[`reg_a]; // set data to output
dataeno <= 1; // enable output data
state <= `cpus_out2; // next state
end
`cpus_out2: begin // continue out #2
writeio <= 1; // enable write I/O data
state <= `cpus_out3; // idle one cycle for write
end
`cpus_out3: begin // continue out #3
`ifndef NOWAIT
if (!waitr)
`endif
begin // no wait selected, otherwise cycle
writeio <= 0; // disable write I/O data
state <= `cpus_out4; // idle hold time
end
end
`cpus_out4: begin // continue write #4
dataeno <= 0; // disable output data
state <= `cpus_fetchi; // Fetch next instruction
end
`endif
`cpus_halt: begin // Halt waiting for interrupt
// If there is an interrupt request and interrupts are enabled, then we
// can leave halt. Otherwise we stay here.
if (intr&&ei) state <= `cpus_fetchi; // Fetch next instruction
else state <= `cpus_halt;
end
`cpus_movtr: begin // move to register
regfil[regd] <= rdatahold; // place data
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
`cpus_movtalua: begin // move to alu a
aluopra <= rdatahold; // place data
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
`cpus_movtalub: begin // move to alu b
aluoprb <= rdatahold; // place data
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
`cpus_alucb: begin // alu cycleback
regfil[`reg_a] <= alures; // place alu result back to A
carry <= alucout; // place carry
sign <= alusout; // place sign
zero <= aluzout; // place zero
parity <= alupar; // place parity
auxcar <= aluaxc; // place auxiliary carry
state <= `cpus_fetchi; // and return to instruction fetch
end
`cpus_indcb: begin // inr/dcr cycleback
regfil[regd] <= alures; // place alu result back to source/dest
sign <= alures[7]; // place sign
zero <= aluzout; // place zero
parity <= alupar; // place parity
auxcar <= aluaxc; // place auxiliary carry
state <= `cpus_fetchi; // and return to instruction fetch
end
`cpus_indm: begin // inr/dcr cycleback to m
waddrhold <= regfil[`reg_h]<<8|regfil[`reg_l]; // place address
wdatahold <= alures; // place data to write
sign <= alures[7]; // place sign
zero <= aluzout; // place zero
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -