1
2-- Company: ZPU4 generic memory interface CPU
3-- Engineer: �yvind Harboe
4
5library IEEE;
6use IEEE.STD_LOGIC_1164.ALL;
7use IEEE.STD_LOGIC_UNSIGNED.ALL;
8use IEEE.STD_LOGIC_arith.ALL;
9
10library work;
11use work.zpu_config.all;
12use work.zpupkg.all;
13
14
15
16
17
18entity zpu_core is
19    Port ( clk : in std_logic;
20	 		  areset : in std_logic;
21	 		  enable : in std_logic;
22	 		  mem_req : out std_logic;
23	 		  mem_we : out std_logic;
24	 		  mem_ack : in std_logic;
25	 		  mem_read : in std_logic_vector(wordSize-1 downto 0);
26	 		  mem_write : out std_logic_vector(wordSize-1 downto 0);
27			  out_mem_addr : out std_logic_vector(maxAddrBitIncIO downto 0);
28	 		  mem_writeMask: out std_logic_vector(wordBytes-1 downto 0);
29	 		  interrupt : in std_logic;
30	 		  break : out std_logic;
31	 		  zpu_status : out std_logic_vector(63 downto 0));
32end zpu_core;
33
34architecture behave of zpu_core is
35
36type InsnType is
37(
38State_AddTop,
39State_Dup,
40State_DupStackB,
41State_Pop,
42State_Popdown,
43State_Add,
44State_Or,
45State_And,
46State_Store,
47State_AddSP,
48State_Shift,
49State_Nop,
50State_Im,
51State_LoadSP,
52State_StoreSP,
53State_Emulate,
54State_Load,
55State_PushPC,
56State_PushSP,
57State_PopPC,
58State_PopPCRel,
59State_Not,
60State_Flip,
61State_PopSP,
62State_Neqbranch,
63State_Eq,
64State_Loadb,
65State_Mult,
66State_Lessthan,
67State_Lessthanorequal,
68State_Ulessthanorequal,
69State_Ulessthan,
70State_Pushspadd,
71State_Call,
72State_Callpcrel,
73State_Sub,
74State_Break,
75State_Storeb,
76State_Interrupt,
77State_InsnFetch
78);
79
80type StateType is
81(
82State_Idle, -- using first state first on the list out of paranoia
83State_Load2,
84State_Popped,
85State_LoadSP2,
86State_LoadSP3,
87State_AddSP2,
88State_Fetch,
89State_Execute,
90State_Decode,
91State_Decode2,
92State_Resync,
93
94State_StoreSP2,
95State_Resync2,
96State_Resync3,
97State_Loadb2,
98State_Storeb2,
99State_Mult2,
100State_Mult3,
101State_Mult5,
102State_Mult6,
103State_Mult4,
104State_BinaryOpResult
105);
106
107
108signal	pc				: std_logic_vector(maxAddrBitIncIO downto 0);
109signal	sp				: std_logic_vector(maxAddrBitIncIO downto minAddrBit);
110signal	incSp			: std_logic_vector(maxAddrBitIncIO downto minAddrBit);
111signal	incIncSp			: std_logic_vector(maxAddrBitIncIO downto minAddrBit);
112signal	decSp			: std_logic_vector(maxAddrBitIncIO downto minAddrBit);
113signal  stackA   		: std_logic_vector(wordSize-1 downto 0);
114signal  binaryOpResult		: std_logic_vector(wordSize-1 downto 0);
115signal  multResult2  		: std_logic_vector(wordSize-1 downto 0);
116signal  multResult3  		: std_logic_vector(wordSize-1 downto 0);
117signal  multResult  		: std_logic_vector(wordSize-1 downto 0);
118signal  multA 		: std_logic_vector(wordSize-1 downto 0);
119signal  multB  		: std_logic_vector(wordSize-1 downto 0);
120signal  stackB  		: std_logic_vector(wordSize-1 downto 0);
121signal	idim_flag			: std_logic;
122signal	busy 				: std_logic;
123signal mem_readEnable : std_logic;
124signal mem_addr : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
125signal mem_delayAddr : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
126signal mem_delayReadEnable : std_logic;
127signal mem_busy : std_logic;
128signal decodeWord : std_logic_vector(wordSize-1 downto 0);
129
130
131signal state : StateType;
132signal insn : InsnType;
133type InsnArray is array(0 to wordBytes-1) of InsnType;
134signal decodedOpcode : InsnArray;
135
136type OpcodeArray is array(0 to wordBytes-1) of std_logic_vector(7 downto 0);
137
138signal opcode : OpcodeArray;
139
140
141
142
143signal	begin_inst			: std_logic;
144signal trace_opcode		: std_logic_vector(7 downto 0);
145signal	trace_pc				: std_logic_vector(maxAddrBitIncIO downto 0);
146signal	trace_sp				: std_logic_vector(maxAddrBitIncIO downto minAddrBit);
147signal	trace_topOfStack				: std_logic_vector(wordSize-1 downto 0);
148signal	trace_topOfStackB				: std_logic_vector(wordSize-1 downto 0);
149
150signal	out_mem_req : std_logic;
151
152signal inInterrupt : std_logic;
153
154-- state machine.
155
156begin
157
158	zpu_status(maxAddrBitIncIO downto 0) <= trace_pc;
159	zpu_status(31) <= '1';
160	zpu_status(39 downto 32) <= trace_opcode;
161	zpu_status(40) <= '1' when (state = State_Idle) else '0';
162	zpu_status(62) <= '1';
163
164	traceFileGenerate:
165   if Generate_Trace generate
166	trace_file: trace port map (
167       	clk => clk,
168       	begin_inst => begin_inst,
169       	pc => trace_pc,
170		opcode => trace_opcode,
171		sp => trace_sp,
172		memA => trace_topOfStack,
173		memB => trace_topOfStackB,
174		busy => busy,
175		intsp => (others => 'U')
176        );
177	end generate;
178
179
180	-- the memory subsystem will tell us one cycle later whether or
181	-- not it is busy
182	out_mem_addr(maxAddrBitIncIO downto minAddrBit) <= mem_addr;
183	out_mem_addr(minAddrBit-1 downto 0) <= (others => '0');
184	mem_req <= out_mem_req;
185
186	incSp <= sp + 1;
187	incIncSp <= sp + 2;
188	decSp <= sp - 1;
189
190	mem_busy <= out_mem_req and not mem_ack; -- '1' when the memory is busy
191
192	opcodeControl:
193	process(clk, areset)
194		variable tOpcode : std_logic_vector(OpCode_Size-1 downto 0);
195		variable spOffset : std_logic_vector(4 downto 0);
196		variable tSpOffset : std_logic_vector(4 downto 0);
197		variable nextPC : std_logic_vector(maxAddrBitIncIO downto 0);
198		variable tNextState : InsnType;
199		variable tDecodedOpcode : InsnArray;
200		variable tMultResult : std_logic_vector(wordSize*2-1 downto 0);
201	begin
202		if areset = '1' then
203			state <= State_Idle;
204			break <= '0';
205			sp <= spStart(maxAddrBitIncIO downto minAddrBit);
206
207			pc <= (others => '0');
208			idim_flag <= '0';
209			begin_inst <= '0';
210			mem_we <= '0';
211			multA <= (others => '0');
212			multB <= (others => '0');
213			mem_writeMask <= (others => '1');
214			out_mem_req <= '0';
215			mem_addr <= (others => DontCareValue);
216			mem_write <= (others => DontCareValue);
217			inInterrupt <= '0';
218		elsif (clk'event and clk = '1') then
219			-- we must multiply unconditionally to get pipelined multiplication
220        	tMultResult := multA * multB;
221    		multResult3 <= multResult2;
222    		multResult2 <= multResult;
223    		multResult <= tMultResult(wordSize-1 downto 0);
224
225
226			spOffset(4):=not opcode(conv_integer(pc(byteBits-1 downto 0)))(4);
227			spOffset(3 downto 0):=opcode(conv_integer(pc(byteBits-1 downto 0)))(3 downto 0);
228			nextPC := pc + 1;
229
230			-- prepare trace snapshot
231			trace_opcode <= opcode(conv_integer(pc(byteBits-1 downto 0)));
232			trace_pc <= pc;
233			trace_sp <=	sp;
234			trace_topOfStack <= stackA;
235			trace_topOfStackB <= stackB;
236			begin_inst <= '0';
237
238			-- we terminate the requeset as soon as we get acknowledge
239			if mem_ack = '1' then
240				out_mem_req <= '0';
241				mem_we <= '0';
242			end if;
243
244			if interrupt='0' then
245				inInterrupt <= '0'; -- no longer in an interrupt
246			end if;
247
248			case state is
249				when State_Idle =>
250					if enable='1' then
251						state <= State_Resync;
252					end if;
253				-- Initial state of ZPU, fetch top of stack + first instruction
254				when State_Resync =>
255					if mem_busy='0' then
256						mem_addr <= sp;
257						out_mem_req <= '1';
258						state <= State_Resync2;
259					end if;
260				when State_Resync2 =>
261					if mem_busy='0' then
262						stackA <= mem_read;
263						mem_addr <= incSp;
264						out_mem_req <= '1';
265						state <= State_Resync3;
266					end if;
267				when State_Resync3 =>
268					if mem_busy='0' then
269						stackB <= mem_read;
270						mem_addr <= pc(maxAddrBitIncIO downto minAddrBit);
271						out_mem_req <= '1';
272						state <= State_Decode;
273					end if;
274				when State_Decode =>
275					if mem_busy='0' then
276						decodeWord <= mem_read;
277						state <= State_Decode2;
278					end if;
279				when State_Decode2 =>
280					-- decode 4 instructions in parallel
281					for i in 0 to wordBytes-1 loop
282						tOpcode := decodeWord((wordBytes-1-i+1)*8-1 downto (wordBytes-1-i)*8);
283
284						tSpOffset(4):=not tOpcode(4);
285						tSpOffset(3 downto 0):=tOpcode(3 downto 0);
286
287						opcode(i) <= tOpcode;
288						if (tOpcode(7 downto 7)=OpCode_Im) then
289							tNextState:=State_Im;
290						elsif (tOpcode(7 downto 5)=OpCode_StoreSP) then
291							if tSpOffset = 0 then
292								tNextState := State_Pop;
293							elsif tSpOffset=1 then
294								tNextState := State_PopDown;
295							else
296								tNextState :=State_StoreSP;
297							end if;
298						elsif (tOpcode(7 downto 5)=OpCode_LoadSP) then
299							if tSpOffset = 0 then
300								tNextState :=State_Dup;
301							elsif tSpOffset = 1 then
302								tNextState :=State_DupStackB;
303							else
304								tNextState :=State_LoadSP;
305							end if;
306						elsif (tOpcode(7 downto 5)=OpCode_Emulate) then
307							tNextState :=State_Emulate;
308							if tOpcode(5 downto 0)=OpCode_Neqbranch then
309								tNextState :=State_Neqbranch;
310							elsif tOpcode(5 downto 0)=OpCode_Eq then
311								tNextState :=State_Eq;
312							elsif tOpcode(5 downto 0)=OpCode_Lessthan then
313								tNextState :=State_Lessthan;
314							elsif tOpcode(5 downto 0)=OpCode_Lessthanorequal then
315								--tNextState :=State_Lessthanorequal;
316							elsif tOpcode(5 downto 0)=OpCode_Ulessthan then
317								tNextState :=State_Ulessthan;
318							elsif tOpcode(5 downto 0)=OpCode_Ulessthanorequal then
319								--tNextState :=State_Ulessthanorequal;
320							elsif tOpcode(5 downto 0)=OpCode_Loadb then
321								tNextState :=State_Loadb;
322							elsif tOpcode(5 downto 0)=OpCode_Mult then
323								tNextState :=State_Mult;
324							elsif tOpcode(5 downto 0)=OpCode_Storeb then
325								tNextState :=State_Storeb;
326							elsif tOpcode(5 downto 0)=OpCode_Pushspadd then
327								tNextState :=State_Pushspadd;
328							elsif tOpcode(5 downto 0)=OpCode_Callpcrel then
329								tNextState :=State_Callpcrel;
330							elsif tOpcode(5 downto 0)=OpCode_Call then
331								--tNextState :=State_Call;
332							elsif tOpcode(5 downto 0)=OpCode_Sub then
333								tNextState :=State_Sub;
334							elsif tOpcode(5 downto 0)=OpCode_PopPCRel then
335								--tNextState :=State_PopPCRel;
336							end if;
337						elsif (tOpcode(7 downto 4)=OpCode_AddSP) then
338							if tSpOffset = 0 then
339								tNextState := State_Shift;
340							elsif tSpOffset = 1 then
341								tNextState := State_AddTop;
342							else
343								tNextState :=State_AddSP;
344							end if;
345						else
346							case tOpcode(3 downto 0) is
347								when OpCode_Nop =>
348									tNextState :=State_Nop;
349								when OpCode_PushSP =>
350									tNextState :=State_PushSP;
351								when OpCode_PopPC =>
352									tNextState :=State_PopPC;
353								when OpCode_Add =>
354									tNextState :=State_Add;
355								when OpCode_Or =>
356									tNextState :=State_Or;
357								when OpCode_And =>
358									tNextState :=State_And;
359								when OpCode_Load =>
360									tNextState :=State_Load;
361								when OpCode_Not =>
362									tNextState :=State_Not;
363								when OpCode_Flip =>
364									tNextState :=State_Flip;
365								when OpCode_Store =>
366									tNextState :=State_Store;
367								when OpCode_PopSP =>
368									tNextState :=State_PopSP;
369								when others =>
370									tNextState := State_Break;
371
372							end case;
373						end if;
374						tDecodedOpcode(i) := tNextState;
375
376					end loop;
377
378					insn <= tDecodedOpcode(conv_integer(pc(byteBits-1 downto 0)));
379
380					-- once we wrap, we need to fetch
381					tDecodedOpcode(0) := State_InsnFetch;
382
383					decodedOpcode <= tDecodedOpcode;
384					state <= State_Execute;
385
386
387
388					-- Each instruction must:
389					--
390					-- 1. set idim_flag
391					-- 2. increase pc if applicable
392					-- 3. set next state if appliable
393					-- 4. do it's operation
394
395				when State_Execute =>
396					insn <= decodedOpcode(conv_integer(nextPC(byteBits-1 downto 0)));
397
398					case insn is
399						when State_InsnFetch =>
400							state <= State_Fetch;
401						when State_Im =>
402							if mem_busy='0' then
403								begin_inst <= '1';
404								idim_flag <= '1';
405								pc <= pc + 1;
406
407								if idim_flag='1' then
408									stackA(wordSize-1 downto 7) <= stackA(wordSize-8 downto 0);
409									stackA(6 downto 0) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6 downto 0);
410								else
411									out_mem_req <= '1';
412									mem_we <= '1';
413									mem_addr <= incSp;
414									mem_write <= stackB;
415									stackB <= stackA;
416									sp <= decSp;
417									for i in wordSize-1 downto 7 loop
418										stackA(i) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6);
419									end loop;
420									stackA(6 downto 0) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6 downto 0);
421								end if;
422							else
423								insn <= insn;
424							end if;
425						when State_StoreSP =>
426							if mem_busy='0' then
427								begin_inst <= '1';
428								idim_flag <= '0';
429								state <= State_StoreSP2;
430
431								out_mem_req <= '1';
432								mem_we <= '1';
433								mem_addr <= sp+spOffset;
434								mem_write <= stackA;
435								stackA <= stackB;
436								sp <= incSp;
437							else
438								insn <= insn;
439							end if;
440
441
442						when State_LoadSP =>
443							if mem_busy='0' then
444								begin_inst <= '1';
445								idim_flag <= '0';
446								state <= State_LoadSP2;
447
448								sp <= decSp;
449								out_mem_req <= '1';
450								mem_we <= '1';
451								mem_addr <= incSp;
452								mem_write <= stackB;
453							else
454								insn <= insn;
455							end if;
456						when State_Emulate =>
457							if mem_busy='0' then
458								begin_inst <= '1';
459								idim_flag <= '0';
460								sp <= decSp;
461								out_mem_req <= '1';
462								mem_we <= '1';
463								mem_addr <= incSp;
464								mem_write <= stackB;
465								stackA <= (others => DontCareValue);
466								stackA(maxAddrBitIncIO downto 0) <= pc + 1;
467								stackB <= stackA;
468
469								-- The emulate address is:
470								--        98 7654 3210
471								-- 0000 00aa aaa0 0000
472								pc <= (others => '0');
473								pc(9 downto 5) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(4 downto 0);
474								state <= State_Fetch;
475							else
476								insn <= insn;
477							end if;
478						when State_Callpcrel =>
479							if mem_busy='0' then
480								begin_inst <= '1';
481								idim_flag <= '0';
482								stackA <= (others => DontCareValue);
483								stackA(maxAddrBitIncIO downto 0) <= pc + 1;
484
485								pc <= pc + stackA(maxAddrBitIncIO downto 0);
486								state <= State_Fetch;
487							else
488								insn <= insn;
489							end if;
490						when State_Call =>
491							if mem_busy='0' then
492								begin_inst <= '1';
493								idim_flag <= '0';
494								stackA <= (others => DontCareValue);
495								stackA(maxAddrBitIncIO downto 0) <= pc + 1;
496								pc <= stackA(maxAddrBitIncIO downto 0);
497								state <= State_Fetch;
498							else
499								insn <= insn;
500							end if;
501						when State_AddSP =>
502							if mem_busy='0' then
503								begin_inst <= '1';
504								idim_flag <= '0';
505								state <= State_AddSP2;
506
507								out_mem_req <= '1';
508								mem_addr <= sp+spOffset;
509							else
510								insn <= insn;
511							end if;
512						when State_PushSP =>
513							if mem_busy='0' then
514								begin_inst <= '1';
515								idim_flag <= '0';
516								pc <= pc + 1;
517
518								sp <= decSp;
519								stackA <= (others => '0');
520								stackA(maxAddrBitIncIO downto minAddrBit) <= sp;
521								stackB <= stackA;
522								out_mem_req <= '1';
523								mem_we <= '1';
524								mem_addr <= incSp;
525								mem_write <= stackB;
526							else
527								insn <= insn;
528							end if;
529						when State_PopPC =>
530							if mem_busy='0' then
531								begin_inst <= '1';
532								idim_flag <= '0';
533								pc <= stackA(maxAddrBitIncIO downto 0);
534								sp <= incSp;
535
536								out_mem_req <= '1';
537								mem_we <= '1';
538								mem_addr <= incSp;
539								mem_write <= stackB;
540								state <= State_Resync;
541							else
542								insn <= insn;
543							end if;
544						when State_PopPCRel =>
545							if mem_busy='0' then
546								begin_inst <= '1';
547								idim_flag <= '0';
548								pc <= stackA(maxAddrBitIncIO downto 0) + pc;
549								sp <= incSp;
550
551								out_mem_req <= '1';
552								mem_we <= '1';
553								mem_addr <= incSp;
554								mem_write <= stackB;
555								state <= State_Resync;
556							else
557								insn <= insn;
558							end if;
559						when State_Add =>
560							if mem_busy='0' then
561								begin_inst <= '1';
562								idim_flag <= '0';
563								stackA <= stackA + stackB;
564
565								out_mem_req <= '1';
566								mem_addr <= incIncSp;
567								sp <= incSp;
568								state <= State_Popped;
569							else
570								insn <= insn;
571							end if;
572						when State_Sub =>
573							begin_inst <= '1';
574							idim_flag <= '0';
575							binaryOpResult <= stackB - stackA;
576							state <= State_BinaryOpResult;
577						when State_Pop =>
578							if mem_busy='0' then
579								begin_inst <= '1';
580								idim_flag <= '0';
581								mem_addr <= incIncSp;
582								out_mem_req <= '1';
583								sp <= incSp;
584								stackA <= stackB;
585								state <= State_Popped;
586							else
587								insn <= insn;
588							end if;
589						when State_PopDown =>
590							if mem_busy='0' then
591								-- PopDown leaves top of stack unchanged
592								begin_inst <= '1';
593								idim_flag <= '0';
594								mem_addr <= incIncSp;
595								out_mem_req <= '1';
596								sp <= incSp;
597								state <= State_Popped;
598							else
599								insn <= insn;
600							end if;
601						when State_Or =>
602							if mem_busy='0' then
603								begin_inst <= '1';
604								idim_flag <= '0';
605								stackA <= stackA or stackB;
606								out_mem_req <= '1';
607								mem_addr <= incIncSp;
608								sp <= incSp;
609								state <= State_Popped;
610							else
611								insn <= insn;
612							end if;
613						when State_And =>
614							if mem_busy='0' then
615								begin_inst <= '1';
616								idim_flag <= '0';
617
618								stackA <= stackA and stackB;
619								out_mem_req <= '1';
620								mem_addr <= incIncSp;
621								sp <= incSp;
622								state <= State_Popped;
623							else
624								insn <= insn;
625							end if;
626						when State_Eq =>
627							begin_inst <= '1';
628							idim_flag <= '0';
629
630		            		binaryOpResult <= (others => '0');
631		                	if (stackA=stackB) then
632		                		binaryOpResult(0) <= '1';
633		                	end if;
634							state <= State_BinaryOpResult;
635		                when State_Ulessthan =>
636							begin_inst <= '1';
637							idim_flag <= '0';
638
639		            		binaryOpResult <= (others => '0');
640		                	if (stackA<stackB) then
641		                		binaryOpResult(0) <= '1';
642		                	end if;
643							state <= State_BinaryOpResult;
644		                when State_Ulessthanorequal =>
645							begin_inst <= '1';
646							idim_flag <= '0';
647
648		            		binaryOpResult <= (others => '0');
649		                	if (stackA<=stackB) then
650		                		binaryOpResult(0) <= '1';
651		                	end if;
652							state <= State_BinaryOpResult;
653		                when State_Lessthan =>
654							begin_inst <= '1';
655							idim_flag <= '0';
656
657		            		binaryOpResult <= (others => '0');
658		                	if (signed(stackA)<signed(stackB)) then
659		                		binaryOpResult(0) <= '1';
660		                	end if;
661							state <= State_BinaryOpResult;
662		                when State_Lessthanorequal =>
663							begin_inst <= '1';
664							idim_flag <= '0';
665
666		            		binaryOpResult <= (others => '0');
667		                	if (signed(stackA)<=signed(stackB)) then
668		                		binaryOpResult(0) <= '1';
669		                	end if;
670							state <= State_BinaryOpResult;
671						when State_Load =>
672							if mem_busy='0' then
673								begin_inst <= '1';
674								idim_flag <= '0';
675								state <= State_Load2;
676
677								mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
678								out_mem_req <= '1';
679							else
680								insn <= insn;
681							end if;
682
683						when State_Dup =>
684							if mem_busy='0' then
685								begin_inst <= '1';
686								idim_flag <= '0';
687								pc <= pc + 1;
688
689								sp <= decSp;
690								stackB <= stackA;
691								mem_write <= stackB;
692								mem_addr <= incSp;
693								out_mem_req <= '1';
694								mem_we <= '1';
695							else
696								insn <= insn;
697							end if;
698						when State_DupStackB =>
699							if mem_busy='0' then
700								begin_inst <= '1';
701								idim_flag <= '0';
702								pc <= pc + 1;
703
704								sp <= decSp;
705								stackA <= stackB;
706								stackB <= stackA;
707								mem_write <= stackB;
708								mem_addr <= incSp;
709								out_mem_req <= '1';
710								mem_we <= '1';
711							else
712								insn <= insn;
713							end if;
714						when State_Store =>
715							if mem_busy='0' then
716								begin_inst <= '1';
717								idim_flag <= '0';
718								pc <= pc + 1;
719								mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
720								mem_write <= stackB;
721								out_mem_req <= '1';
722								mem_we <= '1';
723								sp <= incIncSp;
724								state <= State_Resync;
725							else
726								insn <= insn;
727							end if;
728						when State_PopSP =>
729							if mem_busy='0' then
730								begin_inst <= '1';
731								idim_flag <= '0';
732								pc <= pc + 1;
733
734								mem_write <= stackB;
735								mem_addr <= incSp;
736								out_mem_req <= '1';
737								mem_we <= '1';
738								sp <= stackA(maxAddrBitIncIO downto minAddrBit);
739								state <= State_Resync;
740							else
741								insn <= insn;
742							end if;
743						when State_Nop =>
744							begin_inst <= '1';
745							idim_flag <= '0';
746							pc <= pc + 1;
747						when State_Not =>
748							begin_inst <= '1';
749							idim_flag <= '0';
750							pc <= pc + 1;
751
752							stackA <= not stackA;
753						when State_Flip =>
754							begin_inst <= '1';
755							idim_flag <= '0';
756							pc <= pc + 1;
757
758							for i in 0 to wordSize-1 loop
759								stackA(i) <= stackA(wordSize-1-i);
760				  			end loop;
761						when State_AddTop =>
762							begin_inst <= '1';
763							idim_flag <= '0';
764							pc <= pc + 1;
765
766							stackA <= stackA + stackB;
767						when State_Shift =>
768							begin_inst <= '1';
769							idim_flag <= '0';
770							pc <= pc + 1;
771
772							stackA(wordSize-1 downto 1) <= stackA(wordSize-2 downto 0);
773							stackA(0) <= '0';
774						when State_Pushspadd =>
775							begin_inst <= '1';
776							idim_flag <= '0';
777							pc <= pc + 1;
778
779							stackA <= (others => '0');
780							stackA(maxAddrBitIncIO downto minAddrBit) <= stackA(maxAddrBitIncIO-minAddrBit downto 0)+sp;
781						when State_Neqbranch =>
782							-- branches are almost always taken as they form loops
783							begin_inst <= '1';
784							idim_flag <= '0';
785							sp <= incIncSp;
786		                	if (stackB/=0) then
787		                		pc <= stackA(maxAddrBitIncIO downto 0) + pc;
788		                	else
789		                		pc <= pc + 1;
790		                	end if;
791		                	-- need to fetch stack again.
792							state <= State_Resync;
793		                when State_Mult =>
794							begin_inst <= '1';
795							idim_flag <= '0';
796
797							multA <= stackA;
798							multB <= stackB;
799							state <= State_Mult2;
800						when State_Break =>
801							report "Break instruction encountered" severity failure;
802							break <= '1';
803
804						when State_Loadb =>
805							if mem_busy='0' then
806								begin_inst <= '1';
807								idim_flag <= '0';
808								state <= State_Loadb2;
809
810								mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
811								out_mem_req <= '1';
812							else
813								insn <= insn;
814							end if;
815						when State_Storeb =>
816							if mem_busy='0' then
817								begin_inst <= '1';
818								idim_flag <= '0';
819								state <= State_Storeb2;
820
821								mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
822								out_mem_req <= '1';
823							else
824								insn <= insn;
825							end if;
826
827						when others =>
828--							sp <= (others => DontCareValue);
829							report "Illegal instruction" severity failure;
830							break <= '1';
831					end case;
832
833
834				when State_StoreSP2 =>
835					if mem_busy='0' then
836						mem_addr <= incSp;
837						out_mem_req <= '1';
838						state <= State_Popped;
839					end if;
840				when State_LoadSP2 =>
841					if mem_busy='0' then
842						state <= State_LoadSP3;
843						out_mem_req <= '1';
844						mem_addr <= sp+spOffset+1;
845					end if;
846				when State_LoadSP3 =>
847					if mem_busy='0' then
848						pc <= pc + 1;
849						state <= State_Execute;
850						stackB <= stackA;
851						stackA <= mem_read;
852					end if;
853				when State_AddSP2 =>
854					if mem_busy='0' then
855						pc <= pc + 1;
856						state <= State_Execute;
857						stackA <= stackA + mem_read;
858					end if;
859				when State_Load2 =>
860					if mem_busy='0' then
861						stackA <= mem_read;
862						pc <= pc + 1;
863						state <= State_Execute;
864					end if;
865				when State_Loadb2 =>
866					if mem_busy='0' then
867						stackA <= (others => '0');
868						stackA(7 downto 0) <= mem_read(((wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8);
869						pc <= pc + 1;
870						state <= State_Execute;
871					end if;
872				when State_Storeb2 =>
873					if mem_busy='0' then
874						mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
875						mem_write <= mem_read;
876						mem_write(((wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8) <= stackB(7 downto 0) ;
877						out_mem_req <= '1';
878						mem_we <= '1';
879						pc <= pc + 1;
880						sp <= incIncSp;
881						state <= State_Resync;
882					end if;
883				when State_Fetch =>
884					if mem_busy='0' then
885						if interrupt='1' and inInterrupt='0' and idim_flag='0' then
886							-- We got an interrupt
887							inInterrupt <= '1';
888
889							sp <= decSp;
890							out_mem_req <= '1';
891							mem_we <= '1';
892							mem_addr <= incSp;
893							mem_write <= stackB;
894							stackA <= (others => DontCareValue);
895							stackA(maxAddrBitIncIO downto 0) <= pc;
896							stackB <= stackA;
897
898							pc <= conv_std_logic_vector(32, maxAddrBitIncIo+1); -- interrupt address
899
900			  				report "ZPU jumped to interrupt!" severity note;
901						else
902							mem_addr <= pc(maxAddrBitIncIO downto minAddrBit);
903							out_mem_req <= '1';
904							state <= State_Decode;
905						end if;
906					end if;
907                when State_Mult2 =>
908					state <= State_Mult3;
909                when State_Mult3 =>
910					state <= State_Mult4;
911                when State_Mult4 =>
912					state <= State_Mult5;
913                when State_Mult5 =>
914            		stackA <= multResult3;
915                	state <= State_Mult6;
916                when State_Mult6 =>
917					if mem_busy='0' then
918						out_mem_req <= '1';
919						mem_addr <= incIncSp;
920						sp <= incSp;
921						state <= State_Popped;
922					end if;
923				when State_BinaryOpResult =>
924					if mem_busy='0' then
925						-- NB!!!! we know that the memory isn't busy at this point!!!!
926						out_mem_req <= '1';
927						mem_addr <= incIncSp;
928						sp <= incSp;
929						stackA <= binaryOpResult;
930						state <= State_Popped;
931					end if;
932				when State_Popped =>
933					if mem_busy='0' then
934						pc <= pc + 1;
935						stackB <= mem_read;
936						state <= State_Execute;
937					end if;
938				when others =>
939--					sp <= (others => DontCareValue);
940					report "Illegal state" severity failure;
941					break <= '1';
942			end case;
943		end if;
944	end process;
945
946
947
948end behave;
949