Post on 21-Dec-2015
transcript
The FC16 Forth Core
Lab 7
Module F4.1
ReturnStack
RmuxPmux
PCclrclk
pload
pinc
IRclrclkirload
FC16_control
plus1
R
Tin
Rin
R T
P
Pin
M
M P1
R
M
The FC16Forth Core
clkclr
rpop
rpush
psel rinsel
tsel(2:0)
rload
rdec
rsel
T
icode
E1(15:0)
B(1:4)DataStackclk
clr
dpop
dpush
ssel
nloadnsel
tload
y1(15:0)
T
0 11
1
0
0 2 3Tmux
Funit16
NN2
y(15:0)
y NN2E2E1S
S(1:8)
54 6 7
E2(15:0)
P(15:0)
M(15:0)
clr
clk
T(15:0)
N(15:0)
oe
we
cclk
Fcode(5:0)
digload
ldload
Lab 7
FC16
clk clrT
N
E1
SB
P
M
we
oe
cclk
E2
mclk bn
ProgramROM
P
M DigDisplay
A(3:0) AtoG(6:0)
clk
clrdigload
T
digload
clr
BTN(1:4) SW(1:8)
Lab7main
Hex Opcode Name Function
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 N 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
Data Stack Instructions
Hex Opcode Name Function
0010 + Pop N and add it to T.
0011 - Pop T and subtract it from N.
0012 1+ Add 1 to T
0013 1- Subtract 1 from T
0014 INVERT Complement all bits of T.
0015 AND Pop N1 and AND it to T.
0016 OR Pop N1 and AND it to T.
0017 XOR Pop N1 and AND it to T.
0018 2* Logic shift left T.
0019 U2/ Logic shift right T.
001A 2/ Arithmetic shift right T.
001B RSHIFT Pop T and shift N1 T bits to the right.
001C LSHIFT Pop T and shift N1 T bits to the left.
001D mpp multiply partial product (used for multiplication)
001E shldc shift left and decrement conditionally (used for division)
Funit16 Instructions (fcode = lower 6 bits of opcode)
Code Name Function
0020 TRUE Set all bits in T to ‘1’.
0021 FALSE Clear all bits in T to ‘0’.
0022 NOT0=
TRUE if all bits in T are ‘0’.
0023 0< TRUE if sign bit of T is ‘1’.
0024 U> T <= TRUE if N > T (unsigned), else T <= FALSE
0025 U< T <= TRUE if N < T (unsigned), else T <= FALSE
0026 = T <= TRUE if N = T, else T <= FALSE
0027 U>= T <= TRUE if N >= T (unsigned), else T <= FALSE
0028 U<= T <= TRUE if N1 <= T (unsigned), else T <= FALSE
0029 <> T <= TRUE if N /= T, else T <= FALSE
002A > T <= TRUE if N1 > T (signed), else T <= FALSE
002B < T <= TRUE if N1 < T (signed), else T <= FALSE
002C >= T <= TRUE if N1 >= T (signed), else T <= FALSE
002D <= T <= TRUE if N1 <= T (signed), else T <= FALSE
Funit16 Instructions (cont.) (fcode = lower 6-bits of opcode)
Code Name Function
0030 >R “To-R” Pop T and push it on return stack.
0031 R> “R-from” Pop return stack R and push it into T.
0032 R@ “R-fetch” Copy R to T and push register stack
0033 R>DROP “R-from-drop” Pop return stack R and throw it away
0034 @ Fetch the byte at address T in RAM and load it into T
0035 ! Store the byte in N at the address T. Pop both T and N.
0036 ROM@ Fetch the byte at address T in ROM and load it into T.
0037 S@ Fetch the 8-bit byte from Port S and load it into T.
0038 DIG! Write the 4 hex digits in T to the digit register DigReg
0039 LD! Store T to the LED register LDreg.
Return Stack, Memory Access, and I/O Instructions
Code Name Function
0040 LIT Load inline literal to T and push data stack.
0041 JMP Jump to inline address
0042 JZ Jump if all bits in T are ‘0’
0043 DRJNE Decrement R and jump if R is not zero
0044 CALL Call subroutine
0045 RET Subroutine return
0046 JB1LO Jump if input pin B1 is LO
0047 JB2LO Jump if input pin B2 is LO
0048 JB3LO Jump if input pin B3 is LO
0049 JB4LO Jump if input pin B4 is LO
004A JB1HI Jump if input pin B1 is HI
004B JB2HI Jump if input pin B1 is HI
004C JB3HI Jump if input pin B1 is HI
004D JB4HI Jump if input pin B1 is HI
Literal and Transfer Instructions
Multiplication and Division Instructions
Multiplication
13x11 1313 143 = 8Fh
1101 x1011 1101 1101 100111 0000 100111 1101 10001111
Multiplication
1101 x1011 1101 1101 100111 0000 100111 1101 10001111
11010000101101101101 adsh1101 10011110 adsh
1001111 sh1101 10001111 adsh
MultiplicationUM* ( u1 u2 -- upL upH )
T N
N2
mpp (multiply partial product) if N(0) = 1 then adsh else sh end if;
All other signed and unsigned multiplication can bederived from UM*
: UM* ( u1 u2 - upL upH ) 0 4 FOR mpp NEXT ROT_DROP ;
16 x 16 = 32 Multiply Instruction
: UM* ( u1 u2 - upL upH )
0
16 FOR
mpp
NEXT
ROT_DROP ;
Testing Multiply Instruction
: MAIN ( -- ) BEGIN waitB4 S@ \ get u1LO
waitB4 S@ \ get u1HIwaitB4 S@ \ get u2LOwaitB4 S@ \ get u2HIwaitB4 UM* \ multiplyDIG! \ display upHwaitB4 DIG! \ display upL
AGAIN ;
variable AVector: STD_LOGIC_VECTOR (width downto 0);
variable BVector: STD_LOGIC_VECTOR (width downto 0);
variable CVector: STD_LOGIC_VECTOR (width downto 0);
variable yVector: STD_LOGIC_VECTOR (width downto 0);
variable y_tmp: STD_LOGIC_VECTOR (width-1 downto 0);
variable y2_tmp: STD_LOGIC_VECTOR (width-1 downto 0);
variable yvec0: STD_LOGIC;
AVector := '0' & a;
BVector := '0' & b;
CVector := '0' & c;
y_tmp := false;
y2_tmp := false;
yVector := '0' & false;
begin
when "11110" => -- mpp
if b(0) = '1' then
yVector := AVector + CVector;
else
yVector := AVector;
end if;
y <= yVector(width downto 1);
y2 <= yVector(0) & b(width-1 downto 1);
mpp (multiply partial product) if N(0) = 1 then adsh else sh end if;
T N
N2
Division
1101 100001111010
110100111 0000 01111 1101 00101 0000 0101
13 135 13 05
10
Division 8-bit/4-bit = 4:4
1101 100001111010
110100111 0000 01111 1101 00101 0000 0101
_10000111 1101
numer[8:0]denom[3:0]
If denom < numer[7:4] then overflow (quotient won’t fit in 4 bits)
Let T = numer[8:4] N = numer[3:0] N2 = denom[3:0]
Division 8-bit/4-bit = 4:4
1101 100001111010
110100111 0000 01111 1101 00101 0000 0101
100001110 1101
sllT N
N2
for I in 0 to 3 loop sll T & N; if T[8:4] > N2 then T := T - (0 & N2); N(0) := ‘1’; end if;end loop;
Division 8-bit/4-bit = 4:4
1101 100001111010
110100111 0000 01111 1101 00101 0000 0101
100001110 1101
sllT N
N2
001111110 1101
sub1sll
011111100 1101
sll
001011010 sub1sllrem quot
Division
: UM/MOD ( unumL unumH udenom -- urem uquot )
All other signed and unsigned divisionoperations can be derived as WHYP wordsfrom UM/MOD
TNN2
TN N2
-ROT4 FOR SHLDCNEXT denom quot remROT_DROP_SWAP ;
when "11111" => -- shldc
yVector := a & b(width-1);
y2_tmp := b(width-2 downto 0) & '0';
if yVector > CVector then
yVector := yVector - CVector;
y2_tmp(0) := '1';
end if;
for I in 0 to 3 loop sll T & N; if T[8:4] > N2 then T := T - (0 & N2); N(0) := ‘1’; end if;end loop;
100001110 1101
sllT N
N2
y <= yVector(width-1 downto 0);
y2 <= y2_tmp;
32 / 16 = 16:16 Division
: UM/MOD ( unL unH ud -- ur uq ) -ROT
16 FOR shldc
NEXTROT_DROP_SWAP ;
Testing Divide Instruction
: MAIN ( -- ) BEGIN waitB4 S@ \ get unLLO
waitB4 S@ \ get unLHIwaitB4 S@ \ get unHLO
waitB4 S@ \ get unHHIwaitB4 S@ \ get udLOwaitB4 S@ \ get udHIwaitB4 UM/MOD \ divideDig! \ display uqwaitB4 Dig! \ display ur
AGAIN ;