1 |
52 |
mihal |
|
2 |
51 |
mihal |
|
3 |
45 |
mihal |
///////////////////////////////////////////////////////////////////////////////////////////////////
|
4 |
|
|
// //
|
5 |
|
|
// file name: memstate2.v //
|
6 |
|
|
// description: memory opertions for z80 //
|
7 |
|
|
// project: wb_z80 //
|
8 |
|
|
// //
|
9 |
|
|
// Author: B.J. Porcella //
|
10 |
|
|
// e-mail: bporcella@sbcglobal.net //
|
11 |
|
|
// //
|
12 |
|
|
// //
|
13 |
|
|
// //
|
14 |
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
15 |
|
|
// //
|
16 |
|
|
// Copyright (C) 2000-2002 B.J. Porcella //
|
17 |
|
|
// Real Time Solutions //
|
18 |
|
|
// //
|
19 |
|
|
// //
|
20 |
|
|
// This source file may be used and distributed without //
|
21 |
|
|
// restriction provided that this copyright statement is not //
|
22 |
|
|
// removed from the file and that any derivative work contains //
|
23 |
|
|
// the original copyright notice and the associated disclaimer. //
|
24 |
|
|
// //
|
25 |
|
|
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //
|
26 |
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //
|
27 |
|
|
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //
|
28 |
|
|
// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //
|
29 |
|
|
// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //
|
30 |
|
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //
|
31 |
|
|
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //
|
32 |
|
|
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //
|
33 |
|
|
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //
|
34 |
|
|
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //
|
35 |
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //
|
36 |
|
|
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //
|
37 |
|
|
// POSSIBILITY OF SUCH DAMAGE. //
|
38 |
|
|
// //
|
39 |
|
|
//-------1---------2---------3--------Comments on file -------------7---------8---------9--------0
|
40 |
|
|
// The memory state controller controls the wb bus, and provides address sequencing.
|
41 |
|
|
// Insructions are fetched in order (using PC) until the istate machine indicates that
|
42 |
|
|
// a complete instruction is in the first pipline stage (ir1). In general, operands are being
|
43 |
|
|
// fetched (stored) to satisfy ir1 while concurrently instructions are being executed from ir2.
|
44 |
|
|
// this situation can result in a number of potential hazards. As an example, if the ir2
|
45 |
|
|
// instruction changes the flag register and the ir1 instruction is a conditional jump,
|
46 |
|
|
// a hazard is generated by the hazard logic, and execution of the ir1 operation is delayed
|
47 |
|
|
// until the completion of the flag update.
|
48 |
|
|
//
|
49 |
|
|
// Reset starts execution at 0.
|
50 |
|
|
// The PC and SP are described in this file. modifications to other index registers -
|
51 |
|
|
// HL IX and IY are computed here --
|
52 |
|
|
// For the block moves address updates are computed here -- and commanded here.
|
53 |
|
|
// Strobes for the second address update are generally co-incident with count updates, but
|
54 |
|
|
// we provide seperate strobe update lines for clarity.
|
55 |
|
|
//
|
56 |
|
|
// BASIC ARCHITECTURE OF THIS FILE pc and sp not shown, but are inputs to src mux.
|
57 |
|
|
// _____ and may be updated from adder output.
|
58 |
|
|
// | |
|
59 |
|
|
// | | pc-1 register is required to implement relative jumps.
|
60 |
|
|
// | |
|
61 |
|
|
// _____ |lit | |\
|
62 |
|
|
// | | | | | \
|
63 |
|
|
// | | |src2 | | \ _____ _____
|
64 |
|
|
// | | | |----->| | | | | |
|
65 |
|
|
// |src | |_____| |adder|------->| | | |
|
66 |
|
|
// |mux | | | | | | |
|
67 |
|
|
// | |------------------->| / |2/1 |------->|wb |
|
68 |
|
|
// | | | | / |mux | |adr |
|
69 |
|
|
// |_____| | |/ | | | |
|
70 |
|
|
// ------------------->| | | |
|
71 |
|
|
// |_____| |_____|
|
72 |
|
|
//
|
73 |
|
|
//
|
74 |
|
|
//
|
75 |
|
|
//
|
76 |
|
|
// Operand Stores:
|
77 |
|
|
// At first cut, I thought I'ld execute operand stores immediately from the memory sequencer
|
78 |
|
|
// (essentially before ir2 got the store data). While this might be modestly faster in
|
79 |
|
|
// systems that take multiple clocks to complete a memory store, On consideration, I decided
|
80 |
|
|
// to forgo the extra speed for conceptual simplicity.... execute operand stores on op_ph1,
|
81 |
|
|
// and let the inst_exec engine suply the operand.
|
82 |
|
|
//
|
83 |
|
|
// On second thought, above is not only wastful of time, but also inconsistent with the overall
|
84 |
|
|
// schems of things - and so somewhat more complex. If we simply execute the OS from ir1,
|
85 |
|
|
// There is less state to contdend with, as well as extra speed.
|
86 |
|
|
//
|
87 |
|
|
// Block Moves fundamentally execute from ir2. We initiate the first operand fetch from ir1.
|
88 |
|
|
//
|
89 |
|
|
// 3/18/2004 Second time through. In impleenting the execution logic it became clear that
|
90 |
|
|
// there were "minor" problems with the handling of the DD and FD prefix insts (especially
|
91 |
|
|
// DDCD and FDCB --- collectively called PFxCB below. On review, I had to question the
|
92 |
|
|
// value of "breaking up" the ir0 execution engine between the istate sequencer and the
|
93 |
|
|
// memstate sequencer. While I dislike state sequencers of much more than 16 states --
|
94 |
|
|
// the interaction between these sequencers was becomming harder to track than a single
|
95 |
|
|
// state macine. Thus - this file is getting re-worked. I will call it memstate2 (at least
|
96 |
|
|
// for awhile) as I wish to keep the old file around. I want to show (in the state machine
|
97 |
|
|
// logic) what the next memory operation is.... guess the best method consistent with my
|
98 |
|
|
// documentation practices is to define a register (mem_op) = { if, wb_we, wb_cyc }.
|
99 |
|
|
// This will require auxillary logic for computing the address --- but most of the decodes
|
100 |
|
|
// required will be there anyway.
|
101 |
|
|
// On further reflection, I think I will bite-the-bullet and use an always to define next_state.
|
102 |
|
|
// I don't like to use always to define wires, but I also want to dicument the setting of
|
103 |
|
|
// exec_ir2 in the same place - that is 3 different things.
|
104 |
|
|
//
|
105 |
|
|
// Hazards:
|
106 |
|
|
// There are 2 kinds of hazards: mem_hazard => we are storing into the next instruction location
|
107 |
|
|
// reg_hazard => we are modifying a register (ir2) that we are using
|
108 |
|
|
// here (ir1)
|
109 |
|
|
// In the former case, we throw out the instruction that arrives on the next tick, and restart the
|
110 |
|
|
// instruction pipeline, In the latter case, we simply wait a tick for the ir2 operaton to
|
111 |
|
|
// complete before starting the ir1 operation
|
112 |
|
|
//-------1---------2---------3--------CVS Log -----------------------7---------8---------9--------0
|
113 |
|
|
//
|
114 |
52 |
mihal |
// $Id: memstate2.v,v 1.8 2004-04-19 09:01:35 mihal Exp $
|
115 |
45 |
mihal |
//
|
116 |
52 |
mihal |
// $Date: 2004-04-19 09:01:35 $
|
117 |
|
|
// $Revision: 1.8 $
|
118 |
45 |
mihal |
// $Author: mihal $
|
119 |
|
|
// $Locker: $
|
120 |
|
|
// $State: Exp $
|
121 |
|
|
//
|
122 |
|
|
// Change History:
|
123 |
|
|
// $Log: not supported by cvs2svn $
|
124 |
52 |
mihal |
// Revision 1.7 2004/04/19 08:56:34 mihal
|
125 |
|
|
// testing lint
|
126 |
|
|
//
|
127 |
51 |
mihal |
// Revision 1.6 2004/04/19 08:22:34 mihal
|
128 |
|
|
// testing lint
|
129 |
|
|
//
|
130 |
50 |
mihal |
// Revision 1.5 2004/04/19 08:10:36 mihal
|
131 |
|
|
// testing lint
|
132 |
|
|
//
|
133 |
49 |
mihal |
// Revision 1.4 2004/04/19 07:52:39 mihal
|
134 |
|
|
// testing lint
|
135 |
|
|
//
|
136 |
48 |
mihal |
// Revision 1.3 2004/04/19 07:28:58 mihal
|
137 |
|
|
// testing lint
|
138 |
|
|
//
|
139 |
47 |
mihal |
// Revision 1.2 2004/04/17 08:02:00 mihal
|
140 |
|
|
// testing lint
|
141 |
|
|
//
|
142 |
46 |
mihal |
// Revision 1.1 2004/04/17 07:39:21 mihal
|
143 |
|
|
// testing lint
|
144 |
|
|
//
|
145 |
45 |
mihal |
// Revision 1.4 2004/04/16 18:16:57 bporcella
|
146 |
|
|
// try lint
|
147 |
|
|
//
|
148 |
|
|
// Revision 1.3 2004/04/16 17:06:54 bporcella
|
149 |
|
|
// no code change - added a comment and test lint
|
150 |
|
|
//
|
151 |
|
|
// Revision 1.2 2004/04/16 16:21:04 bporcella
|
152 |
|
|
// no code change - added a comment and test lint
|
153 |
|
|
//
|
154 |
|
|
// Revision 1.1.1.1 2004/04/13 23:50:19 bporcella
|
155 |
|
|
// import first files
|
156 |
|
|
//
|
157 |
|
|
//
|
158 |
|
|
//
|
159 |
46 |
mihal |
//
|
160 |
45 |
mihal |
//-------1---------2---------3--------Module Name and Port List------7---------8---------9--------0
|
161 |
46 |
mihal |
|
162 |
45 |
mihal |
module memstate2(wb_adr, wb_we, wb_cyc, wb_stb, wb_lock, wb_tga_io, wb_dat_o, add_out,
|
163 |
|
|
exec_ir2, ir1, ir2, ir1dd, ir1fd, ir2dd, ir2fd, nn, sp,
|
164 |
|
|
|
165 |
|
|
upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr,
|
166 |
|
|
beq0, ceq0,
|
167 |
|
|
ar, fr, br, cr, dr, er, hr, lr,
|
168 |
|
|
ixr, iyr,
|
169 |
|
|
wb_dat_i, wb_ack, clk, rst,
|
170 |
|
|
wb_int_rq,
|
171 |
|
|
add16
|
172 |
|
|
|
173 |
|
|
|
174 |
|
|
);
|
175 |
|
|
|
176 |
|
|
//-------1---------2---------3--------Output Ports---------6---------7---------8---------9--------0
|
177 |
|
|
// mod only to checkout lint
|
178 |
|
|
// mod again for lint check -- first check pretty wierd
|
179 |
|
|
// 3rd lint try
|
180 |
|
|
output [15:0] wb_adr;
|
181 |
|
|
output wb_we;
|
182 |
|
|
output wb_cyc;
|
183 |
|
|
output wb_stb;
|
184 |
|
|
output wb_lock; // bit set and clear insts should be atomic - could matter sometime
|
185 |
|
|
output wb_tga_io;
|
186 |
|
|
output wb_dat_o; // from nn
|
187 |
|
|
output [15:0] add_out; // output of adder (may not wb_adr)
|
188 |
|
|
|
189 |
|
|
output exec_ir2;
|
190 |
|
|
output [9:0] ir1, ir2;
|
191 |
|
|
output ir1dd, ir2dd;
|
192 |
|
|
output ir1fd, ir2fd;
|
193 |
|
|
output [15:0] nn;
|
194 |
|
|
output [15:0] sp;
|
195 |
|
|
|
196 |
|
|
|
197 |
|
|
|
198 |
|
|
|
199 |
|
|
//-------1---------2---------3--------Input Ports----------6---------7---------8---------9--------0
|
200 |
|
|
input upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr;
|
201 |
|
|
|
202 |
|
|
input beq0, ceq0;
|
203 |
|
|
input [7:0] ar, fr, br, cr, dr, er, hr, lr;
|
204 |
|
|
input [15:0] ixr, iyr;
|
205 |
|
|
input [7:0] wb_dat_i;
|
206 |
|
|
input wb_ack, clk, rst;
|
207 |
|
|
input wb_int_rq;
|
208 |
|
|
input [15:0] add16; // ir2 execution engine output for sp updates
|
209 |
|
|
|
210 |
|
|
|
211 |
|
|
//-------1---------2---------3--------Parameters-----------6---------7---------8---------9--------0
|
212 |
|
|
`include "opcodes.v" // states of the main memory sequencer
|
213 |
|
|
|
214 |
|
|
|
215 |
|
|
parameter TAG_IO = 2'b01, // need to review general wb usage to undrstand how best to
|
216 |
|
|
TAG_INT = 2'b10; // document this.
|
217 |
|
|
// 12na
|
218 |
|
|
parameter IPIPE_NOP = 4'b0000,
|
219 |
|
|
IPIPE_A2 = 4'b0001,
|
220 |
|
|
IPIPE_ENN = 4'b0010,
|
221 |
|
|
IPIPE_ENNA2 = 4'b0011,
|
222 |
|
|
IPIPE_EN2 = 4'b0100,
|
223 |
|
|
IPIPE_EN2A2 = 4'b0101,
|
224 |
|
|
IPIPE_ENNEN2 = 4'b0110,
|
225 |
|
|
IPIPE_ENNEN2A2 = 4'b0111,
|
226 |
|
|
IPIPE_EN1 = 4'b1000,
|
227 |
|
|
IPIPE_EN1A2 = 4'b1001,
|
228 |
|
|
IPIPE_BOGUS = 4'b1010, // no reason (yet) to load both n and ir1
|
229 |
|
|
IPIPE_BOUS2 = 4'b1011,
|
230 |
|
|
IPIPE_EN12 = 4'b1100,
|
231 |
|
|
IPIPE_EN12A2 = 4'b1101,
|
232 |
|
|
IPIPE_BOGUS3 = 4'b1110,
|
233 |
|
|
IPIPE_BOGUS4 = 4'b1111;
|
234 |
|
|
|
235 |
|
|
// well at first cut I tried to make this 2 state macines both less than 16 states.
|
236 |
|
|
// this is 56 states at first cut. Assignemnt is subject to change.
|
237 |
|
|
|
238 |
|
|
// ------ mem state decoder state machine states --------------------------------
|
239 |
|
|
parameter DEC_IDLE = 6'h00,
|
240 |
|
|
DEC_HALT = 6'h01,
|
241 |
|
|
DEC_IF1 = 6'h02,
|
242 |
|
|
DEC_IF2 = 6'h03,
|
243 |
|
|
DEC_IF2A = 6'h04,
|
244 |
|
|
DEC_EXEC = 6'h05,
|
245 |
|
|
DEC_CB = 6'h06,
|
246 |
|
|
DEC_DDFD = 6'h07,
|
247 |
|
|
DEC_ED = 6'h08,
|
248 |
|
|
DEC_EDNN1 = 6'h09,
|
249 |
|
|
DEC_EDNN2 = 6'h0a,
|
250 |
|
|
DEC_EDRD1 = 6'h0b,
|
251 |
|
|
DEC_EDRD2 = 6'h0c,
|
252 |
|
|
DEC_EDWR = 6'h0d,
|
253 |
|
|
DEC_EDBCP1 = 6'h0e,
|
254 |
|
|
DEC_EDBCP2 = 6'h0f,
|
255 |
|
|
DEC_EDBCP3 = 6'h10,
|
256 |
|
|
DEC_EDBIN1 = 6'h11,
|
257 |
|
|
DEC_EDBIN2 = 6'h12,
|
258 |
|
|
DEC_EDBIN3 = 6'h13,
|
259 |
|
|
DEC_EDBOUT1 = 6'h14,
|
260 |
|
|
DEC_EDBOUT2 = 6'h15,
|
261 |
|
|
DEC_EDBOUT3 = 6'h16,
|
262 |
|
|
DEC_EDBMV1 = 6'h17,
|
263 |
|
|
DEC_EDBMV2 = 6'h18,
|
264 |
|
|
DEC_EDBMV3 = 6'h19,
|
265 |
|
|
DEC_N = 6'h1a,
|
266 |
|
|
DEC_NIN = 6'h1b,
|
267 |
|
|
DEC_NN = 6'h1c,
|
268 |
|
|
DEC_NNCALL1 = 6'h1d,
|
269 |
|
|
DEC_NNCALL2 = 6'h1e,
|
270 |
|
|
DEC_NNOS1 = 6'h1f,
|
271 |
|
|
DEC_NNOS2 = 6'h20,
|
272 |
|
|
DEC_NNOS3 = 6'h21,
|
273 |
|
|
DEC_NNOF1 = 6'h22,
|
274 |
|
|
DEC_NNOF2 = 6'h23,
|
275 |
|
|
DEC_NNOF3 = 6'h24,
|
276 |
|
|
DEC_NNOF4 = 6'h25,
|
277 |
|
|
DEC_DDOS = 6'h26,
|
278 |
|
|
DEC_DDOF = 6'h27,
|
279 |
|
|
DEC_OF = 6'h28,
|
280 |
|
|
DEC_POP = 6'h29,
|
281 |
|
|
DEC_PUSH = 6'h2a,
|
282 |
|
|
DEC_RMW = 6'h2b,
|
283 |
|
|
DEC_RMW2 = 6'h2c,
|
284 |
|
|
DEC_CBM = 6'h2d,
|
285 |
|
|
DEC_PFxCB = 6'h2e,
|
286 |
|
|
DEC_PFxCB2 = 6'h2f,
|
287 |
|
|
DEC_PFxCB3 = 6'h30,
|
288 |
|
|
DEC_PFxCB4 = 6'h31,
|
289 |
|
|
DEC_INT1 = 6'h32,
|
290 |
|
|
DEC_INT2 = 6'h33,
|
291 |
|
|
DEC_INT3 = 6'h34,
|
292 |
|
|
DEC_INT4 = 6'h35,
|
293 |
|
|
DEC_INT5 = 6'h36,
|
294 |
|
|
DEC_RET = 6'h37,
|
295 |
|
|
DEC_NNJMP = 6'h38,
|
296 |
|
|
DEC_RET2 = 6'h39 ;
|
297 |
|
|
|
298 |
|
|
// initial decode assignemnts. These assignemens are made to wires on an initial decode
|
299 |
|
|
// to help document next state transitions
|
300 |
|
|
parameter I1_CB = 4'h0,
|
301 |
|
|
I1_DDFD = 4'h1,
|
302 |
|
|
I1_ED = 4'h2,
|
303 |
|
|
I1_JMP = 4'h3,
|
304 |
|
|
I1_N = 4'h4,
|
305 |
|
|
I1_NN = 4'h5,
|
306 |
|
|
I1_OF = 4'h6,
|
307 |
|
|
I1_OS = 4'h7,
|
308 |
|
|
I1_POP = 4'h8,
|
309 |
|
|
I1_PUSH = 4'h9,
|
310 |
|
|
I1_RET = 4'ha,
|
311 |
|
|
I1_RMW = 4'hb,
|
312 |
|
|
I1_RST = 4'hc,
|
313 |
|
|
I1_R2R = 4'hd ;
|
314 |
|
|
|
315 |
|
|
|
316 |
|
|
// A note here on the choices of mnemonics..... in general, the target registers of
|
317 |
|
|
// memory ops are specified by an instruction register (ir1 for stores ir2 for loads).
|
318 |
|
|
// so Menomics in general are specifying the address source. However, there are exceptions.
|
319 |
|
|
//
|
320 |
|
|
parameter MEM_NOP = 5'h00,
|
321 |
|
|
MEM_IFPP1 = 5'h01,
|
322 |
|
|
MEM_OS1 = 5'h02, // only invoked on I1 OS multiple address sources and data sources
|
323 |
|
|
MEM_OF1 = 5'h03, // Address from HL unless LD A,(BC) or LD A,(DE) (used for rmw)
|
324 |
|
|
MEM_OFSP = 5'h04, // works for both POP and RET
|
325 |
|
|
MEM_OSSP = 5'h05, // if DEC_EXEC op from ir1 else msb nn (implies we store from lsb nn)
|
326 |
|
|
// used in CALL also.
|
327 |
|
|
MEM_OFIXpD = 5'h06, // used for prefix op fetches - all single bytes
|
328 |
|
|
MEM_OSIXpD = 5'h07, // data source is same as MEM_OS1
|
329 |
|
|
MEM_OSADR = 5'h08, // used (at lesat) for prefixed rmw -- perhaps others.
|
330 |
|
|
|
331 |
|
|
MEM_CALL = 5'h09, // pc<=nn, nn<=pc, wb_adr<=sp OS
|
332 |
|
|
MEM_OSNN = 5'h0a, // if DEC_EXEC op from ir1 else msb nn
|
333 |
|
|
MEM_OFNN = 5'h0b, // striaghtfoward
|
334 |
|
|
MEM_OFADRP1 = 5'h0c, // used (at least) when double ops above
|
335 |
|
|
MEM_OSADRP1 = 5'h0d, // "" "" ""
|
336 |
|
|
|
337 |
|
|
MEM_IFRST = 5'h0e, // special address transfer
|
338 |
|
|
MEM_IFREL_N = 5'h0f, // special address transfer for jmp rel
|
339 |
|
|
MEM_JMPHL = 5'h10, // another special jump transfer
|
340 |
|
|
MEM_IFNN = 5'h11, // used by call and return
|
341 |
|
|
|
342 |
|
|
|
343 |
|
|
MEM_OFHL_PM = 5'h12, // special block move ops
|
344 |
|
|
MEM_OSHL_PM = 5'h13, // special block move ops
|
345 |
|
|
MEM_OSDE_PM = 5'h14, // special block move ops
|
346 |
|
|
|
347 |
|
|
MEM_IOF_C = 5'h15, // special i/o ops
|
348 |
|
|
MEM_IOS_C = 5'h16, // operand is ar
|
349 |
|
|
MEM_IOF_N = 5'h17,
|
350 |
|
|
MEM_IOS_N = 5'h18,
|
351 |
|
|
MEM_OS_HL_N = 5'h19,
|
352 |
|
|
|
353 |
|
|
MEM_OSSP_PCM2 = 5'h1a, // int code (call
|
354 |
|
|
MEM_OSSP_P = 5'h1b, //
|
355 |
|
|
MEM_INTA = 5'h1c,
|
356 |
|
|
MEM_IFINT = 5'h1d,
|
357 |
|
|
MEM_DECPC = 5'h1e ;
|
358 |
|
|
|
359 |
|
|
|
360 |
|
|
|
361 |
|
|
|
362 |
|
|
|
363 |
|
|
|
364 |
|
|
|
365 |
|
|
|
366 |
|
|
|
367 |
|
|
//-------1---------2---------3--------Wires----------------6---------7---------8---------9--------0
|
368 |
|
|
|
369 |
|
|
|
370 |
|
|
wire use_sp;
|
371 |
|
|
wire use_pc;
|
372 |
|
|
wire use_hl;
|
373 |
|
|
wire use_de;
|
374 |
|
|
wire use_bc;
|
375 |
|
|
wire use_flags;
|
376 |
|
|
wire cb_mem;
|
377 |
|
|
wire br_test8t; // branch test true (8 test field)
|
378 |
|
|
wire br_test4t; // branch test true (4 test field)
|
379 |
|
|
|
380 |
|
|
wire ofos;
|
381 |
|
|
wire any_os; // most terms above only valid on mem_exec this includes all stores
|
382 |
|
|
wire wb_rdy_nhz;
|
383 |
|
|
wire dec_blk_inc;
|
384 |
|
|
wire we_next;
|
385 |
|
|
wire hazard;
|
386 |
|
|
wire wb_int;
|
387 |
|
|
wire [15:0] hl, de, bc;
|
388 |
|
|
wire mem_exec_dec;
|
389 |
|
|
|
390 |
|
|
wire use_a ;
|
391 |
|
|
wire use_b ;
|
392 |
|
|
wire use_c ;
|
393 |
|
|
wire use_d ;
|
394 |
|
|
wire use_e ;
|
395 |
|
|
wire use_h ;
|
396 |
|
|
wire use_l ;
|
397 |
|
|
// don't forget that as 1r1 is executed it is transferred to ir2. Anything I need to know
|
398 |
|
|
// about subsequent operations must be stored.
|
399 |
|
|
// 6 5 4 15
|
400 |
|
|
// assign {next_dec_state, next_mem_state, next_pipe_state} = next_state;
|
401 |
|
|
wire [5:0] next_dec_state;
|
402 |
|
|
wire [4:0] next_mem_state;
|
403 |
|
|
wire [3:0] next_pipe_state;
|
404 |
|
|
wire ed_dbl_rd;
|
405 |
|
|
//-------1---------2---------3--------Registers------------6---------7---------8---------9--------0
|
406 |
|
|
|
407 |
|
|
reg [15:0] pc;
|
408 |
|
|
reg [15:0] sp;
|
409 |
|
|
reg [15:0] wb_adr;
|
410 |
|
|
reg wb_we;
|
411 |
|
|
reg wb_cyc;
|
412 |
|
|
reg wb_stb;
|
413 |
|
|
reg wb_lock;
|
414 |
|
|
reg wb_tga_io;
|
415 |
|
|
|
416 |
|
|
reg blk_inc_flg;
|
417 |
|
|
reg [9:0] ir1, ir2;
|
418 |
|
|
reg ir1dd, ir2dd;
|
419 |
|
|
reg ir1fd, ir2fd;
|
420 |
|
|
reg [15:0] nn;
|
421 |
|
|
|
422 |
|
|
reg [15:0] next_state; // a wire assigned in an alowys loop.
|
423 |
|
|
|
424 |
|
|
reg [5:0] dec_state; // the register set each clock from next_dec_state;
|
425 |
|
|
|
426 |
|
|
reg of16_reg, os16_reg, rmw8_reg, call_reg, ret_reg, ioi;
|
427 |
|
|
reg push_reg;
|
428 |
|
|
reg pop_reg;
|
429 |
|
|
reg inst_haz;
|
430 |
|
|
reg exec_ir2;
|
431 |
|
|
reg blk_rpt_flg;
|
432 |
|
|
reg blk_io_flg;
|
433 |
|
|
reg flag_os1;
|
434 |
|
|
reg int_en, en_int_next;
|
435 |
|
|
reg wb_irq_sync;
|
436 |
|
|
//-------1---------2---------3--------Assignments----------6---------7---------8---------9--------0
|
437 |
|
|
//
|
438 |
|
|
// ir is 10 bits most significant codes ir1[9:8] = { EDgrp, CBgrp } DDgrp and FDgrp are modifiers
|
439 |
|
|
|
440 |
|
|
|
441 |
|
|
assign wb_dat_o = nn[15:8];
|
442 |
|
|
|
443 |
|
|
wire sf, zf, f5f, hf, f3f, pvf, nf, cf;
|
444 |
|
|
assign { sf, zf, f5f, hf, f3f, pvf, nf, cf} = fr;
|
445 |
|
|
|
446 |
|
|
|
447 |
|
|
assign hl = {hr, lr};
|
448 |
|
|
assign de = {dr, er};
|
449 |
|
|
assign bc = {br, cr};
|
450 |
|
|
|
451 |
|
|
|
452 |
|
|
// this "groups" the instructions to determine first memory operation
|
453 |
|
|
|
454 |
|
|
parameter I1DCNT = 4; // parameter used below simply to make possible change easier.
|
455 |
|
|
assign mem_exec_dec =
|
456 |
|
|
{I1DCNT {CBgrp == ir1}} & I1_CB |// CBgrp is rotates and bi
|
457 |
|
|
{I1DCNT {DDgrp == ir1}} & I1_DDFD|// DDgrp
|
458 |
|
|
{I1DCNT {FDgrp == ir1}} & I1_DDFD|// FDgrp FD
|
459 |
|
|
{I1DCNT {EDgrp == ir1}} & I1_ED |// EDgrp ED
|
460 |
|
|
{I1DCNT {JPsHL == ir1}} & I1_JMP |// JP HL ; E9 // doc
|
461 |
|
|
{I1DCNT {ADCsA_N == ir1}} & I1_N |// ADC A,N ; CE XX
|
462 |
|
|
{I1DCNT {ADDsA_N == ir1}} & I1_N |// ADD A,N ; C6 XX
|
463 |
|
|
{I1DCNT {ANDsN == ir1}} & I1_N |// AND N ; E6 XX
|
464 |
|
|
{I1DCNT {CPsN == ir1}} & I1_N |// CP N ; FE XX
|
465 |
|
|
{I1DCNT {INsA_6N7 == ir1}} & I1_N |// IN A,(N) ; DB XX
|
466 |
|
|
{I1DCNT {JRs$t2 == ir1}} & I1_N |// JR $+2 ; 18 XX
|
467 |
|
|
{I1DCNT {JRsC_$t2 == ir1}} & I1_N |// JR C,$+2 ; 38 XX
|
468 |
|
|
{I1DCNT {JRsNC_$t2 == ir1}} & I1_N |// JR NC,$+2 ; 30 XX
|
469 |
|
|
{I1DCNT {JRsZ_$t2 == ir1}} & I1_N |// JR Z,$+2 ; 28 XX
|
470 |
|
|
{I1DCNT {JRsNZ_$t2 == ir1}} & I1_N |// JR NZ,$+2 ; 20 XX
|
471 |
|
|
{I1DCNT {LDs6HL7_N == ir1}} & I1_N |// LD (HL),N ; 36 XX
|
472 |
|
|
{I1DCNT {LDsA_N == ir1}} & I1_N |// LD A,N ; 3E XX
|
473 |
|
|
{I1DCNT {LDsB_N == ir1}} & I1_N |// LD B,N ; 06 XX
|
474 |
|
|
{I1DCNT {LDsC_N == ir1}} & I1_N |// LD C,N ; 0E XX
|
475 |
|
|
{I1DCNT {LDsD_N == ir1}} & I1_N |// LD D,N ; 16 XX
|
476 |
|
|
{I1DCNT {LDsE_N == ir1}} & I1_N |// LD E,N ; 1E XX
|
477 |
|
|
{I1DCNT {LDsH_N == ir1}} & I1_N |// LD H,N ; 26 XX
|
478 |
|
|
{I1DCNT {LDsL_N == ir1}} & I1_N |// LD L,N ; 2E XX
|
479 |
|
|
{I1DCNT {ORsN == ir1}} & I1_N |// OR N ; F6 XX
|
480 |
|
|
{I1DCNT {OUTs6N7_A == ir1}} & I1_N |// OUT (N),A ; D3 XX
|
481 |
|
|
{I1DCNT {SBCsA_N == ir1}} & I1_N |// SBC A,N ; DE XX
|
482 |
|
|
{I1DCNT {SUBsN == ir1}} & I1_N |// SUB N ; D6 XX
|
483 |
|
|
{I1DCNT {XORsN == ir1}} & I1_N |// XOR N ; EE XX
|
484 |
|
|
{I1DCNT {CALLsC_NN == ir1}} & I1_NN |// CALL C,NN ; DC XX XX
|
485 |
|
|
{I1DCNT {CALLsNC_NN == ir1}} & I1_NN |// CALL NC,NN ; D4 XX XX
|
486 |
|
|
{I1DCNT {CALLsNN == ir1}} & I1_NN |// CALL NN ; CD XX XX
|
487 |
|
|
{I1DCNT {CALLsNZ_NN == ir1}} & I1_NN |// CALL NZ,NN ; C4 XX XX
|
488 |
|
|
{I1DCNT {CALLsPE_NN == ir1}} & I1_NN |// CALL PE,NN ; EC XX XX
|
489 |
|
|
{I1DCNT {CALLsPO_NN == ir1}} & I1_NN |// CALL PO,NN ; E4 XX XX
|
490 |
|
|
{I1DCNT {CALLsP_NN == ir1}} & I1_NN |// CALL P,NN ; F4 XX XX
|
491 |
|
|
{I1DCNT {CALLsZ_NN == ir1}} & I1_NN |// CALL Z,NN ; CC XX XX
|
492 |
|
|
{I1DCNT {CALLsM_NN == ir1}} & I1_NN |// CALL M,NN ; FC XX XX
|
493 |
|
|
{I1DCNT {JP == ir1}} & I1_NN |// JP ; C3 XX XX
|
494 |
|
|
{I1DCNT {JPsC == ir1}} & I1_NN |// JP C ; DA XX XX
|
495 |
|
|
{I1DCNT {JPsM == ir1}} & I1_NN |// JP M, ; FA XX XX
|
496 |
|
|
{I1DCNT {JPsNC == ir1}} & I1_NN |// JP NC, ; D2 XX XX
|
497 |
|
|
{I1DCNT {JPsNZ == ir1}} & I1_NN |// JP NZ ; C2 XX XX
|
498 |
|
|
{I1DCNT {JPsP == ir1}} & I1_NN |// JP P ; F2 XX XX
|
499 |
|
|
{I1DCNT {JPsPE == ir1}} & I1_NN |// JP PE, ; EA XX XX
|
500 |
|
|
{I1DCNT {JPsPO == ir1}} & I1_NN |// JP PO ; E2 XX XX
|
501 |
|
|
{I1DCNT {JPsZ == ir1}} & I1_NN |// JP Z ; CA XX XX
|
502 |
|
|
{I1DCNT {LDs6NN7_A == ir1}} & I1_NN |// LD (NN),A ; 32 XX XX
|
503 |
|
|
{I1DCNT {LDs6NN7_HL == ir1}} & I1_NN |// LD (NN),HL ; 22 XX XX
|
504 |
|
|
{I1DCNT {LDsA_6NN7 == ir1}} & I1_NN |// LD A,(NN) ; 3A XX XX
|
505 |
|
|
{I1DCNT {LDsBC_NN == ir1}} & I1_NN |// LD BC,NN ; 01 XX XX
|
506 |
|
|
{I1DCNT {LDsDE_NN == ir1}} & I1_NN |// LD DE,NN ; 11 XX XX
|
507 |
|
|
{I1DCNT {LDsHL_6NN7 == ir1}} & I1_NN |// LD HL,(NN) ; 2A XX XX
|
508 |
|
|
{I1DCNT {LDsHL_NN == ir1}} & I1_NN |// LD HL,NN ; 21 XX XX
|
509 |
|
|
{I1DCNT {LDsSP_NN == ir1}} & I1_NN |// LD SP,NN ; 31 XX XX
|
510 |
|
|
{I1DCNT {ADCsA_6HL7 == ir1}} & I1_OF |// ADC A,(HL) ; 8E
|
511 |
|
|
{I1DCNT {ADDsA_6HL7 == ir1}} & I1_OF |// ADD A,(HL) ; 86
|
512 |
|
|
{I1DCNT {ANDs6HL7 == ir1}} & I1_OF |// AND (HL) ; A6
|
513 |
|
|
{I1DCNT {CPs6HL7 == ir1}} & I1_OF |// CP (HL) ; BE
|
514 |
|
|
{I1DCNT {LDsA_6BC7 == ir1}} & I1_OF |// LD A,(BC) ; 0A
|
515 |
|
|
{I1DCNT {LDsA_6DE7 == ir1}} & I1_OF |// LD A,(DE) ; 1A
|
516 |
|
|
{I1DCNT {LDsA_6HL7 == ir1}} & I1_OF |// LD A,(HL) ; 7E
|
517 |
|
|
{I1DCNT {LDsB_6HL7 == ir1}} & I1_OF |// LD B,(HL) ; 46
|
518 |
|
|
{I1DCNT {LDsC_6HL7 == ir1}} & I1_OF |// LD C,(HL) ; 4E
|
519 |
|
|
{I1DCNT {LDsD_6HL7 == ir1}} & I1_OF |// LD D,(HL) ; 56
|
520 |
|
|
{I1DCNT {LDsE_6HL7 == ir1}} & I1_OF |// LD E,(HL) ; 5E
|
521 |
|
|
{I1DCNT {LDsH_6HL7 == ir1}} & I1_OF |// LD H,(HL) ; 66
|
522 |
|
|
{I1DCNT {LDsL_6HL7 == ir1}} & I1_OF |// LD L,(HL) ; 6E
|
523 |
|
|
{I1DCNT {ORs6HL7 == ir1}} & I1_OF |// OR (HL) ; B6
|
524 |
|
|
{I1DCNT {SBCs6HL7 == ir1}} & I1_OF |// SBC (HL) ; 9E
|
525 |
|
|
{I1DCNT {SUBs6HL7 == ir1}} & I1_OF |// SUB (HL) ; 96
|
526 |
|
|
{I1DCNT {XORs6HL7 == ir1}} & I1_OF |// XOR (HL) ; AE
|
527 |
|
|
{I1DCNT {LDs6BC7_A == ir1}} & I1_OS |// LD (BC),A ; 02
|
528 |
|
|
{I1DCNT {LDs6DE7_A == ir1}} & I1_OS |// LD (DE),A ; 12
|
529 |
|
|
{I1DCNT {LDs6HL7_A == ir1}} & I1_OS |// LD (HL),A ; 77
|
530 |
|
|
{I1DCNT {LDs6HL7_B == ir1}} & I1_OS |// LD (HL),B ; 70
|
531 |
|
|
{I1DCNT {LDs6HL7_C == ir1}} & I1_OS |// LD (HL),C ; 71
|
532 |
|
|
{I1DCNT {LDs6HL7_D == ir1}} & I1_OS |// LD (HL),D ; 72
|
533 |
|
|
{I1DCNT {LDs6HL7_E == ir1}} & I1_OS |// LD (HL),E ; 73
|
534 |
|
|
{I1DCNT {LDs6HL7_H == ir1}} & I1_OS |// LD (HL),H ; 74
|
535 |
|
|
{I1DCNT {LDs6HL7_L == ir1}} & I1_OS |// LD (HL),L ; 75
|
536 |
|
|
{I1DCNT {POPsAF == ir1}} & I1_POP |// POP AF ; F1
|
537 |
|
|
{I1DCNT {POPsBC == ir1}} & I1_POP |// POP BC ; C1
|
538 |
|
|
{I1DCNT {POPsDE == ir1}} & I1_POP |// POP DE ; D1
|
539 |
|
|
{I1DCNT {POPsHL == ir1}} & I1_POP |// POP HL ; E1
|
540 |
|
|
{I1DCNT {PUSHsAF == ir1}} & I1_PUSH|// PUSH AF ; F5
|
541 |
|
|
{I1DCNT {PUSHsBC == ir1}} & I1_PUSH|// PUSH BC ; C5
|
542 |
|
|
{I1DCNT {PUSHsDE == ir1}} & I1_PUSH|// PUSH DE ; D5
|
543 |
|
|
{I1DCNT {PUSHsHL == ir1}} & I1_PUSH|// PUSH HL ; E5
|
544 |
|
|
{I1DCNT {ADCsA_A == ir1}} & I1_R2R |// ADC A,A ; 8F
|
545 |
|
|
{I1DCNT {ADCsA_B == ir1}} & I1_R2R |// ADC A,B ; 88
|
546 |
|
|
{I1DCNT {ADCsA_C == ir1}} & I1_R2R |// ADC A,C ; 89
|
547 |
|
|
{I1DCNT {ADCsA_D == ir1}} & I1_R2R |// ADC A,D ; 8A
|
548 |
|
|
{I1DCNT {ADCsA_E == ir1}} & I1_R2R |// ADC A,E ; 8B
|
549 |
|
|
{I1DCNT {ADCsA_H == ir1}} & I1_R2R |// ADC A,H ; 8C
|
550 |
|
|
{I1DCNT {ADCsA_L == ir1}} & I1_R2R |// ADC A,L ; 8D
|
551 |
|
|
{I1DCNT {ADDsA_A == ir1}} & I1_R2R |// ADD A,A ; 87
|
552 |
|
|
{I1DCNT {ADDsA_B == ir1}} & I1_R2R |// ADD A,B ; 80
|
553 |
|
|
{I1DCNT {ADDsA_C == ir1}} & I1_R2R |// ADD A,C ; 81
|
554 |
|
|
{I1DCNT {ADDsA_D == ir1}} & I1_R2R |// ADD A,D ; 82
|
555 |
|
|
{I1DCNT {ADDsA_E == ir1}} & I1_R2R |// ADD A,E ; 83
|
556 |
|
|
{I1DCNT {ADDsA_H == ir1}} & I1_R2R |// ADD A,H ; 84
|
557 |
|
|
{I1DCNT {ADDsA_L == ir1}} & I1_R2R |// ADD A,L ; 85
|
558 |
|
|
{I1DCNT {ADDsHL_BC == ir1}} & I1_R2R |// ADD HL,BC ; 09
|
559 |
|
|
{I1DCNT {ADDsHL_DE == ir1}} & I1_R2R |// ADD HL,DE ; 19
|
560 |
|
|
{I1DCNT {ADDsHL_HL == ir1}} & I1_R2R |// ADD HL,HL ; 29
|
561 |
|
|
{I1DCNT {ADDsHL_SP == ir1}} & I1_R2R |// ADD HL,SP ; 39
|
562 |
|
|
{I1DCNT {ANDsA == ir1}} & I1_R2R |// AND A ; A7
|
563 |
|
|
{I1DCNT {ANDsB == ir1}} & I1_R2R |// AND B ; A0
|
564 |
|
|
{I1DCNT {ANDsC == ir1}} & I1_R2R |// AND C ; A1
|
565 |
|
|
{I1DCNT {ANDsD == ir1}} & I1_R2R |// AND D ; A2
|
566 |
|
|
{I1DCNT {ANDsE == ir1}} & I1_R2R |// AND E ; A3
|
567 |
|
|
{I1DCNT {ANDsH == ir1}} & I1_R2R |// AND H ; A4
|
568 |
|
|
{I1DCNT {ANDsL == ir1}} & I1_R2R |// AND L ; A5
|
569 |
|
|
{I1DCNT {CCF == ir1}} & I1_R2R |// CCF ; 3F
|
570 |
|
|
{I1DCNT {CPL == ir1}} & I1_R2R |// CPL ; 2F
|
571 |
|
|
{I1DCNT {CPsA == ir1}} & I1_R2R |// CP A ; BF
|
572 |
|
|
{I1DCNT {CPsB == ir1}} & I1_R2R |// CP B ; B8
|
573 |
|
|
{I1DCNT {CPsC == ir1}} & I1_R2R |// CP C ; B9
|
574 |
|
|
{I1DCNT {CPsD == ir1}} & I1_R2R |// CP D ; BA
|
575 |
|
|
{I1DCNT {CPsE == ir1}} & I1_R2R |// CP E ; BB
|
576 |
|
|
{I1DCNT {CPsH == ir1}} & I1_R2R |// CP H ; BC
|
577 |
|
|
{I1DCNT {CPsL == ir1}} & I1_R2R |// CP L ; BD
|
578 |
|
|
{I1DCNT {DAA == ir1}} & I1_R2R |// DAA ; 27
|
579 |
|
|
{I1DCNT {DECsA == ir1}} & I1_R2R |// DEC A ; 3D
|
580 |
|
|
{I1DCNT {DECsB == ir1}} & I1_R2R |// DEC B ; 05
|
581 |
|
|
{I1DCNT {DECsBC == ir1}} & I1_R2R |// DEC BC ; 0B
|
582 |
|
|
{I1DCNT {DECsC == ir1}} & I1_R2R |// DEC C ; 0D
|
583 |
|
|
{I1DCNT {DECsD == ir1}} & I1_R2R |// DEC D ; 15
|
584 |
|
|
{I1DCNT {DECsDE == ir1}} & I1_R2R |// DEC DE ; 1B
|
585 |
|
|
{I1DCNT {DECsE == ir1}} & I1_R2R |// DEC E ; 1D
|
586 |
|
|
{I1DCNT {DECsH == ir1}} & I1_R2R |// DEC H ; 25
|
587 |
|
|
{I1DCNT {DECsHL == ir1}} & I1_R2R |// DEC HL ; 2B
|
588 |
|
|
{I1DCNT {DECsL == ir1}} & I1_R2R |// DEC L ; 2D
|
589 |
|
|
{I1DCNT {DECsSP == ir1}} & I1_R2R |// DEC SP ; 3B
|
590 |
|
|
{I1DCNT {DI == ir1}} & I1_R2R |// DI ; F3
|
591 |
|
|
{I1DCNT {DJNZs$t2 == ir1}} & I1_R2R |// DJNZ $+2 ; 10 XX
|
592 |
|
|
{I1DCNT {EI == ir1}} & I1_R2R |// EI ; FB
|
593 |
|
|
{I1DCNT {EXX == ir1}} & I1_R2R |// EXX ; D9
|
594 |
|
|
{I1DCNT {EXsAF_AFp == ir1}} & I1_R2R |// EX AF,AF' ; 08
|
595 |
|
|
{I1DCNT {EXsDE_HL == ir1}} & I1_R2R |// EX DE,HL ; EB
|
596 |
|
|
{I1DCNT {HALT == ir1}} & I1_R2R |// HALT ; 76
|
597 |
|
|
{I1DCNT {INCsA == ir1}} & I1_R2R |// INC A ; 3C
|
598 |
|
|
{I1DCNT {INCsB == ir1}} & I1_R2R |// INC B ; 04
|
599 |
|
|
{I1DCNT {INCsBC == ir1}} & I1_R2R |// INC BC ; 03
|
600 |
|
|
{I1DCNT {INCsC == ir1}} & I1_R2R |// INC C ; 0C
|
601 |
|
|
{I1DCNT {INCsD == ir1}} & I1_R2R |// INC D ; 14
|
602 |
|
|
{I1DCNT {INCsDE == ir1}} & I1_R2R |// INC DE ; 13
|
603 |
|
|
{I1DCNT {INCsE == ir1}} & I1_R2R |// INC E ; 1C
|
604 |
|
|
{I1DCNT {INCsH == ir1}} & I1_R2R |// INC H ; 24
|
605 |
|
|
{I1DCNT {INCsHL == ir1}} & I1_R2R |// INC HL ; 23
|
606 |
|
|
{I1DCNT {INCsL == ir1}} & I1_R2R |// INC L ; 2C
|
607 |
|
|
{I1DCNT {INCsSP == ir1}} & I1_R2R |// INC SP ; 33
|
608 |
|
|
{I1DCNT {LDsA_A == ir1}} & I1_R2R |// LD A,A ; 7F
|
609 |
|
|
{I1DCNT {LDsA_B == ir1}} & I1_R2R |// LD A,B ; 78
|
610 |
|
|
{I1DCNT {LDsA_C == ir1}} & I1_R2R |// LD A,C ; 79
|
611 |
|
|
{I1DCNT {LDsA_D == ir1}} & I1_R2R |// LD A,D ; 7A
|
612 |
|
|
{I1DCNT {LDsA_E == ir1}} & I1_R2R |// LD A,E ; 7B
|
613 |
|
|
{I1DCNT {LDsA_H == ir1}} & I1_R2R |// LD A,H ; 7C
|
614 |
|
|
{I1DCNT {LDsA_L == ir1}} & I1_R2R |// LD A,L ; 7D
|
615 |
|
|
{I1DCNT {LDsB_A == ir1}} & I1_R2R |// LD B,A ; 47
|
616 |
|
|
{I1DCNT {LDsB_B == ir1}} & I1_R2R |// LD B,B ; 40
|
617 |
|
|
{I1DCNT {LDsB_C == ir1}} & I1_R2R |// LD B,C ; 41
|
618 |
|
|
{I1DCNT {LDsB_D == ir1}} & I1_R2R |// LD B,D ; 42
|
619 |
|
|
{I1DCNT {LDsB_E == ir1}} & I1_R2R |// LD B,E ; 43
|
620 |
|
|
{I1DCNT {LDsB_H == ir1}} & I1_R2R |// LD B,H ; 44
|
621 |
|
|
{I1DCNT {LDsB_L == ir1}} & I1_R2R |// LD B,L ; 45
|
622 |
|
|
{I1DCNT {LDsC_A == ir1}} & I1_R2R |// LD C,A ; 4F
|
623 |
|
|
{I1DCNT {LDsC_B == ir1}} & I1_R2R |// LD C,B ; 48
|
624 |
|
|
{I1DCNT {LDsC_C == ir1}} & I1_R2R |// LD C,C ; 49
|
625 |
|
|
{I1DCNT {LDsC_D == ir1}} & I1_R2R |// LD C,D ; 4A
|
626 |
|
|
{I1DCNT {LDsC_E == ir1}} & I1_R2R |// LD C,E ; 4B
|
627 |
|
|
{I1DCNT {LDsC_H == ir1}} & I1_R2R |// LD C,H ; 4C
|
628 |
|
|
{I1DCNT {LDsC_L == ir1}} & I1_R2R |// LD C,L ; 4D
|
629 |
|
|
{I1DCNT {LDsD_A == ir1}} & I1_R2R |// LD D,A ; 57
|
630 |
|
|
{I1DCNT {LDsD_B == ir1}} & I1_R2R |// LD D,B ; 50
|
631 |
|
|
{I1DCNT {LDsD_C == ir1}} & I1_R2R |// LD D,C ; 51
|
632 |
|
|
{I1DCNT {LDsD_D == ir1}} & I1_R2R |// LD D,D ; 52
|
633 |
|
|
{I1DCNT {LDsD_E == ir1}} & I1_R2R |// LD D,E ; 53
|
634 |
|
|
{I1DCNT {LDsD_H == ir1}} & I1_R2R |// LD D,H ; 54
|
635 |
|
|
{I1DCNT {LDsD_L == ir1}} & I1_R2R |// LD D,L ; 55
|
636 |
|
|
{I1DCNT {LDsE_A == ir1}} & I1_R2R |// LD E,A ; 5F
|
637 |
|
|
{I1DCNT {LDsE_B == ir1}} & I1_R2R |// LD E,B ; 58
|
638 |
|
|
{I1DCNT {LDsE_C == ir1}} & I1_R2R |// LD E,C ; 59
|
639 |
|
|
{I1DCNT {LDsE_D == ir1}} & I1_R2R |// LD E,D ; 5A
|
640 |
|
|
{I1DCNT {LDsE_E == ir1}} & I1_R2R |// LD E,E ; 5B
|
641 |
|
|
{I1DCNT {LDsE_H == ir1}} & I1_R2R |// LD E,H ; 5C
|
642 |
|
|
{I1DCNT {LDsE_L == ir1}} & I1_R2R |// LD E,L ; 5D
|
643 |
|
|
{I1DCNT {LDsH_A == ir1}} & I1_R2R |// LD H,A ; 67
|
644 |
|
|
{I1DCNT {LDsH_B == ir1}} & I1_R2R |// LD H,B ; 60
|
645 |
|
|
{I1DCNT {LDsH_C == ir1}} & I1_R2R |// LD H,C ; 61
|
646 |
|
|
{I1DCNT {LDsH_D == ir1}} & I1_R2R |// LD H,D ; 62
|
647 |
|
|
{I1DCNT {LDsH_E == ir1}} & I1_R2R |// LD H,E ; 63
|
648 |
|
|
{I1DCNT {LDsH_H == ir1}} & I1_R2R |// LD H,H ; 64
|
649 |
|
|
{I1DCNT {LDsH_L == ir1}} & I1_R2R |// LD H,L ; 65
|
650 |
|
|
{I1DCNT {LDsL_A == ir1}} & I1_R2R |// LD L,A ; 6F
|
651 |
|
|
{I1DCNT {LDsL_B == ir1}} & I1_R2R |// LD L,B ; 68
|
652 |
|
|
{I1DCNT {LDsL_C == ir1}} & I1_R2R |// LD L,C ; 69
|
653 |
|
|
{I1DCNT {LDsL_D == ir1}} & I1_R2R |// LD L,D ; 6A
|
654 |
|
|
{I1DCNT {LDsL_E == ir1}} & I1_R2R |// LD L,E ; 6B
|
655 |
|
|
{I1DCNT {LDsL_H == ir1}} & I1_R2R |// LD L,H ; 6C
|
656 |
|
|
{I1DCNT {LDsL_L == ir1}} & I1_R2R |// LD L,L ; 6D
|
657 |
|
|
{I1DCNT {LDsSP_HL == ir1}} & I1_R2R |// LD SP,HL ; F9
|
658 |
|
|
{I1DCNT {NOP == ir1}} & I1_R2R |// NOP ; 00
|
659 |
|
|
{I1DCNT {ORsA == ir1}} & I1_R2R |// OR A ; B7
|
660 |
|
|
{I1DCNT {ORsB == ir1}} & I1_R2R |// OR B ; B0
|
661 |
|
|
{I1DCNT {ORsC == ir1}} & I1_R2R |// OR C ; B1
|
662 |
|
|
{I1DCNT {ORsD == ir1}} & I1_R2R |// OR D ; B2
|
663 |
|
|
{I1DCNT {ORsE == ir1}} & I1_R2R |// OR E ; B3
|
664 |
|
|
{I1DCNT {ORsH == ir1}} & I1_R2R |// OR H ; B4
|
665 |
|
|
{I1DCNT {ORsL == ir1}} & I1_R2R |// OR L ; B5
|
666 |
|
|
{I1DCNT {RLA == ir1}} & I1_R2R |// RLA ; 17
|
667 |
|
|
{I1DCNT {RLCA == ir1}} & I1_R2R |// RLCA ; 07
|
668 |
|
|
{I1DCNT {RRA == ir1}} & I1_R2R |// RRA ; 1F
|
669 |
|
|
{I1DCNT {RRCA == ir1}} & I1_R2R |// RRCA ; 0F
|
670 |
|
|
{I1DCNT {SBCsA == ir1}} & I1_R2R |// SBC A ; 9F
|
671 |
|
|
{I1DCNT {SBCsB == ir1}} & I1_R2R |// SBC B ; 98
|
672 |
|
|
{I1DCNT {SBCsC == ir1}} & I1_R2R |// SBC C ; 99
|
673 |
|
|
{I1DCNT {SBCsD == ir1}} & I1_R2R |// SBC D ; 9A
|
674 |
|
|
{I1DCNT {SBCsE == ir1}} & I1_R2R |// SBC E ; 9B
|
675 |
|
|
{I1DCNT {SBCsH == ir1}} & I1_R2R |// SBC H ; 9C
|
676 |
|
|
{I1DCNT {SBCsL == ir1}} & I1_R2R |// SBC L ; 9D
|
677 |
|
|
{I1DCNT {SCF == ir1}} & I1_R2R |// SCF ; 37
|
678 |
|
|
{I1DCNT {SUBsA == ir1}} & I1_R2R |// SUB A ; 97
|
679 |
|
|
{I1DCNT {SUBsB == ir1}} & I1_R2R |// SUB B ; 90
|
680 |
|
|
{I1DCNT {SUBsC == ir1}} & I1_R2R |// SUB C ; 91
|
681 |
|
|
{I1DCNT {SUBsD == ir1}} & I1_R2R |// SUB D ; 92
|
682 |
|
|
{I1DCNT {SUBsE == ir1}} & I1_R2R |// SUB E ; 93
|
683 |
|
|
{I1DCNT {SUBsH == ir1}} & I1_R2R |// SUB H ; 94
|
684 |
|
|
{I1DCNT {SUBsL == ir1}} & I1_R2R |// SUB L ; 95
|
685 |
|
|
{I1DCNT {XORsA == ir1}} & I1_R2R |// XOR A ; AF
|
686 |
|
|
{I1DCNT {XORsB == ir1}} & I1_R2R |// XOR B ; A8
|
687 |
|
|
{I1DCNT {XORsC == ir1}} & I1_R2R |// XOR C ; A9
|
688 |
|
|
{I1DCNT {XORsD == ir1}} & I1_R2R |// XOR D ; AA
|
689 |
|
|
{I1DCNT {XORsE == ir1}} & I1_R2R |// XOR E ; AB
|
690 |
|
|
{I1DCNT {XORsH == ir1}} & I1_R2R |// XOR H ; AC
|
691 |
|
|
{I1DCNT {XORsL == ir1}} & I1_R2R |// XOR L ; AD
|
692 |
|
|
{I1DCNT {RET == ir1}} & I1_RET |// RET ; C9
|
693 |
|
|
{I1DCNT {RETsC == ir1 & cf }} & I1_RET |// RET C ; D8
|
694 |
|
|
{I1DCNT {RETsM == ir1 & sf }} & I1_RET |// RET M ; F8
|
695 |
|
|
{I1DCNT {RETsNC== ir1 & ~cf }} & I1_RET |// RET NC ; D0
|
696 |
|
|
{I1DCNT {RETsP == ir1 & ~sf }} & I1_RET |// RET P ; F0
|
697 |
|
|
{I1DCNT {RETsPE== ir1 & pvf }} & I1_RET |// RET PE ; E8
|
698 |
|
|
{I1DCNT {RETsPO== ir1 & ~pvf}} & I1_RET |// RET PO ; E0
|
699 |
|
|
{I1DCNT {RETsNZ== ir1 & ~zf }} & I1_RET |// RET NZ ; C0
|
700 |
|
|
{I1DCNT {RETsZ == ir1 & zf }} & I1_RET |// RET Z ; C8
|
701 |
|
|
{I1DCNT {EXs6SP7_HL == ir1}} & I1_RMW |// EX (SP),HL ; E3
|
702 |
|
|
{I1DCNT {DECs6HL7 == ir1}} & I1_RMW |// DEC (HL) ; 35
|
703 |
|
|
{I1DCNT {INCs6HL7 == ir1}} & I1_RMW |// INC (HL) ; 34
|
704 |
|
|
{I1DCNT {RSTs0 == ir1}} & I1_RST |// RST 0 ; C7
|
705 |
|
|
{I1DCNT {RSTs10H == ir1}} & I1_RST |// RST 10H ; D7
|
706 |
|
|
{I1DCNT {RSTs18H == ir1}} & I1_RST |// RST 18H ; DF
|
707 |
|
|
{I1DCNT {RSTs20H == ir1}} & I1_RST |// RST 20H ; E7
|
708 |
|
|
{I1DCNT {RSTs28H == ir1}} & I1_RST |// RST 28H ; EF
|
709 |
|
|
{I1DCNT {RSTs30H == ir1}} & I1_RST |// RST 30H ; F7
|
710 |
|
|
{I1DCNT {RSTs38H == ir1}} & I1_RST |// RST 38H ; FF
|
711 |
|
|
{I1DCNT {RSTs8H == ir1}} & I1_RST ;// RST 8H ; CF
|
712 |
|
|
|
713 |
|
|
//-------- CB decodes -----------------------
|
714 |
|
|
|
715 |
|
|
// First cut below
|
716 |
|
|
// CB_RLC = 7'b01_00_000, // these must be compaired with ir[9:3]
|
717 |
|
|
// CB_RRC = 7'b01_00_001, // these must be compaired with ir[9:3]
|
718 |
|
|
// CB_RL = 7'b01_00_010, // these must be compaired with ir[9:3]
|
719 |
|
|
// CB_RR = 7'b01_00_011, // these must be compaired with ir[9:3]
|
720 |
|
|
// CB_SLA = 7'b01_00_100, // these must be compaired with ir[9:3]
|
721 |
|
|
// CB_SRA = 7'b01_00_101, // these must be compaired with ir[9:3]
|
722 |
|
|
// CB_SLL = 7'b01_00_110, // these must be compaired with ir[9:3]
|
723 |
|
|
// CB_SRL = 7'b01_00_111, // these must be compaired with ir[9:3]
|
724 |
|
|
|
725 |
|
|
// CB_BIT = 4'b01_01, // these must be compaired with ir[9:6]
|
726 |
|
|
// CB_RES = 4'b01_10, // these must be compaired with ir[9:6]
|
727 |
|
|
// CB_SET = 4'b01_11, // these must be compaired with ir[9:6]
|
728 |
|
|
|
729 |
|
|
// note these are all read-modify-writ except CB_BIT
|
730 |
|
|
assign cb_mem = (CB_MEM == ir1[2:0]); // this must be compaired with ir[2:0]
|
731 |
|
|
|
732 |
|
|
// The ED Group
|
733 |
|
|
// These are the "unique instructions in the 46, 47 rows that NEED? to be implemented
|
734 |
|
|
// Not sure I want to worry about all undocumented stuff in these rows - hard to believe
|
735 |
|
|
// It will matter.(IM modes are very system dependent - hard to believe even a programmer
|
736 |
|
|
// would use undocumented instructions to muck with this stuff)
|
737 |
|
|
// reg 2 reg simply executed by ir2 logic
|
738 |
|
|
// ED_IMs0 = 10'h246// IM 0 ; ED 46 set IM0
|
739 |
|
|
// ED_LDsI_A = 10'h247// LD I,A ; ED 47 move a to I
|
740 |
|
|
// ED_IMs1 = 10'h256// IM 1 ; ED 56 set IM1
|
741 |
|
|
// ED_LDsA_I = 10'h257// LD A,I ; ED 57 move I to A
|
742 |
|
|
// ED_IMs2 = 10'h25E// IM 2 ; ED 5E set IM2
|
743 |
|
|
// ED_RRD = 10'h267// RRD ; ED 67 nibble roates A HL
|
744 |
|
|
// ED_RLD = 10'h26F// RLD ; ED 6F nibble roates A HL
|
745 |
|
|
|
746 |
|
|
// set (or clear) repeat flag at DEC_EB.
|
747 |
|
|
// set (or clear) inc flag at DEC_EB.
|
748 |
|
|
// seperate flows for LD, CP, IN, OUT.
|
749 |
|
|
// ED_LDI == ir1// LDI ; ED A0 These are block move
|
750 |
|
|
// ED_CPI == ir1// CPI ; ED A1 type insts that don't repeat
|
751 |
|
|
// ED_INI == ir1// INI ; ED A2
|
752 |
|
|
// ED_OUTI == ir1// OUTI ; ED A3
|
753 |
|
|
// ED_LDD == ir1// LDD ; ED A8
|
754 |
|
|
// ED_CPD == ir1// CPD ; ED A9
|
755 |
|
|
// ED_IND == ir1// IND ; ED AA
|
756 |
|
|
// ED_OUTD == ir1// OUTD ; ED AB
|
757 |
|
|
wire dec_blk_rpt =
|
758 |
|
|
ED_LDIR == ir1 |// LDIR ; ED B0 These are block move
|
759 |
|
|
ED_CPIR == ir1 |// CPIR ; ED B1 type insts that DO repeat
|
760 |
|
|
ED_INIR == ir1 |// INIR ; ED B2
|
761 |
|
|
ED_OTIR == ir1 |// OTIR ; ED B3
|
762 |
|
|
ED_LDDR == ir1 |// LDDR ; ED B8
|
763 |
|
|
ED_CPDR == ir1 |// CPDR ; ED B9
|
764 |
|
|
ED_INDR == ir1 |// INDR ; ED BA
|
765 |
|
|
ED_OTDR == ir1 ;// OTDR ; ED BB
|
766 |
|
|
wire ed_blk_mv = ED_LDIR == ir1 | ED_LDI == ir1 |
|
767 |
|
|
ED_LDDR == ir1 | ED_LDD == ir1 ;
|
768 |
|
|
wire ed_blk_cp = ED_CPIR == ir1 | ED_CPI == ir1 |
|
769 |
|
|
ED_CPDR == ir1 | ED_CPD == ir1 ;
|
770 |
|
|
wire ed_blk_in = ED_INIR == ir1 | ED_INI == ir1 |
|
771 |
|
|
ED_INDR == ir1 | ED_IND == ir1 ;
|
772 |
|
|
|
773 |
|
|
wire ed_blk_out = ED_OTIR == ir1 | ED_OUTI == ir1 |
|
774 |
|
|
ED_OTDR == ir1 | ED_OUTD == ir1 ;
|
775 |
|
|
|
776 |
|
|
wire dec_blk_io = ed_blk_in | ed_blk_in;
|
777 |
|
|
|
778 |
|
|
wire blk_done = ~blk_rpt_flg | beq0 & ceq0 | blk_io_flg & ceq0;
|
779 |
|
|
|
780 |
|
|
assign dec_blk_inc = ED_LDIR == ir1 |
|
781 |
|
|
ED_CPIR == ir1 |
|
782 |
|
|
ED_INIR == ir1 |
|
783 |
|
|
ED_OTIR == ir1 |
|
784 |
|
|
ED_LDI == ir1 |
|
785 |
|
|
ED_CPI == ir1 |
|
786 |
|
|
ED_INI == ir1 |
|
787 |
|
|
ED_OUTI == ir1 ;
|
788 |
|
|
|
789 |
|
|
|
790 |
|
|
//The ED70 instruction reads from I/O port C,
|
791 |
|
|
//but does not store the result.
|
792 |
|
|
//It just affects the flags. Hard to test. like the other IN x,(C) instruction.
|
793 |
|
|
//
|
794 |
|
|
//ED71 simply outs the value 0 to I/O port C.
|
795 |
|
|
// This suggests that we should decode as follows:
|
796 |
|
|
// I hope if I don't get all the IM duplicates right it won't be a tragedy
|
797 |
|
|
// ED_INsREG_6C7 = 7'b1001___000,// compair with {ir[7:6],ir[2:0]}
|
798 |
|
|
//
|
799 |
|
|
// ED_SBCsHL_REG = 8'b1001__0010, // compair with {ir[9:6],ir[3:0]}
|
800 |
|
|
// ED_ADCsHL_REG = 8'b1001__1010, // compair with {ir[9:6],ir[3:0]}
|
801 |
|
|
// ED_LDs6NN7_REG = 8'b1001__0011, // compair with {ir[9:6],ir[3:0]} REG = BC,DE,HL,SP
|
802 |
|
|
// ED_LDsREG_6NN7 = 8'b1001__1011, // compair with {ir[9:6],ir[3:0]} REG = BC,DE,HL,SP
|
803 |
|
|
// ED_NEG = 7'b1001___100, // compair with {ir[9:6],ir[2:0]} all A<= -A
|
804 |
|
|
// ED_RETN = 7'b1001___101, // compair with {ir[9:6],ir[2:0]} and !reti
|
805 |
|
|
wire ed_nn = ED_LDs6NN7_REG == {ir1[9:6],ir1[3:0]} |
|
806 |
|
|
ED_LDsREG_6NN7 == {ir1[9:6],ir1[3:0]} ;
|
807 |
|
|
|
808 |
|
|
// we use all these to enable interrupts
|
809 |
|
|
wire ed_retn = ED_RETN == {ir1[9:6],ir1[2:0]};
|
810 |
|
|
|
811 |
|
|
assign ed_dbl_rd = ED_LDsREG_6NN7 == {ir1[9:6],ir1[3:0]};
|
812 |
|
|
|
813 |
|
|
|
814 |
|
|
// assign cb_mem = CB_MEM = ir1[2:0]; // CB_MEM = 3'h110,
|
815 |
|
|
|
816 |
|
|
|
817 |
|
|
|
818 |
|
|
|
819 |
|
|
wire jmpr_true =
|
820 |
|
|
JRs$t2 == ir1 |
|
821 |
|
|
JRsC_$t2 == ir1 & fr[0] |
|
822 |
|
|
JRsNC_$t2 == ir1 & ~fr[0] |
|
823 |
|
|
JRsZ_$t2 == ir1 & fr[6] |
|
824 |
|
|
JRsNZ_$t2 == ir1 & ~fr[6] ;
|
825 |
|
|
|
826 |
|
|
//assign { sf, zf. f5f, hf, f3f, pvf, nf, cf} = fr;
|
827 |
|
|
wire callnn_true = CALLsC_NN == ir1 & cf |
|
828 |
|
|
CALLsNC_NN == ir1 & ~cf |
|
829 |
|
|
CALLsNN == ir1 |
|
830 |
|
|
CALLsNZ_NN == ir1 & ~zf |
|
831 |
|
|
CALLsPE_NN == ir1 & pvf |
|
832 |
|
|
CALLsPO_NN == ir1 & ~pvf|
|
833 |
|
|
CALLsP_NN == ir1 & ~sf |
|
834 |
|
|
CALLsZ_NN == ir1 & zf |
|
835 |
|
|
CALLsM_NN == ir1 & sf ;
|
836 |
|
|
|
837 |
|
|
wire jmpnn_true = JPsC == ir1 & cf |
|
838 |
|
|
JPsNC == ir1 & ~cf |
|
839 |
|
|
JP == ir1 |
|
840 |
|
|
JPsNZ == ir1 & ~zf |
|
841 |
|
|
JPsPE == ir1 & pvf |
|
842 |
|
|
JPsPO == ir1 & ~pvf|
|
843 |
|
|
JPsP == ir1 & ~sf |
|
844 |
|
|
JPsZ == ir1 & zf |
|
845 |
|
|
JPsM == ir1 & sf ;
|
846 |
|
|
|
847 |
|
|
// PUSHsAF == ir1
|
848 |
|
|
// PUSHsBC == ir1
|
849 |
|
|
// PUSHsDE == ir1
|
850 |
|
|
// PUSHsHL == ir1
|
851 |
|
|
|
852 |
|
|
wire os_a = LDs6BC7_A == ir1 | // LD (BC),A ; 02
|
853 |
|
|
LDs6DE7_A == ir1 | // LD (DE),A ; 12
|
854 |
|
|
LDs6HL7_A == ir1 | // LD (HL),A ; 77
|
855 |
|
|
LDs6NN7_A == ir1 | // LD (NN),A ; 32 XX XX
|
856 |
|
|
PUSHsAF == ir1 |
|
857 |
|
|
OUTs6N7_A == ir1 |
|
858 |
|
|
ED_OUTs6C7_REG == {ir1[9:6],ir1[2:0] && REG8_A == ir1[5:3]} ;
|
859 |
|
|
|
860 |
|
|
wire os_b = LDs6HL7_B == ir1 | // LD (HL),B ; 70
|
861 |
|
|
ED_LDs6NN7_REG == {ir1[9:6],ir1[3:0]} & DBL_REG_BC == ir1[5:4] |
|
862 |
|
|
ED_OUTs6C7_REG == {ir1[9:6],ir1[2:0]} & REG8_B == ir1[5:3] ;
|
863 |
|
|
|
864 |
|
|
wire os_c = LDs6HL7_C == ir1 | // LD (HL),C ; 71
|
865 |
|
|
PUSHsBC == ir1 | // PUSH BC
|
866 |
|
|
ED_OUTs6C7_REG == {ir1[9:6],ir1[2:0]} & REG8_C == ir1[5:3] ;
|
867 |
|
|
|
868 |
|
|
wire os_d = LDs6HL7_D == ir1 | // LD (HL),D ; 72
|
869 |
|
|
ED_LDs6NN7_REG == {ir1[9:6],ir1[3:0]} & DBL_REG_DE == ir1[5:4] |
|
870 |
|
|
ED_OUTs6C7_REG == {ir1[9:6],ir1[2:0]} & REG8_D == ir1[5:3] ;
|
871 |
|
|
|
872 |
|
|
|
873 |
|
|
wire os_e = LDs6HL7_E == ir1 | // LD (HL),E ; 73
|
874 |
|
|
PUSHsDE == ir1 | // PUSH DE
|
875 |
|
|
ED_OUTs6C7_REG == {ir1[9:6],ir1[2:0]} & REG8_E == ir1[5:3] ;
|
876 |
|
|
|
877 |
|
|
wire os_h = LDs6HL7_H == ir1 | // LD (HL),H ; 74
|
878 |
|
|
LDs6NN7_HL == ir1 | // LD (NN),HL ; 22 XX XX
|
879 |
|
|
ED_LDs6NN7_REG == {ir1[9:6],ir1[3:0]} & DBL_REG_HL == ir1[5:4] |
|
880 |
|
|
ED_OUTs6C7_REG == {ir1[9:6],ir1[2:0]} & REG8_H == ir1[5:3] ;
|
881 |
|
|
|
882 |
|
|
wire os_l = LDs6HL7_L == ir1 | // LD (HL),L ; 75
|
883 |
|
|
PUSHsHL == ir1 |
|
884 |
|
|
ED_OUTs6C7_REG == {ir1[9:6],ir1[2:0]} & REG8_L == ir1[5:3] ;
|
885 |
|
|
|
886 |
|
|
wire os_sp = ED_LDs6NN7_REG == {ir1[9:6],ir1[3:0]} & DBL_REG_SP == ir1[5:4];
|
887 |
|
|
|
888 |
|
|
wire os_f = PUSHsAF == ir1 ;
|
889 |
|
|
|
890 |
|
|
|
891 |
|
|
//---------------- inst hazard ----------------------------------------------------------
|
892 |
|
|
//
|
893 |
|
|
// On some reflection, I don't think I'm going to worry about this immediately - it
|
894 |
|
|
// should be easy to kludge in a fix if necessary -- and there are more important things
|
895 |
|
|
// todo. It is a very bad programming practice to muck with the instruction stream in any
|
896 |
|
|
// case -- I have to believe most target applications do not do this -- although I'll probably
|
897 |
|
|
// get hit pretty early with a instruction test that does. Oh well -- if that happens we fix
|
898 |
|
|
// it.
|
899 |
|
|
// Well -- think some here -- the hazard is because of a change in design.
|
900 |
|
|
// If used to any extent.. Somebody WILL
|
901 |
|
|
// want this to act the same way as the origional - even if the programming is "poor".
|
902 |
|
|
// >>>>>>>> bite the bullet and do it.
|
903 |
|
|
//
|
904 |
|
|
// if we do an operand store and the address == pc-1 its an inst hazard, We need to execute the
|
905 |
|
|
// store decrement pc and re-fetch. This is a high priority interrupt.
|
906 |
|
|
// what about multi-byte stores - like LDs6NN7_A or LDs6NN7_HL - i guess we do an IF - to start
|
907 |
|
|
// the pipe before the os -- same logic.
|
908 |
|
|
//
|
909 |
|
|
|
910 |
|
|
|
911 |
|
|
//-----------------data hazard ----------------------------------------------------------
|
912 |
|
|
//
|
913 |
|
|
// Issues here have evolved to a degree as the design progressed. However the
|
914 |
|
|
// Key has always been that for each instruction (no matter how complex) there
|
915 |
|
|
// is only a single state in which the previous instruction can also be active
|
916 |
|
|
// and that is the DEC_EXEC state. If there is a data hazard, we need to delay
|
917 |
|
|
// execution of that state until the ir2 execution completes (which it always does
|
918 |
|
|
// in a single tick). Note that only the RET instructions test the flag register
|
919 |
|
|
// on DEC_EXEC.
|
920 |
|
|
//
|
921 |
|
|
// WARNING: be very careful about this. Data hazard logic is very difficult to
|
922 |
|
|
// verify as there are so many instruction pairs to test.
|
923 |
|
|
//
|
924 |
|
|
// Situations 1) operand stores from ir1 when register is updated in ir2
|
925 |
|
|
// 2) flag tests when fr is being updated
|
926 |
|
|
// 3) sp issues see below LDsSP_HL DECsSP INCsSP
|
927 |
|
|
// ANY OTHERS ???
|
928 |
|
|
//
|
929 |
|
|
// upd_ar, upd_br, upd_cr, upd_dr, upd_er, upd_hr, upd_lr,upd_fr,
|
930 |
|
|
wire use_hl_exec = LDsSP_HL == ir1;
|
931 |
|
|
wire use_sp_exec = MEM_OFSP == next_mem_state |
|
932 |
|
|
MEM_OSSP == next_mem_state ;
|
933 |
|
|
wire upd_sp_exec = DECsSP == ir2 |
|
934 |
|
|
INCsSP == ir2 ;
|
935 |
|
|
|
936 |
|
|
|
937 |
|
|
|
938 |
|
|
wire use_fr_exec = ( RETsC == ir1 |
|
939 |
|
|
RETsM == ir1 |
|
940 |
|
|
RETsNC == ir1 |
|
941 |
|
|
RETsP == ir1 |
|
942 |
|
|
RETsPE == ir1 |
|
943 |
|
|
RETsPO == ir1 |
|
944 |
|
|
RETsNZ == ir1 |
|
945 |
|
|
RETsZ == ir1 ) ;
|
946 |
|
|
|
947 |
|
|
assign hazard = (dec_state == DEC_EXEC & exec_ir2 ) & ( upd_fr & use_fr_exec |
|
948 |
|
|
upd_ar & os_a |
|
949 |
|
|
upd_br & os_b |
|
950 |
|
|
upd_cr & os_c |
|
951 |
|
|
upd_dr & os_d |
|
952 |
|
|
upd_er & os_e |
|
953 |
|
|
upd_hr & os_h |
|
954 |
|
|
upd_lr & os_l |
|
955 |
|
|
upd_hr & use_hl_exec |
|
956 |
|
|
upd_lr & use_hl_exec |
|
957 |
|
|
upd_sp_exec & use_sp_exec );
|
958 |
|
|
|
959 |
|
|
|
960 |
|
|
|
961 |
|
|
|
962 |
|
|
|
963 |
|
|
|
964 |
|
|
// does not include extension stuff as we are mostly looking for hazards here
|
965 |
|
|
// course we do use these terms to build more decodes
|
966 |
|
|
//
|
967 |
|
|
wire opadr_bc = LDsA_6BC7 == ir1 | LDs6BC7_A == ir1;
|
968 |
|
|
wire opadr_de = LDsA_6DE7 == ir1 | LDs6DE7_A == ir1;
|
969 |
|
|
wire opadr_hl = LDsB_6HL7 == ir1 | ORs6HL7 == ir1 | LDs6HL7_B == ir1 |
|
970 |
|
|
LDsD_6HL7 == ir1 | LDsC_6HL7 == ir1 | LDs6HL7_C == ir1 |
|
971 |
|
|
LDsH_6HL7 == ir1 | LDsE_6HL7 == ir1 | LDs6HL7_D == ir1 |
|
972 |
|
|
ADDsA_6HL7 == ir1 | LDsL_6HL7 == ir1 | LDs6HL7_E == ir1 |
|
973 |
|
|
SUBs6HL7 == ir1 | LDsA_6HL7 == ir1 | LDs6HL7_H == ir1 |
|
974 |
|
|
ANDs6HL7 == ir1 | ADCsA_6HL7 == ir1 | LDs6HL7_L == ir1 |
|
975 |
|
|
XORs6HL7 == ir1 | SBCs6HL7 == ir1 | CPs6HL7 == ir1 ;
|
976 |
|
|
|
977 |
|
|
assign use_a = os_a;
|
978 |
|
|
assign use_b = os_b | opadr_bc;
|
979 |
|
|
assign use_c = os_c | opadr_bc;
|
980 |
|
|
assign use_d = os_d | opadr_de;
|
981 |
|
|
assign use_e = os_e | opadr_de;
|
982 |
|
|
assign use_h = os_h | opadr_hl;
|
983 |
|
|
assign use_l = os_l | opadr_hl;
|
984 |
|
|
|
985 |
|
|
|
986 |
|
|
|
987 |
|
|
assign use_flags = c_jmp8 | c_jmp4 | c_call | c_ret;
|
988 |
|
|
|
989 |
|
|
|
990 |
|
|
|
991 |
|
|
wire bc_eq0 = beq0 & ceq0;
|
992 |
|
|
// ??? not used ? why defined ?
|
993 |
|
|
//assign rpt_blk_mv = (blk_mv_reg ) & !bc_eq0 |
|
994 |
|
|
// (blk_cmp_reg) & !bc_eq0 & (nn[7:0] != 8'h0) |
|
995 |
|
|
// (blk_in_reg | blk_out_reg) & !b_eq0 ;
|
996 |
|
|
|
997 |
|
|
|
998 |
|
|
|
999 |
|
|
|
1000 |
|
|
|
1001 |
|
|
|
1002 |
|
|
|
1003 |
|
|
// BASIC ARCHITECTURE OF THIS FILE pc and sp not shown, but are inputs to src mux.
|
1004 |
|
|
// _____ and may be updated from adder output.
|
1005 |
|
|
// | |
|
1006 |
|
|
// | | pc-1 register is required to implement relative jumps.
|
1007 |
|
|
// | |
|
1008 |
|
|
// _____ |lit | |\
|
1009 |
|
|
// | | | | | \
|
1010 |
|
|
// | | |src2 | | \ _____ _____
|
1011 |
|
|
// | | | |----->| | | | | |
|
1012 |
|
|
// |src | |_____| |adder|------->| | | |
|
1013 |
|
|
// |mux | | | | | | |
|
1014 |
|
|
// | |------------------->| / |2/1 |------->|wb |
|
1015 |
|
|
// | | | | / |mux | |adr |
|
1016 |
|
|
// |_____| | |/ | | | |
|
1017 |
|
|
// ------------------->| | | |
|
1018 |
|
|
// |_____| |_____|
|
1019 |
|
|
// MEM_NOP
|
1020 |
|
|
// MEM_IFPP1 MEM_OFIXpD MEM_CALL MEM_IFRST MEM_OFHL_PM MEM_IOF_C
|
1021 |
|
|
// MEM_OS1, MEM_OSIXpD MEM_OSNN, MEM_IFREL_N MEM_OSHL_PM MEM_IOS_C
|
1022 |
|
|
// MEM_OF1, MEM_OSADR MEM_OFNN MEM_JMPHL MEM_OSDE_PM MEM_IOF_N
|
1023 |
|
|
// MEM_OFSP MEM_OSSP_PCM2 MEM_OFADRP1 MEM_IFNN MEM_INTA MEM_IOS_N
|
1024 |
|
|
// MEM_OSSP MEM_OSSP_P MEM_OSADRP1 MEM_IFINT MEM_OS_HL_N
|
1025 |
|
|
//
|
1026 |
|
|
|
1027 |
|
|
wire src_sp = next_mem_state == MEM_OF1 & EXs6SP7_HL == ir1 | //special case rmw
|
1028 |
|
|
next_mem_state == MEM_OFSP |
|
1029 |
|
|
next_mem_state == MEM_OSSP |
|
1030 |
|
|
next_mem_state == MEM_CALL ;
|
1031 |
|
|
wire src_pc = next_mem_state == MEM_IFPP1 |
|
1032 |
|
|
next_mem_state == MEM_IFREL_N ;
|
1033 |
|
|
|
1034 |
|
|
wire src_nn = next_mem_state == MEM_IFNN |
|
1035 |
|
|
next_mem_state == MEM_OSNN |
|
1036 |
|
|
next_mem_state == MEM_OFNN ;
|
1037 |
|
|
|
1038 |
|
|
|
1039 |
|
|
wire src_de = dec_state == DEC_EXEC & LDsA_6DE7 == ir1 | // MEM_OS1 MEM_OF1
|
1040 |
|
|
dec_state == DEC_EXEC & LDs6DE7_A == ir1 | // are both true at this time
|
1041 |
|
|
next_mem_state == MEM_OSDE_PM ;
|
1042 |
|
|
wire src_bc = dec_state == DEC_EXEC & LDsA_6BC7 == ir1 |
|
1043 |
|
|
dec_state == DEC_EXEC & LDs6BC7_A == ir1 |
|
1044 |
|
|
next_mem_state ==MEM_IOF_C |
|
1045 |
|
|
next_mem_state ==MEM_IOS_C ;
|
1046 |
|
|
|
1047 |
|
|
|
1048 |
|
|
// don't forget that hl source can be modified by prefix
|
1049 |
|
|
// this gets messy as we use wb_adr for some of these.
|
1050 |
|
|
//
|
1051 |
|
|
wire src_hl = next_mem_state == MEM_OF1 &
|
1052 |
|
|
(dec_state == DEC_EXEC) &
|
1053 |
|
|
!src_de & !src_bc & !src_sp |
|
1054 |
|
|
next_mem_state == MEM_OS1 &
|
1055 |
|
|
(dec_state == DEC_EXEC) &
|
1056 |
|
|
!src_de & !src_bc |
|
1057 |
|
|
next_mem_state == MEM_OFHL_PM |
|
1058 |
|
|
next_mem_state == MEM_OSHL_PM |
|
1059 |
|
|
next_mem_state == MEM_OS_HL_N |
|
1060 |
|
|
next_mem_state == MEM_JMPHL ;
|
1061 |
|
|
|
1062 |
|
|
wire src_ix = next_mem_state == MEM_OFIXpD & ir1dd |
|
1063 |
|
|
next_mem_state == MEM_OSIXpD & ir1dd ;
|
1064 |
|
|
|
1065 |
|
|
wire src_iy = next_mem_state == MEM_OFIXpD & ir1fd |
|
1066 |
|
|
next_mem_state == MEM_OSIXpD & ir1fd ;
|
1067 |
|
|
|
1068 |
|
|
wire src_adr = next_mem_state == MEM_OFADRP1 |
|
1069 |
|
|
next_mem_state == MEM_OSADRP1 |
|
1070 |
|
|
next_mem_state == MEM_NOP |
|
1071 |
|
|
next_mem_state == MEM_OSADR ;
|
1072 |
|
|
|
1073 |
|
|
wire src_int = next_mem_state == MEM_IOF_N |
|
1074 |
|
|
next_mem_state == MEM_IOS_N ;
|
1075 |
|
|
|
1076 |
|
|
|
1077 |
|
|
|
1078 |
|
|
wire src_mux = {16{ src_sp }} & sp |
|
1079 |
|
|
{16{ src_pc }} & pc |
|
1080 |
|
|
{16{ src_nn }} & nn |
|
1081 |
|
|
{16{ src_hl }} & hl |
|
1082 |
|
|
{16{ src_de }} & de |
|
1083 |
|
|
{16{ src_bc }} & bc |
|
1084 |
|
|
{16{ src_ix }} & ixr |
|
1085 |
|
|
{16{ src_iy }} & iyr |
|
1086 |
|
|
{16{ src_adr }} & wb_adr |
|
1087 |
|
|
{16{ src_int }} & { intr, nn[15:8] } |
|
1088 |
|
|
{16{next_mem_state == MEM_IFRST}} & {10'h0, ir1[6:4], 3'h0} ;
|
1089 |
|
|
|
1090 |
|
|
wire block_mv_inc = (dec_state == DEC_ED) ? dec_blk_inc : blk_inc_flg; // flag set at DEC_ED
|
1091 |
|
|
|
1092 |
|
|
|
1093 |
|
|
|
1094 |
|
|
wire inc_s2 = next_mem_state ==MEM_OFADRP1 |
|
1095 |
|
|
next_mem_state ==MEM_OSADRP1 |
|
1096 |
|
|
next_mem_state ==MEM_OFHL_PM & block_mv_inc |
|
1097 |
|
|
next_mem_state ==MEM_OSHL_PM & block_mv_inc |
|
1098 |
|
|
next_mem_state ==MEM_OSDE_PM & block_mv_inc |
|
1099 |
|
|
next_mem_state ==MEM_OFSP |
|
1100 |
|
|
next_mem_state ==MEM_IFPP1 |
|
1101 |
|
|
next_mem_state ==MEM_OSSP_PCM2 |
|
1102 |
|
|
next_mem_state ==MEM_OSSP_P ;
|
1103 |
|
|
|
1104 |
|
|
wire dec_s2 = next_mem_state ==MEM_OFHL_PM & ~block_mv_inc |
|
1105 |
|
|
next_mem_state ==MEM_OSHL_PM & ~block_mv_inc |
|
1106 |
|
|
next_mem_state ==MEM_OSDE_PM & ~block_mv_inc |
|
1107 |
|
|
next_mem_state == MEM_OFSP ;
|
1108 |
|
|
|
1109 |
|
|
|
1110 |
|
|
wire reln_s2 = next_mem_state == MEM_IFREL_N |
|
1111 |
|
|
next_mem_state == MEM_OFIXpD |
|
1112 |
|
|
next_mem_state == MEM_OSIXpD ;
|
1113 |
|
|
|
1114 |
|
|
wire src2 = {16{ inc }} & 16'h0001 |
|
1115 |
|
|
{16{ dec }} & 16'hffff |
|
1116 |
|
|
{16{ rel }} & {{8{nn[15]}},nn[15:8]}|
|
1117 |
|
|
{16{~(rel_jmp|inc|dec)}} & 16'h0 ;
|
1118 |
|
|
|
1119 |
|
|
wire adr_alu = src2 + src_mux;
|
1120 |
|
|
|
1121 |
|
|
|
1122 |
|
|
wire pre_inc_dec = next_mem_state == MEM_CALL |
|
1123 |
|
|
next_mem_state == MEM_OSSP_P |
|
1124 |
|
|
next_mem_state == MEM_OSSP ;
|
1125 |
|
|
|
1126 |
|
|
|
1127 |
|
|
wire mux21 = pre_inc_dec ? alu : src_mux;
|
1128 |
|
|
|
1129 |
|
|
assign wb_rdy_nhz = (!wb_cyc | wb_ack ) & ~hazard; // wishbone ready with no hazard
|
1130 |
|
|
wire wb_rdy = !wb_cyc | wb_ack;
|
1131 |
|
|
|
1132 |
|
|
assign we_next = next_mem_state == MEM_OS1 |
|
1133 |
|
|
next_mem_state == MEM_OSP |
|
1134 |
|
|
next_mem_state == MEM_OSIXpD |
|
1135 |
|
|
next_mem_state == MEM_OSADR |
|
1136 |
|
|
next_mem_state == MEM_OSSP_PCM2 |
|
1137 |
|
|
next_mem_state == MEM_OSSP_P |
|
1138 |
|
|
next_mem_state == MEM_CALL |
|
1139 |
|
|
next_mem_state == MEM_OSNN |
|
1140 |
|
|
next_mem_state == MEM_OSADRP1 |
|
1141 |
|
|
next_mem_state == MEM_OSHL_PM |
|
1142 |
|
|
next_mem_state == MEM_OSDE_PM |
|
1143 |
|
|
next_mem_state == MEM_OS_HL_N |
|
1144 |
|
|
next_mem_state == MEM_IOS_C |
|
1145 |
|
|
next_mem_state == MEM_IOS_N ;
|
1146 |
|
|
|
1147 |
|
|
|
1148 |
|
|
//-------1---------2---------3--------State Machines-------6---------7---------8---------9--------0
|
1149 |
|
|
// we do this just to save virtual paper below.
|
1150 |
|
|
// 6 5 4 15
|
1151 |
|
|
assign {next_dec_state, next_mem_state, next_pipe_state} = next_state;
|
1152 |
|
|
|
1153 |
|
|
always @(ir1 or wb_int or inst_haz or wb_int or dec_state or mem_exec_dec or cb_mem or ed_nn or
|
1154 |
|
|
ed_blk_cp or ed_blk_in or ed_blk_out or ed_retn or ed_blk_mv or ed_dbl_rd or blk_done or
|
1155 |
|
|
fr or jmpr_true or callnn_true or jmpnn_true )
|
1156 |
|
|
|
1157 |
|
|
begin
|
1158 |
|
|
case (dec_state)
|
1159 |
|
|
DEC_IDLE: next_state = {DEC_IF1, MEM_NOP, IPIPE_NOP};
|
1160 |
|
|
|
1161 |
|
|
DEC_HALT:
|
1162 |
|
|
if (wb_int) next_state = {DEC_INT1,MEM_NOP ,IPIPE_NOP};// stay here until interrupt or reset
|
1163 |
|
|
else next_state = {DEC_HALT,MEM_NOP ,IPIPE_NOP};
|
1164 |
|
|
DEC_IF1 : next_state = {DEC_IF2 ,MEM_IFPP1 ,IPIPE_NOP};
|
1165 |
|
|
DEC_IF2 : next_state = {DEC_EXEC,MEM_IFPP1 ,IPIPE_EN1};
|
1166 |
|
|
DEC_IF2A: next_state = {DEC_EXEC,MEM_IFPP1 ,IPIPE_NOP};
|
1167 |
|
|
DEC_EXEC:
|
1168 |
|
|
if (inst_haz) next_state = {DEC_IF1, MEM_DECPC , IPIPE_NOP};
|
1169 |
|
|
else if (wb_int) next_state = {DEC_INT1,MEM_NOP ,IPIPE_NOP};
|
1170 |
|
|
else
|
1171 |
|
|
case (mem_exec_dec) // full case but can all tools understand ? just make a default
|
1172 |
|
|
I1_CB : next_state = {DEC_CB, MEM_IFPP1, IPIPE_EN1};// IF2_NOP -> nn <= (MEM)
|
1173 |
|
|
I1_DDFD : next_state = {DEC_DDFD, MEM_IFPP1, IPIPE_EN1};// gets real inst
|
1174 |
|
|
I1_ED : next_state = {DEC_ED, MEM_IFPP1, IPIPE_EN1};
|
1175 |
|
|
I1_JMP : next_state = {DEC_IF2, MEM_JMPHL, IPIPE_NOP};
|
1176 |
|
|
I1_N : next_state = {DEC_N, MEM_IFPP1, IPIPE_ENN};
|
1177 |
|
|
I1_NN : next_state = {DEC_NN, MEM_IFPP1, IPIPE_ENN};
|
1178 |
|
|
I1_OF : next_state = {DEC_OF, MEM_OF1, IPIPE_EN12};//transfer, don't activate
|
1179 |
|
|
I1_OS : next_state = {DEC_IF2, MEM_OS1, IPIPE_EN1}; // -> ir2_NOP
|
1180 |
|
|
I1_POP : next_state = {DEC_POP, MEM_OFSP, IPIPE_EN12};
|
1181 |
|
|
I1_PUSH : next_state = {DEC_PUSH, MEM_OSSP, IPIPE_EN12};
|
1182 |
|
|
I1_RET : next_state = {DEC_RET, MEM_OFSP, IPIPE_EN12};
|
1183 |
|
|
I1_RMW : next_state = {DEC_RMW, MEM_OF1, IPIPE_EN12};//can't activate till data rdy
|
1184 |
|
|
I1_RST : next_state = {DEC_IF2, MEM_IFRST, IPIPE_ENN};
|
1185 |
|
|
I1_R2R : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2};
|
1186 |
|
|
default : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; //I1_R2R
|
1187 |
|
|
endcase
|
1188 |
|
|
DEC_CB: if (cb_mem) next_state = {DEC_CBM, MEM_OF1, IPIPE_EN12};
|
1189 |
|
|
else next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2};
|
1190 |
|
|
DEC_DDFD: // except for CB and EB these all act the same H and L get modified by prefix
|
1191 |
|
|
case (mem_exec_dec)
|
1192 |
|
|
I1_CB : next_state = {DEC_PFxCB,MEM_IFPP1, IPIPE_EN1};// IF2_NOP -> nn <= (MEM)
|
1193 |
|
|
I1_DDFD : next_state = {DEC_DDFD, MEM_IFPP1, IPIPE_EN1};
|
1194 |
|
|
I1_ED : next_state = {DEC_ED, MEM_IFPP1, IPIPE_EN1};//How do we clear the prefix?
|
1195 |
|
|
I1_JMP : next_state = {DEC_IF2, MEM_JMPHL, IPIPE_NOP};
|
1196 |
|
|
I1_N : next_state = {DEC_N, MEM_IFPP1, IPIPE_ENN};
|
1197 |
|
|
I1_NN : next_state = {DEC_NN, MEM_IFPP1, IPIPE_ENN};
|
1198 |
|
|
I1_OF : next_state = {DEC_DDOF, MEM_IFPP1, IPIPE_ENN}; // d to nn - need to get d
|
1199 |
|
|
// LD A,(BC) LD A,(DE) will
|
1200 |
|
|
// become ix+d - do we care ?
|
1201 |
|
|
// i hope not
|
1202 |
|
|
I1_OS : next_state = {DEC_DDOS, MEM_IFPP1, IPIPE_ENN}; // d to nn
|
1203 |
|
|
I1_POP : next_state = {DEC_POP, MEM_OFSP, IPIPE_EN12};
|
1204 |
|
|
I1_PUSH : next_state = {DEC_PUSH, MEM_OSSP, IPIPE_EN12};
|
1205 |
|
|
I1_RET : next_state = {DEC_RET, MEM_OFSP, IPIPE_EN12};
|
1206 |
|
|
I1_RMW : next_state = {DEC_RMW, MEM_OF1, IPIPE_EN12};
|
1207 |
|
|
I1_RST : next_state = {DEC_IF2, MEM_IFRST, IPIPE_NOP}; // just dump next inst
|
1208 |
|
|
I1_R2R : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; //I1_R2R
|
1209 |
|
|
default : next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2}; //I1_R2R
|
1210 |
|
|
endcase
|
1211 |
|
|
DEC_ED:
|
1212 |
|
|
if (ed_nn) next_state = {DEC_EDNN1, MEM_IFPP1, IPIPE_ENN};
|
1213 |
|
|
// we need to set inc and io and repeat flags on this state for continued block
|
1214 |
|
|
// processing -- keep the states of this machine somewhat manageable.
|
1215 |
|
|
else if (ed_blk_cp ) next_state = {DEC_EDBCP1, MEM_OFHL_PM, IPIPE_EN12};// MEM_OFHL_PM triggers --BC
|
1216 |
|
|
else if (ed_blk_in ) next_state = {DEC_EDBIN1, MEM_IOF_C, IPIPE_EN12};// MEM_IOF_C triggers --B
|
1217 |
|
|
else if (ed_blk_out) next_state = {DEC_EDBOUT1,MEM_OFHL_PM, IPIPE_EN12};
|
1218 |
|
|
else if (ed_blk_mv ) next_state = {DEC_EDBMV1, MEM_OFHL_PM, IPIPE_EN12};
|
1219 |
|
|
else if (ed_retn ) next_state = {DEC_RET, MEM_OFSP, IPIPE_EN12};// see int logic below
|
1220 |
|
|
else next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2};
|
1221 |
|
|
// double register reads and writes here
|
1222 |
|
|
DEC_EDNN1: next_state = {DEC_EDNN2, MEM_NOP, IPIPE_ENN}; // address to nn
|
1223 |
|
|
DEC_EDNN2:
|
1224 |
|
|
if (ed_dbl_rd) next_state = {DEC_EDRD1, MEM_OFNN, IPIPE_NOP};
|
1225 |
|
|
else next_state = {DEC_EDWR, MEM_OSNN, IPIPE_NOP};// OSNN selects data ok?
|
1226 |
|
|
DEC_EDRD1: next_state = {DEC_EDRD2, MEM_OFADRP1, IPIPE_ENN}; // 1st byte 2n
|
1227 |
|
|
DEC_EDRD2: next_state = {DEC_IF2, MEM_IFPP1, IPIPE_ENNA2}; // 2nd byte 2nn
|
1228 |
|
|
DEC_EDWR: next_state = {DEC_IF1, MEM_OSADRP1, IPIPE_NOP};
|
1229 |
|
|
|
1230 |
|
|
// ED block moves
|
1231 |
|
|
DEC_EDBCP1:
|
1232 |
|
|
if (blk_done) next_state = {DEC_EXEC, MEM_IFPP1,IPIPE_ENNA2};
|
1233 |
|
|
else if(wb_int) next_state = {DEC_INT1, MEM_NOP, IPIPE_ENNA2};
|
1234 |
|
|
else next_state = {DEC_EDBCP2, MEM_NOP, IPIPE_ENNA2};//set flags
|
1235 |
|
|
DEC_EDBCP2: next_state = {DEC_EDBCP3, MEM_NOP, IPIPE_NOP};//wait for fr. alu_out is slow
|
1236 |
|
|
DEC_EDBCP3: if (fr[7]) next_state = {DEC_EXEC , MEM_IFPP1, IPIPE_NOP};
|
1237 |
|
|
else next_state = {DEC_EDBCP1, MEM_OFHL_PM, IPIPE_NOP};
|
1238 |
|
|
|
1239 |
|
|
DEC_EDBIN1: next_state = {DEC_EDBIN2, MEM_NOP, IPIPE_ENN};
|
1240 |
|
|
DEC_EDBIN2: if (blk_done) next_state = {DEC_IF2A, MEM_OSHL_PM,IPIPE_NOP}; // implies nn
|
1241 |
|
|
else if (wb_int) next_state = {DEC_INT1, MEM_OSHL_PM,IPIPE_NOP};
|
1242 |
|
|
else next_state = {DEC_EDBIN1,MEM_OSHL_PM,IPIPE_NOP};//set flags
|
1243 |
|
|
DEC_EDBIN3: next_state = {DEC_EDBIN1, MEM_IOF_C, IPIPE_NOP};
|
1244 |
|
|
|
1245 |
|
|
DEC_EDBOUT1: next_state = {DEC_EDBOUT2, MEM_NOP, IPIPE_ENN};
|
1246 |
|
|
DEC_EDBOUT2:if (blk_done) next_state = {DEC_EXEC, MEM_IOS_C,IPIPE_NOP};
|
1247 |
|
|
else if (wb_int) next_state = {DEC_INT1, MEM_IOS_C,IPIPE_NOP}; // DEC_EDBOUT: if (blk_rpt)
|
1248 |
|
|
else next_state = {DEC_EDBOUT3,MEM_IOS_C,IPIPE_NOP};
|
1249 |
|
|
|
1250 |
|
|
DEC_EDBOUT3: next_state = {DEC_EDBOUT1,MEM_OFHL_PM, IPIPE_NOP};
|
1251 |
|
|
|
1252 |
|
|
DEC_EDBMV1: next_state = {DEC_EDBMV2, MEM_NOP, IPIPE_ENN};
|
1253 |
|
|
DEC_EDBMV2: if (blk_done) next_state = {DEC_EXEC, MEM_OSDE_PM,IPIPE_NOP};
|
1254 |
|
|
else if (wb_int) next_state = {DEC_INT1, MEM_OSDE_PM,IPIPE_NOP}; //DEC_EDBOUT: if (blk_rpt)
|
1255 |
|
|
else next_state = {DEC_EDBMV3,MEM_OSDE_PM,IPIPE_NOP};
|
1256 |
|
|
|
1257 |
|
|
DEC_EDBMV3: next_state = {DEC_EDBMV1,MEM_OFHL_PM, IPIPE_NOP};
|
1258 |
|
|
|
1259 |
|
|
DEC_N:
|
1260 |
|
|
if (INsA_6N7== ir1) next_state = {DEC_NIN, MEM_IOF_N, IPIPE_EN12};
|
1261 |
|
|
else if (OUTs6N7_A==ir1) next_state = {DEC_IF1, MEM_IOS_N, IPIPE_EN12};
|
1262 |
|
|
else if (LDs6HL7_N==ir1) next_state = {DEC_IF1, MEM_OS_HL_N, IPIPE_EN12};
|
1263 |
|
|
else if (jmpr_true) next_state = {DEC_IF2, MEM_IFREL_N, IPIPE_NOP};
|
1264 |
|
|
else next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_EN12A2};//r2r or false jumps
|
1265 |
|
|
DEC_NIN: next_state = {DEC_IF2, MEM_IFPP1, IPIPE_ENNA2};
|
1266 |
|
|
|
1267 |
|
|
|
1268 |
|
|
//ISSUES: LDsSP_NN - load commanded from ir2 decode? and mechaninsm for updating PC on
|
1269 |
|
|
// JMP and CALL
|
1270 |
|
|
// on CALL We have IFNN for JMP
|
1271 |
|
|
// For CALL Use MEM_CALL to transfer pc<=nn, nn<=pc, adr<=sp then MEM_OSSP then IFPP1
|
1272 |
|
|
// For LDsSP_NN yes update from ir2 decode.
|
1273 |
|
|
DEC_NN:
|
1274 |
|
|
if (callnn_true) next_state = {DEC_NNCALL1, MEM_NOP, IPIPE_ENN}; // this gets new adr in nn
|
1275 |
|
|
// if we store from nn we can't do
|
1276 |
|
|
// a mem op now
|
1277 |
|
|
|
1278 |
|
|
else if (jmpnn_true) next_state = {DEC_NNJMP, MEM_NOP, IPIPE_ENN}; // gotta get nn before we can
|
1279 |
|
|
// transfer to adr.
|
1280 |
|
|
else if (LDs6NN7_A==ir1) next_state = {DEC_NNOS3, MEM_IFPP1, IPIPE_ENN};
|
1281 |
|
|
else if (LDs6NN7_HL==ir1) next_state = {DEC_NNOS1, MEM_IFPP1, IPIPE_ENN};
|
1282 |
|
|
else if (LDsA_6NN7==ir1) next_state = {DEC_NNOF3, MEM_IFPP1, IPIPE_ENN};
|
1283 |
|
|
else if (LDsHL_6NN7==ir1) next_state = {DEC_NNOF1, MEM_IFPP1, IPIPE_ENN};
|
1284 |
|
|
else next_state = { DEC_IF2, MEM_IFPP1, IPIPE_ENNEN2A2};
|
1285 |
|
|
|
1286 |
|
|
DEC_NNCALL1: next_state = {DEC_NNCALL2, MEM_CALL , IPIPE_NOP};
|
1287 |
|
|
DEC_NNCALL2: next_state = {DEC_IF1, MEM_OSSP, IPIPE_ENN};//A1 activates r2r xfers from ir1
|
1288 |
|
|
DEC_NNJMP: next_state = {DEC_IF2, MEM_IFNN , IPIPE_NOP};
|
1289 |
|
|
|
1290 |
|
|
// ISSUE: we blow out ir1 here - so need to keep some status to execute OSNN2.
|
1291 |
|
|
// general solution if not DEC_EXEC we get op frmo nn high byte.
|
1292 |
|
|
// note that first MEM_OSNN trabsferrs nn to wb_adr.
|
1293 |
|
|
DEC_NNOS1: next_state = {DEC_NNOS2, MEM_OSNN, IPIPE_EN1};
|
1294 |
|
|
DEC_NNOS2: next_state = {DEC_IF2A, MEM_OSNN, IPIPE_NOP};
|
1295 |
|
|
DEC_NNOS3: next_state = {DEC_IF2A, MEM_OSNN, IPIPE_EN1};
|
1296 |
|
|
|
1297 |
|
|
DEC_NNOF1: next_state = {DEC_NNOF2, MEM_OFNN, IPIPE_EN12};
|
1298 |
|
|
DEC_NNOF2: next_state = {DEC_NNOF4, MEM_OFNN, IPIPE_ENN};
|
1299 |
|
|
DEC_NNOF3: next_state = {DEC_NNOF4, MEM_OFNN, IPIPE_EN12};
|
1300 |
|
|
DEC_NNOF4: next_state = {DEC_EXEC, MEM_IFPP1, IPIPE_ENNA2};
|
1301 |
|
|
|
1302 |
|
|
DEC_DDOS: next_state = {DEC_IF2A, MEM_OSIXpD, IPIPE_EN12};
|
1303 |
|
|
DEC_DDOF: next_state = {DEC_OF , MEM_OFIXpD, IPIPE_EN12};
|
1304 |
|
|
|
1305 |
|
|
|
1306 |
|
|
DEC_OF: next_state = {DEC_EXEC, MEM_IFPP1 , IPIPE_ENNA2};
|
1307 |
|
|
DEC_POP: next_state = {DEC_NNOF4, MEM_OFSP, IPIPE_ENN };
|
1308 |
|
|
DEC_PUSH: next_state = {DEC_IF2A , MEM_OSSP, IPIPE_NOP };
|
1309 |
|
|
|
1310 |
|
|
|
1311 |
|
|
DEC_RET: next_state = { DEC_RET2, MEM_OFSP, IPIPE_ENN };
|
1312 |
|
|
DEC_RET2: next_state = { DEC_NNCALL2, MEM_NOP, IPIPE_ENN };
|
1313 |
|
|
// blow off a tick so we don't gronk adr
|
1314 |
|
|
DEC_RMW: next_state = {DEC_RMW2, MEM_NOP, IPIPE_ENNA2}; //activate
|
1315 |
|
|
DEC_RMW2: next_state = {DEC_IF1 , MEM_OSADR, IPIPE_NOP }; // from nn
|
1316 |
|
|
|
1317 |
|
|
|
1318 |
|
|
// IF memory -- rmw else these are all reg 2 reg
|
1319 |
|
|
DEC_CBM: if (CB_BIT==ir1[9:6]) next_state = {DEC_IF2, MEM_IFPP1, IPIPE_ENNA2};
|
1320 |
|
|
else next_state = {DEC_RMW2 , MEM_NOP, IPIPE_ENNA2};
|
1321 |
|
|
|
1322 |
|
|
// The DDCB anf FDCB all assume memory operands
|
1323 |
|
|
// These beauties always rmw memory. If a register op is default, they also
|
1324 |
|
|
// update the register. Programmers think of this as 2 ops for the price of 1.
|
1325 |
|
|
// unfortunately it is 2 ops for the price of 4.-- its not the number of lines
|
1326 |
|
|
// of assembler code that count but the number of bytes assembled. Oh well I signed
|
1327 |
|
|
// up for this...... and had a notion of what I was getting into.
|
1328 |
|
|
//
|
1329 |
|
|
DEC_PFxCB: next_state = { DEC_PFxCB2, MEM_IFPP1, IPIPE_ENN}; // this gets d
|
1330 |
|
|
DEC_PFxCB2: next_state = { DEC_PFxCB3, MEM_OFIXpD, IPIPE_EN1}; //actual inst
|
1331 |
|
|
DEC_PFxCB3: next_state = { DEC_PFxCB4, MEM_IFPP1, IPIPE_ENNEN2A2};
|
1332 |
|
|
DEC_PFxCB4: next_state = { DEC_IF2A, MEM_OSADR, IPIPE_EN1}; //execute ir2
|
1333 |
|
|
|
1334 |
|
|
// crap gotta subtract 2 (we always increment pc 2 times relative to the inst
|
1335 |
|
|
// that got interrupted. also can't push and dec pc without 2 adders.
|
1336 |
|
|
// choices: 1) fix up pc in 2 ticks 2) fix in 1 tick 3) add adder and do it fast
|
1337 |
|
|
// if there's anyone who knows is there anyone who cares.
|
1338 |
|
|
// guess I'll do it fast -- just a 16 bit subtractor. heck silicon is
|
1339 |
|
|
// cheap.
|
1340 |
|
|
DEC_INT1: next_state <= {DEC_INT2, MEM_OSSP_PCM2, IPIPE_NOP}; //must derement PC
|
1341 |
|
|
DEC_INT2: next_state <= {DEC_INT3, MEM_OSSP_P, IPIPE_NOP}; //must dec sp and PC 2 ops?
|
1342 |
|
|
DEC_INT3: next_state <= {DEC_INT4, MEM_INTA, IPIPE_NOP};
|
1343 |
|
|
DEC_INT4: next_state <= {DEC_INT5, MEM_NOP, IPIPE_ENN};
|
1344 |
|
|
DEC_INT5: next_state <= {DEC_IF2, MEM_IFINT, IPIPE_NOP};
|
1345 |
|
|
default: next_state <= {DEC_IDLE, MEM_NOP, IPIPE_NOP};
|
1346 |
|
|
endcase
|
1347 |
|
|
end
|
1348 |
|
|
|
1349 |
|
|
|
1350 |
|
|
always @(posedge clk or posedge rst)
|
1351 |
|
|
if (rst) dec_state <= DEC_IDLE;
|
1352 |
|
|
else if (wb_rdy_nhz ) dec_state <= next_dec_state;
|
1353 |
|
|
|
1354 |
|
|
|
1355 |
|
|
//-----------------------instruction register #1 ----------------------------------
|
1356 |
|
|
// // next_pipe_state {ir1,ir2,nn,act_ir2}
|
1357 |
|
|
|
1358 |
|
|
wire update_prefix = dec_state == DEC_EXEC | dec_state == DEC_DDFD;
|
1359 |
|
|
|
1360 |
|
|
always @(posedge clk or posedge rst)
|
1361 |
|
|
if (rst) ir1 <= NOP;
|
1362 |
|
|
else if (wb_rdy_nhz & next_pipe_state[3]) ir1 <= {2'b0, wb_dat_i} ;
|
1363 |
|
|
else if ( wb_rdy_nhz &update_prefix ) ir1 <= {ir1[7:0]==8'hed, ir1[7:0]==8'hcd, ir1[7:0]};
|
1364 |
|
|
|
1365 |
|
|
//----------- prefix states -----------------------------------------
|
1366 |
|
|
// strings of prefix insts are ignored up to last one. Also dded and fded are ignored
|
1367 |
|
|
// but ddcd and fdcd are defined prefix sets.
|
1368 |
|
|
//
|
1369 |
|
|
always @(posedge clk)
|
1370 |
|
|
if (wb_rdy_nhz & next_pipe_state[3]) {ir1dd, ir1fd } <= 2'b0;
|
1371 |
|
|
else if ( wb_rdy_nhz & update_prefix )
|
1372 |
|
|
{ir1dd, ir1fd } <= {ir1dd | (ir1[7:0]==8'hdd ) & (ir1[7:0]!=8'hed) & (ir1[7:0]!=8'hfd),
|
1373 |
|
|
ir1fd | (ir1[7:0]==8'hfd ) & (ir1[7:0]!=8'hed) & (ir1[7:0]!=8'hdd) };
|
1374 |
|
|
|
1375 |
|
|
//------------------- inst reg #2 -----------------------------------
|
1376 |
|
|
// This stuff is key to the data hazard logic. Hazards arise only AFTER activation of
|
1377 |
|
|
// a previous instruction. Fundamentally all state changes related to ir1 may be
|
1378 |
|
|
// delayed eithor by a delay in wb response, or by a hazard. Ir2 state changes
|
1379 |
|
|
// are keyed off exec_ir2 - and always happen immediately. ( exec_ir2 always is
|
1380 |
|
|
// immediately reset - unless of course a new instruction is transferred and executed.
|
1381 |
|
|
//
|
1382 |
|
|
//
|
1383 |
|
|
//
|
1384 |
|
|
always @(posedge clk or posedge rst)
|
1385 |
|
|
if (rst) ir2 <= 10'h0;
|
1386 |
|
|
else if (wb_rdy_nhz & next_pipe_state[2]) ir2 <= ir1;
|
1387 |
|
|
|
1388 |
|
|
always @(posedge clk or posedge rst)
|
1389 |
|
|
if (rst)
|
1390 |
|
|
begin
|
1391 |
|
|
ir2dd <= 1'b0;
|
1392 |
|
|
ir2fd <= 1'b0;
|
1393 |
|
|
end
|
1394 |
|
|
else if (wb_rdy_nhz & next_pipe_state[2])
|
1395 |
|
|
begin
|
1396 |
|
|
ir2dd <= ir1dd;
|
1397 |
|
|
ir2fd <= ir1fd;
|
1398 |
|
|
end
|
1399 |
|
|
|
1400 |
|
|
always @(posedge clk )
|
1401 |
|
|
if (wb_rdy_nhz & next_pipe_state[0]) exec_ir2 <= 1'b1;
|
1402 |
|
|
else exec_ir2 <= 1'b0;
|
1403 |
|
|
|
1404 |
|
|
|
1405 |
|
|
|
1406 |
|
|
|
1407 |
|
|
|
1408 |
|
|
//--------------- block move flags ------------------------
|
1409 |
|
|
always @(posedge clk)
|
1410 |
|
|
if (dec_state == DEC_ED) blk_inc_flg <= dec_blk_inc;
|
1411 |
|
|
|
1412 |
|
|
always @(posedge clk)
|
1413 |
|
|
if (dec_state == DEC_ED) blk_rpt_flg <= dec_blk_rpt;
|
1414 |
|
|
|
1415 |
|
|
|
1416 |
|
|
always @(posedge clk)
|
1417 |
|
|
if (dec_state == DEC_ED) blk_io_flg <= dec_blk_io;
|
1418 |
|
|
|
1419 |
|
|
|
1420 |
|
|
//-------------------------- memory interface stuff ----------------------------
|
1421 |
|
|
|
1422 |
|
|
|
1423 |
|
|
// -- wb_adr
|
1424 |
|
|
always @(posedge clk) if (wb_rdy) wb_adr <= mux21;
|
1425 |
|
|
|
1426 |
|
|
// -- wb_we;
|
1427 |
|
|
|
1428 |
|
|
always @(posedge clk or posedge rst)
|
1429 |
|
|
if (rst) wb_we <= 1'b0;
|
1430 |
|
|
else if (wb_rdy_nhz) wb_we <= we_next;
|
1431 |
|
|
|
1432 |
|
|
|
1433 |
|
|
|
1434 |
|
|
// -- wb_cyc
|
1435 |
|
|
|
1436 |
|
|
wire no_wb_start = mem_idle | mem_halt | mem_op3 & blk_cmp_reg | mem_op1 & rmw_reg;
|
1437 |
|
|
always @(posedge clk or posedge rst)
|
1438 |
|
|
if (rst) wb_cyc <= 1'b0;
|
1439 |
|
|
else if (wb_rdy_nhz) wb_cyc <= next_mem_state != MEM_NOP ;
|
1440 |
|
|
|
1441 |
|
|
// -- wb_stb;
|
1442 |
|
|
|
1443 |
|
|
always @(posedge clk or posedge rst)
|
1444 |
|
|
if (rst) wb_stb <= 1'b0;
|
1445 |
|
|
else if (wb_rdy_nhz) wb_stb <= next_mem_state != MEM_NOP ;
|
1446 |
|
|
|
1447 |
|
|
|
1448 |
|
|
// -- wb_lock lets not worry about lock unless somebody thinks it matters.
|
1449 |
|
|
|
1450 |
|
|
// -- wb_tga_io
|
1451 |
|
|
always @(posedge clk or posedge rst)
|
1452 |
|
|
if (rst) wb_tga_io <= 2'b0;
|
1453 |
|
|
else if (wb_rdy_nhz)
|
1454 |
|
|
begin
|
1455 |
|
|
if (next_mem_state == MEM_IOF_C |
|
1456 |
|
|
next_mem_state == MEM_IOS_C |
|
1457 |
|
|
next_mem_state == MEM_IOF_N |
|
1458 |
|
|
next_mem_state == MEM_IOS_N ) wb_tga_io <= TAG_IO;
|
1459 |
|
|
|
1460 |
|
|
else if (next_mem_state == MEM_INTA ) wb_tga_io <= TAG_INT;
|
1461 |
|
|
else wb_tga_io <= 2'b0 ;
|
1462 |
|
|
end
|
1463 |
|
|
|
1464 |
|
|
//------------ the input-output data register (nn) -----------------------------------------
|
1465 |
|
|
// basicaly we store lsb's folowed by msb's
|
1466 |
|
|
// input is always to msb (of input regiser) first (if a 2 byte operand, lsb<=msb before transfer)
|
1467 |
|
|
// this gets nn to position { msb, lsb } before we execute 2 byte transfer.
|
1468 |
|
|
//
|
1469 |
|
|
// if we don't update - we byte swap as well as
|
1470 |
|
|
// when we read
|
1471 |
|
|
// IMPORTANT We store from MSB's so that on block moves read and write from same place.
|
1472 |
|
|
// this makes the output look somewhat bass-ackwards but who is looking?
|
1473 |
|
|
//
|
1474 |
|
|
// There is probably a simpler way to do this. Unfortunately there are a lot of
|
1475 |
|
|
// dependencies here. Ill continue as planned till it proves untractable.
|
1476 |
|
|
// Issue is that we are using ir1 to provide the op specification -- but in general
|
1477 |
|
|
// ir1 gets gronked before 2nd store (if it happens) - so we need to capture both
|
1478 |
|
|
// data first time OSIXpD OS1 OSSP, and MEM_OSNN
|
1479 |
|
|
//
|
1480 |
|
|
// on consideration lets make a flag flag_firstos that gets set on first store after
|
1481 |
|
|
// DEC_EXEC
|
1482 |
|
|
// ISSUE reads both here and in ir1 need to execute on wb_ack ?
|
1483 |
|
|
// I recall wb_ack must stay active until a change in cycle ?
|
1484 |
|
|
// need to review wb spec.
|
1485 |
|
|
//
|
1486 |
|
|
//issue: how is EXs6SP7_HL implemented -- it is known as a rmw - and only trick for this file is
|
1487 |
|
|
// that nn must be properly updates with ir2
|
1488 |
|
|
|
1489 |
|
|
always @(posedge clk or posedge rst)
|
1490 |
|
|
if (rst) flag_os1 <= 1'b0;
|
1491 |
|
|
else if ((DEC_EXEC == next_dec_state) & wb_rdy) flag_os1 <= 1'b0;
|
1492 |
|
|
else if ( we_next ) flag_os1 <= 1'b1;
|
1493 |
|
|
|
1494 |
|
|
|
1495 |
|
|
wire [15:0] pc_2 = pc - 16'h2;
|
1496 |
|
|
always @(posedge clk)
|
1497 |
|
|
if (wb_rdy_nhz)
|
1498 |
|
|
begin
|
1499 |
|
|
if ( we_next & flag_os1) nn <= { nn[7:0], nn[15:8] } ;
|
1500 |
|
|
else if(we_next & ( next_mem_state == MEM_CALL)) nn <= {pc[7:0], pc[15:8]};
|
1501 |
|
|
else if(we_next & ( next_mem_state == MEM_OSSP_PCM2)) nn <= {pc_2[7:0], pc_2[15:8]};
|
1502 |
|
|
else if(EXs6SP7_HL== ir2 & ir2dd & exec_ir2) nn <= ixr;
|
1503 |
|
|
else if(EXs6SP7_HL== ir2 & ir2fd & exec_ir2) nn <= iyr;
|
1504 |
|
|
else if(EXs6SP7_HL== ir2 & exec_ir2) nn <= hl;
|
1505 |
|
|
// these are the general cases with ir1 providing register specification
|
1506 |
|
|
else if(we_next & ( next_mem_state == MEM_OS1 |
|
1507 |
|
|
next_mem_state == MEM_OSIXpD |
|
1508 |
|
|
next_mem_state == MEM_OSSP |
|
1509 |
|
|
next_mem_state == MEM_OSNN ) )
|
1510 |
|
|
begin
|
1511 |
|
|
if (os_a) nn[15:8] <= ar;
|
1512 |
|
|
if (os_b) nn[15:8] <= br;
|
1513 |
|
|
if (os_c) nn <= {cr, br }; // use for PUSHsBC
|
1514 |
|
|
if (os_d) nn[15:8] <= dr;
|
1515 |
|
|
if (os_e) nn <= {er, dr }; // use for PUSHsDE
|
1516 |
|
|
if (os_h) nn[15:8] <= hr;
|
1517 |
|
|
if (os_l) nn <= {lr, hr }; // use for PUSHsHL
|
1518 |
|
|
if (os_f) nn <= {fr, ar }; // use for PUSHsAF
|
1519 |
|
|
end
|
1520 |
|
|
|
1521 |
|
|
else nn <= { wb_dat_i, nn[15:8] };
|
1522 |
|
|
end
|
1523 |
|
|
|
1524 |
|
|
|
1525 |
|
|
|
1526 |
|
|
//------------------- pc and sp ----------------------------------------------------
|
1527 |
|
|
always @(posedge clk or posedge rst)
|
1528 |
|
|
if (rst) pc <= 16'h0;
|
1529 |
|
|
else if (wb_rdy_nhz)
|
1530 |
|
|
begin
|
1531 |
|
|
if (next_mem_state == MEM_DECPC) pc <= pc - 16'h1; // decrementer could perhaps be shared.
|
1532 |
|
|
if (next_mem_state == MEM_IFPP1) pc <= adr_alu;
|
1533 |
|
|
if (next_mem_state == MEM_CALL ) pc <= nn; //Use MEM_CALL to exchange pc<=>nn
|
1534 |
|
|
if (next_mem_state == MEM_IFRST) pc <= src_mux;
|
1535 |
|
|
if (next_mem_state == MEM_JMPHL) pc <= src_mux;
|
1536 |
|
|
if (next_mem_state == MEM_IFNN ) pc <= src_mux;
|
1537 |
|
|
if (next_mem_state == MEM_IFINT) pc <= src_mux;
|
1538 |
|
|
end
|
1539 |
|
|
|
1540 |
|
|
//---------------------------------- sp -----------------------------------------------------
|
1541 |
|
|
//
|
1542 |
|
|
// with pc updates are always made from ir1 as the PC is so critical to instruction flow.
|
1543 |
|
|
// (this of course creates the possibility of an "inst_hazard" - where data is stored in an
|
1544 |
|
|
// instruction already fetched - see below)
|
1545 |
|
|
// with sp the situation is not so simple.
|
1546 |
|
|
// Issues - especially regarding hazards.
|
1547 |
|
|
//
|
1548 |
|
|
// LDsSP_NN this should be done from ir2 - no hazard as active state is ALWAYS IF2
|
1549 |
|
|
//
|
1550 |
|
|
// ADDsHL_SP The add is a pre-add so sp cannot be modified before inst is executed from ir2
|
1551 |
|
|
// DECsSP Just do it with ir1 at DEC_EXEC gotcha need -- IFPP1 in general use ir2 -> hazard
|
1552 |
|
|
// EXs6SP7_HL rmw - no change to sp - no issue here
|
1553 |
|
|
// INCsSP Just do it with ir1 at DEC_EXEC gotcha -- IFPP1 use ir2 -> hazard
|
1554 |
|
|
// LDsSP_HL do from ir1 and use standard hazard logic (if H or L is being
|
1555 |
|
|
// updated -- wait)
|
1556 |
|
|
//
|
1557 |
|
|
// ED_LDs6NN7_REG REG== SP // needs to be done from ir2
|
1558 |
|
|
// ED_LDsREG_6NN7 REG== SP // do from ir2 - no hazard as executed on IF2 - refill pipe
|
1559 |
|
|
|
1560 |
|
|
always @(posedge clk )
|
1561 |
|
|
if (exec_ir2 ) // this has priority of course
|
1562 |
|
|
begin
|
1563 |
|
|
if (LDsSP_NN == ir2) sp <= nn;
|
1564 |
|
|
if (ED_LDsREG_6NN7 == ir2) sp <= nn;
|
1565 |
|
|
if ( DECsSP == ir2 ) sp <= add16;
|
1566 |
|
|
if ( INCsSP == ir2 ) sp <= add16;
|
1567 |
|
|
end
|
1568 |
|
|
else if (wb_rdy_nhz)
|
1569 |
|
|
begin
|
1570 |
|
|
if ( DECsSP == ir1 & dec_state == DEC_EXEC) sp <= adr_alu;
|
1571 |
|
|
if ( INCsSP == ir1 & dec_state == DEC_EXEC) sp <= adr_alu;
|
1572 |
|
|
if ( LDsSP_HL == ir1 & dec_state == DEC_EXEC) sp <= {hr,lr};
|
1573 |
|
|
if (next_mem_state == MEM_OFSP ) sp <= adr_alu;
|
1574 |
|
|
if (next_mem_state == MEM_OSSP ) sp <= adr_alu;
|
1575 |
|
|
if (next_mem_state == MEM_OSSP_PCM2 ) sp <= adr_alu;
|
1576 |
|
|
if (next_mem_state == MEM_OSSP_P ) sp <= adr_alu;
|
1577 |
|
|
end
|
1578 |
|
|
//----------------- inst hazard logic ------------------------------------------
|
1579 |
|
|
|
1580 |
|
|
|
1581 |
|
|
|
1582 |
|
|
always @(posedge clk or posedge rst)
|
1583 |
|
|
if (rst) inst_haz <= 1'b0;
|
1584 |
|
|
else if (we_next & (pc - 16'h1) == mux21) inst_haz <= 1'b1;
|
1585 |
|
|
else if (dec_state == DEC_EXEC) inst_haz <= 1'b0; // highest priority interrupt
|
1586 |
|
|
|
1587 |
|
|
//-------------------- int logic ----------------------------------------
|
1588 |
|
|
// We have a wishbone interrupt system - which i guess does not preclude a
|
1589 |
|
|
// non-maskable interrupt...... but bottom line is that such an interrupt is
|
1590 |
|
|
// definately out of favor with current system thinking. Within an embedded system
|
1591 |
|
|
// ( the target application here ) a single interrupt controller capable of handeling
|
1592 |
|
|
// as many interrupts as desired is the best choice.
|
1593 |
|
|
// Therefore we enable only mode 2 interrupts and a single enable ff.
|
1594 |
|
|
//
|
1595 |
|
|
// This begs the question of what to do with the "RETI" instruction -- ED4D. We opt to
|
1596 |
|
|
// enable interrupts with this instruction (and all its "aliases").
|
1597 |
|
|
//
|
1598 |
|
|
always @(posedge clk or posedge rst)
|
1599 |
|
|
if (rst) int_en <= 1'b0;
|
1600 |
|
|
else if (wb_rdy_nhz)
|
1601 |
|
|
begin
|
1602 |
|
|
if ((dec_state == DEC_EXEC) & (DI== ir1)) int_en <= 1'b0;
|
1603 |
|
|
else if ((dec_state == DEC_EXEC) & en_int_next) int_en <= 1'b1;
|
1604 |
|
|
else if ((dec_state == DEC_ED) & ed_retn) int_en <= 1'b0;
|
1605 |
|
|
if (dec_state == DEC_INT1) int_en <= 1'b0;
|
1606 |
|
|
end
|
1607 |
|
|
|
1608 |
|
|
|
1609 |
|
|
always @(posedge clk or posedge rst)
|
1610 |
|
|
if (rst) en_int_next <=1'b0;
|
1611 |
|
|
else if (wb_rdy_nhz)
|
1612 |
|
|
begin
|
1613 |
|
|
if ((dec_state == DEC_EXEC) & (EI== ir1)) en_int_next <=1'b1;
|
1614 |
|
|
else if (dec_state == DEC_EXEC) en_int_next <=1'b0;
|
1615 |
|
|
end
|
1616 |
|
|
|
1617 |
|
|
always @(posedge clk)
|
1618 |
|
|
wb_irq_sync <= wb_int_rq;
|
1619 |
|
|
|
1620 |
|
|
assign wb_int = wb_irq_sync & int_en;
|
1621 |
|
|
|
1622 |
|
|
endmodule
|
1623 |
|
|
|