OpenCores
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;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.