1 |
2 |
mihal |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
2 |
|
|
// //
|
3 |
|
|
// file name: inst_exec.v //
|
4 |
|
|
// description: main execution engine for wishbone z80 //
|
5 |
|
|
// project: wb_z80 //
|
6 |
|
|
// //
|
7 |
|
|
// Author: B.J. Porcella //
|
8 |
|
|
// e-mail: bporcella@sbcglobal.net //
|
9 |
|
|
// //
|
10 |
|
|
// //
|
11 |
|
|
// //
|
12 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
13 |
|
|
// //
|
14 |
|
|
// Copyright (C) 2000-2002 B.J. Porcella //
|
15 |
|
|
// Real Time Solutions //
|
16 |
|
|
// //
|
17 |
|
|
// //
|
18 |
|
|
// This source file may be used and distributed without //
|
19 |
|
|
// restriction provided that this copyright statement is not //
|
20 |
|
|
// removed from the file and that any derivative work contains //
|
21 |
|
|
// the original copyright notice and the associated disclaimer. //
|
22 |
|
|
// //
|
23 |
|
|
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //
|
24 |
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //
|
25 |
|
|
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //
|
26 |
|
|
// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //
|
27 |
|
|
// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //
|
28 |
|
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //
|
29 |
|
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //
|
30 |
|
|
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //
|
31 |
|
|
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //
|
32 |
|
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //
|
33 |
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //
|
34 |
|
|
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //
|
35 |
|
|
// POSSIBILITY OF SUCH DAMAGE. //
|
36 |
|
|
// //
|
37 |
|
|
//-------1---------2---------3--------Comments on file -------------7---------8---------9--------0
|
38 |
|
|
//
|
39 |
|
|
// This file contains the data related registers of the z80 and the
|
40 |
|
|
// logic required to update them. Included registers are:
|
41 |
|
|
// ar fr
|
42 |
|
|
// br cr
|
43 |
|
|
// dr er
|
44 |
|
|
// hr lr
|
45 |
|
|
// ixr
|
46 |
|
|
// iyr
|
47 |
|
|
// intr
|
48 |
|
|
//
|
49 |
|
|
// and the "prime" registers
|
50 |
|
|
// ap fp
|
51 |
|
|
// bp cp
|
52 |
|
|
// dp ep
|
53 |
|
|
// hp lp
|
54 |
|
|
//
|
55 |
|
|
// This logic can be considered a "slave" to the memstate sequencer (in memstate2.v).
|
56 |
|
|
// as memstate sequencer executes any instruction from ir1 (the of - os pipe) the instruction
|
57 |
|
|
// gets transferred to ir2 - which now becomes active.
|
58 |
|
|
//
|
59 |
|
|
// In the case of any memory type instruction (HL) , the pipeline must stall 1 tick to get the
|
60 |
|
|
// operand into the nn register. This file logic needs not understand any of that -- just
|
61 |
|
|
// execute when told to (ir2_val).
|
62 |
|
|
//
|
63 |
|
|
// From a block diagram standpoint this file is somewhat messy. There are multiple ALU's and
|
64 |
|
|
// multiple source multiplexors. Part of the reason for this is hardware speed - the
|
65 |
|
|
// various additions start pretty early in the cycle ( as not much decode logic is needed to
|
66 |
|
|
// get them started. In parallel with that - the destination selectors ( which require more
|
67 |
|
|
// complex decoding logic ) are "doing thier thing" No claim that this is absolute optimum - any
|
68 |
|
|
// good synthesizer should be able to make the basic structure faster when flattened. However,
|
69 |
|
|
// the intention is that even if the synthesizer is pretty primitive -- reasonably fast hardware
|
70 |
|
|
// will be produced.
|
71 |
|
|
//
|
72 |
|
|
//-------1---------2---------3--------CVS Log -----------------------7---------8---------9--------0
|
73 |
|
|
//
|
74 |
|
|
// $Id: inst_exec.v,v 1.1.1.1 2004-06-18 08:38:42 mihal Exp $
|
75 |
|
|
//
|
76 |
|
|
// $Date: 2004-06-18 08:38:42 $
|
77 |
|
|
// $Revision: 1.1.1.1 $
|
78 |
|
|
// $Author: mihal $
|
79 |
|
|
// $Locker: $
|
80 |
|
|
// $State: Exp $
|
81 |
|
|
//
|
82 |
|
|
// Change History:
|
83 |
|
|
// $Log: not supported by cvs2svn $
|
84 |
|
|
// Revision 1.1.1.1 2004/04/13 23:49:54 bporcella
|
85 |
|
|
// import first files
|
86 |
|
|
//
|
87 |
|
|
//
|
88 |
|
|
//
|
89 |
|
|
//-------1---------2---------3--------Module Name and Port List------7---------8---------9--------0
|
90 |
|
|
module inst_exec( br_eq0,
|
91 |
|
|
cr_eq0,
|
92 |
|
|
upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr,
|
93 |
|
|
ar, fr, br, cr, dr, er, hr, lr, intr,
|
94 |
|
|
ixr, iyr, add16,
|
95 |
|
|
exec_ir2,
|
96 |
|
|
exec_decbc, exec_decb,
|
97 |
|
|
ir2,
|
98 |
|
|
clk,
|
99 |
|
|
rst,
|
100 |
|
|
nn, sp,
|
101 |
|
|
dd_grp,
|
102 |
|
|
fd_grp
|
103 |
|
|
);
|
104 |
|
|
|
105 |
|
|
//-------1---------2---------3--------Output Ports---------6---------7---------8---------9--------0
|
106 |
|
|
output br_eq0;
|
107 |
|
|
output cr_eq0;
|
108 |
|
|
output upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr;
|
109 |
|
|
output [7:0] ar, fr, br, cr, dr, er, hr, lr, intr;
|
110 |
|
|
output [15:0] ixr, iyr;
|
111 |
|
|
output [15:0] add16;
|
112 |
|
|
//-------1---------2---------3--------Input Ports----------6---------7---------8---------9--------0
|
113 |
|
|
input exec_ir2;
|
114 |
|
|
input exec_decbc; // in general this needs to happen at different time from exec
|
115 |
|
|
input exec_decb; // in general - we don't have the EB instruction (yet) when this hits
|
116 |
|
|
input [9:0] ir2;
|
117 |
|
|
input clk;
|
118 |
|
|
input rst;
|
119 |
|
|
input [15:0] nn, sp;
|
120 |
|
|
input dd_grp; // this must be ir2
|
121 |
|
|
input fd_grp;
|
122 |
|
|
|
123 |
|
|
//-------1---------2---------3--------Parameters-----------6---------7---------8---------9--------0
|
124 |
|
|
`include "opcodes.v"
|
125 |
|
|
|
126 |
|
|
//-------1---------2---------3--------Wires----------------6---------7---------8---------9--------0
|
127 |
|
|
|
128 |
|
|
wire [7:0] src_pqr; // arithmetic sources gven by ir2[2:0]
|
129 |
|
|
wire [7:0] src_hr ;
|
130 |
|
|
wire [7:0] src_lr ;
|
131 |
|
|
wire [7:0] alu_out; // {CF. 8bit_result}
|
132 |
|
|
wire alu_cry;
|
133 |
|
|
|
134 |
|
|
wire c_in0, c_out7, c_in8, c_out11, cout15;
|
135 |
|
|
wire [15:0] src_a, src_b;
|
136 |
|
|
wire [15:0] add16;
|
137 |
|
|
wire sf, zf, f5f, hf, f3f, pvf, nf, cf;
|
138 |
|
|
wire [7:0] daa_alu; // {cry, number} hf goes to 0 always.
|
139 |
|
|
wire daa_cry;
|
140 |
|
|
wire upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_fr, upd_hr, upd_lr;
|
141 |
|
|
wire c_8out3;
|
142 |
|
|
wire [7:0] add_8bit;
|
143 |
|
|
|
144 |
|
|
wire src_dblhr ;
|
145 |
|
|
wire src_cb_r20 ;
|
146 |
|
|
wire src_pqr20 ;
|
147 |
|
|
wire src_pqr53 ;
|
148 |
|
|
wire src_dbl ;
|
149 |
|
|
wire [7:0] alu8_fr ;
|
150 |
|
|
wire alu8_nf ;
|
151 |
|
|
wire c_8out7 ;
|
152 |
|
|
wire alu8_cry ;
|
153 |
|
|
wire alu8_hcry ;
|
154 |
|
|
wire [7:0] alu8_out ;
|
155 |
|
|
wire add16_ofl ;
|
156 |
|
|
wire c_16out7 ;
|
157 |
|
|
wire c_16out11 ;
|
158 |
|
|
wire c_16out15 ;
|
159 |
|
|
wire c_16in0 ;
|
160 |
|
|
wire sh_cry ;
|
161 |
|
|
wire [7:0] sh_alu ;
|
162 |
|
|
wire sh_alu_act ;
|
163 |
|
|
wire bit_alu_act ;
|
164 |
|
|
wire [7:0] bit_alu ;
|
165 |
|
|
wire [7:0] decc_alu ;
|
166 |
|
|
wire [7:0] decb_alu ;
|
167 |
|
|
wire upd_a_alu8 ;
|
168 |
|
|
wire up_a_sh_alu ;
|
169 |
|
|
wire up_a_src_pqr ;
|
170 |
|
|
wire up_a_n ;
|
171 |
|
|
wire upd_b_alu8 ;
|
172 |
|
|
wire up_b_src_pqr ;
|
173 |
|
|
wire up_b_add16 ;
|
174 |
|
|
wire [7:0] sh_src ;
|
175 |
|
|
|
176 |
|
|
wire up_c_add16 ;
|
177 |
|
|
wire upd_c_alu8 ;
|
178 |
|
|
wire up_c_src_pqr ;
|
179 |
|
|
wire up_d_add16 ;
|
180 |
|
|
wire upd_d_alu8 ;
|
181 |
|
|
wire up_d_src_pqr ;
|
182 |
|
|
wire up_e_add16 ;
|
183 |
|
|
wire upd_e_alu8 ;
|
184 |
|
|
wire up_e_src_pqr ;
|
185 |
|
|
wire up_h_add16 ;
|
186 |
|
|
wire upd_h_alu8 ;
|
187 |
|
|
wire upd_h_src_pqr ;
|
188 |
|
|
wire up_l_add16 ;
|
189 |
|
|
wire upd_l_alu8 ;
|
190 |
|
|
wire upd_l_src_pqr ;
|
191 |
|
|
|
192 |
|
|
wire upd_fr_alu8 ;
|
193 |
|
|
wire upd_fr_add16 ;
|
194 |
|
|
wire upd_fr_edadd16 ;
|
195 |
|
|
wire upd_fr_sh ;
|
196 |
|
|
wire upd_fr_cbsh ;
|
197 |
|
|
wire eb_blk_mv ;
|
198 |
|
|
|
199 |
|
|
//-------1---------2---------3--------Registers------------6---------7---------8---------9--------0
|
200 |
|
|
|
201 |
|
|
reg [7:0] ar, fr, br, cr, dr, er, hr, lr, intr;
|
202 |
|
|
reg [7:0] ap, fp, bp, cp, dp, ep, hp, lp;
|
203 |
|
|
reg [15:0] ixr, iyr;
|
204 |
|
|
//-------1---------2---------3--------Assignments----------6---------7---------8---------9--------0
|
205 |
|
|
|
206 |
|
|
// it appears that dd and fd as a prefix to cb has a significantly modfied fuction......
|
207 |
|
|
// specifically, it is assumed that a memory operation is to be implemented (ix + d)
|
208 |
|
|
// , In fact the
|
209 |
|
|
// pipeline is such that we can make a fetch for free - so we will do that..... the
|
210 |
|
|
// prefix flags should not be set here -- all we will know on execution is that it is a
|
211 |
|
|
// cb instruction. ---- src is always nn
|
212 |
|
|
|
213 |
|
|
|
214 |
|
|
assign src_hr = dd_grp ? ixr[15:8] :
|
215 |
|
|
fd_grp ? iyr[15:8] :
|
216 |
|
|
hr ;
|
217 |
|
|
|
218 |
|
|
assign src_lr = dd_grp ? ixr[7:0] :
|
219 |
|
|
fd_grp ? iyr[7:0] :
|
220 |
|
|
lr ;
|
221 |
|
|
|
222 |
|
|
assign src_dblhr = dd_grp ? ixr : // ed grp instructions (ADC HL ; SBC HL are not affected -
|
223 |
|
|
fd_grp ? iyr : // instruction assembler assures this - ed_grp has no prefix
|
224 |
|
|
{hr, lr} ;
|
225 |
|
|
|
226 |
|
|
assign src_cb_r20 = (ddcb_grp | fdcb_grp) ? nn[7:0] :
|
227 |
|
|
cb_grp ? src_pqr20 :
|
228 |
|
|
ar ;
|
229 |
|
|
|
230 |
|
|
|
231 |
|
|
assign src_pqr20 = {8{ir2[2:0]==REG8_B }} & br |
|
232 |
|
|
{8{ir2[2:0]==REG8_C }} & cr |
|
233 |
|
|
{8{ir2[2:0]==REG8_D }} & dr |
|
234 |
|
|
{8{ir2[2:0]==REG8_E }} & er |
|
235 |
|
|
{8{ir2[2:0]==REG8_H }} & src_hr |
|
236 |
|
|
{8{ir2[2:0]==REG8_L }} & src_lr |
|
237 |
|
|
{8{ir2[2:0]==REG8_MEM}} & nn[7:0] |
|
238 |
|
|
{8{ir2[2:0]==REG8_A }} & ar ;
|
239 |
|
|
|
240 |
|
|
assign src_pqr53 = {8{ir2[5:3]==REG8_B }} & br |
|
241 |
|
|
{8{ir2[5:3]==REG8_C }} & cr |
|
242 |
|
|
{8{ir2[5:3]==REG8_D }} & dr |
|
243 |
|
|
{8{ir2[5:3]==REG8_E }} & er |
|
244 |
|
|
{8{ir2[5:3]==REG8_H }} & src_hr |
|
245 |
|
|
{8{ir2[5:3]==REG8_L }} & src_lr |
|
246 |
|
|
{8{ir2[5:3]==REG8_MEM}} & nn[7:0] |
|
247 |
|
|
{8{ir2[5:3]==REG8_A }} & ar ;
|
248 |
|
|
|
249 |
|
|
|
250 |
|
|
assign src_dbl = {16{ir2[5:4]==2'b00}} & {br, cr} |
|
251 |
|
|
{16{ir2[5:4]==2'b01}} & {dr, er} |
|
252 |
|
|
{16{ir2[5:4]==2'b10}} & src_sshr |
|
253 |
|
|
{16{ir2[5:4]==2'b11}} & sp ;
|
254 |
|
|
|
255 |
|
|
|
256 |
|
|
|
257 |
|
|
|
258 |
|
|
|
259 |
|
|
// I wonder how well the synthesizer can reduce this??? - It is probably worth spending
|
260 |
|
|
// some time during physical design to see if a more low level description would help --
|
261 |
|
|
// there is somebody out there who knows - and there is probably a good low level description.
|
262 |
|
|
//
|
263 |
|
|
// guess its kind of important to understand precisely what the synthesizer does
|
264 |
|
|
// with some of the status things we need also.
|
265 |
|
|
//
|
266 |
|
|
//
|
267 |
|
|
// The nastiest status to get is HF. Really need 4 bit adders to do that ( or reproduce a lot
|
268 |
|
|
// of logic.) I don't have a lot of confdence in the synthesier's ability to minimize arithmetic
|
269 |
|
|
// operations -- Its a moving target of course, but I've seen some really silly stuff come out
|
270 |
|
|
// of synthesis when you use a "+" operator. guess I will be pretty explicit here.
|
271 |
|
|
// Documentation of the HF is srange. IN and OUT operators are defined as X -- but 16 bit operations
|
272 |
|
|
// get set by CRY from bit 11. (Do I care??? ) well probably not but it is documented - so should
|
273 |
|
|
// be tested i guess.
|
274 |
|
|
//
|
275 |
|
|
//
|
276 |
|
|
// may want to re-define as a module with carry look-ahead ?
|
277 |
|
|
//
|
278 |
|
|
// Had a notion to define a single adder - subtractor for both 8 and 16 bit operations, but
|
279 |
|
|
// getting into source mux issues that solution scared me..... Worry the cry flag might
|
280 |
|
|
// become a worst case path. As defined, a good chunk of the decode process can go on in
|
281 |
|
|
// parallel with the cry computation --- with final decisions made using a small mux at
|
282 |
|
|
// the flag register.
|
283 |
|
|
// ------------ 8 bit adder for accumulator ops plus the INC DEC ops ---------------------
|
284 |
|
|
// It is documented that the hf is modified by the INC and DEC ops even if ar is not the
|
285 |
|
|
// destination of result --- clearly hf and nf are pretty usless on a INC B but ours is
|
286 |
|
|
// not to reason why :-) ---- well its fun to bitch about silly stuff like this.
|
287 |
|
|
// ( not as much fun to deal with instruction tests testing "features" -- or worse programmers
|
288 |
|
|
// who figure out ways to use theses "features". )
|
289 |
|
|
//
|
290 |
|
|
// 8 bit adder with cry out of bit 3 used for most operations on A as well as the
|
291 |
|
|
// inc/dec instructions. also need to get ED44 (ar <= -ar) working here
|
292 |
|
|
wire [7:0] src_pqri; // use just here and below
|
293 |
|
|
wire [7:0] src_aor_cnst = ed_blk_cp ? ar : // CPI CPIR CPD CPDR
|
294 |
|
|
ed_grp ? 8'h0 : // for ed44 -a
|
295 |
|
|
ir2[7] ? ar :
|
296 |
|
|
ir2[0] ? 8'hff :
|
297 |
|
|
8'h00 ;
|
298 |
|
|
|
299 |
|
|
//--------------- the "standard" flag logic -----------------------------
|
300 |
|
|
// sf zf f5f hf
|
301 |
|
|
assign alu8_fr ={alu8_out[7], ~|alu8_out, alu8_out[5], alu8_hcry,
|
302 |
|
|
// f3f fpv fn fc
|
303 |
|
|
alu8_out[3], alu8_out[7], alu8_nf, c_8out7 };
|
304 |
|
|
|
305 |
|
|
//assign alu8_pvf = (ir2[7:3]==5'b10100 | ir2[7:3]==5'b10101 | ir2[7:3]==5'b10110) ?
|
306 |
|
|
// ~^alu8_out : // even parity
|
307 |
|
|
// (src_aor_cnst[7]==src_pqri[7]) & (src_aor_cnst[7]!=alu8_out[7]) ; // ofl
|
308 |
|
|
|
309 |
|
|
assign alu8_nf = (ir2[7:3]==5'b10010) |
|
310 |
|
|
(ir2[7:3]==5'b10011) |
|
311 |
|
|
(ir2[7:6]==2'b00) & ir2[0] |
|
312 |
|
|
ed_grp ;
|
313 |
|
|
|
314 |
|
|
|
315 |
|
|
assign {c_8out3, add_8bit[3:0]} = {1'b0, src_aor_cnst[3:0]} + {1'b0, src_pqri[3:0]} + {4'b0, c_8in0};
|
316 |
|
|
//wire [4:0] ha_temp = {1'b0, src_aor_cnst[3:0]} + {1'b0, src_pqri[3:0]} + {4'b0, c_8in0};
|
317 |
|
|
//assign c_8out3
|
318 |
|
|
|
319 |
|
|
assign {c_8out7, add_8bit[7:4]} = {1'b0, src_aor_cnst[7:4]} + {1'b0, src_pqri[7:4]} + {4'b0, c_8out3};
|
320 |
|
|
|
321 |
|
|
// notice that both inputs and outputs of the adder are being selected below.
|
322 |
|
|
// making ed_blk_cp high priority kind of negates the origional idea of making the
|
323 |
|
|
// decodes fast here --- course when all is included this can't be too fast.
|
324 |
|
|
// Just note for syntheses that this is a slow path that could be improved with some thought.
|
325 |
|
|
//
|
326 |
|
|
assign {alu8_cry, alu8_hcry, alu8_out, src_pqri, c_8in0 }=
|
327 |
|
|
|
328 |
|
|
ed_blk_cp ? {c_8out7,c_8out3, add_8bit, ~src_pqr20, 1'h1} : //CPI CPIR CPD CPDR
|
329 |
|
|
|
330 |
|
|
{14{ir2[7:3]==5'b10000}} & ({c_8out7,c_8out3, add_8bit, src_pqr20, 1'b0} ) |// a+src
|
331 |
|
|
{14{ir2[7:3]==5'b10001}} & ({c_8out7,c_8out3, add_8bit, src_pqr20, cf} ) |// a+src+cf
|
332 |
|
|
{14{ir2[7:3]==5'b10010}} & ({c_8out7,c_8out3, add_8bit, ~src_pqr20, 1'h1} ) |// a-src
|
333 |
|
|
{14{ir2[7:3]==5'b10011}} & ({c_8out7,c_8out3, add_8bit, ~src_pqr20, ~cf } ) |// a-src-cf
|
334 |
|
|
{14{ir2[7:3]==5'b10100}} & ({1'b0 ,1'b1 , ar & src_pqr, src_pqr20, 1'b0} ) |// a&src
|
335 |
|
|
{14{ir2[7:3]==5'b10101}} & ({1'b0 ,1'b0 , ar ^ src_pqr, src_pqr20, 1'b0} ) |// a^src
|
336 |
|
|
{14{ir2[7:3]==5'b10110}} & ({1'b0 ,1'b0 , ar | src_pqr, src_pqr20, 1'b0} ) |// a|src
|
337 |
|
|
{14{ir2[7:3]==5'b10111}} & ({c_8out7,c_8out3, add_8bit, src_pqr20, 1'h1}) |// a-src
|
338 |
|
|
{14{(ir2[7:6]==2'b00)& ~ir2[0] }}& ({ cf,c_8out3, add_8bit, src_pqr53, 1'h1}) |// inc_r main
|
339 |
|
|
{14{(ir2[7:6]==2'b00)& ir2[0] }}& ({ cf,c_8out3, add_8bit, src_pqr53, 1'h0}) |// dec_r
|
340 |
|
|
{14{(ir2[7:6]==2'b01) }}& ({c_8out7,c_8out3, add_8bit, ~a, 1'h1}) ;// ed44 -a
|
341 |
|
|
|
342 |
|
|
|
343 |
|
|
// do some hand decoding here
|
344 |
|
|
// ADDsHL_BC = 'h09, DECsBC = 'h0B, INCsBC = 'h03 compair with {ir2[7:6],ir2[3:0]}
|
345 |
|
|
// ADDsHL_DE = 'h19, DECsDE = 'h1B INCsDE = 'h13 ED_SBCsHL_REG = 6'b01__0010
|
346 |
|
|
// ADDsHL_HL = 'h29, DECsHL = 'h2B INCsHL = 'h23 ED_ADCsHL_REG = 6'b01__1010
|
347 |
|
|
// ADDsHL_SP = 'h39, DECsSP = 'h3B INCsSP = 'h33
|
348 |
|
|
// by inspection just use ir2[3:0] - i guess in a pinch we do't need ir2[2] = but let the
|
349 |
|
|
// synthesizer figure that out. - it should be able to.
|
350 |
|
|
//
|
351 |
|
|
|
352 |
|
|
|
353 |
|
|
// ---------------- 16 bit adder with bit 11 carrry out and bit 8 carry in ------------------
|
354 |
|
|
//
|
355 |
|
|
assign add16_ofl = (src_a[15] == src_b[15]) & (src_a[15] != add16[15]);
|
356 |
|
|
|
357 |
|
|
assign {c_16out7, add16[7:0]} = {1'b0, src_a[7:0]} + {1'b0, src_b[7:0] } + {8'b0, c_16in0};
|
358 |
|
|
assign {c_16out11, add16[11:8]} = {1'b0, src_a[11:8]} + {1'b0, src_b[11:8] } + {4'b0, c_16out7};
|
359 |
|
|
assign {c_16out15, add16[15:12]} = {1'b0, src_a[15:12]} + {1'b0, src_b[15:12]} + {4'b0, c_16out11};
|
360 |
|
|
|
361 |
|
|
assign { src_a, src_b, c_16in0} =
|
362 |
|
|
{17{ir2[3:0] == 4'h9}} & {src_dblhr, src_dbl ,1'b0 } | //ADD
|
363 |
|
|
{17{ir2[3:0] == 4'hb}} & {16'hffff , src_dbl ,1'b0 } | //DEC
|
364 |
|
|
{17{ir2[3:0] == 4'h3}} & {16'h0001 , src_dbl ,1'b0 } | //INC
|
365 |
|
|
{17{ir2[3:0] == 4'h2}} & {src_dblhr, ~src_dbl , ~cf } | //SBC
|
366 |
|
|
{17{ir2[3:0] == 4'ha}} & {src_dblhr, src_dbl , cf } ; //ADC
|
367 |
|
|
|
368 |
|
|
//-------------------------- sh alu --------------------------------------------------
|
369 |
|
|
// shift insructions. Think of these as 8 shift types:
|
370 |
|
|
// RLC RL RRC RR SLA SLL SRA SRL The SLL types appear to be undocumented -- but possibly used
|
371 |
|
|
// in assembly code as they appear to have some utility - and by all accounts operate reliably.
|
372 |
|
|
// The first four are implemented in a single byte inaruction . (A <= sh_op A )
|
373 |
|
|
// All 8 are implemented in the CB group with all registers as potential sources (and dests).
|
374 |
|
|
// if dd_grp or fd_grp is prefix..... source is always the memory. This is undocumented - but
|
375 |
|
|
// may be a useful hint for simplyfing the total machine. Destination registers
|
376 |
|
|
// (if any) get a copy of the updated memory location (This is also true of the bit set and
|
377 |
|
|
// clear instructions in the cb_grp.
|
378 |
|
|
|
379 |
|
|
assign {sh_cry, sh_alu} = {9{ir2[5:3]==3'b000}} & {sh_src, sh_src[7] } | //RLC
|
380 |
|
|
{9{ir2[5:3]==3'b001}} & {sh_src[0], sh_src[0], sh_src[7:1]} | // RRC
|
381 |
|
|
{9{ir2[5:3]==3'b010}} & {sh_src, cf } | //RL
|
382 |
|
|
{9{ir2[5:3]==3'b011}} & {sh_src[0], cf, sh_src[7:1] } | // RR
|
383 |
|
|
{9{ir2[5:3]==3'b100}} & {sh_src, 1'b0} | //SLA
|
384 |
|
|
{9{ir2[5:3]==3'b101}} & {sh_src[0], sh_src[7], sh_src[7:1]} | //SRA
|
385 |
|
|
{9{ir2[5:3]==3'b110}} & {sh_src, 1-b1} | //SLL
|
386 |
|
|
{9{ir2[5:3]==3'b111}} & {sh_src[0], 1'b0, sh_src[7:1]} ; //SRL
|
387 |
|
|
|
388 |
|
|
|
389 |
|
|
// shift insts
|
390 |
|
|
assign sh_alu_act = ir2[9:6] == 4'b0100;
|
391 |
|
|
//CB_RLC = 7'b01_00_000, // these must be compaired with ir2[9:3]
|
392 |
|
|
//CB_RRC = 7'b01_00_001, // these must be compaired with ir2[9:3]
|
393 |
|
|
//CB_RL = 7'b01_00_010, // these must be compaired with ir2[9:3]
|
394 |
|
|
//CB_RR = 7'b01_00_011, // these must be compaired with ir2[9:3]
|
395 |
|
|
//CB_SLA = 7'b01_00_100, // these must be compaired with ir2[9:3]
|
396 |
|
|
//CB_SRA = 7'b01_00_101, // these must be compaired with ir2[9:3]
|
397 |
|
|
//CB_SLL = 7'b01_00_110, // these must be compaired with ir2[9:3]
|
398 |
|
|
//CB_SRL = 7'b01_00_111, // these must be compaired with ir2[9:3]
|
399 |
|
|
|
400 |
|
|
//---------------------------- bit test alu ---------------------------------------
|
401 |
|
|
// bit test insts
|
402 |
|
|
//CB_BIT = 4'b01_01, // these must be compaired with ir2[9:6]
|
403 |
|
|
//CB_RES = 4'b01_10, // these must be compaired with ir2[9:6]assign
|
404 |
|
|
//CB_SET = 4'b01_11, // these must be compaired with ir2[9:6]
|
405 |
|
|
assign bit_alu_act = ir2[9:6] == CB_BIT |
|
406 |
|
|
ir2[9:6] == CB_RES |
|
407 |
|
|
ir2[9:6] == CB_RES ;
|
408 |
|
|
|
409 |
|
|
wire bit_decode = {8{ir2[5:3] == 3'h0}} & 8'h01 |
|
410 |
|
|
{8{ir2[5:3] == 3'h1}} & 8'h02 |
|
411 |
|
|
{8{ir2[5:3] == 3'h2}} & 8'h04 |
|
412 |
|
|
{8{ir2[5:3] == 3'h3}} & 8'h08 |
|
413 |
|
|
{8{ir2[5:3] == 3'h4}} & 8'h10 |
|
414 |
|
|
{8{ir2[5:3] == 3'h5}} & 8'h20 |
|
415 |
|
|
{8{ir2[5:3] == 3'h6}} & 8'h40 |
|
416 |
|
|
{8{ir2[5:3] == 3'h7}} & 8'h80 ;
|
417 |
|
|
|
418 |
|
|
assign bit_alu = {8{ir2[9:6] == CB_BIT}} & ( sh_src & bit_decode) |
|
419 |
|
|
{8{ir2[9:6] == CB_RES}} & ( sh_src & ~bit_decode) |
|
420 |
|
|
{8{ir2[9:6] == CB_RES}} & ( shPsrc | bit_decode) ;
|
421 |
|
|
|
422 |
|
|
|
423 |
|
|
//------------ dec bc alu ---------------------------------------------
|
424 |
|
|
//exec_decbc; these are all we know (in general)
|
425 |
|
|
//exec_decb;
|
426 |
|
|
assign decc_alu = cr + 8'hff ;
|
427 |
|
|
assign decb_alu = br + ( exec_decb ? 8'hff : // just dec b if io blk move
|
428 |
|
|
cr_eq0 ? 8'hff : // cry out if c in this case
|
429 |
|
|
8'h00 ); // only dec c reg this tick
|
430 |
|
|
// ------------------ daa alu -------------------------------------------------------
|
431 |
|
|
// the documentation does not cover all cases here -- only those that matter (i suppose).
|
432 |
|
|
// ( documentation assumes you are operating with 2 daa'd numbers -- but of course the
|
433 |
|
|
// ar can contain many values that don't fit that assumption when this instruction is executed.
|
434 |
|
|
// Any arbitrary instruction test may test un-documented cases.
|
435 |
|
|
//
|
436 |
|
|
// this leaves me to guess what the actual logic is - and how to match it.
|
437 |
|
|
// So I am doing that -- see what happens. If an instruction test breaks this... I should be
|
438 |
|
|
// able to fix it easily.
|
439 |
|
|
//
|
440 |
|
|
wire [3:0] ls_nbl = (!nf & hf) ? 4'h6:
|
441 |
|
|
(!nf & (ar[3:0] > 4'h9)) ? 4'h6:
|
442 |
|
|
(nf & hf ) ? 4'ha:
|
443 |
|
|
4'h0;
|
444 |
|
|
|
445 |
|
|
wire [4:0] ms_nbl = (!nf & cf) ? 5'h16: // includes new cry
|
446 |
|
|
(!nf & (ar[3:0] > 4'h9)) ? 5'h16:
|
447 |
|
|
(!nf & (ar[3:0] == 4'h9) &
|
448 |
|
|
(ar[3:0] > 4'h9)) ? 5'h16:
|
449 |
|
|
(nf & !cf & hf ) ? 5'h0f:
|
450 |
|
|
(nf & cf & !hf ) ? 5'h1a:
|
451 |
|
|
(nf & cf & hf ) ? 5'h19:
|
452 |
|
|
5'h00;
|
453 |
|
|
|
454 |
|
|
|
455 |
|
|
assign {daa_cry, daa_alu} = { ms_nbl[4], {ar + { ms_nbl[3:0], ls_nbl}} } ;
|
456 |
|
|
|
457 |
|
|
|
458 |
|
|
//-------1---------2---------3--------State Machines-------6---------7---------8---------9--------0
|
459 |
|
|
|
460 |
|
|
// update ar
|
461 |
|
|
|
462 |
|
|
assign upd_a_alu8 =
|
463 |
|
|
ADDsA_B == ir2 | SUBsB == ir2 | ANDsB == ir2 | ORsB == ir2 |
|
464 |
|
|
ADDsA_C == ir2 | SUBsC == ir2 | ANDsC == ir2 | ORsC == ir2 |
|
465 |
|
|
ADDsA_D == ir2 | SUBsD == ir2 | ANDsD == ir2 | ORsD == ir2 |
|
466 |
|
|
ADDsA_E == ir2 | SUBsE == ir2 | ANDsE == ir2 | ORsE == ir2 |
|
467 |
|
|
ADDsA_H == ir2 | SUBsH == ir2 | ANDsH == ir2 | ORsH == ir2 |
|
468 |
|
|
ADDsA_L == ir2 | SUBsL == ir2 | ANDsL == ir2 | ORsL == ir2 |
|
469 |
|
|
ADDsA_6HL7 == ir2 | SUBs6HL7 == ir2 | ANDs6HL7 == ir2 | ORs6HL7 == ir2 |
|
470 |
|
|
ADDsA_A == ir2 | SUBsA == ir2 | ANDsA == ir2 | ORsA == ir2 |
|
471 |
|
|
ADCsA_B == ir2 | SBCsB == ir2 | XORsB == ir2 |
|
472 |
|
|
ADCsA_C == ir2 | SBCsC == ir2 | XORsC == ir2 | INCsA == ir2 |
|
473 |
|
|
ADCsA_D == ir2 | SBCsD == ir2 | XORsD == ir2 | DECsA == ir2 |
|
474 |
|
|
ADCsA_E == ir2 | SBCsE == ir2 | XORsE == ir2 |
|
475 |
|
|
ADCsA_H == ir2 | SBCsH == ir2 | XORsH == ir2 |
|
476 |
|
|
ADCsA_L == ir2 | SBCsL == ir2 | XORsL == ir2 |
|
477 |
|
|
ADCsA_6HL7 == ir2 | SBCs6HL7 == ir2 | XORs6HL7 == ir2 |
|
478 |
|
|
ADCsA_A == ir2 | SBCsA == ir2 | XORsA == ir2 |
|
479 |
|
|
ADDsA_N == ir2 | // ADD A,N ; C6 XX ADDsA_6HL7 = 'h86
|
480 |
|
|
ADCsA_N == ir2 | // ADC A,N ; CE XX ADCsA_6HL7 = 'h8E
|
481 |
|
|
SUBsN == ir2 | // SUB N ; D6 XX SUBs6HL7 = 'h96
|
482 |
|
|
SBCsA_N == ir2 | // SBC A,N ; DE XX
|
483 |
|
|
ANDsN == ir2 | // AND N ; E6 XX
|
484 |
|
|
XORsN == ir2 | // XOR N ; EE XX
|
485 |
|
|
ORsN == ir2 ; // OR N ; F6 XX
|
486 |
|
|
assign up_a_sh_alu =
|
487 |
|
|
RLCA == ir2 | // RLCA ; 07
|
488 |
|
|
RRCA == ir2 | // RRCA ; 0F
|
489 |
|
|
RRA == ir2 | // RRA ; 1F
|
490 |
|
|
RLA == ir2 ; // RLA ; 17
|
491 |
|
|
assign up_a_src_pqr =
|
492 |
|
|
LDsA_B == ir2 | // LD A,B ; 78
|
493 |
|
|
LDsA_C == ir2 | // LD A,C ; 79
|
494 |
|
|
LDsA_D == ir2 | // LD A,D ; 7A
|
495 |
|
|
LDsA_E == ir2 | // LD A,E ; 7B
|
496 |
|
|
LDsA_H == ir2 | // LD A,H ; 7C
|
497 |
|
|
LDsA_L == ir2 | // LD A,L ; 7D
|
498 |
|
|
LDsA_6HL7 == ir2 | // LD A,(HL) ; 7E
|
499 |
|
|
LDsA_A == ir2 ; // LD A,A ; 7F
|
500 |
|
|
assign up_a_n =
|
501 |
|
|
LDsA_N == ir2 | // LD A,N ; 3E XX
|
502 |
|
|
LDsA_6BC7 == ir2 | // LD A,(BC) ; 0A
|
503 |
|
|
LDsA_6DE7 == ir2 | // LD A,(DE) ; 1A
|
504 |
|
|
LDsA_6NN7 == ir2 | // LD A,(NN) ; 3A XX XX
|
505 |
|
|
INsA_6N7 == ir2 | // IN A,(N) ; DB XX
|
506 |
|
|
(ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_A) ;
|
507 |
|
|
|
508 |
|
|
|
509 |
|
|
//EXsAF_AFp = 10'h08,// EX AF,AF' ; 08
|
510 |
|
|
//EXX = 10'hD9,// EXX ; D9
|
511 |
|
|
//DAA = 10'h27,// DAA ; 27
|
512 |
|
|
//CPL = 10'h2F,// CPL ; 2F a <= ~a
|
513 |
|
|
//POPsAF = 10'hF1,// POP AF ; F1
|
514 |
|
|
// don't forget these beauties not affected by prefixes
|
515 |
|
|
//ED_RRD = 'h67// RRD ; compair with {ir2[9:6],ir2[3:0]} all
|
516 |
|
|
//ED_RLD = 'h6F// RLD ; ED 6F nibble roates A (HL)
|
517 |
|
|
//ED_NEG = 5'b01___100, // A<= -A compair with {ir2[9:6],ir2[2:0]}
|
518 |
|
|
|
519 |
|
|
//------------------------------- ar ------------------------------------------
|
520 |
|
|
|
521 |
|
|
assign upd_ar = upd_a_alu8 | up_a_sh_alu | up_a_src_pqr | up_a_n | ir2 == EXsAF_AFp |
|
522 |
|
|
ir2 == EXX | ir2 == DAA | ir2 == CPL | ir2 == POPsAF |
|
523 |
|
|
ir2[2:0] == REG8_A & bit_alu_act | ir2[2:0] == REG8_A & sh_alu_act |
|
524 |
|
|
{ir2[9:6], ir2[3:0]} == ED_RRD | {ir2[9:6], ir2[2:0]} == ED_NEG |
|
525 |
|
|
ir2 == ED_LDsA_I ;
|
526 |
|
|
|
527 |
|
|
always @(posedge clk)
|
528 |
|
|
begin
|
529 |
|
|
if (upd_a_alu8 & exec_ir2) ar <= alu8_out;
|
530 |
|
|
if (up_a_sh_alu & exec_ir2) ar <= sh_alu;
|
531 |
|
|
if (up_a_src_pqr & exec_ir2) ar <= src_pqr;
|
532 |
|
|
if (up_a_n & exec_ir2) ar <= nn[7:0];
|
533 |
|
|
if (ir2 == EXsAF_AFp & exec_ir2) ar <= ap;
|
534 |
|
|
if (ir2 == EXX & exec_ir2) ar <= ap;
|
535 |
|
|
if (ir2 == DAA & exec_ir2) ar <= daa_alu;
|
536 |
|
|
if (ir2 == CPL & exec_ir2) ar <= ~ar;
|
537 |
|
|
if (ir2 == POPsAF & exec_ir2) ar <= nn[15:8];
|
538 |
|
|
if (ir2[2:0] == REG8_A &
|
539 |
|
|
bit_alu_act & exec_ir2) ar <= bit_alu;
|
540 |
|
|
if (ir2[2:0] == REG8_A &
|
541 |
|
|
sh_alu_act & exec_ir2) ar <= sh_alu;
|
542 |
|
|
if ({ir2[9:6], ir2[3:0]} == ED_RRD & exec_ir2) ar[3:0] <= nn[3:0];
|
543 |
|
|
if ({ir2[9:6], ir2[3:0]} == ED_RLD & exec_ir2) ar[3:0] <= nn[7:4];
|
544 |
|
|
if ({ir2[9:6], ir2[2:0]} == ED_NEG & exec_ir2) ar <= alu8_out; // ED44 this done by alu8 for flags
|
545 |
|
|
if (ir2 == ED_LDsA_I & exec_ir2) ar <= ir2 ;
|
546 |
|
|
end
|
547 |
|
|
|
548 |
|
|
|
549 |
|
|
|
550 |
|
|
|
551 |
|
|
// update br
|
552 |
|
|
//assign upd_b_decbc =
|
553 |
|
|
// ED_LDI == ir2 | // LDI ; ED A0
|
554 |
|
|
// ED_CPI == ir2 | // CPI ; ED A1
|
555 |
|
|
// ED_LDD == ir2 | // LDD ; ED A8
|
556 |
|
|
// ED_CPD == ir2 | // CPD ; ED A9
|
557 |
|
|
// ED_LDIR == ir2 | // LDIR ; ED B0
|
558 |
|
|
// ED_CPIR == ir2 | // CPIR ; ED B1
|
559 |
|
|
// ED_LDDR == ir2 | // LDDR ; ED B8
|
560 |
|
|
// ED_CPDR == ir2 ;// CPDR ; ED B9
|
561 |
|
|
|
562 |
|
|
//assign eb_io =
|
563 |
|
|
|
564 |
|
|
// ED_INI == ir2 | // INI ; ED A2
|
565 |
|
|
// ED_IND == ir2 | // IND ; ED AA
|
566 |
|
|
// ED_OUTD == ir2 | // OUTD ; ED AB
|
567 |
|
|
// ED_OUTI == ir2 | // OUTI ; ED A3
|
568 |
|
|
// ED_INIR == ir2 | // INIR ; ED B2
|
569 |
|
|
// ED_OTIR == ir2 | // OTIR ; ED B3
|
570 |
|
|
// ED_INDR == ir2 | // INDR ; ED BA
|
571 |
|
|
// ED_OTDR == ir2 ; // OTDR ; ED BB
|
572 |
|
|
|
573 |
|
|
assign upd_b_alu8 =
|
574 |
|
|
INCsB == ir2 |// INC B ; 04
|
575 |
|
|
DECsB == ir2 ;// DEC B ; 05
|
576 |
|
|
|
577 |
|
|
|
578 |
|
|
assign up_b_src_pqr =
|
579 |
|
|
LDsB_B == ir2 |// LD B,B ; 40
|
580 |
|
|
LDsB_C == ir2 |// LD B,C ; 41
|
581 |
|
|
LDsB_D == ir2 |// LD B,D ; 42
|
582 |
|
|
LDsB_E == ir2 |// LD B,E ; 43
|
583 |
|
|
LDsB_H == ir2 |// LD B,H ; 44
|
584 |
|
|
LDsB_L == ir2 |// LD B,L ; 45
|
585 |
|
|
LDsB_6HL7 == ir2 |// LD B,(HL) ; 46
|
586 |
|
|
LDsB_A == ir2 ;// LD B,A ; 47
|
587 |
|
|
assign up_b_add16 =
|
588 |
|
|
INCsBC == ir2 |// INC BC ; 03
|
589 |
|
|
DECsBC == ir2 ;// DEC BC ; 0B
|
590 |
|
|
//LDsBC_nn = 10'h01,// LD BC,NN ; 01 XX XX
|
591 |
|
|
//POPsBC = 10'hC1,// POP BC ; C1
|
592 |
|
|
//EXX = 10'hD9,// EXX ; D9
|
593 |
|
|
//LDsB_N = 10'h06,// LD B,N ; 06 XX
|
594 |
|
|
//DJNZs$t2 = 10'h10,// DJNZ $+2 ; 10 XX //pre dec br
|
595 |
|
|
//ED_RRD = 'h67// RRD ; ED 67 nibble roates A HL
|
596 |
|
|
//ED_RLD = 'h6F// RLD ; ED 6F nibble roates A HL
|
597 |
|
|
//ED_INsREG_6C7 = 5'b01___000,// compair with {ir2[7:6],ir2[2:0]} really (BCio)
|
598 |
|
|
|
599 |
|
|
//------------------------------- br -----------------------------------------
|
600 |
|
|
|
601 |
|
|
assign upd_br = upd_b_alu8 | up_b_src_pqr | up_b_add16 | LDsBC_NN == ir2 |
|
602 |
|
|
POPsBC == ir2 | EXX == ir2 | LDsB_N == ir2 |
|
603 |
|
|
ir2[2:0] == REG8_B & bit_alu_act | ir2[2:0] == REG8_B & sh_alu_act |
|
604 |
|
|
DJNZs$t2 == ir2 | (ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_B);
|
605 |
|
|
|
606 |
|
|
|
607 |
|
|
always @(posedge clk)
|
608 |
|
|
begin
|
609 |
|
|
if ( upd_b_alu8 & exec_ir2) br <= alu8_out;
|
610 |
|
|
if ( up_b_src_pqr & exec_ir2) br <= src_pqr;
|
611 |
|
|
if ( up_b_add16 & exec_ir2) br <= add16[15:8];
|
612 |
|
|
if ( LDsBC_NN == ir2 & exec_ir2) br <= nn[15:8];
|
613 |
|
|
if ( POPsBC == ir2 & exec_ir2) br <= nn[15:8];
|
614 |
|
|
if ( EXX == ir2 & exec_ir2) br <= bp;
|
615 |
|
|
if ( LDsB_N == ir2 & exec_ir2) br <= nn[7:0];
|
616 |
|
|
if (ir2[2:0] == REG8_B &
|
617 |
|
|
bit_alu_act & exec_ir2) br <= bit_alu;
|
618 |
|
|
if (ir2[2:0] == REG8_B &
|
619 |
|
|
sh_alu_act & exec_ir2) br <= sh_alu;
|
620 |
|
|
if ( DJNZs$t2 == ir2 & exec_ir2) br <= br + 8'hff; // use seperate adder here as no flags
|
621 |
|
|
// change -- we need br==0. for now
|
622 |
|
|
// use |br. If we need more speed add
|
623 |
|
|
// a ff.
|
624 |
|
|
if (exec_decb | exec_decbc) br <= decb_alu;
|
625 |
|
|
if ( (ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_B) & exec_ir2 )
|
626 |
|
|
br <= nn[7:0];
|
627 |
|
|
end
|
628 |
|
|
|
629 |
|
|
|
630 |
|
|
// update cr
|
631 |
|
|
assign up_c_add16 =
|
632 |
|
|
INCsBC == ir2 |// INC BC ; 03
|
633 |
|
|
DECsBC == ir2 ;// DEC BC ; 0B,
|
634 |
|
|
assign upd_c_alu8 =
|
635 |
|
|
INCsC == ir2 |// INC C ; 0C
|
636 |
|
|
DECsC == ir2 ;// DEC C ; 0D
|
637 |
|
|
assign up_c_src_pqr =
|
638 |
|
|
LDsC_B == ir2 |// LD C,B ; 48
|
639 |
|
|
LDsC_C == ir2 |// LD C,C ; 49
|
640 |
|
|
LDsC_D == ir2 |// LD C,D ; 4A
|
641 |
|
|
LDsC_E == ir2 |// LD C,E ; 4B
|
642 |
|
|
LDsC_H == ir2 |// LD C,H ; 4C
|
643 |
|
|
LDsC_L == ir2 |// LD C,L ; 4D
|
644 |
|
|
LDsC_6HL7 == ir2 |// LD C,(HL) ; 4E
|
645 |
|
|
LDsC_A == ir2 ;// LD C,A ; 4F
|
646 |
|
|
|
647 |
|
|
|
648 |
|
|
//LDsC_N == ir2 |// LD C,N ; 0E XX
|
649 |
|
|
//LDsBC_NN = 10'h01,// LD BC,NN ; 01 XX XX
|
650 |
|
|
//POPsBC = 10'hC1,// POP BC ; C1
|
651 |
|
|
//EXX = 10'hD9,// EXX ; D9
|
652 |
|
|
//ED_INsREG_6C7 = 5'b01___000,// compair with {ir2[7:6],ir2[2:0]} really (BCio)
|
653 |
|
|
|
654 |
|
|
//------------------------------- cr -----------------------------------------
|
655 |
|
|
assign upd_cr = upd_c_alu8 | up_c_src_pqr | up_c_add16 | LDsBC_NN == ir2 |
|
656 |
|
|
POPsBC == ir2 | EXX == ir2 | LDsC_N == ir2 |
|
657 |
|
|
ir2[2:0] == REG8_C & bit_alu_act | ir2[2:0] == REG8_C & sh_alu_act |
|
658 |
|
|
(ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_C);
|
659 |
|
|
|
660 |
|
|
|
661 |
|
|
|
662 |
|
|
always @(posedge clk)
|
663 |
|
|
begin
|
664 |
|
|
if ( upd_c_alu8 & exec_ir2) cr <= alu8_out;
|
665 |
|
|
if ( up_c_src_pqr & exec_ir2) cr <= src_pqr;
|
666 |
|
|
if ( up_c_add16 & exec_ir2) cr <= add16[7:0];
|
667 |
|
|
if ( LDsBC_NN == ir2 & exec_ir2) cr <= nn[7:0];
|
668 |
|
|
if ( POPsBC == ir2 & exec_ir2) cr <= nn[7:0];
|
669 |
|
|
if ( EXX == ir2 & exec_ir2) cr <= cp;
|
670 |
|
|
if ( LDsC_N == ir2 & exec_ir2) cr <= nn[7:0];
|
671 |
|
|
if (ir2[2:0] == REG8_C &
|
672 |
|
|
bit_alu_act & exec_ir2) cr <= bit_alu;
|
673 |
|
|
if (ir2[2:0] == REG8_C &
|
674 |
|
|
sh_alu_act & exec_ir2) cr <= sh_alu;
|
675 |
|
|
if ( exec_decbc) cr <= decc_alu;
|
676 |
|
|
if ((ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_C) & exec_ir2)
|
677 |
|
|
cr <= nn[7:0];
|
678 |
|
|
|
679 |
|
|
end
|
680 |
|
|
|
681 |
|
|
|
682 |
|
|
// update dr
|
683 |
|
|
assign up_d_add16 =
|
684 |
|
|
INCsDE == 10'h13 | // INC DE ; 13
|
685 |
|
|
DECsDE == 10'h1B ; // DEC DE ; 1B
|
686 |
|
|
|
687 |
|
|
assign upd_d_alu8 =
|
688 |
|
|
INCsD == 10'h14 | // INC D ; 14
|
689 |
|
|
DECsD == 10'h15 ; // DEC D ; 15
|
690 |
|
|
assign up_d_src_pqr =
|
691 |
|
|
LDsD_B == ir2 | //LD D,B ; 50
|
692 |
|
|
LDsD_C == ir2 | //LD D,C ; 51
|
693 |
|
|
LDsD_D == ir2 | //LD D,D ; 52
|
694 |
|
|
LDsD_E == ir2 | //LD D,E ; 53
|
695 |
|
|
LDsD_H == ir2 | //LD D,H ; 54
|
696 |
|
|
LDsD_L == ir2 | //LD D,L ; 55
|
697 |
|
|
LDsD_6HL7 == ir2 | //LD D,(HL) ; 56endmodule
|
698 |
|
|
LDsD_A == ir2 ; //LD D,A ; 57
|
699 |
|
|
|
700 |
|
|
|
701 |
|
|
//LDsD_N = 10'h16,// LD D,N ; 16 XX
|
702 |
|
|
//LDsDE_NN = 10'h11,// LD DE,NN ; 11 XX XX
|
703 |
|
|
//POPsDE = 10'hD1,// POP DE ; D1
|
704 |
|
|
//EXX = 10'hD9,// EXX ; D9
|
705 |
|
|
//EXsDE_HL = 10'hEB,// EX DE,HL ; EB
|
706 |
|
|
//ED_INsREG_6C7 = 5'b01___000,// compair with {ir2[7:6],ir2[2:0]} really (BCio)
|
707 |
|
|
|
708 |
|
|
//---------------------------------- dr ------------------------------------
|
709 |
|
|
|
710 |
|
|
assign upd_dr = upd_d_alu8 | up_d_src_pqr | up_d_add16 | LDsDE_NN == ir2 |
|
711 |
|
|
POPsDE == ir2 | EXX == ir2 | EXsDE_HL == ir2 | LDsD_N == ir2 |
|
712 |
|
|
ir2[2:0] == REG8_D & bit_alu_act | ir2[2:0] == REG8_D & sh_alu_act |
|
713 |
|
|
(ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_D);
|
714 |
|
|
|
715 |
|
|
|
716 |
|
|
|
717 |
|
|
|
718 |
|
|
|
719 |
|
|
|
720 |
|
|
always @(posedge clk)
|
721 |
|
|
begin
|
722 |
|
|
if ( upd_d_alu8 & exec_ir2) dr <= alu8_out;
|
723 |
|
|
if ( up_d_src_pqr & exec_ir2) dr <= src_pqr;
|
724 |
|
|
if ( up_d_add16 & exec_ir2) dr <= add16[15:8];
|
725 |
|
|
if ( LDsDE_NN == ir2 & exec_ir2) dr <= nn[15:8];
|
726 |
|
|
if ( POPsDE == ir2 & exec_ir2) dr <= nn[15:8];
|
727 |
|
|
if ( EXX == ir2 & exec_ir2) dr <= dp;
|
728 |
|
|
if ( EXsDE_HL == ir2 & exec_ir2) dr <= hr;
|
729 |
|
|
if ( LDsD_N == ir2 & exec_ir2) dr <= nn[7:0];
|
730 |
|
|
if (ir2[2:0] == REG8_D &
|
731 |
|
|
bit_alu_act & exec_ir2) dr <= bit_alu;
|
732 |
|
|
if (ir2[2:0] == REG8_D &
|
733 |
|
|
sh_alu_act & exec_ir2) dr <= sh_alu;
|
734 |
|
|
if ((ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]})
|
735 |
|
|
& (ir2[5:3] == REG8_D) & exec_ir2)
|
736 |
|
|
dr <= nn[7:0];
|
737 |
|
|
|
738 |
|
|
end
|
739 |
|
|
|
740 |
|
|
// update er
|
741 |
|
|
assign up_e_add16 =
|
742 |
|
|
INCsDE == ir2 |// INC DE ; 13
|
743 |
|
|
DECsDE == ir2 ;// DEC DE ; 1B
|
744 |
|
|
assign upd_e_alu8 =
|
745 |
|
|
INCsE == ir2 |// INC E ; 1C
|
746 |
|
|
DECsE == ir2 ;// DEC E ; 1D
|
747 |
|
|
assign up_e_src_pqr =
|
748 |
|
|
LDsE_B == ir2 |// LD E,B ; 58
|
749 |
|
|
LDsE_C == ir2 |// LD E,C ; 59
|
750 |
|
|
LDsE_D == ir2 |// LD E,D ; 5A
|
751 |
|
|
LDsE_E == ir2 |// LD E,E ; 5B
|
752 |
|
|
LDsE_H == ir2 |// LD E,H ; 5C
|
753 |
|
|
LDsE_L == ir2 |// LD E,L ; 5D
|
754 |
|
|
LDsE_6HL7 == ir2 |// LD E,(HL) ; 5E
|
755 |
|
|
LDsE_A == ir2 ;// LD E,A ; 5F
|
756 |
|
|
|
757 |
|
|
//LDsE_N = 10'h1E,// LD E,N ; 1E XX
|
758 |
|
|
//LDsDE_NN = 10'h11,// LD DE,NN ; 11 XX XX
|
759 |
|
|
//POPsDE = 10'hD1,// POP DE ; D1
|
760 |
|
|
//EXX = 10'hD9,// EXX ; D9
|
761 |
|
|
//EXsDE_HL = 10'hEB,// EX DE,HL ; EB
|
762 |
|
|
//ED_INsREG_6C7 = 5'b01___000,// compair with {ir2[7:6],ir2[2:0]} really (BCio)
|
763 |
|
|
|
764 |
|
|
//---------------------------------- er ------------------------------------
|
765 |
|
|
|
766 |
|
|
|
767 |
|
|
assign upd_er = upd_e_alu8 | up_e_src_pqr | up_e_add16 | LDsDE_NN == ir2 |
|
768 |
|
|
POPsDE == ir2 | EXX == ir2 | EXsDE_HL == ir2 | LDsD_N == ir2 |
|
769 |
|
|
ir2[2:0] == REG8_E & bit_alu_act | ir2[2:0] == REG8_E & sh_alu_act |
|
770 |
|
|
(ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_E);
|
771 |
|
|
|
772 |
|
|
|
773 |
|
|
|
774 |
|
|
|
775 |
|
|
|
776 |
|
|
|
777 |
|
|
|
778 |
|
|
|
779 |
|
|
|
780 |
|
|
always @(posedge clk)
|
781 |
|
|
begin
|
782 |
|
|
if ( upd_e_alu8 & exec_ir2) er <= alu8_out;
|
783 |
|
|
if ( up_e_src_pqr & exec_ir2) er <= src_pqr;
|
784 |
|
|
if ( up_e_add16 & exec_ir2) er <= add16;
|
785 |
|
|
if ( LDsDE_NN == ir2 & exec_ir2) er <= nn[7:0];
|
786 |
|
|
if ( POPsDE == ir2 & exec_ir2) er <= nn[7:0];
|
787 |
|
|
if ( EXX == ir2 & exec_ir2) er <= ep;
|
788 |
|
|
if ( EXsDE_HL == ir2 & exec_ir2) er <= hr;
|
789 |
|
|
if ( LDsE_N == ir2 & exec_ir2) er <= nn[7:0];
|
790 |
|
|
if (ir2[2:0] == REG8_E &
|
791 |
|
|
bit_alu_act & exec_ir2) er <= bit_alu;
|
792 |
|
|
if (ir2[2:0] == REG8_E &
|
793 |
|
|
sh_alu_act & exec_ir2) er <= sh_alu;
|
794 |
|
|
if ((ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_E) & exec_ir2)
|
795 |
|
|
er <= nn[7:0];
|
796 |
|
|
|
797 |
|
|
end
|
798 |
|
|
|
799 |
|
|
|
800 |
|
|
// update hr
|
801 |
|
|
assign up_h_add16 =
|
802 |
|
|
ADDsHL_BC == ir2 | // ADD HL,BC ; 09
|
803 |
|
|
ADDsHL_DE == ir2 | // ADD HL,DE ; 19
|
804 |
|
|
ADDsHL_HL == ir2 | // ADD HL,HL ; 29
|
805 |
|
|
ADDsHL_SP == ir2 | // ADD HL,SP ; 39
|
806 |
|
|
INCsHL == ir2 | // INC HL ; 23
|
807 |
|
|
DECsHL == ir2 ; // DEC HL ; 2B
|
808 |
|
|
assign upd_h_alu8 =
|
809 |
|
|
INCsH == ir2 | // INC H ; 24
|
810 |
|
|
DECsH == ir2 ; // DEC H ; 25
|
811 |
|
|
assign upd_h_src_pqr =
|
812 |
|
|
LDsH_B == ir2 | // LD H,B ; 60
|
813 |
|
|
LDsH_C == ir2 | // LD H,C ; 61
|
814 |
|
|
LDsH_D == ir2 | // LD H,D ; 62
|
815 |
|
|
LDsH_E == ir2 | // LD H,E ; 63
|
816 |
|
|
LDsH_H == ir2 | // LD H,H ; 64
|
817 |
|
|
LDsH_L == ir2 | // LD H,L ; 65
|
818 |
|
|
LDsH_6HL7 == ir2 | // LD H,(HL) ; 66
|
819 |
|
|
LDsH_A == ir2 ; // LD H,A ; 67
|
820 |
|
|
//ED_INsREG_6C7 = 5'b01___000,// compair with {ir2[7:6],ir2[2:0]} really (BCio)
|
821 |
|
|
|
822 |
|
|
//POPsHL = 10'hE1,// POP HL ; E1
|
823 |
|
|
//EXs6SP7_HL = 10'hE3,// EX (SP),HL ; E3
|
824 |
|
|
//LDsHL_NN = 10'h21,// LD HL,NN ; 21 XX XX
|
825 |
|
|
//LDsHL_6NN7 = 10'h2A,// LD HL,(NN) ; 2A XX XX
|
826 |
|
|
//LDsH_N = 10'h26,// LD H,N ; 26 XX
|
827 |
|
|
|
828 |
|
|
// only these are not affected by dd and fd prefixes
|
829 |
|
|
//EXsDE_HL = 10'hEB,// EX DE,HL ; EB
|
830 |
|
|
//EXX = 10'hD9,// EXX ; D9
|
831 |
|
|
|
832 |
|
|
//---------------------------------- hr ------------------------------------
|
833 |
|
|
// we just check hr and lr - the prefixes for use of ix and iy imply that something
|
834 |
|
|
// pretty strange has to happen for a hazard related to use of those registers. We can
|
835 |
|
|
// assume upd hr impies upd ix and iy without adverse timing consequences.
|
836 |
|
|
//
|
837 |
|
|
assign upd_hr = upd_h_alu8 | up_h_src_pqr | up_h_add16 | LDsHL_NN == ir2 | LDsHL_6NN7== ir2 |
|
838 |
|
|
POPsHL == ir2 | EXX == ir2 | EXsDE_HL == ir2 | LDsH_N == ir2 |
|
839 |
|
|
ir2[2:0] == REG8_H & bit_alu_act | ir2[2:0] == REG8_H & sh_alu_act |
|
840 |
|
|
(ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_H);
|
841 |
|
|
|
842 |
|
|
|
843 |
|
|
|
844 |
|
|
|
845 |
|
|
wire exec_hlir2 = exec_ir2 & !(dd_grp | fd_grp);
|
846 |
|
|
|
847 |
|
|
always @(posedge clk)
|
848 |
|
|
begin
|
849 |
|
|
if ( upd_h_alu8 & exec_hlir2) hr <= alu8_out;
|
850 |
|
|
if ( up_h_src_pqr & exec_hlir2) hr <= src_pqr;
|
851 |
|
|
if ( up_h_add16 & exec_hlir2) hr <= add16[15:8];
|
852 |
|
|
if ( LDsHL_NN == ir2 & exec_hlir2) hr <= nn[15:8];
|
853 |
|
|
if ( LDsHL_6NN7== ir2 & exec_hlir2) hr <= nn[15:8];
|
854 |
|
|
if ( POPsHL == ir2 & exec_hlir2) hr <= nn[15:8];
|
855 |
|
|
if ( EXs6SP7_HL== ir2 & exec_hlir2) hr <= nn[15:8];
|
856 |
|
|
if ( EXX == ir2 & exec_ir2) hr <= hp;
|
857 |
|
|
if ( EXsDE_HL == ir2 & exec_ir2) hr <= dr;
|
858 |
|
|
if ( LDsH_N == ir2 & exec_hlir2) hr <= nn[7:0];
|
859 |
|
|
if (ir2[2:0] == REG8_H &
|
860 |
|
|
bit_alu_act & exec_hlir2) hr <= bit_alu;
|
861 |
|
|
if (ir2[2:0] == REG8_H &
|
862 |
|
|
sh_alu_act & exec_hlir2) hr <= sh_alu;
|
863 |
|
|
if ((ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_H) & exec_ir2)
|
864 |
|
|
hr <= nn[7:0];
|
865 |
|
|
|
866 |
|
|
end
|
867 |
|
|
|
868 |
|
|
// update lr
|
869 |
|
|
assign up_l_add16 =
|
870 |
|
|
ADDsHL_BC == ir2 |// ADD HL,BC ; 09
|
871 |
|
|
ADDsHL_DE == ir2 |// ADD HL,DE ; 19
|
872 |
|
|
ADDsHL_HL == ir2 |// ADD HL,HL ; 29
|
873 |
|
|
ADDsHL_SP == ir2 |// ADD HL,SP ; 39
|
874 |
|
|
INCsHL == ir2 |// INC HL ; 23
|
875 |
|
|
DECsHL == ir2 ;// DEC HL ; 2B
|
876 |
|
|
assign upd_l_alu8 =
|
877 |
|
|
INCsL == ir2 |// INC L ; 2C
|
878 |
|
|
DECsL == ir2 ;// DEC L ; 2D
|
879 |
|
|
assign upd_l_src_pqr =
|
880 |
|
|
LDsL_B == ir2 |// LD L,B ; 68
|
881 |
|
|
LDsL_C == ir2 |// LD L,C ; 69
|
882 |
|
|
LDsL_D == ir2 |// LD L,D ; 6A
|
883 |
|
|
LDsL_E == ir2 |// LD L,E ; 6B
|
884 |
|
|
LDsL_H == ir2 |// LD L,H ; 6C
|
885 |
|
|
LDsL_L == ir2 |// LD L,L ; 6D
|
886 |
|
|
LDsL_6HL7 == ir2 |// LD L,(HL) ; 6E
|
887 |
|
|
LDsL_A == ir2 ;// LD L,A ; 6F
|
888 |
|
|
//EXX = 10'hD9,// EXX ; D9
|
889 |
|
|
//POPsHL = 10'hE1,// POP HL ; E1
|
890 |
|
|
//EXs6SP7_HL = 10'hE3,// EX (SP),HL ; E3
|
891 |
|
|
//EXsDE_HL = 10'hEB,// EX DE,HL ; EB
|
892 |
|
|
//LDsHL_NN = 10'h21,// LD HL,NN ; 21 XX XX
|
893 |
|
|
//LDsHL_6NN7 = 10'h2A,// LD HL,(NN) ; 2A XX XX
|
894 |
|
|
//LDsL_N = 10'h2E,// LD L,N ; 2E XX
|
895 |
|
|
//ED_INsREG_6C7
|
896 |
|
|
|
897 |
|
|
|
898 |
|
|
|
899 |
|
|
//---------------------------------- lr ------------------------------------
|
900 |
|
|
assign upd_lr = upd_l_alu8 | up_l_src_pqr | up_l_add16 | LDsHL_NN == ir2 | LDsHL_6NN7== ir2 |
|
901 |
|
|
POPsHL == ir2 | EXX == ir2 | EXsDE_HL == ir2 | LDsL_N == ir2 |
|
902 |
|
|
ir2[2:0] == REG8_L & bit_alu_act | ir2[2:0] == REG8_L & sh_alu_act |
|
903 |
|
|
(ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_L);
|
904 |
|
|
|
905 |
|
|
|
906 |
|
|
|
907 |
|
|
always @(posedge clk)
|
908 |
|
|
begin
|
909 |
|
|
if ( upd_l_alu8 & exec_hlir2) lr <= alu8_out;
|
910 |
|
|
if ( up_l_src_pqr & exec_hlir2) lr <= src_pqr;
|
911 |
|
|
if ( up_l_add16 & exec_hlir2) lr <= add16[7:0];
|
912 |
|
|
if ( LDsHL_NN == ir2 & exec_hlir2) lr <= nn[7:0];
|
913 |
|
|
if ( LDsHL_6NN7== ir2 & exec_hlir2) lr <= nn[7:0];
|
914 |
|
|
if ( POPsHL == ir2 & exec_hlir2) lr <= nn[7:0];
|
915 |
|
|
if ( EXs6SP7_HL== ir2 & exec_hlir2) lr <= nn[7:0];
|
916 |
|
|
if ( EXX == ir2 & exec_ir2) lr <= lp;
|
917 |
|
|
if ( EXsDE_HL == ir2 & exec_ir2) lr <= er;
|
918 |
|
|
if ( LDsL_N == ir2 & exec_hlir2) lr <= nn[7:0];
|
919 |
|
|
if (ir2[2:0] == REG8_L &
|
920 |
|
|
bit_alu_act & exec_hlir2) lr <= bit_alu;
|
921 |
|
|
if (ir2[2:0] == REG8_L &
|
922 |
|
|
sh_alu_act & exec_hlir2) lr <= sh_alu;
|
923 |
|
|
if ((ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) & (ir2[5:3] == REG8_L) & exec_ir2)
|
924 |
|
|
lr <= nn[7:0];
|
925 |
|
|
|
926 |
|
|
end
|
927 |
|
|
//------------------------ ixr ---------------------------------------------
|
928 |
|
|
wire exec_ixir2 = exec_ir2 & dd_grp;
|
929 |
|
|
always @(posedge clk)
|
930 |
|
|
begin
|
931 |
|
|
if ( upd_l_alu8 & exec_ixir2) ixr[7:0] <= alu8_out;
|
932 |
|
|
if ( up_l_src_pqr & exec_ixir2) ixr[7:0] <= src_pqr;
|
933 |
|
|
if ( up_l_add16 & exec_ixir2) ixr[7:0] <= add16[7:0];
|
934 |
|
|
if ( LDsHL_NN == ir2 & exec_ixir2) ixr[7:0] <= nn[7:0];
|
935 |
|
|
if ( LDsHL_6NN7== ir2 & exec_ixir2) ixr[7:0] <= nn[7:0];
|
936 |
|
|
if ( POPsHL == ir2 & exec_ixir2) ixr[7:0] <= nn[7:0];
|
937 |
|
|
if ( EXs6SP7_HL== ir2 & exec_ixir2) ixr[7:0] <= nn[7:0];
|
938 |
|
|
|
939 |
|
|
if ( LDsL_N == ir2 & exec_ixir2) ixr[7:0] <= nn[7:0];
|
940 |
|
|
if (ir2[2:0] == REG8_L &
|
941 |
|
|
bit_alu_act & exec_ixir2) ixr[7:0] <= bit_alu;
|
942 |
|
|
if (ir2[2:0] == REG8_L &
|
943 |
|
|
sh_alu_act & exec_ixir2) ixr[7:0] <= sh_alu;
|
944 |
|
|
|
945 |
|
|
end
|
946 |
|
|
|
947 |
|
|
always @(posedge clk)
|
948 |
|
|
begin
|
949 |
|
|
if ( upd_h_alu8 & exec_ixir2) ixr[15:8] <= alu8_out;
|
950 |
|
|
if ( up_h_src_pqr & exec_ixir2) ixr[15:8] <= src_pqr;
|
951 |
|
|
if ( up_h_add16 & exec_ixir2) ixr[15:8] <= add16[15:8];
|
952 |
|
|
if ( LDsHL_NN == ir2 & exec_ixir2) ixr[15:8] <= nn[15:8];
|
953 |
|
|
if ( LDsHL_6NN7== ir2 & exec_ixir2) ixr[15:8] <= nn[15:8];
|
954 |
|
|
if ( POPsHL == ir2 & exec_ixir2) ixr[15:8] <= nn[15:8];
|
955 |
|
|
if ( EXs6SP7_HL== ir2 & exec_ixir2) ixr[15:8] <= nn[15:8];
|
956 |
|
|
|
957 |
|
|
if ( LDsH_N == ir2 & exec_ixir2) ixr[15:8] <= nn[7:0];
|
958 |
|
|
if (ir2[2:0] == REG8_H &
|
959 |
|
|
bit_alu_act & exec_ixir2) ixr[15:8] <= bit_alu;
|
960 |
|
|
if (ir2[2:0] == REG8_H &
|
961 |
|
|
sh_alu_act & exec_ixir2) ixr[15:8] <= sh_alu;
|
962 |
|
|
|
963 |
|
|
end
|
964 |
|
|
|
965 |
|
|
//------------------------ iyr ---------------------------------------------
|
966 |
|
|
wire exec_iyir2 = exec_ir2 & fd_grp;
|
967 |
|
|
always @(posedge clk)
|
968 |
|
|
begin
|
969 |
|
|
if ( upd_l_alu8 & exec_iyir2) iyr[7:0] <= alu8_out;
|
970 |
|
|
if ( up_l_src_pqr & exec_iyir2) iyr[7:0] <= src_pqr;
|
971 |
|
|
if ( up_l_add16 & exec_iyir2) iyr[7:0] <= add16[7:0];
|
972 |
|
|
if ( LDsHL_NN == ir2 & exec_iyir2) iyr[7:0] <= nn[7:0];
|
973 |
|
|
if ( LDsHL_6NN7== ir2 & exec_iyir2) iyr[7:0] <= nn[7:0];
|
974 |
|
|
if ( POPsHL == ir2 & exec_iyir2) iyr[7:0] <= nn[7:0];
|
975 |
|
|
if ( EXs6SP7_HL== ir2 & exec_iyir2) iyr[7:0] <= nn[7:0];
|
976 |
|
|
|
977 |
|
|
if ( LDsL_N == ir2 & exec_iyir2) iyr[7:0] <= nn[7:0];
|
978 |
|
|
if (ir2[2:0] == REG8_L &
|
979 |
|
|
bit_alu_act & exec_iyir2) iyr[7:0] <= bit_alu;
|
980 |
|
|
if (ir2[2:0] == REG8_L &
|
981 |
|
|
sh_alu_act & exec_iyir2) iyr[7:0] <= sh_alu;
|
982 |
|
|
|
983 |
|
|
end
|
984 |
|
|
|
985 |
|
|
always @(posedge clk)
|
986 |
|
|
begin
|
987 |
|
|
if ( upd_h_alu8 & exec_iyir2) iyr[15:8] <= alu8_out;
|
988 |
|
|
if ( up_h_src_pqr & exec_iyir2) iyr[15:8] <= src_pqr;
|
989 |
|
|
if ( up_h_add16 & exec_iyir2) iyr[15:8] <= add16[15:8];
|
990 |
|
|
if ( LDsHL_NN == ir2 & exec_iyir2) iyr[15:8] <= nn[15:8];
|
991 |
|
|
if ( LDsHL_6NN7== ir2 & exec_iyir2) iyr[15:8] <= nn[15:8];
|
992 |
|
|
if ( POPsHL == ir2 & exec_iyir2) iyr[15:8] <= nn[15:8];
|
993 |
|
|
if ( EXs6SP7_HL== ir2 & exec_iyir2) iyr[15:8] <= nn[15:8];
|
994 |
|
|
|
995 |
|
|
if ( LDsH_N == ir2 & exec_iyir2) iyr[15:8] <= nn[7:0];
|
996 |
|
|
if (ir2[2:0] == REG8_H &
|
997 |
|
|
bit_alu_act & exec_iyir2) iyr[15:8] <= bit_alu;
|
998 |
|
|
if (ir2[2:0] == REG8_H &
|
999 |
|
|
sh_alu_act & exec_iyir2) iyr[15:8] <= sh_alu;
|
1000 |
|
|
|
1001 |
|
|
end
|
1002 |
|
|
|
1003 |
|
|
|
1004 |
|
|
//---------------------------- prime regiters (shadows?) ----------------
|
1005 |
|
|
|
1006 |
|
|
always @(posedge clk)
|
1007 |
|
|
begin
|
1008 |
|
|
if (ir2 == EXsAF_AFp & exec_ir2)
|
1009 |
|
|
begin
|
1010 |
|
|
ap <= ar;
|
1011 |
|
|
fp <= fr;
|
1012 |
|
|
end
|
1013 |
|
|
if (ir2 == EXX & exec_ir2)
|
1014 |
|
|
begin
|
1015 |
|
|
ap <= ar;
|
1016 |
|
|
fp <= fr;
|
1017 |
|
|
bp <= br;
|
1018 |
|
|
cp <= cr;
|
1019 |
|
|
dp <= dr;
|
1020 |
|
|
ep <= er;
|
1021 |
|
|
hp <= hr;
|
1022 |
|
|
lp <= lr;
|
1023 |
|
|
end
|
1024 |
|
|
end
|
1025 |
|
|
//-------------------------- flag registers -------------------------------
|
1026 |
|
|
// This is a mess - There is in general no reasonable way to get this stuff to follow
|
1027 |
|
|
// z80 exactly. --- in some of the undocumented cases, there is not even a
|
1028 |
|
|
// guess expressed about what is actually done. In some of the other undocumented
|
1029 |
|
|
// cases, what is claimed happens is soo silly that It is hard for me to believe
|
1030 |
|
|
// it matters ( unfortunately i am far too aware that one man's garbage can be
|
1031 |
|
|
// anothers treasure --- or....., its amazing how silly
|
1032 |
|
|
// behavior (bug?) can become a feature. In any case, The attempt (at first blush) is
|
1033 |
|
|
// only to get the documented stuff right -- although if undocumented behavior
|
1034 |
|
|
// falls out, great. For exmple, I will typically update f3f and f5f with alu output -
|
1035 |
|
|
// these flags are documented as "undefined".
|
1036 |
|
|
//
|
1037 |
|
|
// some of the wierd stuff to worry about:
|
1038 |
|
|
// 16 bit ops:
|
1039 |
|
|
// the ed insts SBC ADC muck with all flags but
|
1040 |
|
|
// the ADD inst doesn't change sf zf or pvf.
|
1041 |
|
|
// and the 16 bit INC and DEC insts touch nothing
|
1042 |
|
|
//
|
1043 |
|
|
// the ED_RLD and RRD instructions muck with flags based on ar -- these operations
|
1044 |
|
|
// should be correct rleative to subsequent DAA's i suppose.
|
1045 |
|
|
|
1046 |
|
|
// update all flags from alu8 for logic operations pv <= parity else ofl
|
1047 |
|
|
// INC and DEC same as but no cf change oh my god why? done in logic above
|
1048 |
|
|
|
1049 |
|
|
assign upd_fr_alu8 =
|
1050 |
|
|
ADCsA_A == ir2 | ANDsA == ir2 | ORsA == ir2 | SUBsA == ir2 | DECsA == ir2 |
|
1051 |
|
|
ADCsA_B == ir2 | ANDsB == ir2 | ORsB == ir2 | SUBsB == ir2 | DECsB == ir2 |
|
1052 |
|
|
ADCsA_C == ir2 | ANDsC == ir2 | ORsC == ir2 | SUBsC == ir2 | DECsC == ir2 |
|
1053 |
|
|
ADCsA_D == ir2 | ANDsD == ir2 | ORsD == ir2 | SUBsD == ir2 | DECsD == ir2 |
|
1054 |
|
|
ADCsA_E == ir2 | ANDsE == ir2 | ORsE == ir2 | SUBsE == ir2 | DECsE == ir2 |
|
1055 |
|
|
ADCsA_H == ir2 | ANDsH == ir2 | ORsH == ir2 | SUBsH == ir2 | DECsH == ir2 |
|
1056 |
|
|
ADCsA_L == ir2 | ANDsL == ir2 | ORsL == ir2 | SUBsL == ir2 | DECsL == ir2 |
|
1057 |
|
|
ADCsA_6HL7==ir2 | ANDs6HL7 ==ir2 | ORs6HL7 ==ir2 | SUBs6HL7 ==ir2 | INCsA == ir2 |
|
1058 |
|
|
ADDsA_A == ir2 | CPsA == ir2 | SBCsA == ir2 | XORsA == ir2 | INCsB == ir2 |
|
1059 |
|
|
ADDsA_B == ir2 | CPsB == ir2 | SBCsA_6HL7==ir2 | XORsB == ir2 | INCsC == ir2 |
|
1060 |
|
|
ADDsA_C == ir2 | CPsC == ir2 | SBCsB == ir2 | XORsC == ir2 | INCsD == ir2 |
|
1061 |
|
|
ADDsA_D == ir2 | CPsD == ir2 | SBCsC == ir2 | XORsD == ir2 | INCsE == ir2 |
|
1062 |
|
|
ADDsA_E == ir2 | CPsE == ir2 | SBCsD == ir2 | XORsE == ir2 | INCsH == ir2 |
|
1063 |
|
|
ADDsA_H == ir2 | CPsH == ir2 | SBCsE == ir2 | XORsH == ir2 | INCsL == ir2 |
|
1064 |
|
|
ADDsA_L == ir2 | CPsL == ir2 | SBCsH == ir2 | XORsL == ir2 | INCs6HL7 == ir2 |
|
1065 |
|
|
ADDsA_6HL7== ir2| CPs6HL7 ==ir2 | SBCsL == ir2 | XORs6HL7 == ir2 | DECs6HL7 == ir2 |
|
1066 |
|
|
ED_NEG == {ir2[9:6],ir2[2:0]} ; //7'b1001___100, A<= -A
|
1067 |
|
|
|
1068 |
|
|
|
1069 |
|
|
|
1070 |
|
|
// update h n c (f5, f3) from alu16
|
1071 |
|
|
assign upd_fr_add16 =
|
1072 |
|
|
ADDsHL_BC == ir2 | // ADD HL,BC ; 09
|
1073 |
|
|
ADDsHL_DE == ir2 | // ADD HL,DE ; 19
|
1074 |
|
|
ADDsHL_HL == ir2 | // ADD HL,HL ; 29
|
1075 |
|
|
ADDsHL_SP == ir2 ; // ADD HL,SP ; 39
|
1076 |
|
|
// INCsBC == ir2 | // INC BC ; 03 no flag changes for these
|
1077 |
|
|
// INCsDE == ir2 | // INC DE ; 13
|
1078 |
|
|
// INCsHL == ir2 | // INC HL ; 23
|
1079 |
|
|
// INCsSP == ir2 ; // INC SP ; 33
|
1080 |
|
|
|
1081 |
|
|
// update all flags from alu16
|
1082 |
|
|
assign upd_fr_edadd16 =
|
1083 |
|
|
ED_SBCsHL_REG == {ir2[7:6],ir2[3:0]} | // compair with {ir2[7:6],ir2[3:0]}
|
1084 |
|
|
ED_ADCsHL_REG == {ir2[7:6],ir2[3:0]} ; // compair with {ir2[7:6],ir2[3:0]}
|
1085 |
|
|
|
1086 |
|
|
|
1087 |
|
|
// the shifts probably muck with all flags (some operations are
|
1088 |
|
|
// guarenteed not to change certain flags )
|
1089 |
|
|
// docs say sf and zf never change for these ops.
|
1090 |
|
|
assign upd_fr_sh =
|
1091 |
|
|
RLA == ir2 |// RLA ; 17
|
1092 |
|
|
RLCA == ir2 |// RLCA ; 07
|
1093 |
|
|
RRA == ir2 |// RRA ; 1F
|
1094 |
|
|
RRCA == ir2 ;// RRCA ; 0F
|
1095 |
|
|
// sf and zf do change for theses
|
1096 |
|
|
assign upd_fr_cbsh =
|
1097 |
|
|
CB_RLC == ir2[9:3] | // these must be compaired with ir2[9:3]
|
1098 |
|
|
CB_RRC == ir2[9:3] | // these must be compaired with ir2[9:3]
|
1099 |
|
|
CB_RL == ir2[9:3] | // these must be compaired with ir2[9:3]
|
1100 |
|
|
CB_RR == ir2[9:3] | // these must be compaired with ir2[9:3]
|
1101 |
|
|
CB_SLA == ir2[9:3] | // these must be compaired with ir2[9:3]
|
1102 |
|
|
CB_SRA == ir2[9:3] | // these must be compaired with ir2[9:3]
|
1103 |
|
|
CB_SLL == ir2[9:3] | // these must be compaired with ir2[9:3]
|
1104 |
|
|
CB_SRL == ir2[9:3] ; // these must be compaired with ir2[9:3]
|
1105 |
|
|
|
1106 |
|
|
// pretty nomal stuff here
|
1107 |
|
|
//CB_BIT = 4'b01_01, // these must be compaired with ir2[9:6]
|
1108 |
|
|
// which alu? -- done from alu8
|
1109 |
|
|
//ED_NEG = 5'b01___100, // compair with {ir2[7:6],ir2[2:0]} all A<= -A
|
1110 |
|
|
|
1111 |
|
|
// rmw 8 types these handled by standard INC and DEC logic done.
|
1112 |
|
|
//INCs6HL7 = 'h34,// INC (HL) ; 34
|
1113 |
|
|
//DECs6HL7 = 'h35,// DEC (HL) ; 35
|
1114 |
|
|
|
1115 |
|
|
// ED Block Move messyness upd_b_decbc
|
1116 |
|
|
// hf and nf <= 0 pnf<= BC==0
|
1117 |
|
|
assign eb_blk_mv =
|
1118 |
|
|
ED_LDI == ir2 | // LDI ; ED A0 (DE++) <= (HL++) , BC--
|
1119 |
|
|
ED_LDD == ir2 | // LDD ; ED A8 (DE--) <= (HL--) , BC--
|
1120 |
|
|
ED_LDIR == ir2 | // LDIR ; ED B0 (DE++) <= (HL++) , BC-- Repeat til BC==0
|
1121 |
|
|
ED_LDDR == ir2 ;// LDDR ; ED B8 (DE--) <= (HL--) , BC-- Repeat til BC==0
|
1122 |
|
|
// only c not affected - nf<=1 ?
|
1123 |
|
|
assign ed_blk_cp =
|
1124 |
|
|
ED_CPI == ir2 | // CPI ; ED A1 A - (HL++) , BC--
|
1125 |
|
|
ED_CPD == ir2 | // CPD ; ED A9 A - (HL--) , BC--
|
1126 |
|
|
ED_CPIR == ir2 | // CPIR ; ED B1 A - (HL++) , BC-- repeat if(|B
|
1127 |
|
|
ED_CPDR == ir2 ;// CPDR ; ED B9 A - (HL--) , BC-- repeat if(|B
|
1128 |
|
|
|
1129 |
|
|
// all the ed i/o muck with all flags -- wonderful cf?
|
1130 |
|
|
// use the aluoutput for the b-1 computation.
|
1131 |
|
|
// --------- eb_io
|
1132 |
|
|
//ED_INI = 'hA2// INI ; ED A2 (HL++) <- (Cio) , B--
|
1133 |
|
|
//ED_IND = 'hAA// IND ; ED AA (HL--) <- (Cio) , B--
|
1134 |
|
|
//ED_INIR = 'hB2// INIR ; ED B2 (HL++) <- (Cio) , B-- repeat if(|B)
|
1135 |
|
|
//ED_INDR = 'hBA// INDR ; ED BA (HL--) <- (Cio) , B-- repeat if(|B)
|
1136 |
|
|
//ED_OUTI = 'hA3// OUTI ; ED A3 (Cio) <-(HL++) , B--
|
1137 |
|
|
//ED_OUTD = 'hAB// OUTD ; ED AB (Cio) <-(HL--) , B--
|
1138 |
|
|
//ED_OTIR = 'hB3// OTIR ; ED B3 (Cio) <-(HL++) , B-- rpt if(|B)
|
1139 |
|
|
//ED_OTDR = 'hBB// OTDR ; ED BB (Cio) <-(HL--) , B-- rpt if(|B)
|
1140 |
|
|
|
1141 |
|
|
//ED_INsREG_6C7 = 5'b01___000,// compair with {ir2[7:6],ir2[2:0]} really (BCio)
|
1142 |
|
|
|
1143 |
|
|
|
1144 |
|
|
|
1145 |
|
|
// special problems -- lol more special problems ????
|
1146 |
|
|
//CCF = 'h3F,// CCF ; 3F // h<=c c<=~C N<=0 F3,F5?
|
1147 |
|
|
//CPL = 'h2F,// CPL ; 2F // H<=1 N<=1 F3,F5?
|
1148 |
|
|
//DAA = 'h27,// DAA ; 27 // H<=0???
|
1149 |
|
|
//SCF = 'h37,// SCF ; 37
|
1150 |
|
|
//ED_RRD = 'h67// RRD ; ED 67 nibble roates A HL
|
1151 |
|
|
//ED_RLD = 'h6F// RLD ; ED 6F nibble roates A HL
|
1152 |
|
|
//ED_LDsA_I = 'h57// LD A,I ; ED 57 move I to A
|
1153 |
|
|
|
1154 |
|
|
assign { sf, zf, f5f, hf, f3f, pvf, nf, cf} = fr;
|
1155 |
|
|
// gotta say those little ~^ operators down there worry me. Only 4 levels of xor - but jeeze
|
1156 |
|
|
// there are a lot of them. I guess in most FPGA's it doesn't matter what the op is - just
|
1157 |
|
|
// how many terms.
|
1158 |
|
|
|
1159 |
|
|
|
1160 |
|
|
// do we need the exe_ir2 term here? isn't it added in the hazard term anyway?
|
1161 |
|
|
assign upd_fr = exec_ir2 & ( ( upd_fr_alu8 ) |
|
1162 |
|
|
( upd_fr_add16) |
|
1163 |
|
|
( upd_fr_edadd16) |
|
1164 |
|
|
( upd_fr_sh ) |
|
1165 |
|
|
( upd_fr_cbsh ) |
|
1166 |
|
|
(CB_BIT == ir2[9:6]) |
|
1167 |
|
|
( ed_blk_cp ) |
|
1168 |
|
|
(ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]}) |
|
1169 |
|
|
(CCF == ir2 ) |
|
1170 |
|
|
(CPL == ir2 ) |
|
1171 |
|
|
(DAA == ir2 ) |
|
1172 |
|
|
(SCF == ir2 ) |
|
1173 |
|
|
(ED_RRD == ir2) |
|
1174 |
|
|
(ED_RLD == ir2) |
|
1175 |
|
|
(ED_LDsA_I == ir2) ) ;
|
1176 |
|
|
|
1177 |
|
|
|
1178 |
|
|
|
1179 |
|
|
wire iff2 = 1'b0; // this is supposed to be int ff #2 which is not (yet) implmented
|
1180 |
|
|
always @(posedge clk)
|
1181 |
|
|
begin
|
1182 |
|
|
if (exec_ir2)
|
1183 |
|
|
begin
|
1184 |
|
|
if ( upd_fr_alu8 ) fr <= alu8_fr; // assembled above with 8 bit ALU
|
1185 |
|
|
if ( upd_fr_add16) fr <= {sf, zf, add16[13], c_16out11, add16[11], pvf, 1'b0, c_16out15};
|
1186 |
|
|
if ( upd_fr_edadd16) fr <= {add16[15], ~|add16, add16[13], c_out11,
|
1187 |
|
|
add16[11], add16_ofl, ~ir2[3], c_16out15};
|
1188 |
|
|
if ( upd_fr_sh ) fr <= {sf, zf, sh_alu[5], 1'b0, sh_alu[3], pvf, 1'b0, sh_cry};
|
1189 |
|
|
if ( upd_fr_cbsh ) fr <= {sh_alu[7], ~|sh_alu, sh_alu[5], 1'b0,
|
1190 |
|
|
sh_alu[3], ~^sh_alu, 1'b0, sh_cry};
|
1191 |
|
|
if (CB_BIT == ir2[9:6]) fr <={bit_alu[7], ~|bit_alu, bit_alu[5], 1'b1, //no idea why hf<=1
|
1192 |
|
|
bit_alu[3], ~|bit_alu, 1'b0 , cf };// pvf == zf ???
|
1193 |
|
|
if ( ed_blk_cp ) fr <= {alu8_out[7], ~|alu8_out, alu8_out[5], alu8_hcry,//std a-n stuff
|
1194 |
|
|
alu8_out[3], alu8_out[7], 1'b1, cf }; //cept nf and cf
|
1195 |
|
|
if (ED_INsREG_6C7 == {ir2[7:6],ir2[2:0]})
|
1196 |
|
|
fr <= {nn[7], ~|nn[7:0], nn[5], 1'b0, nn[3], ~^nn[7:0], 1'b0, cf};
|
1197 |
|
|
if (CCF == ir2 ) fr <= {sf, zf, f5f, cf, f3f, pvf, nf, ~cf};
|
1198 |
|
|
if (CPL == ir2 ) fr <= {sf, zf, ar[5], 1'b1, ar[3], pvf, 1'b1, cf};
|
1199 |
|
|
if (DAA == ir2 ) fr <= {daa_alu[7], ~|daa_alu, daa_alu[5], 1'b0, // hf sb (logically) 0
|
1200 |
|
|
daa_alu[3], ~^daa_alu, nf, daa_cry };
|
1201 |
|
|
if (SCF == ir2 ) fr <= { sf, zf, ar[5], 1'b0, ar[3], pvf, 1'b0, 1'b1 }; // very strange
|
1202 |
|
|
if (ED_RRD == ir2) fr <= { sf, ~|{ar[7:4],nn[3:0]}, ar[5], 1'b0,
|
1203 |
|
|
ar[3], ~^{ar[7:4],nn[3:0]}, 1'b0 , cf };
|
1204 |
|
|
if (ED_RLD == ir2) fr <= { sf, ~|{ar[7:4],nn[7:4]}, ar[5], 1'b0,
|
1205 |
|
|
ar[3], ~^{ar[7:4],nn[7:4]}, 1'b0 , cf };
|
1206 |
|
|
if (ED_LDsA_I == ir2) fr <= { ir2[7], ~|ir2, ir2[5], 1'b0, ir2[3], iff2, 1'b0, cf }; // iff2 ?
|
1207 |
|
|
|
1208 |
|
|
end
|
1209 |
|
|
// in the case of blk_cp the update above is executed 2nd - and so these are don't cares.
|
1210 |
|
|
if (exec_decb ) fr <= {decb_alu[7], ~|decb_alu, decb_alu[5], hf,
|
1211 |
|
|
decb_alu[3], pvf, 1'b0, cf };
|
1212 |
|
|
if (exec_decbc ) fr[5:1] <= { decb_alu[5], 1'b0, decb_alu[3], ~|decb_alu, 1'b0 };
|
1213 |
|
|
end
|
1214 |
|
|
|
1215 |
|
|
|
1216 |
|
|
//----------------------- intr -----------------------------------------------------------
|
1217 |
|
|
|
1218 |
|
|
always @(posedge clk)
|
1219 |
|
|
begin
|
1220 |
|
|
if (( ED_LDsI_A == ir2) & exec_ir2) intr <= ar;
|
1221 |
|
|
end
|
1222 |
|
|
|
1223 |
|
|
|
1224 |
|
|
endmodule
|