1% ===================================================================== %
2% 14 June 1989 - modified for HOL88					%
3%									%
4% The following bits are needed to make this proof run in HOL88.	%
5
6set_flag (`sticky`,true);;
7load_library `string`;;
8let EXP = (LIST_CONJ o (map SPEC_ALL) o CONJUNCTS) EXP;;
9let new_definition = SPEC_ALL o new_definition;;
10let new_prim_rec_definition  =
11	LIST_CONJ o (map SPEC_ALL) o CONJUNCTS o new_prim_rec_definition;;
12
13% ===================================================================== %
14% Jeff Joyce, University of Cambridge, 1 November 1988			%
15%									%
16% Specify register-transfer level implementation and functional		%
17% behaviour of a very simple microprocessor.				%
18
19new_theory `tamarack`;;
20
21new_parent `mod`;;
22new_parent `div`;;
23
24new_type_abbrev (`time`,":num");;
25new_type_abbrev (`wire`,":time->bool");;
26new_type_abbrev (`bus`,":time->num");;
27new_type_abbrev (`mem`,":time->num->num");;
28
29let INCn = new_definition (`INCn`,"INCn n a = (a + 1) MOD (2 EXP n)");;
30let SUBn = new_definition (`SUBn`,"SUBn n (a,b) = (a + b) MOD (2 EXP n)");;
31let ADDn = new_definition (`ADDn`,"ADDn n (a,b) = (a + b) MOD (2 EXP n)");;
32
33let Bits = new_definition (
34	`Bits`,
35	"Bits (n,m) w = ((w Div (2 EXP n)) MOD (2 EXP m))");;
36
37let Update = new_definition (
38	`Update`,
39	"Update (s:*->**,x,y) = \x'. (x = x') => y | (s x')");;
40
41let PWR = new_definition (`PWR`,"PWR (w:wire) = !t. w t = T");;
42
43let GND = new_definition (`GND`,"GND (w:wire) = !t. w t = F");;
44
45let AND = new_definition (
46	`AND`,
47	"AND (a:wire,b:wire,out:wire) = !t. out t = a t /\ b t");;
48
49let OR = new_definition (
50	`OR`,
51	"OR (a:wire,b:wire,out:wire) = !t. out t = a t \/ b t");;
52
53let MUX = new_definition (
54	`MUX`,
55	"MUX (cntl:wire,a:bus,b:bus,out:bus) =
56	  !t. out t = (cntl t => b t | a t)");;
57
58let BITS = new_definition (
59	`BITS`,
60	"BITS (n,m) (in:bus,out:bus) = !t. out t = Bits (n,m) (in t)");;
61
62let TNZ = new_definition (
63	`TNZ`,
64	"TNZ (in:bus,flag:wire) = !t. flag t = ~(in t = 0)");;
65
66let HWC = new_definition (`HWC`,"HWC c (b:bus) = !t. b t = c");;
67
68let ADDER = new_definition (
69	`ADDER`,
70	"ADDER n (a:bus,b:bus,out:bus) = !t. out t = ADDn n (a t,b t)");;
71
72let ALU = new_definition (
73	`ALU`,
74	"ALU n (f0:wire,f1:wire,a:bus,b:bus,out:bus) =
75	  !t.
76	    ?w.
77	      out t =
78	        (((f0 t,f1 t) = (T,T)) => w |
79	         ((f0 t,f1 t) = (F,T)) => INCn n (b t) |
80	         ((f0 t,f1 t) = (F,F)) => ADDn n (a t,b t) |
81	                                  SUBn n (a t,b t))");;
82
83let DEL = new_definition (
84	`DEL`,
85	"DEL (in:bus,out:bus) = !t. out (t+1) = in t");;
86
87let REG = new_definition (
88	`REG`,
89	"REG ((w:wire,r:wire,in:bus,bus:bus,out:bus),P) =
90	  !t.
91	    ((out (t+1) = (w t => in t | out t)) /\
92	     (P t ==> r t ==> (bus t = out t)))");;
93
94let MEM = new_definition (
95	`MEM`,
96	"MEM n ((w:wire,r:wire,addr:bus,bus:bus),(P,mem:mem)) =
97	  !t.
98	    (mem (t+1) = (w t => Update (mem t,addr t,bus t) | mem t)) /\
99	    (P t ==> r t ==> (bus t = mem t (addr t)))");;
100
101let CheckCntls = new_definition (
102	`CheckCntls`,
103	"CheckCntls (rmem,rpc,racc,rir,rbuf,P) =
104	  !t.
105	    P t =
106	      ((rmem t)	=> (~(rpc t \/ racc t \/ rir t \/ rbuf t)) |
107	      ((rpc t)	=> (~(racc t \/ rir t \/ rbuf t)) |
108	      ((racc t)	=> (~(rir t \/ rbuf t)) |
109	      ((rir t)	=> (~(rbuf t)) | T))))");;
110
111let DataPath = new_definition (
112	`DataPath`,
113	"DataPath n (
114	  (wmem,rmem,wmar,wpc,rpc,wacc,racc,wir,rir,warg,alu0,alu1,rbuf,
115	   zeroflag,opcode),
116	  (mem,mar,pc,acc,ir,arg,buf)) =
117	  ?P bus addr alu pwr gnd.
118	    CheckCntls (rmem,rpc,racc,rir,rbuf,P) /\
119	    MEM n ((wmem,rmem,addr,bus),(P,mem)) /\
120	    REG ((wmar,gnd,bus,bus,mar),P) /\
121	    BITS (0,n) (mar,addr) /\
122	    REG ((wpc,rpc,bus,bus,pc),P) /\
123	    REG ((wacc,racc,bus,bus,acc),P) /\
124	    TNZ (acc,zeroflag) /\
125	    REG ((wir,rir,bus,bus,ir),P) /\
126	    BITS (n,3) (ir,opcode) /\
127	    REG ((warg,gnd,bus,bus,arg),P) /\
128	    ALU (n+3) (alu0,alu1,arg,bus,alu) /\
129	    REG ((pwr,rbuf,alu,bus,buf),P) /\
130	    PWR pwr /\
131	    GND gnd");;
132
133let Cntls = new_definition (
134	`Cntls`,
135	"Cntls (tok1,tok2) =
136	  ((tok2 = `wmem`),
137	   (tok1 = `rmem`),
138	   (tok2 = `wmar`),
139	   (tok2 = `wpc`),
140	   (tok1 = `rpc`),
141	   (tok2 = `wacc`),
142	   (tok1 = `racc`),
143	   (tok2 = `wir`),
144	   (tok1 = `rir`),
145	   (tok2 = `warg`),
146	   (tok2 = `sub`),
147	   (tok2 = `inc`),
148	   (tok1 = `rbuf`))");;
149
150let NextMpc = new_definition (
151	`NextMpc`,
152	"NextMpc (tok,addr:num) =
153	  (tok = `jop`) => ((T,F),addr) |
154	  (tok = `jnz`) => ((F,T),addr) |
155	  (tok = `jmp`) => ((T,T),addr) |
156			   ((F,F),addr)");;
157
158let Microcode = new_definition (
159	`Microcode`,
160	"Microcode n =
161	  ((n = 0)  => (Cntls (`rpc`,`wmar`),  NextMpc (`inc`,0))  |
162	   (n = 1)  => (Cntls (`rmem`,`wir`),  NextMpc (`inc`,0))  |
163	   (n = 2)  => (Cntls (`rir`,`wmar`),  NextMpc (`jop`,0))  |
164	   (n = 3)  => (Cntls (`none`,`none`), NextMpc (`jnz`,10)) | % JZR %
165	   (n = 4)  => (Cntls (`rir`,`wpc`),   NextMpc (`jmp`,0))  | % JMP %
166	   (n = 5)  => (Cntls (`racc`,`warg`), NextMpc (`jmp`,12)) | % ADD %
167	   (n = 6)  => (Cntls (`racc`,`warg`), NextMpc (`jmp`,13)) | % SUB %
168	   (n = 7)  => (Cntls (`rmem`,`wacc`), NextMpc (`jmp`,10)) | % LD %
169	   (n = 8)  => (Cntls (`racc`,`wmem`), NextMpc (`jmp`,10)) | % ST %
170	   (n = 9)  => (Cntls (`none`,`none`), NextMpc (`inc`,0))  | % NOP %
171	   (n = 10) => (Cntls (`rpc`,`inc`),   NextMpc (`inc`,0))  | % NOP %
172	   (n = 11) => (Cntls (`rbuf`,`wpc`),  NextMpc (`jmp`,0))  |
173	   (n = 12) => (Cntls (`rmem`,`add`),  NextMpc (`jmp`,14)) |
174	   (n = 13) => (Cntls (`rmem`,`sub`),  NextMpc (`inc`,0))  |
175	   (n = 14) => (Cntls (`rbuf`,`wacc`), NextMpc (`jmp`,10)) |
176	               (Cntls (`none`,`none`), NextMpc (`jmp`,0)))");;
177
178let miw_ty = hd (tl (snd (dest_type (type_of "Microcode"))));;
179
180let ROM = new_definition (
181	`ROM`,
182	"ROM contents (addr:bus,data:time->^miw_ty) =
183	  !t. data t = contents (addr t)");;
184
185let Decoder = new_definition (
186	`Decoder`,
187	"Decoder (
188	  miw:time->^miw_ty,test0,test1,addr,
189	  wmem,rmem,wmar,wpc,rpc,wacc,racc,wir,rir,warg,alu0,alu1,rbuf) =
190	  !t.
191	    ((wmem t,rmem t,wmar t,wpc t,rpc t,wacc t,
192	      racc t,wir t,rir t,warg t,alu0 t,alu1 t,rbuf t),
193	     ((test0 t,test1 t),addr t)) =
194	    miw t");;
195
196let MpcUnit = new_definition (
197	`MpcUnit`,
198	"MpcUnit (test0,test1,zeroflag,opcode,addr,mpc) =
199	  ?w1 w2 const0 const1 const3 b1 b2 b3 b4 b5.
200	    AND (test1,zeroflag,w1) /\
201	    OR (test0,w1,w2) /\
202	    MUX (test1,opcode,addr,b1) /\
203	    MUX (w2,mpc,b1,b2) /\
204	    HWC 0 const0 /\
205	    HWC 3 const3 /\
206	    MUX (test1,const3,const0,b3) /\
207	    HWC 1 const1 /\
208	    MUX (w2,const1,b3,b4) /\
209	    ADDER 4 (b2,b4,b5) /\
210	    DEL (b5,mpc)");;
211
212let CntlUnit = new_definition (
213	`CntlUnit`,
214	"CntlUnit (
215	  (zeroflag,opcode,
216	   wmem,rmem,wmar,wpc,rpc,wacc,racc,wir,rir,warg,alu0,alu1,rbuf),
217	  mpc) =
218	  ?miw test0 test1 addr.
219	    ROM Microcode (mpc,miw) /\
220	    Decoder (
221	      miw,test0,test1,addr,
222	      wmem,rmem,wmar,wpc,rpc,wacc,racc,wir,rir,warg,alu0,alu1,rbuf) /\
223	    MpcUnit (test0,test1,zeroflag,opcode,addr,mpc)");;
224
225let Tamarack = new_definition (
226	`Tamarack`,
227	"Tamarack n (mpc,mem,mar,pc,acc,ir,arg,buf) =
228	  ?zeroflag opcode
229	   wmem rmem wmar wpc rpc wacc racc wir rir warg alu0 alu1 rbuf.
230	    CntlUnit (
231	      (zeroflag,opcode,
232	       wmem,rmem,wmar,wpc,rpc,wacc,racc,wir,rir,warg,alu0,alu1,rbuf),
233	      (mpc)) /\
234	    DataPath n (
235	      (wmem,rmem,wmar,wpc,rpc,wacc,racc,wir,rir,warg,alu0,alu1,rbuf,
236	       zeroflag,opcode),
237	      (mem,mar,pc,acc,ir,arg,buf))");;
238
239let Inst = new_definition (
240	`Inst`,
241	"Inst n (mem:num->num,pc) = mem (pc MOD (2 EXP n))");;
242
243let Opc = new_definition (
244	`Opc`,
245	"Opc n inst = ((inst Div (2 EXP n)) MOD (2 EXP 3))");;
246
247let Addr = new_definition (
248	`Addr`,
249	"Addr n inst = (inst MOD (2 EXP n))");;
250
251let NextState = new_definition (
252	`NextState`,
253	"NextState n (mem,pc,acc) =
254	  let inst = Inst n (mem,pc) in
255	  let opc = Opc n inst in
256	  let addr = Addr n inst in
257	  ((opc = 0) => (mem,((acc = 0) => inst | (INCn (n+3) pc)),acc) |
258	   (opc = 1) => (mem,inst,acc) |
259	   (opc = 2) => (mem,(INCn (n+3) pc),(ADDn (n+3) (acc,mem addr))) |
260	   (opc = 3) => (mem,(INCn (n+3) pc),(SUBn (n+3) (acc,mem addr))) |
261	   (opc = 4) => (mem,(INCn (n+3) pc),mem addr) |
262	   (opc = 5) => (Update (mem,addr,acc),(INCn (n+3) pc),acc) |
263 	                (mem,(INCn (n+3) pc),acc))");;
264
265let Behaviour = new_definition (
266	`Behaviour`,
267	"Behaviour n (mem,pc,acc) =
268	  !t.
269	    (mem (t+1),pc (t+1),acc (t+1)) =
270	      NextState n (mem t,pc t,acc t)");;
271
272close_theory ();;
273