NameDateSize

..30-Nov-202068

AES/H25-Jul-20196

booth/H25-Jul-20196

compile.sigH A D25-Jul-201940.7 KiB

compile.smlH A D25-Jul-2019103.5 KiB

compileScript.smlH A D25-Jul-201938 KiB

composeScript.smlH A D25-Jul-201991.5 KiB

devScript.smlH A D25-Jul-201968.8 KiB

dff/H25-Jul-20197

doc/H25-Jul-20193

Fact.mlH A D25-Jul-20196.3 KiB

Fact32/H25-Jul-201910

FactScript.smlH A D25-Jul-20199.7 KiB

HolmakefileH A D25-Jul-201914

hwdefnH A D25-Jul-20198.8 KiB

inlineCompile.smlH A D25-Jul-201913.6 KiB

READMEH A D25-Jul-201929.7 KiB

sw/H25-Jul-201944

sw2/H25-Jul-201930

vsynth.smlH A D25-Jul-201933.3 KiB

README

1
2===============================================================================
3== This directory contains Juliano's HOL files modified by MJCG & KXS        ==
4== [see end of this file for version history]                                ==
5===============================================================================
6
7composeScript.sml ......... definition of devices and their composition
8devScript.sml.............. definition and theorems on liveness
9compileScript.sml ......... definitions and theorems to support compiler
10compile.sml ............... convert to combinators and compile to circuits
11vsynth.sml ................ convert a circuit made with MAKE_CIRCUIT to Verilog
12FactScript.sml ............ synthesise naive factorial and dump Verilog
13Fact.ml ................... synthesise and simulate factorial and run gtkwave
14Fact32 .................... directory with word32 examples (including factorial)
15dff ....................... Melham's temporal abstraction theory
16Holmakefile ............... instructions for Holmake
17
18*******************************************************************************
19There are six levels of abstraction:
20
21 S: Source       (subset of TFL)
22 I: Intermediate (source combinators Atm, Seq, Par, Ite, Rec)
23 D: Devices      (handshake hardware combinators: ATM, SEQ, PAR, ITE, REC)
24 N: Netlist      (abstract device predicates: unclocked DEL, DELT, DELT and DFF)
25 C: Circuit      (clocked synchronous device predicates: Dtype, Dff)
26 V: Verilog      (netlist pretty-printed into Verilog)
27
28The main user-level functions are hwDefine, cirDefine, REFINE_ALL and
29MAKE_NETLIST for creating hardware, refining it and then creating a
30netlist representation, and MAKE_CIRCUIT and MAKE_VERILOG for creating
31Verilog HDL output.
32*******************************************************************************
33
34To make generated hardware devices a bit more readable, the following
35(experimental) infixes are now defined in composeScript.sml
36
37   set_fixity ";;" (Infixl 750); overload_on (";;", ``SEQ``)
38   set_fixity "||" (Infixl 650); overload_on ("||", ``PAR``)
39
40The bus concatenation operator <> is defined by:
41
42   |- !f g. f <> g = (\t. (f t,g t))
43
44Abstract device netlists are generated by MAKE_NETLIST and contain the
45following combinational components:
46
47  |- COMB f (inp,out)      = !t. out t = f (inp t)
48  |- CONSTANT c out        = !t. out t = c
49  |- MUX (sel,in1,in2,out) = !t. out t = (if sel t then in1 t else in2 t
50  |- AND (in1,in2,out)     = !t. out t = in1 t /\ in2 t
51  |- OR (in1,in2,out)      = !t. out t = in1 t \/ in2 t
52  |- NOT (inp,out)         = !t. out t = ~inp t
53
54and sequential components (registers):
55
56  |- DEL (inp,out) = !t. out(t+1) = inp t
57  |- DELT(inp,out) = (out 0 = T) /\ !t. out(t+1) = inp t
58  |- DELF(inp,out) = (out 0 = F) /\ !t. out(t+1) = inp t
59  |- DFF (d,clk,q) = !t. q(t+1) = if POSEDGE clk (t+1) then d(t+1) else q t
60
61where:
62
63  |- POSEDGE s t = if t=0 then F else ~s(t-1) /\ s t
64
65The sequential components are then implemented in terms of clocked reqisters:
66
67  |- Dtype  (ck,d,q) = !t. q (t+1) = (if Rise ck t then d t else q t)
68  |- DtypeT (ck,d,q) = (q 0 = T) /\ Dtype(ck,d,q)
69  |- DtypeF (ck,d,q) = (q 0 = F) /\ Dtype(ck,d,q)
70
71where:
72
73 |- Rise s t = ~(s t) /\ s(t+1)
74
75The implementation of DEL, DELT, DELF, DFF in terms of Dtype, DtypeT
76and DtypeF involves a temporal abstraction, since Dtype and the
77flip-flops are edge-triggered on a clock, but DEL, DELT, DELF, DFF are
78not.  The refinement from the unclocked level of abstraction to the
79clocked circuit level is implemented formally using infrastructure
80from Melham's theory of temporal abstraction in the directory dff:
81
82Using Melham's dff theories it is proved in compileScript.sml that:
83
84 |- InfRise clk ==> !d q. Dtype (clk,d,q)  ==> DEL (d at clk,q at clk)
85 |- InfRise clk ==> !d q. DtypeT (clk,d,q) ==> DELT (d at clk,q at clk)
86 |- InfRise clk ==> !d q. DtypeF (clk,d,q) ==> DELF (d at clk,q at clk)
87
88Where
89
90 |- Inf sig = !t. ?t'. t < t' /\ sig t'        (* sig true infinitely often) *)
91 |- InfRise clk = Inf(Rise clk)      (* clk has infinitely many rising edges *)
92 |- s at clk = s when (Rise clk)         (* s sampled at rising edges of clk *)
93
94The term ``(s when P) n`` gives the value of s at the time when P is
95true on the n-th occasion (``when`` is defined using the choice
96operator in dff/tempabsScript.sml). Thus ``s at clk`` is ``s`` sampled
97at rising edges of ``clk`` (the sampling being just before the clock rises).
98Note that ``s at clk`` is similar to ``s@clk`` in PSL.
99
100Clocked synchronous circuits using combinational logic and the
101registers Dtype and Dff are synthesised using MAKE_CIRCUIT.
102
103*******************************************************************************
104
105
106hwDefine : term frag list -> thm * thm * thm
107--------------------------------------------
108
109Single entrypoint for definitions where proof of termination will
110succeed. Allows measure function to be indicated in same quotation as
111definition, or not.
112                                                                         
113    hwDefine lib `(eqns) measuring f`                                    
114                                                                         
115will use f as the measure function and attempt automatic termination
116proof. If successful, returns (|- eqns, |- ind, |- dev) 
117
118NB. the recursion equations must be parenthesized; otherwise, strange
119    parse errors result. Also, the name of the defined function must be
120    alphanumeric.
121                                                                         
122One can also not mention the measure function, as in Define:             
123                                                                         
124    hwDefine `eqns`                                                  
125                                                                         
126which will accept either non-recursive or recursive specifications. It
127returns a triple (|- eqns, |- ind, |- dev) where the ind theorem
128should be ignored (it will be boolTheory.TRUTH).
129
130The result of a call to hwRefine is added to the front of a global
131reference hwDefineLib, which is accessed by REFINE_ALL.
132
133See FactScript.sml for examples.
134
135REFINE: (term -> thm) -> thm -> thm
136-----------------------------------
137 
138The first argument of REFINE is a "refine function", refine say,
139which maps a term representing a circuit, <circuit> say, to a theorem
140
141   |- <circuit'> ===> <circuit>
142
143where ``===>`` is defined by:
144
145   |- P ===> Q  =  !x. P x ==> Q x.
146
147and <circuit'> is a term representing the result of refining <circuit>
148with the function refine.
149
150Evaluating
151
152   REFINE refine (|- <circuit> ===> Dev f)
153
154applies refine to <circuit> to get
155
156   |- <circuit'> ===> <circuit>
157
158and then uses transitivity of ===> (DEV_IMP_TRANS) to deduce:
159
160   |- <circuit'> ===> Dev f
161
162Two useful refine functions are ATM_REFINE and LIB_REFINE.
163
164
165ATM_REFINE : term -> thm
166------------------------
167
168This maps ``DEV f`` to |- ATM f ===> DEV f
169
170
171LIB_REFINE : thm list -> term -> thm
172------------------------------------
173
174Evaluating
175
176   LIB_REFINE
177    [|- <circuit> ===> DEV f1,
178     |- <circuit> ===> DEV f2
179     ...
180     |- <circuit> ===> DEV fn]
181    ``DEV fi``
182
183returns the first theorem |- <circuit> ===> DEV fi that it finds in
184the supplied list (i.e. the supplied library). Fails if no refinement
185theorem found.
186
187Refinement functions (analogously to conversions and tactics) can be
188combined using combinators THENR, ORELSER, REPEATR, DEPTHR. 
189
190
191THENR : (term -> thm) * (term -> thm) -> (term -> thm)
192------------------------------------------------------
193
194Combines refinements sequentially.
195
196
197ORELSER : (term -> thm) * (term -> thm) -> (term -> thm)
198--------------------------------------------------------
199
200Tries first refinement and if that fails tries the second one.
201
202REPEATR : (term -> thm) -> term -> thm
203--------------------------------------
204
205Repeates a refinement until no change. Will fail if the refinement
206being repeated fails.
207
208ALL_REFINE: term -> thm
209-----------------------
210
211ALL_REFINE tm evaluatges to the identity refinement |- tm ===> tm
212
213DEPTHR : (term -> thm) -> (term -> thm)
214---------------------------------------------
215
216Scans through a term representing a circuit applying the supplied
217refinement function to each subterm of the form ``DEV f`` and 
218either generating
219
220 |- DEV g ===> DEV f
221
222if the refinement function returns this, or, if the refinement
223function fails:
224
225 |- DEV f ===> DEV f
226
227A refined circuit is then build up using the "monotonicity" theorems:
228
229  SEQ_DEV_IMP =
230   |- !P1 P2 Q1 Q2.
231       P1 ===> Q1 /\ P2 ===> Q2
232       ==>
233       (SEQ P1 P2 ===> SEQ Q1 Q2)
234
235  PAR_DEV_IMP =
236   |- !P1 P2 Q1 Q2.
237       P1 ===> Q1 /\ P2 ===> Q2
238       ==>
239       (PAR P1 P2 ===> PAR Q1 Q2)
240
241  ITE_DEV_IMP =
242   |- !P1 P2 P3 Q1 Q2 Q3.
243       P1 ===> Q1 /\ P2 ===> Q2 /\ P3 ===> Q3
244       ==>
245       (ITE P1 P2 P3 ===> ITE Q1 Q2 Q3)
246
247  REC_DEV_IMP =
248   |- !P1 P2 P3 Q1 Q2 Q3.
249       P1 ===> Q1 /\ P2 ===> Q2 /\ P3 ===> Q3
250       ==>
251       (REC P1 P2 P3 ===> REC Q1 Q2 Q3)
252
253  PRECEDE_DEV_IMP
254  |- !f P Q. P ===> Q ==> PRECEDE f P ===> PRECEDE f Q 
255
256Note that "DEPTHR refine" should never fail.
257
258REFINE: thm -> thm
259------------------
260
261Refine using definitions in hwDefineLib and then convert all remaining
262DEVs to ATMs. The definition is:
263
264  fun REFINE_ALL th =
265   REFINE
266    (REPEATR
267      (DEPTHR
268        (LIB_REFINE(map #3 (!hwDefineLib))
269          ORELSER ATM_REFINE
270          ORELSER ALL_REFINE)))
271    th;
272
273
274add_combinational : string list -> unit
275---------------------------------------
276
277Add a list of constant names to the constants that are implemented as
278combinational by the compiler. The definition is:
279
280 fun add_combinational l = 
281  (combinational_constants := union l (!combinational_constants)); 
282
283The initial list of combinational constant names (i.e. the initial
284value of the reference combinational_constants) is:
285
286  ["T","F","/\\","\\/","~",",","o","CURRY","UNCURRY","COND",
287   "FST","SND","=","Seq","Par","Ite","0","NUMERAL","BIT1","BIT2","ZERO",
288   "+","-"];
289
290
291is_combinational : term -> bool
292-------------------------------
293
294Test whether a terms is a combinational function of its free variables
295(i.e. is built up using only combinational constants).
296
297AddUnop : string * (term * string) -> unit
298------------------------------------------
299
300Evaluating
301
302  AddUnop("<component name>", (``<HOL operator>``, "<Verilog operator>"))
303
304defines a HOL component and a corresponding Verilog module and adds
305these to the synthesis engine. Currently only types ``:bool``,
306``:num`` and ``:word<n>`` are supported; ``:num`` is converted to
307Verilog words of width [31:0] (and a warning is issued, since this is
308in general invalid). Example:
309
310 AddUnop  ("NOT32", (``$~:word32->word32`` , "~"));
311
312If one doesn't intend to generate Verilog, then just give an arbitrary
313string as the Verilog operator (invoking PRINT_VERILOG will then print
314a module that uses this string, but you will only get an error when
315the Verilog is used, e.g. a simulation is attempted).
316
317
318AddBinop : string * (term * string) -> unit
319-------------------------------------------
320
321Evaluating
322
323  AddBinop
324   ("<component name>",
325    (``<uncurried HOL binary operator>``, "<Verilog operator>"))
326
327defines a HOL component and a corresponding Verilog module and adds
328these to the synthesis engine. Currently only types ``:bool``,
329``:num`` and ``:word<n>`` are supported; ``:num`` is converted to
330Verilog words of width [31:0] (and a warning is issued, since this is
331in general invalid). Examples:
332
333 AddBinop ("ADD",     (``UNCURRY $+ : num#num->num``,           "+"))
334 AddBinop ("SUB",     (``UNCURRY $- : num#num->num``,           "-"))
335
336 AddBinop ("ADD32",   (``UNCURRY $+ : word32#word32->word32``,  "+"));
337 AddBinop ("SUB32",   (``UNCURRY $- : word32#word32->word32``,  "-"))
338
339 AddBinop ("LESS32",  (``UNCURRY $< : word32#word32->bool``,    "<"));
340 AddBinop ("EQ32",    (``UNCURRY $= : word32#word32->bool``,    "=="))
341
342If one doesn't intend to generate Verilog, then just give an arbitrary
343string as the Verilog operator (invoking PRINT_VERILOG will then print
344a module that uses this string, but you will only get an error when
345the Verilog is used, e.g. a simulation is attempted).
346
347
348MAKE_NETLIST : thm -> thm
349-------------------------
350
351Evaluating
352
353 MAKE_NETLIST (|- <device> ===> DEV f)
354
355unfolds <device> using the definitions of ATM, SEQ, PAR, ITE and REC
356and normalises the resulting term into a form, <netlist> say,
357corresponding to a netlist, and returns
358
359 |- <netlist> 
360    ==> 
361    DEV f (load,(inp1<>...<>inpm),done,(out1<>...<>outn))
362
363
364MAKE_CIRCUIT : thm -> thm
365-------------------------
366
367Evaluating
368
369 MAKE_CIRCUIT (|- <device> ===> DEV f)
370
371unfolds <device> into a netlist, then replaces DFF by an
372implementation in terms of DEL and DELT, and then, using Melham's
373temporal abstraction theory in dff, refines any unclocked DEL, DELT
374and DELF to clocked Dtype and Dff, and returns:
375
376 |- InfClock clk
377    ==>
378    <circuit> 
379    ==> 
380    DEV f (load at clk,
381           (inp1<>...<>inpm) at clk,
382           done at clk,
383           (out1<>...<>outn) at clk)
384
385See FactScript.sml for examples (e.g. FACT_cir).
386
387
388cirDefine : term frag list -> thm * thm * thm
389--------------------------------------------
390
391Invoke hwDefine and then apply MAKE_CIRCUIT and REFINE_ALL to the device:
392
393fun cirDefine qdef =
394 let val (def,ind,dev) = hwDefine qdef
395 in
396  (def, ind, MAKE_CIRCUIT(REFINE_ALL dev))
397 end;
398
399
400PRINT_VERILOG : thm -> unit
401---------------------------
402
403Evaluating
404
405 PRINT_VERILOG
406  (|- InRise clk 
407      ==>
408      (?v0 .... vn. <circuit>)
409      ==>
410      DEV fun (load at clk,
411               (inp1 <> ... <> inpu) at clk,
412               done at clk,
413               (out1 <> ... <> outv) at clk))
414
415creates a module called fun that has the definitions of the modules
416used in <circuit>, and prints it and the definitions it needs to
417fun.vl.
418
419The header is:
420
421 module fun (clk,load,inp1,...,inpu,done,out1,...,outv);
422  input  clk,load;
423  input  [<size>:0] inp1,inp2;
424  output done;
425  output [<size>:0] out;
426  wire   clk,done;
427
428where <size> is the appropriate width computed from the types.  The
429internal variables v0, ... ,vn are declared to be wires of appropriate
430widths (computed from their types).
431
432Types ``:num`` are converted to Verilog wires or registers of width
433[31:0], which is not in general valid. When such a conversion occurs,
434a warning like:
435
436 Warning: type of inp is ``:num``, but is compiled to [31:0].
437
438is printed. These warnings can be suppressed by evaluating:
439
440 numWarning := false;
441
442(the ML reference numWarning has a default of true).
443
444
445SIMULATE : thm -> (string * string) list -> unit
446------------------------------------------------
447
448If thm is:
449
450  |- InRise clk 
451      ==>
452      (?v0 .... vn. <circuit>)
453      ==>
454      DEV fun (load at clk,
455               (inp1 <> ... <> inpu) at clk,
456               done at clk,
457               (out1 <> ... <> outv) at clk)
458
459the evaluating:
460
461 SIMULATE thm [("inp1","val1"),...,("inpn","valn")]
462
463dumps Verilog using 
464
465 PRINT_SIMULATION thm (!period_default) [("inp1","val1"),...,("inpn","valn")]
466
467(see below). It then runs a Verilog simulator on fun.vl and then calls
468a waveform viewer on fun.vcd.
469
470Currently iverilog (Icarus Verilog:
471http://www.icarus.com/eda/verilog/) and cver (GPL Cver:
472http://www.pragmatic-c.com/gpl-cver/) are supported as Verilog
473simulators and gtkwave (GTKWave:
474ftp://ftp.cs.man.ac.uk/pub/amulet/balsa/other-software/gtkwave-2.0.0pre5.tar.gz)
475and dinotrace (which comes with GPS Cver) as waveform viewers.
476
477GPS Cver and dinotrace are particularly easy to install, and are now
478the default.  To install them, connect to examples/dev and execute:
479
480 wget http://www.pragmatic-c.com/gpl-cver/downloads/gplcver-2.10c.linux.bin.tar.bz2;
481 bunzip2 gplcver-2.10c.linux.bin.tar.bz2;
482 tar -xf gplcver-2.10c.linux.bin.tar
483
484which should create a directory gplcver-2.10c.linux.bin.
485
486SIMULATE should then just work. Test by evaluating "use Fact.ml;" in hol,
487which should launch dinotrace showing a trace of FACT 4 being computed.
488
489You can change the default clock period, which is held in a reference
490
491 val period_default   = ref 5;
492
493To change the default simulator and viewer change the references
494verilog_simulator and waveform_viewer. For example, to change to
495iverilog and gtkwave do:
496
497 val verilog_simulator = ref iverilog;
498 val waveform_viewer   = ref gtkwave;
499
500The executables are held in references, which have default values:
501
502 val iverilog_path   = ref "/usr/bin/iverilog";
503 val vvp_path        = ref "/usr/bin/vvp";
504 val gtkwave_path    = ref "/usr/bin/gtkwave -a";
505 val cver_path       = ref "./gplcver-2.10c.linux.bin/bin/cver";
506 val dinotrace_path  = ref "./gplcver-2.10c.linux.bin/bin/dinotrace";
507
508Note that cver_path and dinotrace_path are correct if the installation
509described above is performed.
510
511
512PRINT_SIMULATION : thm -> int -> (string * string) list -> unit
513---------------------------------------------------------------
514
515Evaluating
516
517 PRINT_SIMULATION thm period stimulus
518 
519prints both the Verilog corresponding to thm (see PRINT_VERILOG) and
520then adds a clock and a module Main containing an instance of the
521clock and an instance of the module generated from thm.
522
523The instance of Clock is created with time between edges as specified
524by the parameter period (so really period is 2*period).
525
526The clock line clk and the handshake completion line done are declared
527to be boolean wires. 
528
529The input load is declared to be a boolean register and the inputs
530inp1, ... ,inpu are declared to be registers of the appropriate width.
531
532A dumpfile called "file.vcd" is created. If the reference variable
533dump_all_flag is false (the default) then only changes to clk, load,
534and signals inp1, ... ,inpu, done, out1, ... ,outv are declared to
535have their changes dumped to the VCD file. If dump_all_flag is true,
536then changes to all variables are dumped.
537
538The input variables are driven according to the parameter stimulus,
539which is an ML list of tuples of the form:
540
541 [("inp1",val),...,("inpu",val)]
542
543where each input is driven with the supplied value (a string that
544prints to a valid Verilog expression).
545
546I am using Icarus Verilog for simulation
547(http://www.icarus.com/eda/verilog/) and GTKWave
548(http://www.cs.man.ac.uk/apt/tools/gtkwave/) for viewing VCD files.
549Both are public domain and seem to work.
550
551
552*******************************************************************************
553
554Auxiliary functions of interest include the following.
555
556Convert : thm -> thm
557--------------------
558
559Convert (|- f x = e) returns a theorem |- f = p, where p is a
560combinatory expression built from the combinators Seq, Par and Ite.
561
562
563RecConvert: : thm -> thm -> thm
564-------------------------------
565
566RecConvert (|- f x = if f1 x then f2 x else f(f3 x)) (|- TOTAL(f1,f2,f3))
567returns a theorem
568
569 |- f = Rec(p1,p2,p3)
570
571where p1, p2 and p3 are combinatory expressions built from the
572combinators Seq, Par and Ite.
573
574A term PRECEDE f d represents a device d preceded by combinational
575logic and a term FOLLOW d f represents a device d followed by
576combinational logic. 
577
578  |- PRECEDE f d =
579      (\(load,inp,done,out). ?v. COMB f (inp,v) /\ d(load,v,done,out))
580
581  |- FOLLOW d f =
582      (\(load,inp,done,out). ?v. d(load,inp,done,v) /\ COMB f (v,out))
583
584The function f representing the combinational logic must only contain
585constants declared combinational by having their names included in the
586ML assignable list "combinational_constants".
587
588Currently PRECEDE and FOLLOW are eliminated when generating netlists,
589but they may appear in the output of the compiler (see the
590CompileConvert example below).
591
592
593CompileProg : thm list -> term -> thm
594-------------------------------------
595
596CompileProg takes a program and a constant defined in the program
597
598 CompileProg : thm list -> term -> thm
599               --------    ----
600               program   constant
601
602When the compiler encounters a function f that isn't an application of
603Seq, Par or Ite, then DEV f is generated. It is assumed this
604will subsequently be refined to hardware (see Refine).
605
606Compile : thm -> thm
607--------------------
608
609Compile (|- c = e)  =  CompileProg [|- c = e] ``c``
610
611
612CompileConvert : thm -> thm
613---------------------------
614
615Converts a non-recursive equation to combinators and then compiles to
616a device implementation.
617
618Example: 
619
620 Fact;
621 > val it = |- !n. Fact n = SND (FactIter (n,1)) : thm
622
623 - CompileConvert Fact;
624 > val it =
625     |- FOLLOW (PRECEDE (Par (\n. n) (\n. 1)) (DEV FactIter)) SND 
626        ===>
627        DEV Fact : thm
628
629
630RecCompileConvert : thm -> thm -> thm
631-------------------------------------
632
633Converts a recursive equation to combinators and then compiles to a
634device implementation. Needs a totality theorem (user-supplied as third
635argument).
636
637Example:
638
639- val FactIter =
640    |- FactIter (n,acc) =
641       (if n = 0 then (n,acc) else FactIter (n - 1,n * acc))
642
643- val FactIter_TOTAL =
644    |- TOTAL
645         ((\(n,acc). n = 0),(\(n,acc). (n,acc)),(\(n,acc). (n - 1,n * acc)))
646
647 - RecCompileConvert FactIter FactIter_TOTAL;
648 > val it =
649     |- REC(FOLLOW (DEV (\(n,acc). n) || DEV (\(n,acc). 0)) (UNCURRY $=))
650           (DEV (\x. x))
651           (DEV (\x. FST x - 1) || PRECEDE (\x. x) (DEV (UNCURRY $*)))
652        ===>
653        DEV FactIter
654
655
656COMB_SYNTH_CONV : term -> thm
657-----------------------------
658
659One step of conversion of
660
661 ``COMB 
662    (\(i1,...,im). (<term1>,...,<termn>) 
663    (inp1 <> ... <> inpm, out1 <> .... outn)``
664
665to a netlist.
666
667Example:
668
669- COMB_SYNTH_CONV 
670   ``COMB (\(m,n,p). (m-p, SUC(m+n+(p-1)))) (in1<>in2<>in3,out1<>out2)``;
671> val it =
672    |- COMB (\(m,n,p). (m - p,SUC (m + n + (p - 1))))
673         (in1 <> in2 <> in3,out1 <> out2) =
674       COMB (\(m,n,p). m - p) (in1 <> in2 <> in3,out1) /\
675       COMB (\(m,n,p). SUC (m + n + (p - 1))) (in1 <> in2 <> in3,out2) : thm
676
677To completely convert to a netlist COMB_SYNTH_CONV needs to be
678iterated. Example:
679
680- REDEPTH_CONV COMB_SYNTH_CONV 
681   ``COMB (\(m,n,p). (m-p, SUC(m+n+(p-1)))) (in1<>in2<>in3,out1<>out2)``;
682> val it =
683    |- COMB (\(m,n,p). (m - p,SUC (m + n + (p - 1))))
684         (in1 <> in2 <> in3,out1 <> out2) =
685       (?v709 v710.
686          (v709 = in1) /\ (v710 = in3) /\
687          COMB (UNCURRY $-) (v709 <> v710,out1)) /\
688       ?v711.
689         (?v712 v713.
690            (?v714 v715.
691               (v714 = in1) /\ (v715 = in2) /\
692               COMB (UNCURRY $+)
693                 (v714 <> v715,v712)) /\
694            (?v716 v717.
695               (v716 = in3) /\ CONSTANT 1 v717 /\
696               COMB (UNCURRY $-)
697                 (v716 <> v717,v713)) /\
698            COMB (UNCURRY $+)
699              (v712 <> v713,v711)) /\
700         COMB SUC (v711,out2) : thm
701
702Note that the redundant variables are pruned by MAKE_NETLIST and also,
703for readability, the example above uses ``v709`` but COMB_SYNTH_CONV
704actually generates ``%%genvar%%709`.
705
706COMB_SYNTH_CONV may print out some diagnostic stuff if it fails to
707prove certain subgoals (though it may nevertheless still produce
708something reasonable).  This output can be switched off by setting the
709ML reference "if_print_flag" to false.
710
711
712=============================================================================== 
713====== ML definitions and commands to define 32-bit bitwise exclusive-or ======
714=============================================================================== 
715
716(*****************************************************************************)
717(* The sources have lots of cut-and-paste-and-tweak style repetition for the *)
718(* various combinational components (NOT, AND, OR, MUX, ADD, SUB, LESS, EQ). *)
719(*                                                                           *)
720(* The functions AddUnop and AddBinop cope with some of the repetition,      *)
721(* but what follows might also be useful documentation.                      *)
722(*                                                                           *)
723(* Here are the steps currently needed to add a new component,               *)
724(* illustrated with the addition of 32-bit bitwise exclusive-or (XOR32).     *)
725(*                                                                           *)
726(* These steps are a manual version of what is done when                     *)
727(*                                                                           *)
728(*  AddBinop ("XOR32", (``UNCURRY $# : word32#word32->word32``, "^"));       *)
729(*                                                                           *)
730(* is evaluated.                                                             *)
731(*****************************************************************************)
732
733(*****************************************************************************)
734(* Step 1                                                                    *)
735(* ------                                                                    *)
736(* Define the component in HOL                                               *)
737(* (assumes word32Theory loaded and open)                                    *)
738(*****************************************************************************)
739val XOR32_def =
740 Define 
741  `XOR32(in1,in2,out) = !t. out t = (in1 t) # (in2 t)`;
742
743(*****************************************************************************)
744(* Step 2                                                                    *)
745(* ------                                                                    *)
746(* Prove some boilerplate theorems and add to global lists:                  *)
747(*****************************************************************************)
748val COMB_XOR32 =
749 store_thm
750  ("COMB_XOR32",
751   ``COMB (UNCURRY $#) (in1 <> in2, out) = XOR32(in1,in2,out)``,
752   RW_TAC std_ss [COMB_def,BUS_CONCAT_def,XOR32_def]);
753
754add_combinational_components[COMB_XOR32];
755
756val XOR32_at =
757 store_thm
758  ("XOR32_at",
759   ``XOR32(in1,in2,out)
760     ==>
761     XOR32(in1 at clk,in2 at clk,out at clk)``,
762   RW_TAC std_ss [XOR32_def,at_def,tempabsTheory.when]);
763
764add_temporal_abstractions[XOR32_at];
765
766(*****************************************************************************)
767(* Step 3                                                                    *)
768(* ------                                                                    *)
769(* Define a Verilog module as an ML string (XOR32vDef), a function to        *)
770(* create an instance with a given size as a string (XOR32vInst), an         *)
771(* instance counter (XOR32vInst_count -- used to create unique names for     *)
772(* instances) and a function to print a HOL term ``XOR32(in1,in2,out)`` as   *)
773(* an instance, using the type of ``out`` to compute the word width          *)
774(* needed to set parameter "size" in XOR32vDef (termToVerilog_XOR32).        *)
775(* These functions are added to a couple of global lists.                    *)
776(*****************************************************************************)
777val XOR32vDef =
778"// Combinational bitwise XOR32\n\
779\module XOR32 (in1,in2,out);\n\
780\ parameter size = 31;\n\
781\ input  [size:0] in1,in2;\n\
782\ output [size:0] out;\n\
783\\n\
784\ assign out = in1 ^ in2;\n\
785\\n\
786\endmodule\n\
787\\n";
788
789val XOR32vInst_count = ref 0;
790fun XOR32vInst (out:string->unit) [("size",size)] [in1_name,in2_name,out_name] =
791 let val count = !XOR32vInst_count
792     val _ = (XOR32vInst_count := count+1);
793     val inst_name = "XOR32" ^ "_" ^ Int.toString count
794 in
795 (out " XOR32        "; out inst_name;
796  out " (";out in1_name;out",";out in2_name;out",";out out_name; out ");\n";
797  out "   defparam ";out inst_name; out ".size = "; out size;
798  out ";\n\n")
799 end;
800
801add_module ("XOR32", (XOR32vDef, XOR32vInst));
802
803fun termToVerilog_XOR32 (out:string->unit) tm =
804 if is_comb tm
805     andalso is_const(fst(strip_comb tm))
806     andalso (fst(dest_const(fst(strip_comb tm))) = "XOR32")
807     andalso is_pair(rand tm)
808     andalso (length(strip_pair(rand tm)) = 3)
809     andalso all is_var (strip_pair(rand tm))
810  then XOR32vInst
811        out
812        [("size", var2size(last(strip_pair(rand tm))))]
813        (map (fst o dest_var) (strip_pair(rand tm)))
814  else raise ERR "termToVerilog_XOR32" "bad component term";
815
816termToVerilogLib := (!termToVerilogLib) @ [termToVerilog_XOR32];
817
818===============================================================================
819== This directory contains Juliano's HOL files modified by MJCG & KXS        ==
820== [Revised version incorporating Juliano's new treatment of recursion]      ==
821== [Revised version incorporating liveness]                                  ==
822== [04.01.05: improved proofs from KXS in composeScript.sml & devScript.sml] ==
823== [09.01.05: MJCG added converter to combinators Seq, Par, Ite, Rec]        ==
824== [13.01.05: major tidy and update by MJCG]                                 ==
825== [17.01.05: MJCG installed hwDefine and improved examples from KXS]        ==
826== [18.01.05: MJCG added Refine and revised FactScript.sml]                  ==
827== [19.01.05: MJCG changed to use refinement combinators]                    ==
828== [20.01.05: MJCG added netlist synthesis]                                  ==
829== [21.01.05: MJCG minor changes and README update]                          ==
830== [27.01.05: MJCG added hw synthesis improvements]                          ==
831== [28.01.05: MJCG more optimisations and updated README]                    ==
832== [29.01.05: MJCG added COMB_SYNTH_CONV removed SEL operators]              ==
833== [30.01.05: MJCG added dff: Melham's temporal abstraction theory]          ==
834== [01.02.05: MJCG minor tweaks to MAKE_NETLIST and COMB_SYNTH_CONV]         ==
835== [06.02.05: MJCG added refinement to clocked dtype registers]              ==
836== [08.02.05: MJCG added ?-quantification of internal wires to MAKE_CIRCUIT] ==
837== [10.02.05: MJCG split input and output busses]                            ==
838== [11.02.05: Holmakefile (thanks to MN) + code improvements (thanks to KXS)]==
839== [14.02.05: MJCG added vsynth (defines MAKE_VERILOG)]                      ==
840== [15.02.05: MJCG revised MAKE_NETLIST and MAKE_CIRCUIT]                    ==
841== [18.02.05: MJCG revised MAKE_VERILOG in vsynth; added MAKE_SIMULATION]    ==
842== [28.02.05: MJCG revised added SIMULATE to run iverilog and gtkwave]       ==
843== [20.04.05: MJCG updated section on adding new components]                 ==
844== [17.05.05: MJCG added hwDefineLib and REFINE_ALL]                         ==
845== [30.05.05: MJCG added cirDefine]                                          ==
846===============================================================================
847