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 22 to Rev 23
    Reverse comparison

Rev 22 → Rev 23

/trunk/rtl/z80_core_top.v
37,10 → 37,10
///////////////////////////////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: z80_core_top.v,v 1.2 2004-04-27 21:38:22 bporcella Exp $
// $Id: z80_core_top.v,v 1.3 2004-05-13 14:58:53 bporcella Exp $
//
// $Date: 2004-04-27 21:38:22 $
// $Revision: 1.2 $
// $Date: 2004-05-13 14:58:53 $
// $Revision: 1.3 $
// $Author: bporcella $
// $Locker: $
// $State: Exp $
47,6 → 47,9
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.2 2004/04/27 21:38:22 bporcella
// test lint on core
//
// Revision 1.1 2004/04/27 21:27:13 bporcella
// first core build
//
62,21 → 65,24
// z80_sdram_config.v // fundamentally wishbone glue logic - not on top per design guidelines
// add a comment test lint
//-------1---------2---------3--------Module Name and Port List------7---------8---------9--------0
module z80_core_top( wb_dat_o,
module z80_core_top(
wb_dat_o,
wb_stb_o,
wb_cyc_o,
wb_we_o,
wb_adr_o,
wb_tga_o,
bist_ack_o,
bist_err_o,
wb_ack_i,
wb_clk_i,
wb_dat_i,
wb_rst_i,
`ifdef COMPILE_BIST
bist_ack_o,
bist_err_o,
bist_req_i,
`endif
int_req_i
 
 
);
 
//-------1---------2---------3--------Output Ports---------6---------7---------8---------9--------0
87,8 → 93,6
output wb_we_o;
output [15:0] wb_adr_o;
output [1:0] wb_tga_o;
output bist_ack_o;
output bist_err_o;
 
 
//-------1---------2---------3--------Input Ports----------6---------7---------8---------9--------0
96,18 → 100,24
input wb_ack_i;
input wb_clk_i;
input [7:0] wb_dat_i;
input bist_req_i;
input wb_rst_i;
input int_req_i;
 
 
`ifdef COMPILE_BIST
output bist_err_o;
output bist_ack_o;
input bist_req_i;
`endif
 
 
//-------1---------2---------3--------Parameters-----------6---------7---------8---------9--------0
//-------1---------2---------3--------Wires------5---------6---------7---------8---------9--------0
wire [15:0] wb_adr_o;
wire [15:0] add_out; // output of adder (may not wb_adr_o)
wire [9:0] ir1, ir2;
wire [15:0] nn;
wire [15:0] sp;
wire [7:0] ar, fr, br, cr, dr, er, hr, lr;
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
122,19 → 132,30
//-------1---------2---------3--------Assignments----------6---------7---------8---------9--------0
//-------1---------2---------3--------State Machines-------6---------7---------8---------9--------0
 
 
`ifdef COMPILE_BIST
z80_bist_logic i_z80_bist_logic(
.bist_err_o(bist_err_o), .bist_ack_o(bist_ack_o),
.wb_adr_i(wb_adr_o), .wb_dat_i(wb_dat_o), .wb_we_i(wb_we_o), .wb_cyc_i(wb_cyc_o),
.wb_stb_i(wb_stb_o), .wb_tga_i(wb_tga_o), .wb_clk_i(wb_clk_i), .wb_rst_i(wb_rst_i)
);
`endif
 
 
 
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),
.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(beq0), .ceq0(ceq0),
.beq0(br_eq0), .ceq0(cr_eq0),
.ar(ar), .fr(fr), .br(br), .cr(cr), .dr(dr), .er(er), .hr(hr), .lr(lr),
.ixr(ixr), .iyr(iyr),
.wb_dat_i(cfg_do), .wb_ack_i(wb_ack_i),
.wb_dat_i(cfg_do), .wb_ack_i(cfg_ack_o),
.int_req_i(int_req_i),
.add16(add16),
.wb_clk_i(wb_clk_i),
.rst_i(rst_i) // keep this generic - may turn out to be different from wb_rst
);
.rst_i(wb_rst_i) // keep this generic - may turn out to be different from wb_rst
);
 
 
z80_inst_exec i_z80_inst_exec(
141,16 → 162,16
.br_eq0(br_eq0),
.cr_eq0(cr_eq0),
.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),
.ar(ar), .fr(fr), .br(br), .cr(cr), .dr(dr), .er(er), .hr(hr), .lr(lr), .intr(intr),
.ixr(ixr), .iyr(iyr), .add16(add16),
.exec_ir2(exec_ir2),
.exec_decbc(exec_decbc), .exec_decb(exec_decb),
.ir2(ir2),
.clk(wb_clk_i),
.rst(rst_i),
.rst(wb_rst_i),
.nn(nn), .sp(sp),
.dd_grp(dd_grp),
.fd_grp(fd_grp)
.ir2dd(ir2dd),
.ir2fd(ir2fd)
);
 
// The parameter passed to i_generic_sprem specifies the number of address bits used by the
162,21 → 183,22
// happy with this...... Depending on which target technology is specified, read behavior changes.
// It is easy to insure all possible behavior will in fact operate properly -- see the data reduction
// logic in sdram_cfg.v -- but still... I guess the important thing to be aware of is that
// big memories like this typically require special back-end handleing. This is likely to prove
// big memories like this typically require special back-end handeling. This is likely to prove
// no exception - despite the work that has been done to make this file as generally useful as
// possible.
 
generic_spram #(12) i_generic_spram(
generic_spram #(15) i_generic_spram(
// Generic synchronous single-port RAM interface
.clk(wb_clk_i), .rst(rst_i), .ce(cfg_ce_spram_o), .we(wb_we_o), .oe(1'b1), .addr(wb_adr_o[11:0]), .di(wb_dat_o), .do(sdram_do)
);
.clk(wb_clk_i), .rst(wb_rst_i), .ce(cfg_ce_spram_o), .we(wb_we_o), .oe(1'b1), .addr(wb_adr_o[14:0]), .di(wb_dat_o), .do(sdram_do)
);
 
 
 
z80_sdram_cfg i_z80_sdram_cfg(
.cfg_ce_spram_o(cfg_ce_spram_o), .cfg_do(cfg_do), .cfg_ack_o(cfg_ack_o), .sdram_di(sdram_do),
.wb_adr_i(wb_adr_o), .wb_dat_i(wb_dat_i), .wb_ack_i(wb_ack_i), .wb_stb_i(wd_stb_o),
.wb_cyc_i(wb_cyc_o), .wb_tga_i(wb_tga_o) );
.wb_adr_i(wb_adr_o), .wb_dat_i(wb_dat_i), .wb_ack_i(wb_ack_i), .wb_stb_i(wb_stb_o),
.wb_cyc_i(wb_cyc_o), .wb_tga_i(wb_tga_o)
);
 
 
endmodule
/trunk/rtl/files.txt
1,8 → 1,10
+incdir+.
z80_core_top.v
z80_inst_exec.v
z80_memstate2.v
z80_sdram_cfg.v
generic_spram.v
+incdir+rtl
rtl\z80_testbed.v
rtl\z80_bist_logic.v
rtl\z80_core_top.v
rtl\z80_inst_exec.v
rtl\z80_memstate2.v
rtl\z80_sdram_cfg.v
rtl\generic_spram.v
 
 
/trunk/rtl/generic_spram.v
67,6 → 67,9
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1 2004/04/27 21:27:13 bporcella
// first core build
//
// Revision 1.3 2001/11/09 00:34:19 samg
// minor changes: unified with all common rams
//
90,7 → 93,21
//`define VENDOR_XILINX
//`define VENDOR_ALTERA
//`define VENDOR_FPGA
 
//
//--------------------- WARNING ------------------------------------
//
// The way this "generic" ram works is not compatable with ANY SRAM that
// I have used in 30 years in this industry.......
//
// WHY register the address on read - but not on write? makes absolutly
// no sense to me. I suppose that there might be no real register file
// compatable SRAMS in some of the FPGA libraries. In which case, I probably
// need to make modifications to the basic core.
//
// Well for now just patch this to work like I expected,
//
// AS OF 4/29/2004 this is a seriously modified file. bjp
// see changes under bjp below
module generic_spram(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
118,155 → 135,7
// Module body
//
 
`ifdef VENDOR_FPGA
//
// Instantiation synthesizeable FPGA memory
//
// This code has been tested using LeonardoSpectrum and Synplicity.
// The code correctly instantiates Altera EABs and Xilinx BlockRAMs.
//
reg [dw-1 :0] mem [(1<<aw) -1:0];
reg [aw-1:0] raddr;
 
always@(posedge clk)
begin
// read operation
raddr <= #1 addr; // read address needs to be registered to read clock
 
// write operation
if (we && ce)
mem[addr] <= #1 di;
end
 
assign #1 do = mem[raddr];
 
`else
 
`ifdef VENDOR_XILINX
 
wire [dw-1:0] q; // output from xilinx ram
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2 BlockRAMs
//
xilinx_ram_sp xilinx_ram(
.clk(clk),
.rst(rst),
.addr(addr),
.di(di),
.en(ce),
.we(we),
.do(do)
);
 
defparam
xilinx_ram.dwidth = dw,
xilinx_ram.awidth = aw;
 
`else
 
`ifdef VENDOR_ALTERA
 
//
// Instantiation of FPGA memory:
//
// Altera FLEX EABs
//
 
altera_ram_sp altera_ram(
.inclock(clk),
.address(addr),
.data(di),
.we(we && ce),
.q(do)
);
 
defparam
altera_ram.dwidth = dw,
altera_ram.awidth = aw;
 
`else
 
`ifdef VENDOR_ARTISAN
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
artisan_ssp #(dw, 1<<aw, aw) artisan_ssp(
.CLK(clk),
.CEN(~ce),
.WEN(~we),
.A(addr),
.D(di),
.OEN(~oe),
.Q(do)
);
 
`else
 
`ifdef VENDOR_AVANT
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VENDOR_VIRAGE
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VENDOR_VIRTUALSILICON
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_spram #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
274,156 → 143,33
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
wire [dw-1:0] q; // RAM output
reg [aw-1:0] raddr; // RAM read address
 
// bjp change was
//reg [aw-1:0] raddr; // RAM read address
//wire raddr = addr;
//
// Data output drivers
//
assign do = (oe & ce) ? q : {dw{1'bz}};
assign do = (oe & ce) ? mem[addr] : {dw{1'bz}};
 
//
// RAM read and write
//
 
// read operation
always@(posedge clk)
if (ce) // && !we)
raddr <= #1 addr; // read address needs to be registered to read clock
// bjp read operation made asynchronous (only write is on clock)
//always@(posedge clk)
//if (ce) // && !we)
// raddr <= #1 addr; // read address needs to be registered to read clock
 
assign #1 q = rst ? {dw{1'b0}} : mem[raddr];
 
// write operation
always@(posedge clk)
if (ce && we)
mem[addr] <= #1 di;
mem[addr] <= di;
 
// Task prints range of memory
// *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations.
task print_ram;
input [aw-1:0] start;
input [aw-1:0] finish;
integer rnum;
begin
for (rnum=start;rnum<=finish;rnum=rnum+1)
$display("Addr %h = %h",rnum,mem[rnum]);
end
endtask
 
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
`endif // !VENDOR_ALTERA
`endif // !VENDOR_XILINX
`endif // !VENDOR_FPGA
 
endmodule
 
 
//
// Black-box modules
//
 
`ifdef VENDOR_ALTERA
module altera_ram_sp (
address,
inclock,
we,
data,
q) /* synthesis black_box */;
 
parameter awidth = 7;
parameter dwidth = 8;
 
input [awidth -1:0] address;
input inclock;
input we;
input [dwidth -1:0] data;
output [dwidth -1:0] q;
 
// synopsis translate_off
// exemplar translate_off
 
syn_ram_irou #(
"UNUSED",
dwidth,
awidth,
1 << awidth
)
altera_spram_model (
.Inclock(inclock),
.Address(address),
.Data(data),
.WE(we),
.Q(q)
);
 
// exemplar translate_on
// synopsis translate_on
 
endmodule
`endif // VENDOR_ALTERA
 
`ifdef VENDOR_XILINX
module xilinx_ram_sp (
clk,
rst,
addr,
di,
en,
we,
do) /* synthesis black_box */ ;
 
parameter awidth = 7;
parameter dwidth = 8;
 
input clk;
input rst;
input [awidth -1:0] addr;
input [dwidth -1:0] di;
input en;
input we;
output [dwidth -1:0] do;
 
// insert simulation model
 
 
// synopsys translate_off
// exemplar translate_off
 
C_MEM_SP_BLOCK_V1_0 #(
awidth,
1,
"0",
1 << awidth,
1,
1,
1,
1,
1,
1,
1,
"",
16,
0,
0,
1,
1,
dwidth
)
xilinx_spram_model (
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di),
.EN(en),
.WE(we),
.DO(do)
);
 
// exemplar translate_on
// synopsys translate_on
 
endmodule
`endif // VENDOR_XILINX
 
/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.1 2004-04-27 21:27:13 bporcella Exp $
// $Id: z80_inst_exec.v,v 1.2 2004-05-13 14:58:53 bporcella Exp $
//
// $Date: 2004-04-27 21:27:13 $
// $Revision: 1.1 $
// $Date: 2004-05-13 14:58:53 $
// $Revision: 1.2 $
// $Author: bporcella $
// $Locker: $
// $State: Exp $
81,6 → 81,9
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.1 2004/04/27 21:27:13 bporcella
// first core build
//
// Revision 1.4 2004/04/19 19:13:27 bporcella
// real lint problems pretty much fixed -- need another look - but need to get on to other things first
//
99,7 → 102,7
module z80_inst_exec( br_eq0,
cr_eq0,
upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr,
ar, fr, br, cr, dr, er, hr, lr,
ar, fr, br, cr, dr, er, hr, lr, intr,
ixr, iyr, add16,
exec_ir2,
exec_decbc, exec_decb,
107,8 → 110,8
clk,
rst,
nn, sp,
dd_grp,
fd_grp
ir2dd,
ir2fd
);
 
//-------1---------2---------3--------Output Ports---------6---------7---------8---------9--------0
115,7 → 118,7
output br_eq0;
output cr_eq0;
output upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr;
output [7:0] ar, fr, br, cr, dr, er, hr, lr;
output [7:0] ar, fr, br, cr, dr, er, hr, lr, intr;
output [15:0] ixr, iyr;
output [15:0] add16;
//-------1---------2---------3--------Input Ports----------6---------7---------8---------9--------0
126,8 → 129,8
input clk;
input rst;
input [15:0] nn, sp;
input dd_grp; // this must be ir2
input fd_grp;
input ir2dd; // this must be ir2
input ir2fd;
 
//-------1---------2---------3--------Parameters-----------6---------7---------8---------9--------0
`include "opcodes.v"
203,7 → 206,7
wire upd_fr_edadd16 ;
wire upd_fr_sh ;
wire upd_fr_cbsh ;
wire eb_blk_mv ;
//wire eb_blk_mv ;
wire ed_blk_cp ;
wire c_8in0 ;
 
220,16 → 223,16
// pipeline is such that we can make a fetch for free - so we will do that..... the
// prefix flags should not be set here -- all we will know on execution is that it is a
// cb instruction. ---- src is always nn
assign src_hr = dd_grp ? ixr[15:8] :
fd_grp ? iyr[15:8] :
assign src_hr = ir2dd ? ixr[15:8] :
ir2fd ? iyr[15:8] :
hr ;
assign src_lr = dd_grp ? ixr[7:0] :
fd_grp ? iyr[7:0] :
assign src_lr = ir2dd ? ixr[7:0] :
ir2fd ? iyr[7:0] :
lr ;
 
assign src_dblhr = dd_grp ? ixr : // ed grp instructions (ADC HL ; SBC HL are not affected -
fd_grp ? iyr : // instruction assembler assures this - ed_grp has no prefix
assign src_dblhr = ir2dd ? ixr : // ed grp instructions (ADC HL ; SBC HL are not affected -
ir2fd ? iyr : // instruction assembler assures this - ed_grp has no prefix
{hr, lr} ;
// ddcb_grp not defined - src_cb_r20 not used. Why these lines? 4/17/2004
//assign src_cb_r20 = (ddcb_grp | fdcb_grp) ? nn[7:0] :
261,9 → 264,9
{16{ir2[5:4]==2'b10}} & src_dblhr | // HL, ixr, iyr
{16{ir2[5:4]==2'b11}} & sp ;
 
assign sh_src = ir2[8] & dd_grp ? nn[15:8] :
ir2[8] & fd_grp ? nn[15:8] :
ir2 ? src_pqr20 :
assign sh_src = ir2[8] & ir2dd ? nn[15:8] :
ir2[8] & ir2fd ? nn[15:8] :
ir2[8] ? src_pqr20 :
ar ;
// I wonder how well the synthesizer can reduce this??? - It is probably worth spending
// some time during physical design to see if a more low level description would help --
311,7 → 314,7
// f3f fpv fn fc
alu8_out[3], alu8_out[7], alu8_nf, c_8out7 };
 
//assign alu8_pvf = (ir2[7:3]==5'b10100 | ir2[7:3]==5'b10101 | ir2[7:3]==5'b10110) ?
//assign alu8_pvf = (ir2[9:3]==5'b10100 | ir2[9:3]==5'b10101 | ir2[7:3]==5'b10110) ?
// ~^alu8_out : // even parity
// (src_aor_cnst[7]==src_pqri[7]) & (src_aor_cnst[7]!=alu8_out[7]) ; // ofl
 
335,16 → 338,16
ed_blk_cp ? {c_8out7,c_8out3, add_8bit, ~src_pqr20, 1'h1} : //CPI CPIR CPD CPDR
 
{19{ir2[7:3]==5'b10000}} & ({c_8out7,c_8out3, add_8bit, src_pqr20, 1'b0} ) |// a+src
{19{ir2[7:3]==5'b10001}} & ({c_8out7,c_8out3, add_8bit, src_pqr20, cf} ) |// a+src+cf
{19{ir2[7:3]==5'b10010}} & ({c_8out7,c_8out3, add_8bit, ~src_pqr20, 1'h1} ) |// a-src
{19{ir2[7:3]==5'b10011}} & ({c_8out7,c_8out3, add_8bit, ~src_pqr20, ~cf } ) |// a-src-cf
{19{ir2[7:3]==5'b10100}} & ({1'b0 ,1'b1 , ar & src_pqr20, src_pqr20, 1'b0} ) |// a&src
{19{ir2[7:3]==5'b10101}} & ({1'b0 ,1'b0 , ar ^ src_pqr20, src_pqr20, 1'b0} ) |// a^src
{19{ir2[7:3]==5'b10110}} & ({1'b0 ,1'b0 , ar | src_pqr20, src_pqr20, 1'b0} ) |// a|src
{19{ir2[7:3]==5'b10111}} & ({c_8out7,c_8out3, add_8bit, src_pqr20, 1'h1}) |// a-src
{19{(ir2[7:6]==2'b00)& ~ir2[0] }}& ({ cf,c_8out3, add_8bit, src_pqr53, 1'h1}) |// inc_r main
{19{(ir2[7:6]==2'b00)& ir2[0] }}& ({ cf,c_8out3, add_8bit, src_pqr53, 1'h0}) |// dec_r
{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
{19{ir2[7] & ir2[5:3]==5'b010}} & ({c_8out7,c_8out3, add_8bit, ~src_pqr20, 1'h1} ) |// a-src
{19{ir2[7] & ir2[5:3]==5'b011}} & ({c_8out7,c_8out3, add_8bit, ~src_pqr20, ~cf } ) |// a-src-cf
{19{ir2[7] & ir2[5:3]==5'b100}} & ({1'b0 ,1'b1 , ar & src_pqr20, src_pqr20, 1'b0} )|// a&src
{19{ir2[7] & ir2[5:3]==5'b101}} & ({1'b0 ,1'b0 , ar ^ src_pqr20, src_pqr20, 1'b0} )|// a^src
{19{ir2[7] & ir2[5:3]==5'b110}} & ({1'b0 ,1'b0 , ar | src_pqr20, src_pqr20, 1'b0} )|// a|src
{19{ir2[7] & ir2[5:3]==5'b111}} & ({c_8out7,c_8out3, add_8bit, ~src_pqr20, 1'h1}) |// a-src
{19{(ir2[7:6]==2'b00)& ~ir2[0] }}& ({ cf,c_8out3, add_8bit, src_pqr53, 1'h1}) |// inc_r main
{19{(ir2[7:6]==2'b00)& ir2[0] }}& ({ cf,c_8out3, add_8bit, src_pqr53, 1'h0}) |// dec_r
{19{(ir2[7:6]==2'b01) }}& ({c_8out7,c_8out3, add_8bit, ~ar, 1'h1}) ;// ed44 -a
 
 
379,7 → 382,7
// in assembly code as they appear to have some utility - and by all accounts operate reliably.
// The first four are implemented in a single byte inaruction . (A <= sh_op A )
// All 8 are implemented in the CB group with all registers as potential sources (and dests).
// if dd_grp or fd_grp is prefix..... source is always the memory. This is undocumented - but
// if ir2dd or ir2fd is prefix..... source is always the memory. This is undocumented - but
// may be a useful hint for simplyfing the total machine. Destination registers
// (if any) get a copy of the updated memory location (This is also true of the bit set and
// clear instructions in the cb_grp.
537,7 → 540,7
if (upd_a_alu8 & exec_ir2) ar <= alu8_out;
if (up_a_sh_alu & exec_ir2) ar <= sh_alu;
if (up_a_src_pqr & exec_ir2) ar <= src_pqr20;
if (up_a_n & exec_ir2) ar <= nn[7:0];
if (up_a_n & exec_ir2) ar <= nn[15:8]; // changed for LD A N
if (ir2 == EXsAF_AFp & exec_ir2) ar <= ap;
if (ir2 == EXX & exec_ir2) ar <= ap;
if (ir2 == DAA & exec_ir2) ar <= daa_alu;
620,7 → 623,7
if ( LDsBC_NN == ir2 & exec_ir2) br <= nn[15:8];
if ( POPsBC == ir2 & exec_ir2) br <= nn[15:8];
if ( EXX == ir2 & exec_ir2) br <= bp;
if ( LDsB_N == ir2 & exec_ir2) br <= nn[7:0];
if ( LDsB_N == ir2 & exec_ir2) br <= nn[15:8];
if (ir2[2:0] == REG8_B &
bit_alu_act & exec_ir2) br <= bit_alu;
if (ir2[2:0] == REG8_B &
630,7 → 633,7
// use |br. If we need more speed add
// a ff.
if (exec_decb | exec_decbc) br <= decb_alu;
if ( (ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_B) & exec_ir2 )
if ( (ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) & (ir2[5:3] == REG8_B) & exec_ir2 )
br <= nn[7:0];
end
 
675,7 → 678,7
if ( LDsBC_NN == ir2 & exec_ir2) cr <= nn[7:0];
if ( POPsBC == ir2 & exec_ir2) cr <= nn[7:0];
if ( EXX == ir2 & exec_ir2) cr <= cp;
if ( LDsC_N == ir2 & exec_ir2) cr <= nn[7:0];
if ( LDsC_N == ir2 & exec_ir2) cr <= nn[15:8];
if (ir2[2:0] == REG8_C &
bit_alu_act & exec_ir2) cr <= bit_alu;
if (ir2[2:0] == REG8_C &
734,7 → 737,7
if ( POPsDE == ir2 & exec_ir2) dr <= nn[15:8];
if ( EXX == ir2 & exec_ir2) dr <= dp;
if ( EXsDE_HL == ir2 & exec_ir2) dr <= hr;
if ( LDsD_N == ir2 & exec_ir2) dr <= nn[7:0];
if ( LDsD_N == ir2 & exec_ir2) dr <= nn[15:8];
if (ir2[2:0] == REG8_D &
bit_alu_act & exec_ir2) dr <= bit_alu;
if (ir2[2:0] == REG8_D &
794,7 → 797,7
if ( POPsDE == ir2 & exec_ir2) er <= nn[7:0];
if ( EXX == ir2 & exec_ir2) er <= ep;
if ( EXsDE_HL == ir2 & exec_ir2) er <= hr;
if ( LDsE_N == ir2 & exec_ir2) er <= nn[7:0];
if ( LDsE_N == ir2 & exec_ir2) er <= nn[15:8];
if (ir2[2:0] == REG8_E &
bit_alu_act & exec_ir2) er <= bit_alu;
if (ir2[2:0] == REG8_E &
850,7 → 853,7
 
 
 
wire exec_hlir2 = exec_ir2 & !(dd_grp | fd_grp);
wire exec_hlir2 = exec_ir2 & !(ir2dd | ir2fd);
 
always @(posedge clk)
begin
863,7 → 866,7
if ( EXs6SP7_HL== ir2 & exec_hlir2) hr <= nn[15:8];
if ( EXX == ir2 & exec_ir2) hr <= hp;
if ( EXsDE_HL == ir2 & exec_ir2) hr <= dr;
if ( LDsH_N == ir2 & exec_hlir2) hr <= nn[7:0];
if ( LDsH_N == ir2 & exec_hlir2) hr <= nn[15:8];
if (ir2[2:0] == REG8_H &
bit_alu_act & exec_hlir2) hr <= bit_alu;
if (ir2[2:0] == REG8_H &
923,7 → 926,7
if ( EXs6SP7_HL== ir2 & exec_hlir2) lr <= nn[7:0];
if ( EXX == ir2 & exec_ir2) lr <= lp;
if ( EXsDE_HL == ir2 & exec_ir2) lr <= er;
if ( LDsL_N == ir2 & exec_hlir2) lr <= nn[7:0];
if ( LDsL_N == ir2 & exec_hlir2) lr <= nn[15:8];
if (ir2[2:0] == REG8_L &
bit_alu_act & exec_hlir2) lr <= bit_alu;
if (ir2[2:0] == REG8_L &
933,7 → 936,7
end
//------------------------ ixr ---------------------------------------------
wire exec_ixir2 = exec_ir2 & dd_grp;
wire exec_ixir2 = exec_ir2 & ir2dd;
always @(posedge clk)
begin
if ( upd_l_alu8 & exec_ixir2) ixr[7:0] <= alu8_out;
944,7 → 947,7
if ( POPsHL == ir2 & exec_ixir2) ixr[7:0] <= nn[7:0];
if ( EXs6SP7_HL== ir2 & exec_ixir2) ixr[7:0] <= nn[7:0];
 
if ( LDsL_N == ir2 & exec_ixir2) ixr[7:0] <= nn[7:0];
if ( LDsL_N == ir2 & exec_ixir2) ixr[7:0] <= nn[15:8];
if (ir2[2:0] == REG8_L &
bit_alu_act & exec_ixir2) ixr[7:0] <= bit_alu;
if (ir2[2:0] == REG8_L &
962,7 → 965,7
if ( POPsHL == ir2 & exec_ixir2) ixr[15:8] <= nn[15:8];
if ( EXs6SP7_HL== ir2 & exec_ixir2) ixr[15:8] <= nn[15:8];
 
if ( LDsH_N == ir2 & exec_ixir2) ixr[15:8] <= nn[7:0];
if ( LDsH_N == ir2 & exec_ixir2) ixr[15:8] <= nn[15:8];
if (ir2[2:0] == REG8_H &
bit_alu_act & exec_ixir2) ixr[15:8] <= bit_alu;
if (ir2[2:0] == REG8_H &
971,7 → 974,7
end
 
//------------------------ iyr ---------------------------------------------
wire exec_iyir2 = exec_ir2 & fd_grp;
wire exec_iyir2 = exec_ir2 & ir2fd;
always @(posedge clk)
begin
if ( upd_l_alu8 & exec_iyir2) iyr[7:0] <= alu8_out;
982,7 → 985,7
if ( POPsHL == ir2 & exec_iyir2) iyr[7:0] <= nn[7:0];
if ( EXs6SP7_HL== ir2 & exec_iyir2) iyr[7:0] <= nn[7:0];
 
if ( LDsL_N == ir2 & exec_iyir2) iyr[7:0] <= nn[7:0];
if ( LDsL_N == ir2 & exec_iyir2) iyr[7:0] <= nn[15:8];
if (ir2[2:0] == REG8_L &
bit_alu_act & exec_iyir2) iyr[7:0] <= bit_alu;
if (ir2[2:0] == REG8_L &
1000,7 → 1003,7
if ( POPsHL == ir2 & exec_iyir2) iyr[15:8] <= nn[15:8];
if ( EXs6SP7_HL== ir2 & exec_iyir2) iyr[15:8] <= nn[15:8];
 
if ( LDsH_N == ir2 & exec_iyir2) iyr[15:8] <= nn[7:0];
if ( LDsH_N == ir2 & exec_iyir2) iyr[15:8] <= nn[15:8];
if (ir2[2:0] == REG8_H &
bit_alu_act & exec_iyir2) iyr[15:8] <= bit_alu;
if (ir2[2:0] == REG8_H &
1071,6 → 1074,7
ADDsA_H == ir2 | CPsH == ir2 | SBCsE == ir2 | XORsH == ir2 | INCsL == ir2 |
ADDsA_L == ir2 | CPsL == ir2 | SBCsH == ir2 | XORsL == ir2 | INCs6HL7 == ir2 |
ADDsA_6HL7== ir2| CPs6HL7 ==ir2 | SBCsL == ir2 | XORs6HL7 == ir2 | DECs6HL7 == ir2 |
CPsN == ir2 |
ED_NEG == {ir2[9:6],ir2[2:0]} ; //7'b1001___100, A<= -A
 
1114,7 → 1118,7
// pretty nomal stuff here
//CB_BIT = 4'b01_01, // these must be compaired with ir2[9:6]
// which alu? -- done from alu8
//ED_NEG = 5'b01___100, // compair with {ir2[7:6],ir2[2:0]} all A<= -A
//ED_NEG = 5'b01___100, // compair with {ir2[9:6],ir2[2:0]} all A<= -A
 
// rmw 8 types these handled by standard INC and DEC logic done.
//INCs6HL7 = 'h34,// INC (HL) ; 34
1146,7 → 1150,7
//ED_OTIR = 'hB3// OTIR ; ED B3 (Cio) <-(HL++) , B-- rpt if(|B)
//ED_OTDR = 'hBB// OTDR ; ED BB (Cio) <-(HL--) , B-- rpt if(|B)
 
//ED_INsREG_6C7 = 5'b01___000,// compair with {ir2[7:6],ir2[2:0]} really (BCio)
//ED_INsREG_6C7 = 5'b01___000,// compair with {ir2[9:6],ir2[2:0]} really (BCio)
 
 
 
1173,7 → 1177,7
( upd_fr_cbsh ) |
(CB_BIT == ir2[9:6]) |
( ed_blk_cp ) |
(ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) |
(ED_INsREG_6C7 == {ir2[9:6],ir2[2:0]}) |
(CCF == ir2 ) |
(CPL == ir2 ) |
(DAA == ir2 ) |
1202,7 → 1206,7
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[7:6],ir2[2:0]})
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};
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};
/trunk/rtl/z80_memstate2.v
1,6 → 1,6
///////////////////////////////////////////////////////////////////////////////////////////////////
// //
// file name: memstate2.v //
// file name: memstate2.v //
// description: memory opertions for z80 //
// project: wb_z80 //
// //
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.1 2004-04-27 21:27:13 bporcella Exp $
// $Id: z80_memstate2.v,v 1.2 2004-05-13 14:58:53 bporcella Exp $
//
// $Date: 2004-04-27 21:27:13 $
// $Revision: 1.1 $
// $Date: 2004-05-13 14:58:53 $
// $Revision: 1.2 $
// $Author: bporcella $
// $Locker: $
// $State: Exp $
119,6 → 119,9
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.1 2004/04/27 21:27:13 bporcella
// first core build
//
// Revision 1.8 2004/04/19 19:13:28 bporcella
// real lint problems pretty much fixed -- need another look - but need to get on to other things first
//
301,7 → 304,9
I1_RET = 4'ha,
I1_RMW = 4'hb,
I1_RST = 4'hc,
I1_R2R = 4'hd ;
I1_R2R = 4'hd,
I1_JMPR = 4'he,
I1_HALT = 4'hf;
 
 
// A note here on the choices of mnemonics..... in general, the target registers of
326,7 → 331,7
MEM_OSADRP1 = 5'h0d, // "" "" ""
MEM_IFRST = 5'h0e, // special address transfer
MEM_IFREL_N = 5'h0f, // special address transfer for jmp rel
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
454,11 → 459,11
{I1DCNT {ANDsN == ir1}} & I1_N |// AND N ; E6 XX
{I1DCNT {CPsN == ir1}} & I1_N |// CP N ; FE XX
{I1DCNT {INsA_6N7 == ir1}} & I1_N |// IN A,(N) ; DB XX
{I1DCNT {JRs$t2 == ir1}} & I1_N |// JR $+2 ; 18 XX
{I1DCNT {JRsC_$t2 == ir1}} & I1_N |// JR C,$+2 ; 38 XX
{I1DCNT {JRsNC_$t2 == ir1}} & I1_N |// JR NC,$+2 ; 30 XX
{I1DCNT {JRsZ_$t2 == ir1}} & I1_N |// JR Z,$+2 ; 28 XX
{I1DCNT {JRsNZ_$t2 == ir1}} & I1_N |// JR NZ,$+2 ; 20 XX
{I1DCNT {JRs$t2 == ir1}} & I1_JMPR|// JR $+2 ; 18 XX
{I1DCNT {JRsC_$t2 == ir1}} & I1_JMPR|// JR C,$+2 ; 38 XX
{I1DCNT {JRsNC_$t2 == ir1}} & I1_JMPR|// JR NC,$+2 ; 30 XX
{I1DCNT {JRsZ_$t2 == ir1}} & I1_JMPR|// JR Z,$+2 ; 28 XX
{I1DCNT {JRsNZ_$t2 == ir1}} & I1_JMPR|// JR NZ,$+2 ; 20 XX
{I1DCNT {LDs6HL7_N == ir1}} & I1_N |// LD (HL),N ; 36 XX
{I1DCNT {LDsA_N == ir1}} & I1_N |// LD A,N ; 3E XX
{I1DCNT {LDsB_N == ir1}} & I1_N |// LD B,N ; 06 XX
584,7 → 589,7
{I1DCNT {EXX == ir1}} & I1_R2R |// EXX ; D9
{I1DCNT {EXsAF_AFp == ir1}} & I1_R2R |// EX AF,AF' ; 08
{I1DCNT {EXsDE_HL == ir1}} & I1_R2R |// EX DE,HL ; EB
{I1DCNT {HALT == ir1}} & I1_R2R |// HALT ; 76
{I1DCNT {HALT == ir1}} & I1_HALT |// HALT ; 76
{I1DCNT {INCsA == ir1}} & I1_R2R |// INC A ; 3C
{I1DCNT {INCsB == ir1}} & I1_R2R |// INC B ; 04
{I1DCNT {INCsBC == ir1}} & I1_R2R |// INC BC ; 03
812,7 → 817,14
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] ;
wire jmpr =
JRs$t2 == ir1 |
JRsC_$t2 == ir1 |
JRsNC_$t2 == ir1 |
JRsZ_$t2 == ir1 |
JRsNZ_$t2 == ir1 ;
//assign { sf, zf. f5f, hf, f3f, pvf, nf, cf} = fr;
wire callnn_true = CALLsC_NN == ir1 & cf |
916,16 → 928,32
// 2) flag tests when fr is being updated
// 3) sp issues see below LDsSP_HL DECsSP INCsSP
// ANY OTHERS ???
// 4) Indirect addressing -(HL) (BC) (DE) when address registers are updated
//
// upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr,
wire use_hl_exec = LDsSP_HL == ir1;
wire use_hl_exec = LDsSP_HL == ir1 | INCs6HL7 == ir1 |
ADCsA_6HL7 == ir1 | SBCs6HL7 == ir1 |
ADDsA_6HL7 == ir1 | SUBs6HL7 == ir1 |
ANDs6HL7 == ir1 | XORs6HL7 == ir1 |
CPs6HL7 == ir1 | LDs6HL7_A == ir1 |
LDsA_6HL7 == ir1 | LDs6HL7_B == ir1 |
LDsB_6HL7 == ir1 | LDs6HL7_C == ir1 |
LDsC_6HL7 == ir1 | LDs6HL7_D == ir1 |
LDsD_6HL7 == ir1 | LDs6HL7_E == ir1 |
LDsE_6HL7 == ir1 | LDs6HL7_H == ir1 |
LDsH_6HL7 == ir1 | LDs6HL7_L == ir1 |
LDsL_6HL7 == ir1 | JPsHL == ir1 |
ORs6HL7 == ir1 | DECs6HL7 == ir1 ;
wire use_bc_exec = LDsA_6BC7 == ir1 |
LDs6BC7_A == ir1 ;
wire use_de_exec = LDs6DE7_A == ir1 |
LDsA_6DE7 == ir1 ;
wire use_sp_exec = MEM_OFSP == next_mem_state |
MEM_OSSP == next_mem_state ;
wire upd_sp_exec = DECsSP == ir2 |
INCsSP == ir2 ;
 
 
 
wire use_fr_exec = ( RETsC == ir1 |
RETsM == ir1 |
RETsNC == ir1 |
937,10 → 965,14
 
assign hazard = (dec_state == DEC_EXEC & exec_ir2 ) & ( upd_fr & use_fr_exec |
upd_ar & os_a |
upd_br & os_b |
upd_cr & os_c |
upd_dr & os_d |
upd_er & os_e |
upd_br & os_b |
upd_br & use_bc_exec |
upd_cr & os_c |
upd_cr & use_bc_exec |
upd_dr & os_d |
upd_dr & use_de_exec |
upd_er & os_e |
upd_er & use_de_exec |
upd_hr & os_h |
upd_lr & os_l |
upd_hr & use_hl_exec |
1009,7 → 1041,7
// |_____| |_____|
// MEM_NOP
// MEM_IFPP1 MEM_OFIXpD MEM_CALL MEM_IFRST MEM_OFHL_PM MEM_IOF_C
// MEM_OS1, MEM_OSIXpD MEM_OSNN, MEM_IFREL_N MEM_OSHL_PM MEM_IOS_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
// MEM_OSSP MEM_OSSP_P MEM_OSADRP1 MEM_IFINT MEM_OS_HL_N
1020,7 → 1052,7
next_mem_state == MEM_OSSP |
next_mem_state == MEM_CALL ;
wire src_pc = next_mem_state == MEM_IFPP1 |
next_mem_state == MEM_IFREL_N ;
next_mem_state == MEM_REL2PC ;
 
wire src_nn = next_mem_state == MEM_IFNN |
next_mem_state == MEM_OSNN |
1090,15 → 1122,17
next_mem_state ==MEM_OFSP |
next_mem_state ==MEM_IFPP1 |
next_mem_state ==MEM_OSSP_PCM2 |
next_mem_state ==MEM_IFNN |
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_OFSP ;
next_mem_state ==MEM_CALL |
next_mem_state == MEM_OSSP ;
 
wire reln = next_mem_state == MEM_IFREL_N |
wire reln = next_mem_state == MEM_REL2PC |
next_mem_state == MEM_OFIXpD |
next_mem_state == MEM_OSIXpD ;
 
1114,6 → 1148,9
 
wire pre_inc_dec = next_mem_state == MEM_CALL |
next_mem_state == MEM_OSSP_P |
next_mem_state == MEM_REL2PC |
next_mem_state == MEM_OFIXpD |
next_mem_state == MEM_OSIXpD |
next_mem_state == MEM_OSSP ;
 
 
1166,10 → 1203,10
I1_DDFD : next_state = {DEC_DDFD, MEM_IFPP1, IPIPE_EN1};// gets real inst
I1_ED : next_state = {DEC_ED, MEM_IFPP1, IPIPE_EN1};
I1_JMP : next_state = {DEC_IF2, MEM_JMPHL, IPIPE_NOP};
I1_N : next_state = {DEC_N, MEM_IFPP1, IPIPE_ENN};
I1_N : next_state = {DEC_N, MEM_IFPP1, IPIPE_ENNEN2};
I1_NN : next_state = {DEC_NN, MEM_IFPP1, IPIPE_ENN};
I1_OF : next_state = {DEC_OF, MEM_OF1, IPIPE_EN12};//transfer, don't activate
I1_OS : next_state = {DEC_IF2, MEM_OS1, IPIPE_EN1}; // -> ir2_NOP
I1_OS : next_state = {DEC_IF2A, MEM_OS1, IPIPE_EN1}; // -> ir2_NOP
I1_POP : next_state = {DEC_POP, MEM_OFSP, IPIPE_EN12};
I1_PUSH : next_state = {DEC_PUSH, MEM_OSSP, IPIPE_EN12};
I1_RET : next_state = {DEC_RET, MEM_OFSP, IPIPE_EN12};
1176,6 → 1213,8
I1_RMW : next_state = {DEC_RMW, MEM_OF1, IPIPE_EN12};//can't activate till data rdy
I1_RST : next_state = {DEC_IF2, MEM_IFRST, IPIPE_ENN};
I1_R2R : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2};
I1_JMPR : next_state = {DEC_N, MEM_NOP, IPIPE_ENN};
I1_HALT : next_state = {DEC_HALT, MEM_NOP , IPIPE_EN2};
default : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; //I1_R2R
endcase
DEC_CB: if (cb_mem) next_state = {DEC_CBM, MEM_OF1, IPIPE_EN12};
1199,6 → 1238,8
I1_RMW : next_state = {DEC_RMW, MEM_OF1, IPIPE_EN12};
I1_RST : next_state = {DEC_IF2, MEM_IFRST, 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_HALT : next_state = {DEC_HALT, MEM_NOP , IPIPE_EN2};
default : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; //I1_R2R
endcase
DEC_ED:
1251,10 → 1292,11
DEC_N:
if (INsA_6N7== ir1) next_state = {DEC_NIN, MEM_IOF_N, IPIPE_EN12};
else if (OUTs6N7_A==ir1) next_state = {DEC_IF1, MEM_IOS_N, IPIPE_EN12};
else if (OUTs6N7_A==ir1) next_state = {DEC_IF2A, MEM_IOS_N, IPIPE_EN1};
else if (LDs6HL7_N==ir1) next_state = {DEC_IF1, MEM_OS_HL_N, IPIPE_EN12};
else if (jmpr_true) next_state = {DEC_IF2, MEM_IFREL_N, IPIPE_NOP};
else next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2};//r2r or false jumps
else if (jmpr_true) next_state = {DEC_IF1, MEM_REL2PC, IPIPE_NOP};
else if (jmpr) next_state = {DEC_IF2, MEM_IFPP1, IPIPE_NOP};
else next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2};//r2r
DEC_NIN: next_state = {DEC_IF2, MEM_IFPP1, IPIPE_ENNA2};
1302,7 → 1344,7
DEC_RET: next_state = { DEC_RET2, MEM_OFSP, IPIPE_ENN };
DEC_RET2: next_state = { DEC_NNCALL2, MEM_NOP, IPIPE_ENN };
DEC_RET2: next_state = { DEC_NNJMP, MEM_NOP, IPIPE_ENN };
// blow off a tick so we don't gronk adr
DEC_RMW: next_state = {DEC_RMW2, MEM_NOP, IPIPE_ENNA2}; //activate
DEC_RMW2: next_state = {DEC_IF1 , MEM_OSADR, IPIPE_NOP }; // from nn
1353,7 → 1395,7
always @(posedge wb_clk_i or posedge rst_i)
if (rst_i) ir1 <= NOP;
else if (wb_rdy_nhz & next_pipe_state[3]) ir1 <= {2'b0, wb_dat_i} ;
else if ( wb_rdy_nhz &update_prefix ) ir1 <= {ir1[7:0]==8'hed, ir1[7:0]==8'hcd, ir1[7:0]};
else if ( wb_rdy_nhz &update_prefix ) ir1 <= {ir1[7:0]==8'hed, ir1[7:0]==8'hcb, ir1[7:0]};
 
//----------- prefix states -----------------------------------------
// strings of prefix insts are ignored up to last one. Also dded and fded are ignored
1360,10 → 1402,10
// but ddcd and fdcd are defined prefix sets.
//
always @(posedge wb_clk_i)
if (wb_rdy_nhz & next_pipe_state[3]) {ir1dd, ir1fd } <= 2'b0;
if (wb_rdy_nhz & next_dec_state == DEC_EXEC) {ir1dd, ir1fd } <= 2'b0;
else if ( wb_rdy_nhz & update_prefix )
{ir1dd, ir1fd } <= {ir1dd | (ir1[7:0]==8'hdd ) & (ir1[7:0]!=8'hed) & (ir1[7:0]!=8'hfd),
ir1fd | (ir1[7:0]==8'hfd ) & (ir1[7:0]!=8'hed) & (ir1[7:0]!=8'hdd) };
{ir1dd, ir1fd } <= { (ir1[7:0]==8'hdd ) | ir1dd & (ir1[7:0]!=8'hed) & (ir1[7:0]!=8'hfd),
(ir1[7:0]==8'hfd ) | ir1fd & (ir1[7:0]!=8'hed) & (ir1[7:0]!=8'hdd) };
//------------------- inst reg #2 -----------------------------------
// This stuff is key to the data hazard logic. Hazards arise only AFTER activation of
1413,8 → 1455,8
//-------------------------- memory interface stuff ----------------------------
 
 
// -- wb_adr_o
always @(posedge wb_clk_i) if (wb_rdy) wb_adr_o <= mux21;
// -- wb_adr_o 4/30/04 to wb_rdy_nhz -- hazard gronks this otherwise
always @(posedge wb_clk_i) if (wb_rdy_nhz) wb_adr_o <= mux21;
 
// -- wb_we_o;
 
1427,15 → 1469,16
// -- wb_cyc_o
// below is old logic -- appears not needed
//wire no_wb_start = mem_idle | mem_halt | mem_op3 & blk_cmp_reg | mem_op1 & rmw_reg;
wire no_mem_start = (next_mem_state == MEM_NOP) | (next_mem_state == MEM_REL2PC);
always @(posedge wb_clk_i or posedge rst_i)
if (rst_i) wb_cyc_o <= 1'b0;
else if (wb_rdy_nhz) wb_cyc_o <= next_mem_state != MEM_NOP ;
else if (wb_rdy_nhz) wb_cyc_o <= ~no_mem_start;
 
// -- wb_stb_o;
 
always @(posedge wb_clk_i or posedge rst_i)
if (rst_i) wb_stb_o <= 1'b0;
else if (wb_rdy_nhz) wb_stb_o <= next_mem_state != MEM_NOP ;
else if (wb_rdy_nhz) wb_stb_o <= ~no_mem_start ;
 
 
// -- wb_lock lets not worry about lock unless somebody thinks it matters.
1479,18 → 1522,22
//issue: how is EXs6SP7_HL implemented -- it is known as a rmw - and only trick for this file is
// that nn must be properly updates with ir2
 
// 4/30/04 changed else if (we_next) we had a hazard and this term
// seemed to be gronking nn. see if it works now. Pretty tricky stuff.
always @(posedge wb_clk_i or posedge rst_i)
if (rst_i) flag_os1 <= 1'b0;
if (rst_i) flag_os1 <= 1'b0;
else if ((DEC_EXEC == next_dec_state) & wb_rdy) flag_os1 <= 1'b0;
else if ( we_next ) flag_os1 <= 1'b1;
else if ( we_next & wb_rdy_nhz ) flag_os1 <= 1'b1;
 
 
wire [15:0] pc_2 = pc - 16'h2;
always @(posedge wb_clk_i)
if (wb_rdy_nhz)
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] } ;
else if(we_next & ( next_mem_state == MEM_CALL)) nn <= {pc[7:0], pc[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(EXs6SP7_HL== ir2 & ir2dd & exec_ir2) nn <= ixr;
else if(EXs6SP7_HL== ir2 & ir2fd & exec_ir2) nn <= iyr;
1499,16 → 1546,17
else if(we_next & ( next_mem_state == MEM_OS1 |
next_mem_state == MEM_OSIXpD |
next_mem_state == MEM_OSSP |
next_mem_state == MEM_IOS_N |
next_mem_state == MEM_OSNN ) )
begin
if (os_a) nn[15:8] <= ar;
if (os_b) nn[15:8] <= br;
if (os_c) nn <= {cr, br }; // use for PUSHsBC
if (os_c) nn <= {br, cr }; // use for PUSHsBC
if (os_d) nn[15:8] <= dr;
if (os_e) nn <= {er, dr }; // use for PUSHsDE
if (os_e) nn <= {dr, er }; // use for PUSHsDE
if (os_h) nn[15:8] <= hr;
if (os_l) nn <= {lr, hr }; // use for PUSHsHL
if (os_f) nn <= {fr, ar }; // use for PUSHsAF
if (os_l) nn <= {hr, lr }; // use for PUSHsHL
if (os_f) nn <= {ar, fr }; // use for PUSHsAF
end
// 4/19/2004 previously no if here - if not needed we don't need next_pipe_state[1] eithor
else if (next_pipe_state[1]) nn <= { wb_dat_i, nn[15:8] };
1526,7 → 1574,8
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_IFNN ) pc <= src_mux;
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;
end
 
1551,6 → 1600,7
// ED_LDsREG_6NN7 REG== SP // do from ir2 - no hazard as executed on IF2 - refill pipe
 
always @(posedge wb_clk_i )
begin
if (exec_ir2 ) // this has priority of course
begin
if (LDsSP_NN == ir2) sp <= nn;
1558,7 → 1608,7
if ( DECsSP == ir2 ) sp <= add16;
if ( INCsSP == ir2 ) sp <= add16;
end
else if (wb_rdy_nhz)
if (wb_rdy_nhz) //the no hazard term should kill these if any abvove is happening in parallel
begin
if ( DECsSP == ir1 & dec_state == DEC_EXEC) sp <= adr_alu;
if ( INCsSP == ir1 & dec_state == DEC_EXEC) sp <= adr_alu;
1567,7 → 1617,9
if (next_mem_state == MEM_OSSP ) sp <= adr_alu;
if (next_mem_state == MEM_OSSP_PCM2 ) sp <= adr_alu;
if (next_mem_state == MEM_OSSP_P ) sp <= adr_alu;
if (next_mem_state == MEM_CALL ) sp <= adr_alu;
end
end
//----------------- inst hazard logic ------------------------------------------
 
 

powered by: WebSVN 2.1.0

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