URL
https://opencores.org/ocsvn/wb_z80/wb_z80/trunk
Subversion Repositories wb_z80
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 25 to Rev 26
- ↔ Reverse comparison
Rev 25 → Rev 26
/trunk/asm/BJS80TST.ASM
60,7 → 60,7
fail: db 'failed' |
pass: db 'passed' |
message_addr: equ #be58 |
in_port: equ #ff |
in_port: equ #10 |
out_port: equ #10 |
; |
data_55: equ #55 |
/trunk/rtl/z80_core_top.v
37,10 → 37,10
/////////////////////////////////////////////////////////////////////////////////////////////// |
// CVS Log |
// |
// $Id: z80_core_top.v,v 1.4 2004-05-18 22:31:21 bporcella Exp $ |
// $Id: z80_core_top.v,v 1.5 2004-05-21 02:51:25 bporcella Exp $ |
// |
// $Date: 2004-05-18 22:31:21 $ |
// $Revision: 1.4 $ |
// $Date: 2004-05-21 02:51:25 $ |
// $Revision: 1.5 $ |
// $Author: bporcella $ |
// $Locker: $ |
// $State: Exp $ |
47,6 → 47,9
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2004/05/18 22:31:21 bporcella |
// instruction test getting to final stages |
// |
// Revision 1.3 2004/05/13 14:58:53 bporcella |
// testbed built and verification in progress |
// |
123,7 → 126,8
wire [7:0] ar, fr, br, cr, dr, er, hr, lr, intr; |
wire [15:0] ixr, iyr; |
wire [7:0] wb_dat_i, wb_dat_o, sdram_do, cfg_do; |
wire [15:0] add16; // ir2 execution engine output for sp updates |
wire [15:0] add16; // ir2 execution engine output for sp updates |
wire [15:0] adr_alu; // address alu to inst to update hl and de on block moves |
wire [7:0] alu8_out, sh_alu, bit_alu; |
|
|
148,7 → 152,9
|
z80_memstate2 i_z80_memstate2( |
.wb_adr_o(wb_adr_o), .wb_we_o(wb_we_o), .wb_cyc_o(wb_cyc_o), .wb_stb_o(wb_stb_o), .wb_tga_o(wb_tga_o), .wb_dat_o(wb_dat_o), |
.exec_ir2(exec_ir2), .ir1(ir1), .ir2(ir2), .ir1dd(ir1dd), .ir1fd(ir1fd), .ir2dd(ir2dd), .ir2fd(ir2fd), .nn(nn), .sp(sp), |
.exec_ir2(exec_ir2), |
.exec_decbc(exec_decbc), .exec_decb(exec_decb), |
.ir1(ir1), .ir2(ir2), .ir1dd(ir1dd), .ir1fd(ir1fd), .ir2dd(ir2dd), .ir2fd(ir2fd), .nn(nn), .sp(sp), |
.upd_ar(upd_ar), .upd_br(upd_br), .upd_cr(upd_cr), .upd_dr(upd_dr), .upd_er(upd_er), .upd_hr(upd_hr), .upd_lr(upd_lr),.upd_fr(upd_fr), |
.beq0(br_eq0), .ceq0(cr_eq0), |
.ar(ar), .fr(fr), .br(br), .cr(cr), .dr(dr), .er(er), .hr(hr), .lr(lr), |
157,6 → 163,9
.int_req_i(int_req_i), |
.add16(add16), |
.alu8_out(alu8_out), |
.adr_alu(adr_alu), |
.blk_mv_upd_hl(blk_mv_upd_hl), |
.blk_mv_upd_de(blk_mv_upd_de), |
.sh_alu(sh_alu), |
.bit_alu(bit_alu), |
.wb_clk_i(wb_clk_i), |
170,6 → 179,9
.upd_ar(upd_ar), .upd_br(upd_br), .upd_cr(upd_cr), .upd_dr(upd_dr), .upd_er(upd_er), .upd_hr(upd_hr), .upd_lr(upd_lr),.upd_fr(upd_fr), |
.ar(ar), .fr(fr), .br(br), .cr(cr), .dr(dr), .er(er), .hr(hr), .lr(lr), .intr(intr), |
.ixr(ixr), .iyr(iyr), .add16(add16), .alu8_out(alu8_out), |
.adr_alu(adr_alu), |
.blk_mv_upd_hl(blk_mv_upd_hl), |
.blk_mv_upd_de(blk_mv_upd_de), |
.sh_alu(sh_alu), |
.bit_alu(bit_alu), |
.exec_ir2(exec_ir2), |
/trunk/rtl/z80_testbed.v
38,10 → 38,10
/////////////////////////////////////////////////////////////////////////////////////////////////// |
// CVS Log |
// |
// $Id: z80_testbed.v,v 1.2 2004-05-18 22:31:21 bporcella Exp $ |
// $Id: z80_testbed.v,v 1.3 2004-05-21 02:51:25 bporcella Exp $ |
// |
// $Date: 2004-05-18 22:31:21 $ |
// $Revision: 1.2 $ |
// $Date: 2004-05-21 02:51:25 $ |
// $Revision: 1.3 $ |
// $Author: bporcella $ |
// $Locker: $ |
// $State: Exp $ |
48,6 → 48,9
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2004/05/18 22:31:21 bporcella |
// instruction test getting to final stages |
// |
// Revision 1.1 2004/05/13 14:57:35 bporcella |
// testbed files |
// |
83,7 → 86,7
.wb_tga_o(wb_tga), |
.wb_ack_i(ack), |
.wb_clk_i(clk), |
.wb_dat_i(8'b0), |
.wb_dat_i(io_i), |
.wb_rst_i(rst), |
.bist_ack_o(bist_ack), |
.bist_err_o(bist_err), |
97,25 → 100,52
wire [15:0] wb_adr; |
wire wb_stb, wb_cyc, wb_we; |
wire [7:0] wb_dat; |
wire [7:0] io_i; |
reg [7:0] out_state; |
|
parameter TAG_IO = 2'b01, // need to review general wb usage to undrstand how best to |
TAG_INT = 2'b10; // document this. |
|
// a pretty simple output device |
parameter MY_IO_ADR = 8'h10 ; |
// ----------------- a pretty simple I/O device ------- |
// output simply displays the data written -- |
// input cycles through |
// various interesting data patterens as used by the instruction test |
// namely 7f 55 80 0 ff aa |
|
wire wr2me = (wb_adr[7:0] == 8'h10) & wb_stb & wb_cyc & (wb_tga == TAG_IO) & wb_we; |
|
assign io_i = (wb_adr[7:0] == MY_IO_ADR) & wb_stb & wb_cyc & (wb_tga == TAG_IO) & !wb_we ? |
out_state : 8'hz; |
wire a2me = (wb_adr[7:0] == MY_IO_ADR) & wb_stb & wb_cyc & (wb_tga == TAG_IO); |
|
always @(posedge clk or posedge rst) |
begin |
if (rst ) ack <= 1'b0; |
else if (wr2me & !ack) |
else if (a2me & !ack) |
begin |
ack <= 1'b1; |
$write("%s",wb_dat); |
if (wb_we) $write("%s",wb_dat); |
end |
else ack <= 1'b0; |
|
else ack <= 1'b0; |
end |
|
always @(posedge clk or posedge rst) |
begin |
if (rst) out_state <= 8'h7f; |
else if (a2me & !wb_we & ack) |
case (out_state) |
8'h7f: out_state <= 8'h55 ; |
8'h55: out_state <= 8'h80 ; |
8'h80: out_state <= 8'h00 ; |
8'h00: out_state <= 8'hff ; |
8'hff: out_state <= 8'haa ; |
8'haa: out_state <= 8'h7f ; |
default: out_state <= 8'h7f ; |
endcase |
end |
|
|
|
initial |
begin |
clk = 0; |
/trunk/rtl/opcodes.v
64,10 → 64,10
// |
//-------1---------2---------3--------CVS Log -----------------------7---------8---------9--------0 |
// |
// $Id: opcodes.v,v 1.2 2004-05-18 22:31:20 bporcella Exp $ |
// $Id: opcodes.v,v 1.3 2004-05-21 02:51:25 bporcella Exp $ |
// |
// $Date: 2004-05-18 22:31:20 $ |
// $Revision: 1.2 $ |
// $Date: 2004-05-21 02:51:25 $ |
// $Revision: 1.3 $ |
// $Author: bporcella $ |
// $Locker: $ |
// $State: Exp $ |
74,6 → 74,9
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.2 2004/05/18 22:31:20 bporcella |
// instruction test getting to final stages |
// |
// Revision 1.1 2004/04/17 18:26:06 bporcella |
// put this here to try an end-run around lint mikefile problem |
// |
370,8 → 373,8
ED_IMs1 = 10'h256, // IM 1 ; ED 56 set IM1 |
ED_LDsA_I = 10'h257, // LD A,I ; ED 57 move I to A |
ED_IMs2 = 10'h25E, // IM 2 ; ED 5E set IM2 |
ED_RRD = 10'h267, // RRD ; ED 67 nibble roates A HL |
ED_RLD = 10'h26F, // RLD ; ED 6F nibble roates A HL |
ED_RRD = 10'h267, // RRD ; ED 67 nibble roates A (HL) |
ED_RLD = 10'h26F, // RLD ; ED 6F nibble roates A (HL) |
|
|
ED_LDI = 10'h2A0, // LDI ; ED A0 These are block move |
414,7 → 417,7
|
//The ED70 instruction reads from I/O port C, |
//but does not store the result. |
//It just affects the flags. Hard to test. like the other IN x,(C) instruction. |
//It just affects the flags. like the other IN x,(C) instruction. |
// |
//ED71 simply outs the value 0 to I/O port C. |
// This suggests that we should decode as follows: |
/trunk/rtl/z80_inst_exec.v
71,10 → 71,10
// |
//-------1---------2---------3--------CVS Log -----------------------7---------8---------9--------0 |
// |
// $Id: z80_inst_exec.v,v 1.3 2004-05-18 22:31:21 bporcella Exp $ |
// $Id: z80_inst_exec.v,v 1.4 2004-05-21 02:51:25 bporcella Exp $ |
// |
// $Date: 2004-05-18 22:31:21 $ |
// $Revision: 1.3 $ |
// $Date: 2004-05-21 02:51:25 $ |
// $Revision: 1.4 $ |
// $Author: bporcella $ |
// $Locker: $ |
// $State: Exp $ |
81,6 → 81,9
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2004/05/18 22:31:21 bporcella |
// instruction test getting to final stages |
// |
// Revision 1.2 2004/05/13 14:58:53 bporcella |
// testbed built and verification in progress |
// |
108,7 → 111,10
ar, fr, br, cr, dr, er, hr, lr, intr, |
ixr, iyr, add16, alu8_out, sh_alu, bit_alu, |
exec_ir2, |
exec_decbc, exec_decb, |
exec_decbc, exec_decb, |
adr_alu, |
blk_mv_upd_hl, |
blk_mv_upd_de, |
ir2, |
clk, |
rst, |
138,7 → 144,9
input [15:0] nn, sp; |
input ir2dd; // this must be ir2 |
input ir2fd; |
|
input [15:0] adr_alu; |
input blk_mv_upd_hl; |
input blk_mv_upd_de; |
//-------1---------2---------3--------Parameters-----------6---------7---------8---------9--------0 |
`include "opcodes.v" |
|
208,7 → 216,7
wire up_l_add16 ; |
wire upd_l_alu8 ; |
wire upd_l_src_pqr ; |
|
wire upd_bc_cpi ; |
wire upd_fr_alu8 ; |
wire upd_fr_add16 ; |
wire upd_fr_edadd16 ; |
344,7 → 352,7
// 1 1 8 8 1 |
assign {alu8_cry, alu8_hcry, alu8_out, src_pqri, c_8in0 }= |
|
ed_blk_cp ? {c_8out7,c_8out3, add_8bit, ~src_pqr20, 1'h1} : //CPI CPIR CPD CPDR |
ed_blk_cp ? {c_8out7,c_8out3, add_8bit, ~nn[15:8], 1'h1} : //CPI CPIR CPD CPDR |
|
{19{ir2[7] & ir2[5:3]==3'b000}} & ({c_8out7,c_8out3, add_8bit, src_pqr20, 1'b0} ) |// a+src |
{19{ir2[7] & ir2[5:3]==5'b001}} & ({c_8out7,c_8out3, add_8bit, src_pqr20, cf} ) |// a+src+cf |
421,9 → 429,8
//CB_BIT = 4'b01_01, // these must be compaired with ir2[9:6] |
//CB_RES = 4'b01_10, // these must be compaired with ir2[9:6]assign |
//CB_SET = 4'b01_11, // these must be compaired with ir2[9:6] |
assign bit_alu_act = ir2[9:6] == CB_BIT | |
ir2[9:6] == CB_RES | |
ir2[9:6] == CB_RES ; |
assign bit_alu_act = ir2[9:6] == CB_RES | |
ir2[9:6] == CB_SET ; |
|
wire [7:0] bit_decode = {8{ir2[5:3] == 3'h0}} & 8'h01 | |
{8{ir2[5:3] == 3'h1}} & 8'h02 | |
436,7 → 443,7
|
assign bit_alu = {8{ir2[9:6] == CB_BIT}} & ( sh_src & bit_decode) | |
{8{ir2[9:6] == CB_RES}} & ( sh_src & ~bit_decode) | |
{8{ir2[9:6] == CB_RES}} & ( sh_src | bit_decode) ; |
{8{ir2[9:6] == CB_SET}} & ( sh_src | bit_decode) ; |
|
|
//------------ dec bc alu --------------------------------------------- |
558,8 → 565,8
bit_alu_act & exec_ir2) ar <= bit_alu; |
if (ir2[2:0] == REG8_A & |
sh_alu_act & exec_ir2) ar <= sh_alu; |
if (ir2 == ED_RRD & exec_ir2) ar[3:0] <= nn[3:0]; |
if (ir2 == ED_RLD & exec_ir2) ar[3:0] <= nn[7:4]; |
if (ir2 == ED_RRD & exec_ir2) ar[3:0] <= nn[11:8]; |
if (ir2 == ED_RLD & exec_ir2) ar[3:0] <= nn[15:12]; |
if ({ir2[9:6], ir2[2:0]} == ED_NEG & exec_ir2) ar <= alu8_out; // ED44 this done by alu8 for flags |
if (ir2 == ED_LDsA_I & exec_ir2) ar <= intr ; |
end |
617,6 → 624,8
|
//------------------------------- br ----------------------------------------- |
|
assign upd_bc_cpi = ed_blk_cp & exec_ir2; |
|
assign upd_br = upd_b_alu8 | up_b_src_pqr | up_b_add16 | LDsBC_NN == ir2 | |
POPsBC == ir2 | EXX == ir2 | LDsB_N == ir2 | |
ir2[2:0] == REG8_B & bit_alu_act | ir2[2:0] == REG8_B & sh_alu_act | |
641,8 → 650,8
// change -- we need br==0. for now |
// use |br. If we need more speed add |
// a ff. |
if (exec_decb | exec_decbc) br <= decb_alu; |
if ( (ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) & (ir2[5:3] == REG8_B) & exec_ir2 ) br <= nn[7:0]; |
if (exec_decb | exec_decbc |upd_bc_cpi) br <= decb_alu; |
if ( (ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) & (ir2[5:3] == REG8_B) & exec_ir2 ) br <= nn[15:8]; |
if ( (ED_LDsREG_6NN7 == {ir2[9:6],ir2[3:0]}) & (ir2[5:4] == DBL_REG_BC) & exec_ir2 ) br <= nn[15:8]; |
end |
|
693,9 → 702,9
bit_alu_act & exec_ir2) cr <= bit_alu; |
if (ir2[2:0] == REG8_C & |
sh_alu_act & exec_ir2) cr <= sh_alu; |
if ( exec_decbc) cr <= decc_alu; |
if ( exec_decbc |upd_bc_cpi) cr <= decc_alu; |
if ((ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) & (ir2[5:3] == REG8_C) & exec_ir2) |
cr <= nn[7:0]; |
cr <= nn[15:8]; |
if ( (ED_LDsREG_6NN7 == {ir2[9:6],ir2[3:0]}) & (ir2[5:4] == DBL_REG_BC) & exec_ir2 ) cr <= nn[7:0]; |
|
end |
756,10 → 765,10
sh_alu_act & exec_ir2) dr <= sh_alu; |
if ((ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) |
& (ir2[5:3] == REG8_D) & exec_ir2) |
dr <= nn[7:0]; |
dr <= nn[15:8]; |
if ( ed_ld_dereg & exec_ir2 ) |
dr <= nn[15:8]; |
|
if (blk_mv_upd_de) dr <= adr_alu[15:8]; |
end |
|
// update er |
810,10 → 819,11
if (ir2[2:0] == REG8_E & |
sh_alu_act & exec_ir2) er <= sh_alu; |
if ((ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) & (ir2[5:3] == REG8_E) & exec_ir2) |
er <= nn[7:0]; |
er <= nn[15:8]; |
if ( ed_ld_dereg & exec_ir2 ) |
er <= nn[7:0]; |
|
er <= nn[7:0]; |
if (blk_mv_upd_de) er <= adr_alu[7:0]; |
|
end |
|
|
885,9 → 895,10
if (ir2[2:0] == REG8_H & |
sh_alu_act & exec_hlir2) hr <= sh_alu; |
if ((ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) & (ir2[5:3] == REG8_H) & exec_ir2) |
hr <= nn[7:0]; |
hr <= nn[15:8]; |
if ( (ED_LDsREG_6NN7 == {ir2[9:6],ir2[3:0]}) & (ir2[5:4] == DBL_REG_HL) & exec_ir2 ) |
hr <= nn[15:8]; |
if (blk_mv_upd_hl) hr <= adr_alu[15:8]; |
|
end |
|
950,10 → 961,11
if (ir2[2:0] == REG8_L & |
sh_alu_act & exec_hlir2) lr <= sh_alu; |
if ((ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) & (ir2[5:3] == REG8_L) & exec_ir2) |
lr <= nn[7:0]; |
lr <= nn[15:8]; |
if ( (ED_LDsREG_6NN7 == {ir2[9:6],ir2[3:0]}) & (ir2[5:4] == DBL_REG_HL) & exec_ir2 ) |
lr <= nn[7:0]; |
|
if (blk_mv_upd_hl) lr <= adr_alu[7:0]; |
|
end |
//------------------------ ixr --------------------------------------------- |
wire exec_ixir2 = exec_ir2 & ir2dd; |
1212,6 → 1224,8
|
|
wire iff2 = 1'b0; // this is supposed to be int ff #2 which is not (yet) implmented |
wire upd_fr_ed_in = ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]} ; |
wire bc_eq1 = {br,cr} == 16'h1; |
always @(posedge clk) |
begin |
if (exec_ir2) |
1226,18 → 1240,18
if (CB_BIT == ir2[9:6]) fr <={bit_alu[7], ~|bit_alu, bit_alu[5], 1'b1, //no idea why hf<=1 |
bit_alu[3], ~|bit_alu, 1'b0 , cf };// pvf == zf ??? |
if ( ed_blk_cp ) fr <= {alu8_out[7], ~|alu8_out, alu8_out[5], alu8_hcry,//std a-n stuff |
alu8_out[3], alu8_out[7], 1'b1, cf }; //cept nf and cf |
if (ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) |
fr <= {nn[7], ~|nn[7:0], nn[5], 1'b0, nn[3], ~^nn[7:0], 1'b0, cf}; |
alu8_out[3], ~bc_eq1, 1'b1, cf }; //cept nf and cf |
if (upd_fr_ed_in) |
fr <= {nn[15], ~|nn[15:8], nn[13], 1'b0, nn[11], ~^nn[15:8], 1'b0, cf}; |
if (CCF == ir2 ) fr <= {sf, zf, f5f, cf, f3f, pvf, nf, ~cf}; |
if (CPL == ir2 ) fr <= {sf, zf, ar[5], 1'b1, ar[3], pvf, 1'b1, cf}; |
if (DAA == ir2 ) fr <= {daa_alu[7], ~|daa_alu, daa_alu[5], 1'b0, // hf sb (logically) 0 |
daa_alu[3], ~^daa_alu, nf, daa_cry }; |
if (SCF == ir2 ) fr <= { sf, zf, ar[5], 1'b0, ar[3], pvf, 1'b0, 1'b1 }; // very strange |
if (ED_RRD == ir2) fr <= { sf, ~|{ar[7:4],nn[3:0]}, ar[5], 1'b0, |
ar[3], ~^{ar[7:4],nn[3:0]}, 1'b0 , cf }; |
if (ED_RLD == ir2) fr <= { sf, ~|{ar[7:4],nn[7:4]}, ar[5], 1'b0, |
ar[3], ~^{ar[7:4],nn[7:4]}, 1'b0 , cf }; |
if (ED_RRD == ir2) fr <= { ar[7], ~|{ar[7:4],nn[11:8]}, ar[5], 1'b0, |
ar[3], ~^{ar[7:4],nn[11:8]}, 1'b0 , cf }; |
if (ED_RLD == ir2) fr <= { ar[7], ~|{ar[7:4],nn[15:12]}, ar[5], 1'b0, |
ar[3], ~^{ar[7:4],nn[15:12]}, 1'b0 , cf }; |
if (ED_LDsA_I == ir2) fr <= { intr[7], ~|intr, intr[5], 1'b0, intr[3], iff2, 1'b0, cf }; // iff2 ? |
if (ir2 == EXsAF_AFp) fr <= fp; |
if (ir2 == EXX ) fr <= fp; |
1248,7 → 1262,8
// in the case of blk_cp the update above is executed 2nd - and so these are don't cares. |
if (exec_decb ) fr <= {decb_alu[7], ~|decb_alu, decb_alu[5], hf, |
decb_alu[3], pvf, 1'b0, cf }; |
if (exec_decbc ) fr[5:1] <= { decb_alu[5], 1'b0, decb_alu[3], ~|decb_alu, 1'b0 }; |
if (exec_decbc ) fr[5:1] <= { decb_alu[5], 1'b0, decb_alu[3], |
((|decb_alu) | (|decc_alu)) , 1'b0 }; |
end |
|
|
/trunk/rtl/z80_memstate2.v
109,10 → 109,10
// complete before starting the ir1 operation |
//-------1---------2---------3--------CVS Log -----------------------7---------8---------9--------0 |
// |
// $Id: z80_memstate2.v,v 1.3 2004-05-18 22:31:21 bporcella Exp $ |
// $Id: z80_memstate2.v,v 1.4 2004-05-21 02:51:25 bporcella Exp $ |
// |
// $Date: 2004-05-18 22:31:21 $ |
// $Revision: 1.3 $ |
// $Date: 2004-05-21 02:51:25 $ |
// $Revision: 1.4 $ |
// $Author: bporcella $ |
// $Locker: $ |
// $State: Exp $ |
119,6 → 119,9
// |
// Change History: |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2004/05/18 22:31:21 bporcella |
// instruction test getting to final stages |
// |
// Revision 1.2 2004/05/13 14:58:53 bporcella |
// testbed built and verification in progress |
// |
154,7 → 157,9
// |
//-------1---------2---------3--------Module Name and Port List------7---------8---------9--------0 |
module z80_memstate2(wb_adr_o, wb_we_o, wb_cyc_o, wb_stb_o, wb_tga_o, wb_dat_o, |
exec_ir2, ir1, ir2, ir1dd, ir1fd, ir2dd, ir2fd, nn, sp, |
exec_ir2, |
exec_decbc, exec_decb, |
ir1, ir2, ir1dd, ir1fd, ir2dd, ir2fd, nn, sp, |
|
upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr, |
beq0, ceq0, |
164,6 → 169,9
int_req_i, |
add16, |
alu8_out, |
adr_alu, |
blk_mv_upd_hl, |
blk_mv_upd_de, |
sh_alu, |
bit_alu, |
wb_clk_i, |
184,8 → 192,11
//output wb_lock; // bit set and clear insts should be atomic - could matter sometime |
output [1:0] wb_tga_o; |
output [7:0] wb_dat_o; // from nn |
//output [15:0] add_out; (may not wb_adr_o) 4/18/2004?? why? |
output [15:0] adr_alu; // 4/18/2004?? why? 5/20 to update hl on |
// block moves silly |
|
output blk_mv_upd_hl; |
output blk_mv_upd_de; |
output exec_ir2; |
output [9:0] ir1, ir2; |
output ir1dd, ir2dd; |
192,6 → 203,7
output ir1fd, ir2fd; |
output [15:0] nn; |
output [15:0] sp; |
output exec_decbc, exec_decb; |
|
|
|
340,7 → 352,7
MEM_OFADRP1 = 5'h0c, // used (at least) when double ops above |
MEM_OSADRP1 = 5'h0d, // "" "" "" |
|
MEM_IFRST = 5'h0e, // special address transfer |
//spare = 5'h0e, // use MEM_OSSP_PCM2 |
MEM_REL2PC = 5'h0f, // special address transfer for jmp rel |
MEM_JMPHL = 5'h10, // another special jump transfer |
MEM_IFNN = 5'h11, // used by call and return |
445,7 → 457,17
// |
// ir is 10 bits most significant codes ir1[9:8] = { EDgrp, CBgrp } DDgrp and FDgrp are modifiers |
|
assign blk_mv_upd_hl = next_mem_state == MEM_OFHL_PM & wb_rdy_nhz| |
next_mem_state == MEM_OSHL_PM & wb_rdy_nhz ; |
assign blk_mv_upd_de = next_mem_state == MEM_OSDE_PM & wb_rdy_nhz; |
// this term not active for compairs as it mucks with flag register in a "blk_mv" way. |
// we use exec_ir2 to do everything in blk compairs - on the inst_exec file. |
assign exec_decbc = (dec_state == DEC_ED) & ( ed_blk_mv) & wb_rdy_nhz | |
(dec_state == DEC_EDBMV3) & wb_rdy_nhz ; |
|
assign exec_decb = (dec_state == DEC_ED) & ( ed_blk_in | ed_blk_out) & wb_rdy_nhz| |
(dec_state == DEC_EDBIN3) & wb_rdy_nhz | |
(dec_state == DEC_EDBOUT3) & wb_rdy_nhz ; |
assign wb_dat_o = nn[15:8]; |
|
wire sf, zf, f5f, hf, f3f, pvf, nf, cf; |
598,7 → 620,7
{I1DCNT {DECsL == ir1}} & I1_R2R |// DEC L ; 2D |
{I1DCNT {DECsSP == ir1}} & I1_R2R |// DEC SP ; 3B |
{I1DCNT {DI == ir1}} & I1_R2R |// DI ; F3 |
{I1DCNT {DJNZs$t2 == ir1}} & I1_R2R |// DJNZ $+2 ; 10 XX |
{I1DCNT {DJNZs$t2 == ir1}} & I1_JMPR|// DJNZ $+2 ; 10 XX |
{I1DCNT {EI == ir1}} & I1_R2R |// EI ; FB |
{I1DCNT {EXX == ir1}} & I1_R2R |// EXX ; D9 |
{I1DCNT {EXsAF_AFp == ir1}} & I1_R2R |// EX AF,AF' ; 08 |
783,10 → 805,10
wire ed_blk_out = ED_OTIR == ir1 | ED_OUTI == ir1 | |
ED_OTDR == ir1 | ED_OUTD == ir1 ; |
|
wire dec_blk_io = ed_blk_in | ed_blk_in; |
wire dec_blk_io = ed_blk_in | ed_blk_out; |
|
wire blk_done = ~blk_rpt_flg | beq0 & ceq0 | blk_io_flg & ceq0; |
|
wire blk_done = ~blk_rpt_flg | beq0 & ceq0 | blk_io_flg & beq0; |
wire blk_cpi_done = ~blk_rpt_flg | ({br, cr} == 16'h1); |
assign dec_blk_inc = ED_LDIR == ir1 | |
ED_CPIR == ir1 | |
ED_INIR == ir1 | |
804,8 → 826,9
//ED71 simply outs the value 0 to I/O port C. |
// This suggests that we should decode as follows: |
// I hope if I don't get all the IM duplicates right it won't be a tragedy |
// ED_INsREG_6C7 = 7'b1001___000,// compair with {ir[7:6],ir[2:0]} |
// |
// ED_INsREG_6C7 = 7'b1001___000, // compair with {ir[9:6],ir[2:0]} |
// ED_OUTs6C7_REG = 7'b1001___001, // compair with {ir[9:6],ir[2:0]} |
// ED_SBCsHL_REG = 8'b1001__0010, // compair with {ir[9:6],ir[3:0]} |
// ED_ADCsHL_REG = 8'b1001__1010, // compair with {ir[9:6],ir[3:0]} |
// ED_LDs6NN7_REG = 8'b1001__0011, // compair with {ir[9:6],ir[3:0]} REG = BC,DE,HL,SP |
812,11 → 835,17
// ED_LDsREG_6NN7 = 8'b1001__1011, // compair with {ir[9:6],ir[3:0]} REG = BC,DE,HL,SP |
// ED_NEG = 7'b1001___100, // compair with {ir[9:6],ir[2:0]} all A<= -A |
// ED_RETN = 7'b1001___101, // compair with {ir[9:6],ir[2:0]} and !reti |
|
wire ed_in_reg = ED_INsREG_6C7 == {ir1[9:6],ir1[2:0]}; |
wire ed_out_reg = ED_OUTs6C7_REG == {ir1[9:6],ir1[2:0]}; |
|
wire ed_nn = ED_LDs6NN7_REG == {ir1[9:6],ir1[3:0]} | |
ED_LDsREG_6NN7 == {ir1[9:6],ir1[3:0]} ; |
|
// we use all these to enable interrupts |
wire ed_retn = ED_RETN == {ir1[9:6],ir1[2:0]}; |
wire ed_rmw = ED_RRD == ir1 | // ED 67 nibble roates A (HL) |
ED_RLD == ir1 ; // ED 6F nibble roates A (HL) |
|
assign ed_dbl_rd = ED_LDsREG_6NN7 == {ir1[9:6],ir1[3:0]}; |
|
831,13 → 860,15
JRsC_$t2 == ir1 & fr[0] | |
JRsNC_$t2 == ir1 & ~fr[0] | |
JRsZ_$t2 == ir1 & fr[6] | |
JRsNZ_$t2 == ir1 & ~fr[6] ; |
JRsNZ_$t2 == ir1 & ~fr[6] | |
DJNZs$t2 == ir1 & (br != 8'h1); |
wire jmpr = |
JRs$t2 == ir1 | |
JRsC_$t2 == ir1 | |
JRsNC_$t2 == ir1 | |
JRsZ_$t2 == ir1 | |
JRsNZ_$t2 == ir1 ; |
JRsNZ_$t2 == ir1 | |
DJNZs$t2 == ir1; |
|
|
//assign { sf, zf. f5f, hf, f3f, pvf, nf, cf} = fr; |
1071,7 → 1102,7
// ------------------->| | | | |
// |_____| |_____| |
// MEM_NOP |
// MEM_IFPP1 MEM_OFIXpD MEM_CALL MEM_IFRST MEM_OFHL_PM MEM_IOF_C |
// MEM_IFPP1 MEM_OFIXpD MEM_CALL MEM_RST MEM_OFHL_PM MEM_IOF_C |
// MEM_OS1, MEM_OSIXpD MEM_OSNN, MEM_REL2PC MEM_OSHL_PM MEM_IOS_C |
// MEM_OF1, MEM_OSADR MEM_OFNN MEM_JMPHL MEM_OSDE_PM MEM_IOF_N |
// MEM_OFSP MEM_OSSP_PCM2 MEM_OFADRP1 MEM_IFNN MEM_INTA MEM_IOS_N |
1080,6 → 1111,7
|
wire src_sp = next_mem_state == MEM_OFSP | |
next_mem_state == MEM_OSSP | |
next_mem_state == MEM_OSSP_PCM2 | |
next_mem_state == MEM_CALL ; |
wire src_pc = next_mem_state == MEM_IFPP1 | |
next_mem_state == MEM_REL2PC ; |
1108,12 → 1140,14
next_mem_state == MEM_OFHL_PM | |
next_mem_state == MEM_OSHL_PM | |
next_mem_state == MEM_OS_HL_N | |
next_mem_state == MEM_JMPHL ; |
next_mem_state == MEM_JMPHL & !( ir1dd | ir1fd); |
|
wire src_ix = next_mem_state == MEM_OFIXpD & ir1dd | |
next_mem_state == MEM_JMPHL & ir1dd | |
next_mem_state == MEM_OSIXpD & ir1dd ; |
|
wire src_iy = next_mem_state == MEM_OFIXpD & ir1fd | |
next_mem_state == MEM_JMPHL & ir1fd | |
next_mem_state == MEM_OSIXpD & ir1fd ; |
|
wire src_adr = next_mem_state == MEM_OFADRP1 | |
1134,9 → 1168,8
{16{ src_bc }} & bc | |
{16{ src_ix }} & ixr | |
{16{ src_iy }} & iyr | |
{16{ src_adr }} & wb_adr_o | |
{16{ src_int }} & { intr, nn[15:8] } | |
{16{next_mem_state == MEM_IFRST}} & {10'h0, ir1[6:4], 3'h0} ; |
{16{ src_adr }} & wb_adr_o | |
{16{ src_int }} & { intr, nn[15:8] } ; |
|
wire block_mv_inc = (dec_state == DEC_ED) ? dec_blk_inc : blk_inc_flg; // flag set at DEC_ED |
|
1149,15 → 1182,17
next_mem_state ==MEM_OSDE_PM & block_mv_inc | |
next_mem_state ==MEM_OFSP | |
next_mem_state ==MEM_IFPP1 | |
next_mem_state ==MEM_OSSP_PCM2 | |
next_mem_state ==MEM_JMPHL | |
next_mem_state ==MEM_IFNN | |
next_mem_state ==MEM_OFNN | |
next_mem_state ==MEM_OSNN | |
next_mem_state ==MEM_RST | |
next_mem_state ==MEM_OSSP_P ; |
|
wire dec = next_mem_state ==MEM_OFHL_PM & ~block_mv_inc | |
next_mem_state ==MEM_OSHL_PM & ~block_mv_inc | |
next_mem_state ==MEM_OSDE_PM & ~block_mv_inc | |
next_mem_state ==MEM_OSSP_PCM2 | |
next_mem_state ==MEM_CALL | |
next_mem_state == MEM_OSSP ; |
|
1183,7 → 1218,6
next_mem_state == MEM_OSIXpD | |
next_mem_state == MEM_OFADRP1 | |
next_mem_state == MEM_OSADRP1 | |
|
next_mem_state == MEM_OSSP ; |
|
|
1244,9 → 1278,9
I1_PUSH : next_state = {DEC_PUSH, MEM_OSSP, IPIPE_EN12}; |
I1_RET : next_state = {DEC_RET, MEM_OFSP, IPIPE_EN12}; |
I1_RMW : next_state = {DEC_RMW, MEM_OF1, IPIPE_EN12};//can't gronk ir1 - blow off if |
I1_RST : next_state = {DEC_IF2, MEM_IFRST, IPIPE_ENN}; |
I1_RST : next_state = {DEC_NNCALL2, MEM_OSSP_PCM2, IPIPE_NOP}; |
I1_R2R : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; |
I1_JMPR : next_state = {DEC_N, MEM_NOP, IPIPE_ENN}; |
I1_JMPR : next_state = {DEC_N, MEM_NOP, IPIPE_ENNEN2A2}; |
I1_HALT : next_state = {DEC_HALT, MEM_NOP , IPIPE_EN2}; |
default : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; //I1_R2R |
endcase |
1272,9 → 1306,9
I1_PUSH : next_state = {DEC_PUSH, MEM_OSSP, IPIPE_EN12}; |
I1_RET : next_state = {DEC_RET, MEM_OFSP, IPIPE_EN12}; |
I1_RMW : next_state = {DEC_RMWDD1, MEM_IFPP1, IPIPE_ENNEN2}; |
I1_RST : next_state = {DEC_IF2, MEM_IFRST, IPIPE_NOP}; // just dump next inst |
I1_RST : next_state = {DEC_NNCALL2, MEM_OSSP_PCM2, IPIPE_NOP}; // just dump next inst |
I1_R2R : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; //I1_R2R |
I1_JMPR : next_state = {DEC_N, MEM_NOP, IPIPE_ENN}; |
I1_JMPR : next_state = {DEC_N, MEM_NOP, IPIPE_ENNEN2A2}; |
I1_HALT : next_state = {DEC_HALT, MEM_NOP , IPIPE_EN2}; |
default : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; //I1_R2R |
endcase |
1282,11 → 1316,14
if (ed_nn) next_state = {DEC_EDNN1, MEM_IFPP1, IPIPE_ENNEN2}; |
// we need to set inc and io and repeat flags on this state for continued block |
// processing -- keep the states of this machine somewhat manageable. |
else if (ed_rmw ) next_state = {DEC_RMW, MEM_OF1, IPIPE_EN12}; // RLD RRD |
else if (ed_blk_cp ) next_state = {DEC_EDBCP1, MEM_OFHL_PM, IPIPE_EN12};// MEM_OFHL_PM triggers --BC |
else if (ed_blk_in ) next_state = {DEC_EDBIN1, MEM_IOF_C, IPIPE_EN12};// MEM_IOF_C triggers --B |
else if (ed_blk_out) next_state = {DEC_EDBOUT1,MEM_OFHL_PM, IPIPE_EN12}; |
else if (ed_blk_mv ) next_state = {DEC_EDBMV1, MEM_OFHL_PM, IPIPE_EN12}; |
else if (ed_retn ) next_state = {DEC_RET, MEM_OFSP, IPIPE_EN12};// see int logic below |
else if (ed_in_reg ) next_state = {DEC_EDRD2, MEM_IOF_C, IPIPE_EN12}; |
else if (ed_out_reg ) next_state = {DEC_IF2A, MEM_IOS_C, IPIPE_EN12}; |
else next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; |
// double register reads and writes here |
DEC_EDNN1: next_state = {DEC_EDNN2, MEM_IFPP1, IPIPE_ENN}; // address to nn |
1297,23 → 1334,27
DEC_EDRD2: next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_ENNA2}; // 2nd byte 2nn |
DEC_EDWR: next_state = {DEC_IF2A, MEM_OSADRP1, IPIPE_NOP}; |
|
// ED block moves |
// ED block compair |
// Got a tricky problem here..... fr is updated in a different manner for cpi and |
// we really can't test blk_done here (bc is updated on this tick). So make the test |
// for done be bc==1 and use enna2 for everything. Course this begs the question if |
// this approach is not best for all block moves ????? |
DEC_EDBCP1: |
if (blk_done) next_state = {DEC_EXEC, MEM_IFPP1,IPIPE_ENNA2}; |
else if(wb_int) next_state = {DEC_INT1, MEM_NOP, IPIPE_ENNA2}; |
else next_state = {DEC_EDBCP2, MEM_NOP, IPIPE_ENNA2};//set flags |
if (blk_cpi_done) next_state = {DEC_EXEC, MEM_IFPP1,IPIPE_ENNA2}; |
else if(wb_int) next_state = {DEC_INT1, MEM_NOP, IPIPE_ENNA2}; |
else next_state = {DEC_EDBCP2, MEM_NOP, IPIPE_ENNA2};//set flags |
DEC_EDBCP2: next_state = {DEC_EDBCP3, MEM_NOP, IPIPE_NOP};//wait for fr. alu_out is slow |
DEC_EDBCP3: if (fr[7]) next_state = {DEC_EXEC , MEM_IFPP1, IPIPE_NOP}; |
DEC_EDBCP3: if (fr[6]) next_state = {DEC_EXEC , MEM_IFPP1, IPIPE_NOP}; |
else next_state = {DEC_EDBCP1, MEM_OFHL_PM, IPIPE_NOP}; |
|
DEC_EDBIN1: next_state = {DEC_EDBIN2, MEM_NOP, IPIPE_ENN}; |
DEC_EDBIN2: if (blk_done) next_state = {DEC_IF2A, MEM_OSHL_PM,IPIPE_NOP}; // implies nn |
else if (wb_int) next_state = {DEC_INT1, MEM_OSHL_PM,IPIPE_NOP}; |
else next_state = {DEC_EDBIN1,MEM_OSHL_PM,IPIPE_NOP};//set flags |
else next_state = {DEC_EDBIN3,MEM_OSHL_PM,IPIPE_NOP};//set flags |
DEC_EDBIN3: next_state = {DEC_EDBIN1, MEM_IOF_C, IPIPE_NOP}; |
|
DEC_EDBOUT1: next_state = {DEC_EDBOUT2, MEM_NOP, IPIPE_ENN}; |
DEC_EDBOUT2:if (blk_done) next_state = {DEC_EXEC, MEM_IOS_C,IPIPE_NOP}; |
DEC_EDBOUT2:if (blk_done) next_state = {DEC_IF2A, MEM_IOS_C,IPIPE_NOP}; |
else if (wb_int) next_state = {DEC_INT1, MEM_IOS_C,IPIPE_NOP}; // DEC_EDBOUT: if (blk_rpt) |
else next_state = {DEC_EDBOUT3,MEM_IOS_C,IPIPE_NOP}; |
|
1320,7 → 1361,7
DEC_EDBOUT3: next_state = {DEC_EDBOUT1,MEM_OFHL_PM, IPIPE_NOP}; |
|
DEC_EDBMV1: next_state = {DEC_EDBMV2, MEM_NOP, IPIPE_ENN}; |
DEC_EDBMV2: if (blk_done) next_state = {DEC_EXEC, MEM_OSDE_PM,IPIPE_NOP}; |
DEC_EDBMV2: if (blk_done) next_state = {DEC_IF2A, MEM_OSDE_PM,IPIPE_NOP}; |
else if (wb_int) next_state = {DEC_INT1, MEM_OSDE_PM,IPIPE_NOP}; //DEC_EDBOUT: if (blk_rpt) |
else next_state = {DEC_EDBMV3,MEM_OSDE_PM,IPIPE_NOP}; |
|
1361,7 → 1402,7
else next_state = { DEC_IF2, MEM_IFPP1, IPIPE_ENNEN2A2}; |
|
DEC_NNCALL1: next_state = {DEC_NNCALL2, MEM_CALL , IPIPE_NOP}; |
DEC_NNCALL2: next_state = {DEC_IF1, MEM_OSSP, IPIPE_ENN};//A1 activates r2r xfers from ir1 |
DEC_NNCALL2: next_state = {DEC_IF1, MEM_OSSP, IPIPE_NOP};//A1 activates r2r xfers from ir1 |
DEC_NNJMP: next_state = {DEC_IF2, MEM_IFNN , IPIPE_NOP}; |
|
// ISSUE: we blow out ir1 here - so need to keep some status to execute OSNN2. |
1495,14 → 1536,16
|
//--------------- block move flags ------------------------ |
always @(posedge wb_clk_i) |
if (dec_state == DEC_ED) blk_inc_flg <= dec_blk_inc; |
|
if (dec_state == DEC_ED) blk_inc_flg <= dec_blk_inc; |
else if (dec_state == DEC_EXEC) blk_inc_flg <= 1'b0; |
always @(posedge wb_clk_i) |
if (dec_state == DEC_ED) blk_rpt_flg <= dec_blk_rpt; |
if (dec_state == DEC_ED) blk_rpt_flg <= dec_blk_rpt; |
else if (dec_state == DEC_EXEC) blk_rpt_flg <= 1'b0; |
|
|
always @(posedge wb_clk_i) |
if (dec_state == DEC_ED) blk_io_flg <= dec_blk_io; |
if (dec_state == DEC_ED) blk_io_flg <= dec_blk_io; |
else if (dec_state == DEC_EXEC) blk_io_flg <= 1'b0; |
|
|
//-------------------------- memory interface stuff ---------------------------- |
1590,21 → 1633,30
(ir2[9:6] == CB_SET ) ; |
|
|
wire [15:0] pc_2 = pc - 16'h2; |
wire [15:0] pc_12 = pc - ( (DEC_INT1 == dec_state ) ? 16'h2 : 16'h1 ); |
|
// bjp comment -- logic here is getting pretty slow --- the else if's are out of |
// line need to get this cleaned up for synthesis -- but first get it logically |
// correct. |
always @(posedge wb_clk_i or posedge rst_i) |
if (rst_i) nn <= 6'h00; |
else if (wb_rdy_nhz) |
begin |
if ( we_next & flag_os1) nn <= { nn[7:0], nn[15:8] } ; |
// This term forces the second store data in any flow to be from nn[7:0] |
// LOL better not do this for block repeat flows |
if ( we_next & flag_os1 & ~blk_rpt_flg) nn <= { nn[7:0], nn[15:8] } ; |
|
else if(we_next & ( next_mem_state == MEM_CALL)) nn <= {pc}; |
else if(we_next & ( next_mem_state == MEM_OSSP_PCM2)) nn <= {pc_2[7:0], pc_2[15:8]}; |
else if( next_mem_state == MEM_CALL) nn <= {pc}; |
else if( next_mem_state == MEM_OSSP_PCM2) nn <= {pc_12}; |
else if(EXs6SP7_HL== ir2 & ir2dd & exec_ir2) nn <= ixr; |
else if(EXs6SP7_HL== ir2 & ir2fd & exec_ir2) nn <= iyr; |
else if(EXs6SP7_HL== ir2 & exec_ir2) nn <= hl; |
else if((INCs6HL7==ir2 | DECs6HL7==ir2) & exec_ir2) nn[15:8] <= alu8_out; |
else if( ir2_cb_shift & MEM_OSADR == next_mem_state ) nn[15:8] <= sh_alu; |
else if( ir2_cb_bit & MEM_OSADR == next_mem_state ) nn[15:0] <= bit_alu; |
else if( ir2_cb_shift & MEM_OSADR == next_mem_state ) nn[15:8] <= sh_alu; |
else if( ir2_cb_bit & MEM_OSADR == next_mem_state ) nn[15:8] <= bit_alu; |
else if( ED_RRD == ir2 & MEM_OSADR == next_mem_state) nn[15:8] <= {ar[3:0], nn[15:12]}; |
else if( ED_RLD == ir2 & MEM_OSADR == next_mem_state) nn[15:8] <= {nn[11:8], ar[3:0] }; |
|
else if (next_pipe_state[1]) nn <= { wb_dat_i, nn[15:8] }; // ENN overides os stuff |
// these are the general cases with ir1 providing register specification |
// let PUSH have priority (we need os_h for some indexed stores under ir1dd) |
1613,6 → 1665,7
next_mem_state == MEM_OSIXpD | |
next_mem_state == MEM_OSSP | |
next_mem_state == MEM_IOS_N | |
next_mem_state == MEM_IOS_C | |
next_mem_state == MEM_OSNN ) ) |
// oh my god -- operands go out in different order to stack than they |
// do to normal stores. Oh well, guess that makes ordering consistent in |
1645,8 → 1698,9
if (next_mem_state == MEM_DECPC) pc <= pc - 16'h1; // decrementer could perhaps be shared. |
if (next_mem_state == MEM_IFPP1) pc <= adr_alu; |
if (next_mem_state == MEM_CALL ) pc <= nn; //Use MEM_CALL to exchange pc<=>nn |
if (next_mem_state == MEM_IFRST) pc <= src_mux; |
if (next_mem_state == MEM_JMPHL) pc <= src_mux; |
if (next_mem_state == MEM_RST) pc <= adr_alu; |
if (next_mem_state == MEM_JMPHL) pc <= adr_alu; |
if (next_mem_state == MEM_OSSP_PCM2) pc <= { 10'h0, ir1[5:3], 3'h0} ; |
if (next_mem_state == MEM_IFNN ) pc <= adr_alu; //on jumps get adr+1 in pc immediately. |
if (next_mem_state == MEM_REL2PC) pc <= adr_alu; |
if (next_mem_state == MEM_IFINT) pc <= src_mux; |