240 likes | 353 Views
Data Stack. Lecture 8.2 A VHDL Forth Core for FPGAs: Sect. 3. FC16 Forth Core. Data Stack. A 32 x 16 Stack. A 32 x 16 Stack Module. stack_ctrl32. entity stack_ctrl is port ( clr: in STD_LOGIC; clk: in STD_LOGIC; push: in STD_LOGIC;
E N D
Data Stack Lecture 8.2 A VHDL Forth Core for FPGAs: Sect. 3
FC16 Forth Core
stack_ctrl32 entity stack_ctrl is port ( clr: in STD_LOGIC; clk: in STD_LOGIC; push: in STD_LOGIC; pop: in STD_LOGIC; we: out STD_LOGIC; amsel: out STD_LOGIC; wr_addr: out STD_LOGIC_VECTOR (4 downto 0); rd_addr: out STD_LOGIC_VECTOR (4 downto 0); full: out STD_LOGIC; empty: out STD_LOGIC ); end stack_ctrl; 00000 wr_addr rd_addr 11111
stack_ctrl32 architecture stack_ctrl_arch of stack_ctrl is signal full_flag, empty_flag: STD_LOGIC; begin stk: process(clr, clk, push, pop, full_flag, empty_flag) variable push_addr, pop_addr: STD_LOGIC_VECTOR(4 downto 0); begin if clr = '1' then push_addr := "11111"; pop_addr := "00000"; empty_flag <= '1'; full_flag <= '0'; wr_addr <= "11111"; rd_addr <= "00000"; full <= full_flag; empty <= empty_flag;
00000 wr_addr rd_addr 11111 stack_ctrl32 elsif clk'event and clk = '1' then if push = '1' then if pop = ‘0' then if full_flag = '0' then push_addr := push_addr - 1; pop_addr := push_addr + 1; empty_flag <= '0'; if push_addr = "11111” then full_flag <= '1'; push_addr := "00000"; end if; end if; else –- write to top of stack (pop_addr) without pushing -- don’t change push_addr and pop_addr end if;
00000 wr_addr rd_addr 11111 stack_ctrl32 elsif pop = '1' then if empty_flag = '0' then pop_addr := pop_addr + 1; if full_flag = '0' then push_addr := push_addr + 1; end if; full_flag <= '0'; if pop_addr = "00000" then empty_flag <= '1'; end if; end if; end if; wr_addr <= push_addr; rd_addr <= pop_addr; end if;
00000 wr_addr rd_addr 11111 stack_ctrl full <= full_flag; empty <= empty_flag; if push = '1' and full_flag = '0' then we <= '1'; else we <= '0'; end if; if push = '1' and pop = ‘1' then amsel <= '1'; else amsel <= '0'; end if; end process stk; end stack_ctrl_arch;
WHYP Data Stack Instructions DUP ( n -- n n ) SWAP ( a b -- b a ) DROP ( a -- ) OVER ( a b -- a b a ) ROT ( a b c -- b c a ) -ROT ( a b c -- c a b ) NIP ( a b -- b ) TUCK ( a b -- b a b ) ROT_DROP ( a b c -- b c ) ROT_DROP_SWAP ( a b c -- c b ) 2DUP ( a b -- a b a b ) Note: 2DUP = OVER OVER
Hex Opcode Name Function Data Stack Instructions 0000 NOP No operation 0001 DUP Duplicate T and push data stack. N <= T; N2 <= N; 0002 SWAP Exchange T and N. T <= N; N <= T; 0003 DROP Drop T and pop data stack. T <= N; N <= N2; 0004 OVER Duplicate N into T and push data stack. T <= N; N <= T; N2 <= N; 0005 ROT Rotate top 3 elements on stack clockwise. T <= N2; N <= T; N2 <= N; 0006 -ROT Rotate top 3 elements on stack counter-clockwise. T <= N; N <= N2; N2 <= T; 0007 NIP Drop N and pop rest of data stack. T is unchanged. N <= N2; 0008 TUCK Duplicate T into N2 and push rest of data stack. N2 <= T; 0009 ROT_DROP Drop N2 and pop rest of data stack. T and N are unchanged. Equivalent to ROT DROP 000A ROT_DROP_SWAP Drop N2 and pop rest of data stack. T and N are exchanged. Equivalent to ROT DROP SWAP
DUP ( n -- n n ) Duplicate T and push data stack. N <= T; N2 <= N; when dup => nload <= '1'; dpush <= '1';
SWAP ( a b -- b a ) Exchange T and N. T <= N; N <= T; when swap => tload <= '1'; nload <= '1'; tsel <= "111";
DROP ( a -- ) Drop T and pop data stack. T <= N; N <= N2; when drop => tload <= '1'; nload <= '1'; tsel <= "111"; nsel <= "01"; dpop <= '1';
OVER ( a b -- a b a ) Duplicate N into T and push data stack. T <= N; N <= T; N2 <= N; when over => tload <= '1'; nload <= '1'; tsel <= "111"; dpush <= '1';
ROT ( a b c -- b c a ) Rotate top 3 elements on stack clockwise. T <= N2; N <= T; N2 <= N; when rot => tload <= '1'; nload <= '1'; tsel <= "110"; dpush <= '1'; dpop <= '1';
-ROT ( a b c -- c a b ) Rotate top 3 elements on stack counter-clockwise. T <= N; N <= N2; N2 <= T; when mrot => tload <= '1'; nload <= '1'; tsel <= "111"; nsel <= "01"; ssel <= '1'; dpush <= '1'; dpop <= '1';
NIP ( a b -- b ) Drop N and pop rest of data stack. T is unchanged. N <= N2; when nip => nload <= '1'; nsel <= "01"; dpop <= '1';
TUCK ( a b -- b a b ) Duplicate T into N2 and push rest of data stack. N2 <= T; when tuck => ssel <= '1'; dpush <= '1';
ROT_DROP ( a b c -- b c ) Drop N2 and pop rest of data stack. T and N are unchanged. Equivalent to ROT DROP when rot_drop => dpop <= '1';
ROT_DROP_SWAP ( a b c -- c b ) Drop N2 and pop rest of data stack. T and N are exchanged. Equivalent to ROT DROP SWAP when rot_drop_swap => tload <= '1'; nload <= '1'; tsel <= "111"; dpop <= '1';