📄 8080 cpu .v
字号:
parity <= alupar; // place parity
auxcar <= aluaxc; // place auxiliary carry
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
`cpus_movmtbc: begin // finish LXI B
regfil[`reg_b] <= rdatahold; // place upper
regfil[`reg_c] <= rdatahold2; // place lower
state <= `cpus_fetchi; // and return to instruction fetch
end
`cpus_movmtde: begin // finish LXI D
regfil[`reg_d] <= rdatahold; // place upper
regfil[`reg_e] <= rdatahold2; // place lower
state <= `cpus_fetchi; // and return to instruction fetch
end
`cpus_movmthl: begin // finish LXI H
regfil[`reg_h] <= rdatahold; // place upper
regfil[`reg_l] <= rdatahold2; // place lower
state <= `cpus_fetchi; // and return to instruction fetch
end
`cpus_movmtsp: begin // finish LXI SP
sp <= { rdatahold, rdatahold2 }; // place
state <= `cpus_fetchi; // and return to instruction fetch
end
`cpus_movrtw: begin // move read to write
wdatahold <= rdatahold; // move read to write data
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
`cpus_movrtwa: begin // move read data to write address
waddrhold <= { rdatahold, rdatahold2 };
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
`cpus_movrtra: begin // move read data to read address
raddrhold <= { rdatahold, rdatahold2 };
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro
end
`cpus_lhld: begin // load HL from read data
regfil[`reg_l] <= rdatahold2; // low
regfil[`reg_h] <= rdatahold; // high
state <= nextstate; // get next macro state
statesel <= statesel+6'b1; // and index next in macro CNS
end
`cpus_accimm: begin
aluoprb <= rdatahold; // load as alu b
state <= `cpus_alucb; // go to alu cycleback
end
`cpus_daa: begin
if (regfil[`reg_a][7:4] > 9 || carry)
{ carry, regfil[`reg_a] } <= regfil[`reg_a]+8'h60;
state <= `cpus_fetchi; // and return to instruction fetch
end
default: state <= 5'bx;
endcase
// Enable drive for data output
assign data = dataeno ? datao: 8'bz;
//
// State macro generator
//
// This ROM contains series of state execution lists that perform various
// tasks, usually involving reads or writes.
//
always @(statesel) case (statesel)
// mac_writebyte: write a byte
1: nextstate = `cpus_fetchi; // fetch next instruction
// mac_readbtoreg: read a byte, place in register
2: nextstate = `cpus_movtr; // move to register
3: nextstate = `cpus_fetchi; // Fetch next instruction
// mac_readdtobc: read double byte to BC
4: nextstate = `cpus_read; // get high byte
5: nextstate = `cpus_movmtbc; // place in BC
// mac_readdtode: read double byte to DE
6: nextstate = `cpus_read; // get high byte
7: nextstate = `cpus_movmtde; // place in DE
// mac_readdtohl: read double byte to HL
8: nextstate = `cpus_read; // get high byte
9: nextstate = `cpus_movmthl; // place in HL
// mac_readdtosp: read double byte to SP
10: nextstate = `cpus_read; // get high byte
11: nextstate = `cpus_movmtsp; // place in SP
// mac_readbmtw: read byte and move to write
12: nextstate = `cpus_movrtw; // move read to write
13: nextstate = `cpus_write; // write to destination
14: nextstate = `cpus_fetchi; // Fetch next instruction
// mac_readbmtr: read byte and move to register
15: nextstate = `cpus_movtr; // place in register
16: nextstate = `cpus_fetchi; // Fetch next instruction
// mac_sta: STA
17: nextstate = `cpus_read; // read high byte
18: nextstate = `cpus_movrtwa; // move read to write address
19: nextstate = `cpus_write; // write to destination
20: nextstate = `cpus_fetchi; // Fetch next instruction
// mac_lda: LDA
21: nextstate = `cpus_read; // read high byte
22: nextstate = `cpus_movrtra; // move read to write address
23: nextstate = `cpus_read; // read byte
24: nextstate = `cpus_movtr; // move to register
25: nextstate = `cpus_fetchi; // Fetch next instruction
// mac_shld: SHLD
26: nextstate = `cpus_read; // read high byte
27: nextstate = `cpus_movrtwa; // move read to write address
28: nextstate = `cpus_write; // write to destination low
29: nextstate = `cpus_write; // write to destination high
30: nextstate = `cpus_fetchi; // Fetch next instruction
// mac_lhld: LHLD
31: nextstate = `cpus_read; // read high byte
32: nextstate = `cpus_movrtra; // move read to write address
33: nextstate = `cpus_read; // read byte low
34: nextstate = `cpus_read; // read byte high
35: nextstate = `cpus_lhld; // move to register
36: nextstate = `cpus_fetchi; // Fetch next instruction
// mac_writedbyte: write double byte
37: nextstate = `cpus_write; // double write
38: nextstate = `cpus_fetchi; // then fetch
// mac_pop: POP
39: nextstate = `cpus_read; // double it
40: nextstate = `cpus_pop; // then finish
// mac_xthl: XTHL
41: nextstate = `cpus_read; // double it
42: nextstate = `cpus_write; // then write
43: nextstate = `cpus_write; // double it
44: nextstate = `cpus_movmthl; // place word in hl
// mac_accimm: accumulator immediate
45: nextstate = `cpus_accimm; // finish
// mac_jmp: JMP
46: nextstate = `cpus_read; // double read
47: nextstate = `cpus_jmp; // then go pc
// mac_call: CALL
48: nextstate = `cpus_read; // double read
49: nextstate = `cpus_write; // then write
50: nextstate = `cpus_write; // double write
51: nextstate = `cpus_call; // then go to that
// mac_in: IN
52: nextstate = `cpus_in; // go to IN after getting that
// mac_out: OUT
53: nextstate = `cpus_out; // go to OUT after getting that
// mac_rst: RST
54: nextstate = `cpus_write; // double write
55: nextstate = `cpus_jmp; // then go to that
// mac_ret: RET
56: nextstate = `cpus_read; // double read
57: nextstate = `cpus_ret; // then go to that
// mac_alum: op a,m
58: nextstate = `cpus_movtalub; // go move to alu a
59: nextstate = `cpus_alucb; // cycle back to acc
// mac_idm: inc/dec m
60: nextstate = `cpus_movtalua; // go move to alu b
61: nextstate = `cpus_indm; // set up alu result
62: nextstate = `cpus_write; // write it
63: nextstate = `cpus_fetchi; // Fetch next instruction
default nextstate = 6'bx; // other states never reached
endcase
endmodule
//
// Alu module
//
// Finds arithmetic operations needed. Latches on the positive edge of the
// clock. There are 8 different types of operations, which come from bits
// 3-5 of the instruction.
//
module alu(res, opra, oprb, cin, cout, zout, sout, parity, auxcar, sel);
input [7:0] opra; // Input A
input [7:0] oprb; // Input B
input cin; // Carry in
output cout; // Carry out
output zout; // Zero out
output sout; // Sign out
output parity; // parity
output auxcar; // auxiliary carry
input [2:0] sel; // Operation select
output [7:0] res; // Result of alu operation
reg cout; // Carry out
reg zout; // Zero out
reg sout; // sign out
reg parity; // parity
reg auxcar; // auxiliary carry
reg [7:0] resi; // Result of alu operation intermediate
reg [7:0] res; // Result of alu operation
always @(opra, oprb, cin, sel, res, resi) begin
case (sel)
`aluop_add: begin // add
{ cout, resi } = opra+oprb; // find result and carry
// find auxiliary carry
auxcar = (((opra[3:0]+oprb[3:0]) >> 4) & 8'b1) ? 1'b1 : 1'b0;
end
`aluop_adc: begin // adc
{ cout, resi } = opra+oprb+cin; // find result and carry
// find auxiliary carry
auxcar = (((opra[3:0]+oprb[3:0]+cin) >> 4) & 8'b1) ? 1'b1 : 1'b0;
end
`aluop_sub, `aluop_cmp: begin // sub/cmp
{ cout, resi } = opra-oprb; // find result and carry
// find auxiliary borrow
auxcar = (((opra[3:0]-oprb[3:0]) >> 4) & 8'b1) ? 1'b1 : 1'b0;
end
`aluop_sbb: begin // sbb
{ cout, resi } = opra-oprb-cin; // find result and carry
// find auxiliary borrow
auxcar = (((opra[3:0]-oprb[3:0]-cin >> 4)) & 8'b1) ? 1'b1 : 1'b0;
end
`aluop_and: begin // ana
{ cout, resi } = {1'b0, opra&oprb}; // find result and carry
auxcar = 1'b0; // clear auxillary carry
end
`aluop_xor: begin // xra
{ cout, resi } = {1'b0, opra^oprb}; // find result and carry
auxcar = 1'b0; // clear auxillary carry
end
`aluop_or: begin // ora
{ cout, resi } = {1'b0, opra|oprb}; // find result and carry
auxcar = 1'b0; // clear auxillary carry
end
endcase
if (sel != `aluop_cmp) res = resi; else res = opra;
zout <= ~|resi; // set zero flag from result
sout <= resi[7]; // set sign flag from result
parity <= ~^resi; // set parity flag from result
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -