confluence-0.10.6/0040755002340600244710000000000010312276326013326 5ustar hawkit1cadgrpconfluence-0.10.6/lib/0040755002340600244710000000000010312276326014074 5ustar hawkit1cadgrpconfluence-0.10.6/lib/base_test/0040755002340600244710000000000010312276326016045 5ustar hawkit1cadgrpconfluence-0.10.6/lib/base_test/base_test.cf0100644002340600244710000007001610266541655020341 0ustar hawkit1cadgrp(* Confluence System Design Library Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) (** Unit testing of base.cf. *) -suite with ut general components systems numbers integers floats booleans records lists vectors is ut <- import "$CF_LIB/common/unit_test.cf" {ut.run_test "" "all" suite} component suite +N is {ut.run_test N "TestGeneral" general } {ut.run_test N "TestComponents" components } {ut.run_test N "TestSystems" systems } {ut.run_test N "TestNumbers" numbers } {ut.run_test N "TestIntegers" integers } {ut.run_test N "TestFloats" floats } {ut.run_test N "TestBooleans" booleans } {ut.run_test N "TestRecords" records } {ut.run_test N "TestLists" lists } {ut.run_test N "TestVectors" vectors } end component general +N is {ut.assert_equal N "string_of_1" {string_of 1 [] $} "1"} {ut.assert_equal N "string_of_2" {string_of true [] $} "true"} {ut.assert_equal N "string_of_3" {string_of '0011' [] $} ""} {ut.assert_equal N "string_of_4" {string_of [1 2 3 [4 5]] [] $} "[1 2 3 [4 5]]"} {ut.assert_equal N "(==)_0" (1 == 2) false} {ut.assert_equal N "(==)_1" (1 == 1) true} {ut.assert_equal N "(!=)_0" (1 != 2) true} {ut.assert_equal N "(!=)_1" (1 != 1) false} end component components +N is {ut.assert_equal N "is_component_1" {is_component 1 $} false} {ut.assert_equal N "is_component_2" {is_component is_component $} true} {ut.assert_equal N "string_of_component" {string_of_component is_component $} ""} end component systems +N is {ut.assert_equal N "is_system_1" {is_system {is_system 1 _} $} true} {ut.assert_equal N "is_system_2" {is_system [] $} false} {ut.assert_equal N "string_of_system" {string_of_system {is_system 1 _} [] $} ""} {ut.assert_equal N "ports_of_system" {ports_of_system {(::) 1 [2 3] _} $} (hd:1 tl:[2 3] list:[1 2 3])} local test_comp test_sys_dot_name test_sys_dot_position test_rec_dot_name test_rec_dot_position test_app_name test_func_name is component test_comp +a +b -x is x = a + b end test_sys_dot_name = {test_comp _ 2 _} test_sys_dot_position = {test_comp _ _ _} test_rec_dot_name = {ports_of_system test_sys_dot_name $} test_rec_dot_position = {ports_of_system test_sys_dot_position $} test_sys_dot_name.a = 1 test_sys_dot_position.1 = 2 test_sys_dot_position.2 = 4 {ut.assert_equal N "Sys.Name_1" test_sys_dot_name.a 1} {ut.assert_equal N "Sys.Name_2" test_sys_dot_name.b 2} {ut.assert_equal N "Sys.Name_3" test_sys_dot_name.x 3} {ut.assert_equal N "Sys.Position_1" test_sys_dot_position.1 2} {ut.assert_equal N "Sys.Position_2" test_sys_dot_position.2 4} {ut.assert_equal N "Sys.Position_3" test_sys_dot_position.3 6} {ut.assert_equal N "Rec.Name_1" test_rec_dot_name.a 1} {ut.assert_equal N "Rec.Name_2" test_rec_dot_name.b 2} {ut.assert_equal N "Rec.Name_3" test_rec_dot_name.x 3} {ut.assert_equal N "Rec.Position_1" test_rec_dot_position.1 2} {ut.assert_equal N "Rec.Position_2" test_rec_dot_position.2 4} {ut.assert_equal N "Rec.Position_3" test_rec_dot_position.3 6} {test_app_name : test_comp 1 2 _} _ = {test_func_name : test_comp 2 4 $} {ut.assert_equal N "{name : comp _}_1" test_app_name.1 1} {ut.assert_equal N "{name : comp _}_2" test_app_name.2 2} {ut.assert_equal N "{name : comp _}_3" test_app_name.3 3} {ut.assert_equal N "{name : comp $}_1" test_func_name.1 2} {ut.assert_equal N "{name : comp $}_2" test_func_name.2 4} {ut.assert_equal N "{name : comp $}_3" test_func_name.3 6} end local sys is sys = local a b c is a = 1 b = 2 c = "yep" end {ut.assert_equal N "name = local 1" sys.1 1} {ut.assert_equal N "name = local 2" sys.b 2} {ut.assert_equal N "name = local 3" sys.c "yep"} end end component numbers +N is {ut.assert_equal N "(<)_0" (1 < 2) true} {ut.assert_equal N "(<)_1" (2.0 < 1.0) false} {ut.assert_equal N "(<=)_0" (1 <= 1) true} {ut.assert_equal N "(<=)_1" (0.0 <= -2.0) false} {ut.assert_equal N "(>)_0" (1 > 2) false} {ut.assert_equal N "(>)_1" (2.0 > 1.0) true} {ut.assert_equal N "(>=)_0" (1 >= 1) true} {ut.assert_equal N "(>=)_1" (0.0 >= -2.0) true} {ut.assert_equal N "(+)_0" (1 + 1) 2} {ut.assert_equal N "(+)_1" (-1.0 + -1.0) -2.0} {ut.assert_equal N "(-)_0" (1 - 2) -1} {ut.assert_equal N "(-)_1" (1.0 - -1.0) 2.0} {ut.assert_equal N "(*)_0" (3 * 2) 6} {ut.assert_equal N "(*)_1" (3.0 * -1.0) -3.0} {ut.assert_equal N "(/)_0" (10 / 2) 5} {ut.assert_equal N "(/)_1" (10.0 / -2.0) -5.0} {ut.assert_equal N "(**)_0" (2 ** 4) 16} {ut.assert_equal N "(**)_1" (2.0 ** 4.0) 16.0} end component integers +N is {ut.assert_boolean N "Integer constants 1" (0 == 0x0 && 0 == 0b0)} {ut.assert_boolean N "Integer constants 2" (1 == 0x1 && 1 == 0b1)} {ut.assert_boolean N "Integer constants 3" (-2 == 1xE && -2 == 1b0)} {ut.assert_equal N "is_integer1" {is_integer 22 $} true} {ut.assert_equal N "is_integer2" {is_integer 0xAB $} true} {ut.assert_equal N "is_integer3" {is_integer 1xAB $} true} {ut.assert_equal N "is_integer4" {is_integer [1] $} false} {ut.assert_equal N "string_of_integer" {string_of_integer 16 $} "16"} {ut.assert_equal N "integer_of_string_1" {integer_of_string "-8" $} -8} {ut.assert_equal N "integer_of_string_2" {integer_of_string "123456789012345678901234567890" $} 123456789012345678901234567890} {ut.assert_equal N "float_of_integer" {integer_of_float {float_of_integer -8 $} $} -8} {ut.assert_equal N "range_1" {range 0 0 $} [0]} {ut.assert_equal N "range_2" {range -2 3 $} [-2 -1 0 1 2 3]} {ut.assert_equal N "range_3" {range 2 -3 $} [2 1 0 -1 -2 -3]} {ut.assert_equal N "(%)_0" (5 % 2) 1} {ut.assert_equal N "(%)_1" (10 % 2) 0} {ut.assert_equal N "(%)_2" (-5 % 2) 1} {ut.assert_equal N "(~)_0" (~ 1) -2} {ut.assert_equal N "(&)_0" (0b0011 & 0b0101) 0b0001} {ut.assert_equal N "(^)_0" (0b0011 ^ 0b0101) 0b0110} {ut.assert_equal N "(|)_0" (0b0011 | 0b0101) 0b0111} {ut.assert_equal N "(<<)_0" (0b0011 << 2) 0b1100} {ut.assert_equal N "(>>)_0" (0b0011 >> 1) 0b0001} {ut.assert_equal N "(>>)_1" (1b0011 >> 1) 1b1001} {ut.assert_equal N "(:)_0" [0 : 2] [0 1 2]} {ut.assert_equal N "(:)_1" [-1 : -1] [-1]} {ut.assert_equal N "binary_of_integer_0" {binary_of_integer 2 4 $} "0010"} {ut.assert_equal N "binary_of_integer_1" {binary_of_integer -1 8 $} "11111111"} {ut.assert_equal N "binary_of_integer_2" {binary_of_integer -1 0 $} ""} {ut.assert_equal N "integer_of_binary_0" {integer_of_binary "1100" $} 0b1100} {ut.assert_equal N "integer_of_binary_1" {integer_of_binary "1" $} 0b1} {ut.assert_equal N "integer_of_binary_2" {integer_of_binary "" $} 0} {ut.assert_equal N "bits_required_1" {bits_required 1 $} 1} {ut.assert_equal N "bits_required_2" {bits_required 2 $} 1} {ut.assert_equal N "bits_required_3" {bits_required 3 $} 2} {ut.assert_equal N "bits_required_4" {bits_required 4 $} 2} {ut.assert_equal N "bits_required_5" {bits_required 5 $} 3} end component floats +N is {ut.assert_equal N "is_float_1" {is_float 1.1 $} true} {ut.assert_equal N "is_float_2" {is_float -0.2e15 $} true} {ut.assert_equal N "is_float_3" {is_float 1 $} false} {ut.assert_equal N "string_of_float" {string_of_float 1.0 $} "1.0"} {ut.assert_equal N "float_of_string" {float_of_string "1.0" $} 1.0} {ut.assert_equal N "ceil_1" {ceil 0.5 $} 1.0} {ut.assert_equal N "ceil_2" {ceil -0.5 $} 0.0} {ut.assert_equal N "floor_1" {floor 0.5 $} 0.0} {ut.assert_equal N "floor_2" {floor -0.5 $} -1.0} {ut.assert_equal N "round_1" {round 0.4 $} 0.0} {ut.assert_equal N "round_2" {round 0.6 $} 1.0} {ut.assert_equal N "round_3" {round -0.4 $} 0.0} {ut.assert_equal N "round_4" {round -0.6 $} -1.0} end component booleans +N is {ut.assert_equal N "is_boolean_1" {is_boolean true $} true} {ut.assert_equal N "is_boolean_2" {is_boolean false $} true} {ut.assert_equal N "is_boolean_3" {is_boolean 3.14 $} false} {ut.assert_equal N "string_of_boolean_1" {string_of_boolean true $} "true"} {ut.assert_equal N "string_of_boolean_2" {string_of_boolean false $} "false"} {ut.assert_equal N "(!)_0" (! true) false} {ut.assert_equal N "(!)_1" (! false) true} {ut.assert_equal N "then_else_0" (true then 1 else 2) 1} {ut.assert_equal N "then_else_1" (false then 1 else 2) 2} {ut.assert_equal N "||_1" (false || false || 8) 8} {ut.assert_equal N "||_2" (false || true || 8) true} {ut.assert_equal N "&&_1" (false && false && 8) false} {ut.assert_equal N "&&_2" (true && false && 8) false} {ut.assert_equal N "&&_3" (true && true && 8) 8} end component records +N is {ut.assert_equal N "record_1" () ()} {ut.assert_equal N "record_2" (A:1 B:2) (A:1 B:2)} local R1 R2 is R1 = (A:R2 B:2) R2 = (A:R1 B:2) {ut.assert_equal N "record_3" R1 R2} end {ut.assert_equal N "is_record_1" {is_record () $} true} {ut.assert_equal N "is_record_2" {is_record (A:1 B:2) $} true} {ut.assert_equal N "is_record_3" {is_record "ListAreRecordsToo" $} true} {ut.assert_equal N "is_record_4" {is_record 1024 $} false} {ut.assert_equal N "record_info_1" {record_info (A:1 B:2) $} [(name:"A" value:1) (name:"B" value:2)]} {ut.assert_equal N "record_info_2" {record_info () $} []} {ut.assert_equal N "string_of_record_0" {string_of_record (A:1 B:2) [] $} "(A:1 B:2)"} local r is r = (a:1 b:r) {ut.assert_equal N "string_of_record_1" {string_of_record r [] $} "(a:1 b:rec)"} end end component lists +N is {ut.assert_equal N "list_1" [] ""} {ut.assert_equal N "list_2" [1 2 3 4] [1 : 4]} {ut.assert_equal N "list_3" [0 -1 -2] [0 : -2]} {ut.assert_equal N "list_4" [0 1 2 3 4 5] [0 1 : 4 5]} {ut.assert_equal N "is_list_1" {is_list [] $} true} {ut.assert_equal N "is_list_2" {is_list [1 2 3] $} true} {ut.assert_equal N "is_list_3" {is_list "abc" $} true} {ut.assert_equal N "string_1" "abc" [97 98 99]} {ut.assert_equal N "string_2" "abc" [@a @b @c]} {ut.assert_equal N "string_3" "\\" [@\]} {ut.assert_equal N "string_4" "\"" [@"]} {ut.assert_equal N "string_5" "\t" [9]} {ut.assert_equal N "string_6" "\n" [10]} {ut.assert_equal N "string_7" "\r" [13]} {ut.assert_equal N "string_of_list_0" {string_of_list [1 2 [3 4] [5 6]] [] $} "[1 2 [3 4] [5 6]]"} {ut.assert_equal N "string_of_list_1" {string_of_list [1 2 [3 4] [5 6]] [] $} "[1 2 [3 4] [5 6]]"} local l is l = [1 2 l] {ut.assert_equal N "string_of_list_2" {string_of_list l [] $} "[1 2 rec]"} end {ut.assert_equal N "(head)_0" (head [1 2 3]) 1} {ut.assert_equal N "(tail)_0" (tail [1 2 3]) [2 3]} {ut.assert_equal N "(tail)_1" (tail [1]) []} {ut.assert_equal N "(length)_0" (length []) 0} {ut.assert_equal N "(length)_1" (length [1 2 3]) 3} {ut.assert_equal N "(++)_0" ([] ++ [1 2]) [1 2]} {ut.assert_equal N "(++)_1" ([1 2] ++ []) [1 2]} {ut.assert_equal N "(++)_2" ([1 2] ++ [3]) [1 2 3]} {ut.assert_equal N "(::)_0" (1 :: [2 3]) [1 2 3]} {ut.assert_equal N "(#)_0" ([1 2] # 0) []} {ut.assert_equal N "(#)_1" ([1 2] # 3) [1 2 1 2 1 2]} {ut.assert_equal N "List.nth_1" {List.nth [1 2 3] 0 $} 1} {ut.assert_equal N "List.nth_2" {List.nth [1 2 3] 2 $} 3} {ut.assert_equal N "List.take_1" {List.take [1 2 3] 0 $} []} {ut.assert_equal N "List.take_2" {List.take [1 2 3] 1 $} [1]} {ut.assert_equal N "List.take_3" {List.take [1 2 3] 3 $} [1 2 3]} {ut.assert_equal N "List.drop_1" {List.drop [1 2 3] 0 $} [1 2 3]} {ut.assert_equal N "List.drop_2" {List.drop [1 2 3] 1 $} [2 3]} {ut.assert_equal N "List.drop_3" {List.drop [1 2 3] 3 $} []} {ut.assert_equal N "List.reverse_1" {List.reverse [] $} []} {ut.assert_equal N "List.reverse_2" {List.reverse [1 2 3] $} [3 2 1]} {ut.assert_equal N "List.flatten_1" {List.flatten [] $} []} {ut.assert_equal N "List.flatten_2" {List.flatten [1 2 3] $} [1 2 3]} {ut.assert_equal N "List.flatten_3" {List.flatten [1 2 [3 4 [5 6] 7] 8] $} [1 2 3 4 5 6 7 8]} {ut.assert_equal N "List.isolate_1" {List.isolate [] $} []} {ut.assert_equal N "List.isolate_2" {List.isolate [1 2 3] $} [[1] [2] [3]]} {ut.assert_equal N "List.transpose" {List.transpose [[1 2 3] [4 5 6]] $} [[1 4] [2 5] [3 6]]} {ut.assert_equal N "List.map_1" {List.map (~) [] $} []} {ut.assert_equal N "List.map_2" {List.map (~) [0x0 0x1 0x3] $} [1xF 1xE 1xC]} {ut.assert_equal N "List.map2_1" {List.map2 (+) [] [] $} []} {ut.assert_equal N "List.map2_2" {List.map2 (+) [1 2 3] [4 5 6] $} [5 7 9]} {ut.assert_equal N "List.fold_left_1" {List.fold_left (+) 2 [] $} 2} {ut.assert_equal N "List.fold_left_2" {List.fold_left (+) 2 [3 4] $} 9} {ut.assert_equal N "List.fold_right1" {List.fold_right (+) [] 3 $} 3} {ut.assert_equal N "List.fold_right2" {List.fold_right (+) [3 4] 3 $} 10} {ut.assert_equal N "List.tree_1" {List.tree (+) comp +A -X is A * 2 -> X end [1 2 3] $} 9} {ut.assert_equal N "List.tree_2" {List.tree (+) comp +A -X is A * 2 -> X end [1 2 3 4 5] $} 30} {ut.assert_equal N "List.Assoc.find_1" {List.Assoc.find [[1 2] [2 4] [3 6]] 1 $} 2} {ut.assert_equal N "List.Assoc.find_2" {List.Assoc.find [[1 2] [2 4] [3 6]] 2 $} 4} {ut.assert_equal N "List.Assoc.find_3" {List.Assoc.find [[1 2] [2 4] [3 6]] 3 $} 6} {ut.assert_equal N "List.Assoc.member_1" {List.Assoc.member [[1 2] [2 4] [3 6]] 1 $} true} {ut.assert_equal N "List.Assoc.member_2" {List.Assoc.member [[1 2] [2 4] [3 6]] 2 $} true} {ut.assert_equal N "List.Assoc.member_3" {List.Assoc.member [[1 2] [2 4] [3 6]] 4 $} false} {ut.assert_equal N "List.Assoc.add_1" {List.Assoc.add [[1 2] [2 4] [3 6]] 0 0 $} [[0 0] [1 2] [2 4] [3 6]]} {ut.assert_equal N "List.Assoc.remove_0" {List.Assoc.remove [[1 2] [2 4] [3 6]] 0 $} [[1 2] [2 4] [3 6]]} {ut.assert_equal N "List.Assoc.remove_1" {List.Assoc.remove [[1 2] [2 4] [3 6]] 1 $} [[2 4] [3 6]]} {ut.assert_equal N "List.Assoc.remove_3" {List.Assoc.remove [[1 2] [2 4] [3 6]] 3 $} [[1 2] [2 4]]} {ut.assert_equal N "List.Assoc.replace_1" {List.Assoc.replace [[1 2] [2 4] [3 6]] 0 0 $} [[1 2] [2 4] [3 6] [0 0]]} {ut.assert_equal N "List.Assoc.replace_2" {List.Assoc.replace [[1 2] [2 4] [3 6]] 3 7 $} [[1 2] [2 4] [3 7]]} {ut.assert_equal N "List.member_1" {List.member [0 1 2 3] 1 $} true} {ut.assert_equal N "List.member_2" {List.member [0 1 2 3] 5 $} false} {ut.assert_equal N "List.satisfy_and_1" {List.satisfy_and comp +A -X is A > 2 -> X end [3 7 4] $} true} {ut.assert_equal N "List.satisfy_and_2" {List.satisfy_and comp +A -X is A > 2 -> X end [3 2 4] $} false} {ut.assert_equal N "List.satisfy_or_1" {List.satisfy_or comp +A -X is A > 2 -> X end [0 1 -1] $} false} {ut.assert_equal N "List.satisfy_or_2" {List.satisfy_or comp +A -X is A > 2 -> X end [0 3 1] $} true} {ut.assert_equal N "List.find_1" {List.find comp +A -X is A > 2 -> X end [0 3 1] $} 3} {ut.assert_equal N "List.filter_1" {List.filter comp +A -X is A > 2 -> X end [0 -1 1] $} []} {ut.assert_equal N "List.filter_2" {List.filter comp +A -X is A > 2 -> X end [0 3 4 5 -2 7 1] $} [3 4 5 7]} local Trues Falses is {List.partition comp +A -X is A > 2 = X end [0 3 4 5 -2 7 1] Trues Falses} {ut.assert_equal N "List.partition_1" Trues [3 4 5 7]} {ut.assert_equal N "List.partition_2" Falses [0 -2 1]} end {ut.assert_equal N "List.sort_1" {List.sort (<) [] $} []} {ut.assert_equal N "List.sort_2" {List.sort (<) [0 2 4 1 3 5] $} [0 1 2 3 4 5]} end component vectors +N is {ut.assert_logic N "Vector constants 1" (('0000' '==' '0x0') '&' ('0' '==' '0b0'))} {ut.assert_logic N "Vector constants 2" (('0001' '==' '0x1') '&' ('1' '==' '0b1'))} {ut.assert_logic N "Vector constants 3" (('1110' '==' '0xE') '&' ('0' '==' '1b0'))} {output "req_tb_output" '1'} (* Required for test bench generation. *) {ut.assert_equal N "is_vector_1" {is_vector '0011' $} true} {ut.assert_equal N "is_vector_2" {is_vector 1 $} false} {ut.assert_equal N "string_of_vector" {string_of_vector '0011' $} ""} (* XXX {display '1' {vector_of_string "Hello Confluence!" $}} *) {ut.assert_logic N "bin_of_vector_1" ({bin_of_vector '00110101' $} '==' '0x3030313130313031')} {ut.assert_logic N "bin_of_vector_2" ({bin_of_vector '10001' $} '==' '0x3130303031')} {ut.assert_logic N "bin_of_vector_3" ({bin_of_vector '0011' $} '==' '0x30303131')} {ut.assert_logic N "hex_of_vector_1" ({hex_of_vector '011' $} '==' '0x33')} {ut.assert_logic N "hex_of_vector_2" ({hex_of_vector '0111111' $} '==' '0x3346')} {ut.assert_logic N "hex_of_vector_3" ({hex_of_vector '00001111' $} '==' '0x3046')} {ut.assert_logic N "const_1" ({const 1 0 $} '==' '0')} {ut.assert_logic N "const_2" ({const 3 -1 $} '==' '111')} {ut.assert_logic N "const_3" ({const 8 0xABC $} '==' '0xBC')} {ut.assert_equal N "one_1" (width {one 2 $}) 2} {ut.assert_logic N "one_2" ({one 3 $} '==' '001')} {ut.assert_logic N "one_3" ({one 1 $} '==' '1')} {ut.assert_equal N "ones_1" (width {ones 3 $}) 3} {ut.assert_logic N "ones_2" ({ones 3 $} '==' '111')} {ut.assert_logic N "ones_3" ({ones 1 $} '==' '1')} {ut.assert_equal N "zero_1" (width {zero 3 $}) 3} {ut.assert_logic N "zero_2" ({zero 3 $} '==' '000')} {ut.assert_logic N "zero_3" ({zero 1 $} '==' '0')} {ut.assert_equal N "reg_0" (width {reg 2 '00' $}) 2} {ut.assert_logic N "reg_1" ({reg 2 '00' $} '==' '00')} {ut.assert_logic N "reg_2" ({reg 2 '11' $} '==' '00')} {ut.assert_equal N "regs_0" (width {regs 2 3 '00' $}) 2} {ut.assert_logic N "regs_1" ({regs 2 0 '10' $} '==' '10')} {ut.assert_logic N "regs_2" ({regs 3 1 '001' $} '==' '000')} (* {ut.assert_logic N "rom_1" ({rom 4 [3 2 1 0] '11' $} '==' '0000')} *) (* local :ExtComb {NewExternalCombinatorialComponent "TestExtComb" 1 comp +Params -WidthIn -WidthOut WidthIn <- WidthOut <- head Params end ExternalComponent {ut.assert_logic N "NewExternalCombinatorialComponent" { end *) {ut.assert_equal N "'then'_'else'_0" (width ('0' 'then' '0xAB' 'else' '0xCD')) 8} {ut.assert_logic N "'then'_'else'_1" (('0' 'then' '0xAB' 'else' '0xCD') '==' '0xCD')} {ut.assert_equal N "'|'_1" (width ('0xC' '|' '0xA')) 4} {ut.assert_logic N "'|'_2" (('0xC' '|' '0xA') '==' '0xE')} {ut.assert_equal N "'^'_1" (width ('0x1C' '^' '0x1A')) 8} {ut.assert_logic N "'^'_2" (('0xC' '^' '0xA') '==' '0x6')} {ut.assert_equal N "'&'_1" (width ('0x12C' '&' '0x12A')) 12} {ut.assert_logic N "'&'_2" (('0xC' '&' '0xA') '==' '0x8')} {ut.assert_equal N "'=='_0" (width ('00' '==' '11')) 1} {ut.assert_logic N "'=='_1" (('00' '==' '11') '==' '0')} {ut.assert_equal N "'!='_0" (width ('00' '!=' '11')) 1} {ut.assert_logic N "'!='_1" (('00' '!=' '11') '==' '1')} {ut.assert_equal N "'#'_1" (width ('00' '#' 0)) 0 } {ut.assert_equal N "'#'_2" (width ('00' '#' 1)) 2 } {ut.assert_equal N "'#'_3" (width ('00' '#' 3)) 6 } {ut.assert_equal N "'#'_4" (width ('' '#' 3)) 0 } {ut.assert_logic N "'#'_5" (('011' '#' 3) '==' '011011011')} {ut.assert_equal N "'<'_1" (width ('00' '<' '00')) 1} {ut.assert_logic N "'<'_2" ('~'('001' '<' '001'))} {ut.assert_logic N "'<'_3" ('~'('001' '<' '000'))} {ut.assert_logic N "'<'_4" ( ('001' '<' '010'))} {ut.assert_logic N "'<'_5" ( ('001' '<' '110'))} {ut.assert_equal N "'<+'_1" (width ('00' '<+' '00')) 1} {ut.assert_logic N "'<+'_2" ('~'('001' '<+' '001'))} {ut.assert_logic N "'<+'_3" ('~'('001' '<+' '000'))} {ut.assert_logic N "'<+'_4" ( ('001' '<+' '010'))} {ut.assert_logic N "'<+'_5" ('~'('001' '<+' '110'))} {ut.assert_equal N "'>'_1" (width ('00' '>' '00')) 1} {ut.assert_logic N "'>'_2" ('~'('001' '>' '001'))} {ut.assert_logic N "'>'_3" ( ('001' '>' '000'))} {ut.assert_logic N "'>'_4" ('~'('001' '>' '010'))} {ut.assert_logic N "'>'_5" ('~'('001' '>' '110'))} {ut.assert_equal N "'>+'_1" (width ('00' '>+' '00')) 1} {ut.assert_logic N "'>+'_2" ('~'('001' '>+' '001'))} {ut.assert_logic N "'>+'_3" ( ('001' '>+' '000'))} {ut.assert_logic N "'>+'_4" ('~'('001' '>+' '010'))} {ut.assert_logic N "'>+'_5" ( ('001' '>+' '110'))} {ut.assert_equal N "'<='_1" (width ('00' '<=' '00')) 1} {ut.assert_logic N "'<='_2" ( ('001' '<=' '001'))} {ut.assert_logic N "'<='_3" ('~'('001' '<=' '000'))} {ut.assert_logic N "'<='_4" ( ('001' '<=' '010'))} {ut.assert_logic N "'<='_5" ( ('001' '<=' '110'))} {ut.assert_equal N "'<=+'_1" (width ('00' '<=+' '00')) 1} {ut.assert_logic N "'<=+'_2" ( ('001' '<=+' '001'))} {ut.assert_logic N "'<=+'_3" ('~'('001' '<=+' '000'))} {ut.assert_logic N "'<=+'_4" ( ('001' '<=+' '010'))} {ut.assert_logic N "'<=+'_5" ('~'('001' '<=+' '110'))} {ut.assert_equal N "'>='_1" (width ('00' '>=' '00')) 1} {ut.assert_logic N "'>='_2" ( ('001' '>=' '001'))} {ut.assert_logic N "'>='_3" ( ('001' '>=' '000'))} {ut.assert_logic N "'>='_4" ('~'('001' '>=' '010'))} {ut.assert_logic N "'>='_5" ('~'('001' '>=' '110'))} {ut.assert_equal N "'>=+'_1" (width ('00' '>=+' '00')) 1} {ut.assert_logic N "'>=+'_2" ( ('001' '>=+' '001'))} {ut.assert_logic N "'>=+'_3" ( ('001' '>=+' '000'))} {ut.assert_logic N "'>=+'_4" ('~'('001' '>=+' '010'))} {ut.assert_logic N "'>=+'_5" ( ('001' '>=+' '110'))} {ut.assert_equal N "'<<'_1" (width ('00' '<<' 1)) 2} {ut.assert_logic N "'<<'_2" (('011' '<<' 0) '==' '011')} {ut.assert_logic N "'<<'_3" (('011' '<<' 2) '==' '100')} {ut.assert_equal N "'>>'_1" (width ('000' '>>' 2)) 3} {ut.assert_logic N "'>>'_2" (('011' '>>' 0) '==' '011')} {ut.assert_logic N "'>>'_3" (('011' '>>' 1) '==' '001')} {ut.assert_logic N "'>>'_4" (('111' '>>' 1) '==' '011')} {ut.assert_equal N "'>>+'_1" (width ('000' '>>+' 2)) 3} {ut.assert_logic N "'>>+'_2" (('011' '>>+' 0) '==' '011')} {ut.assert_logic N "'>>+'_3" (('011' '>>+' 1) '==' '001')} {ut.assert_logic N "'>>+'_4" (('111' '>>+' 1) '==' '111')} {ut.assert_equal N "'+'_1" (width ('00' '+' '01')) 2} {ut.assert_logic N "'+'_2" (('000' '+' '000') '==' '000')} {ut.assert_logic N "'+'_3" (('001' '+' '011') '==' '100')} {ut.assert_logic N "'+'_4" (('101' '+' '011') '==' '000')} {ut.assert_logic N "'+'_5" (('100' '+' '011') '==' '111')} {ut.assert_equal N "'-'_1" (width ('00' '-' '01')) 2} {ut.assert_logic N "'-'_2" (('000' '-' '000') '==' '000')} {ut.assert_logic N "'-'_3" (('000' '-' '010') '==' '110')} {ut.assert_logic N "'-'_4" (('110' '-' '001') '==' '101')} {ut.assert_logic N "'-'_5" (('0x01A40000' '-' '0xFFFEC000') '==' '0x01A54000')} {ut.assert_equal N "'*'_1" (width ('00' '*' '00')) 4} {ut.assert_equal N "'*'_2" (width ('00' '*' '000')) 5} {ut.assert_logic N "'*'_3" (('000' '*' '101') '==' '000000')} {ut.assert_logic N "'*'_4" (('001' '*' '101') '==' '000101')} {ut.assert_logic N "'*'_5" (('101' '*' '100') '==' '010100')} {ut.assert_logic N "'*'_6" (('111' '*' '11') '==' '10101')} {ut.assert_equal N "'*+'_1" (width ('0' '*+' '00')) 3} {ut.assert_equal N "'*+'_2" (width ('0' '*+' '000')) 4} {ut.assert_logic N "'*+'_3" (('000' '*+' '101') '==' '000000')} {ut.assert_logic N "'*+'_4" (('001' '*+' '101') '==' '111101')} {ut.assert_logic N "'*+'_5" (('011' '*+' '011') '==' '001001')} {ut.assert_logic N "'*+'_6" (('111' '*+' '11') '==' '00001')} {ut.assert_logic N "'*+'_7" (('0x000005FC' '*+' '0xFFF08000') '==' '0xFFFFFFFFA33E0000')} {ut.assert_equal N "(width)_1" (width '') 0} {ut.assert_equal N "(width)_2" (width '00') 2} {ut.assert_equal N "(width)_3" (width '0xAB') 8} {ut.assert_equal N "('msb')_1" (width 'msb' '0') 1} {ut.assert_equal N "('msb')_2" (width 'msb' '000') 1} {ut.assert_logic N "('msb')_3" (('msb' '001') '==' '0')} {ut.assert_logic N "('msb')_4" (('msb' '100') '==' '1')} {ut.assert_equal N "('lsb')_1" (width 'lsb' '0') 1} {ut.assert_equal N "('lsb')_2" (width 'lsb' '000') 1} {ut.assert_logic N "('lsb')_3" (('lsb' '001') '==' '1')} {ut.assert_logic N "('lsb')_4" (('lsb' '100') '==' '0')} {ut.assert_equal N "('msbs')_1" (width 'msbs' '0') 0} {ut.assert_equal N "('msbs')_2" (width 'msbs' '000') 2} {ut.assert_logic N "('msbs')_3" (('msbs' '011') '==' '01')} {ut.assert_logic N "('msbs')_4" (('msbs' '110') '==' '11')} {ut.assert_equal N "('lsbs')_1" (width 'lsbs' '0') 0} {ut.assert_equal N "('lsbs')_2" (width 'lsbs' '000') 2} {ut.assert_logic N "('lsbs')_3" (('lsbs' '011') '==' '11')} {ut.assert_logic N "('lsbs')_4" (('lsbs' '110') '==' '10')} {ut.assert_equal N "('++')_0" (width ('00010111' '++' '010')) 11} {ut.assert_logic N "('++')_1" ('00010111' '++' '010' '==' '00010111010')} {ut.assert_logic N "('++')_2" ('0xFF' '++' '0x00000000' '==' '0xFF00000000')} {ut.assert_equal N "(')_1" (width '0000''[3 : 0]) 4} {ut.assert_equal N "(')_2" (width '0000''[1 : 2]) 2} {ut.assert_logic N "(')_3" (('00010111''[] '++' '010') '==' '010')} {ut.assert_logic N "(')_4" (('00010111''[7 : 0]) '==' '00010111')} {ut.assert_logic N "(')_5" (('00010111''[0 : 7]) '==' '11101000')} {ut.assert_logic N "(')_6" (('00010111''[7 5 3 1 0 2 4 6]) '==' '00011110')} {ut.assert_logic N "(')_7" (1'0 '==' '0')} {ut.assert_logic N "(')_8" (3'-1 '==' '111')} {ut.assert_logic N "(')_9" (8'0xABC '==' '0xBC')} local bits is {list_of_bits '001101' bits} {ut.assert_equal N "list_of_bits_0" (length bits) 6} {ut.assert_logic N "list_of_bits_1" ({List.nth bits 0 $} '==' '0')} {ut.assert_logic N "list_of_bits_2" ({List.nth bits 1 $} '==' '0')} {ut.assert_logic N "list_of_bits_3" ({List.nth bits 2 $} '==' '1')} {ut.assert_logic N "list_of_bits_4" ({List.nth bits 3 $} '==' '1')} {ut.assert_logic N "list_of_bits_5" ({List.nth bits 4 $} '==' '0')} {ut.assert_logic N "list_of_bits_6" ({List.nth bits 5 $} '==' '1')} end {ut.assert_logic N "all_bits_high_1" ('~' {all_bits_high '0011' $})} {ut.assert_logic N "all_bits_high_2" {all_bits_high '1111' $}} {ut.assert_logic N "all_bits_high_3" ('~' {all_bits_high '0000' $})} {ut.assert_logic N "all_bits_low_1" ('~' {all_bits_low '0011' $})} {ut.assert_logic N "all_bits_low_2" ('~' {all_bits_low '1111' $})} {ut.assert_logic N "all_bits_low_3" {all_bits_low '0000' $}} {ut.assert_logic N "all_bits_same_1" ('~' {all_bits_same '0011' $})} {ut.assert_logic N "all_bits_same_2" {all_bits_same '1111' $}} {ut.assert_logic N "all_bits_same_3" {all_bits_same '0000' $}} {ut.assert_logic N "mux_1" ({mux '00' ['00' '01' '10' '11'] $} '==' '00')} {ut.assert_logic N "mux_2" ({mux '01' ['00' '01' '10' '11'] $} '==' '01')} {ut.assert_logic N "mux_3" ({mux '10' ['00' '01' '10' '11'] $} '==' '10')} {ut.assert_logic N "mux_4" ({mux '11' ['00' '01' '10' '11'] $} '==' '11')} {ut.assert_logic N "truth_table_1" ({truth_table [["0-" "00"] ["10" "10"] ["11" "11"]] '00' $} '==' '00')} {ut.assert_logic N "truth_table_2" ({truth_table [["0-" "00"] ["10" "10"] ["11" "11"]] '01' $} '==' '00')} {ut.assert_logic N "truth_table_3" ({truth_table [["0-" "00"] ["10" "10"] ["11" "11"]] '10' $} '==' '10')} {ut.assert_logic N "truth_table_4" ({truth_table [["0-" "00"] ["10" "10"] ["11" "11"]] '11' $} '==' '11')} {ut.assert_logic N "decoder_1" ({decoder '0' '00' $} '==' '0000')} {ut.assert_logic N "decoder_2" ({decoder '0' '01' $} '==' '0000')} {ut.assert_logic N "decoder_3" ({decoder '0' '10' $} '==' '0000')} {ut.assert_logic N "decoder_4" ({decoder '0' '11' $} '==' '0000')} {ut.assert_logic N "decoder_5" ({decoder '1' '00' $} '==' '0001')} {ut.assert_logic N "decoder_6" ({decoder '1' '01' $} '==' '0010')} {ut.assert_logic N "decoder_7" ({decoder '1' '10' $} '==' '0100')} {ut.assert_logic N "decoder_8" ({decoder '1' '11' $} '==' '1000')} {ut.assert_logic N "state_machine_1" ({state_machine [(i:"--11" s:"0" n:"1" o:"00")] '0000' $} '==' '00')} end confluence-0.10.6/lib/base_test/run_test0100755002340600244710000000065710266541655017653 0ustar hawkit1cadgrp#!/bin/bash # Invoke Confluence. cf base_test.cf fnf -read_fnf out.fnf -write_c out -write_fnf out.fnf # Compile C. gcc -Wall -c out.c # Compile and execute Verilog. #iverilog -Wall -o lib_unit_test_v lib_unit_test_bench.v lib_unit_test.v #./lib_unit_test_v # Compile and execute VHDL. #ghdl -a lib_unit_test_bench.vhd lib_unit_test.vhd # Validate XML netlist. #xmllint -noout -valid lib_unit_test.xml # Clean up. #rm out.* confluence-0.10.6/lib/base.cf0100644002340600244710000010370110266541654015326 0ustar hawkit1cadgrp(* Confluence System Design Library Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) rootenvironment (* General *) (==) (!=) error string_of show unify (* Components *) is_component string_of_component (* Systems *) is_system string_of_system ports_of_system (* Numbers (integers and floats) *) (<) (>) (<=) (>=) (+) (-) (*) (/) (**) (* Integers *) is_integer string_of_integer integer_of_string float_of_integer (%) (~) (&) (^) (|) (<<) (>>) range (:) binary_of_integer integer_of_binary bits_required (* Floats *) is_float string_of_float float_of_string integer_of_float ceil floor round exp log sqrt sin cos tan asin acos atan atan2 e pi (* Booleans *) is_boolean string_of_boolean (!) (* Records *) is_record record_info string_of_record (* Lists *) is_list string_of_list print argv (head) (tail) (length) (++) (::) (#) List (* nth take drop reverse flatten isolate transpose map mapi map2 fold_left fold_right tree iter iteri Assoc (* find member add remove replace *) member satisfy_and satisfy_or find filter partition sort *) (* Vectors *) is_vector string_of_vector vector_of_string bin_of_vector hex_of_vector (width) clock reset enable assert input output inout display const one ones zero reg regs bbox rom ram_wbr ram_rbw ('~') ('&') ('^') ('|') ('then') tristate ('++') ('#') (') ('==') ('!=') ('<') ('>') ('<=') ('>=') ('<+') ('>+') ('<=+') ('>=+') ('+') ('-') ('*') ('*+') ('<<') ('>>') ('>>+') ('/') ('%') ('**') ('msb') ('msbs') ('lsb') ('lsbs') external_combinatorial external_sequential external_softvector list_of_bits all_bits_high all_bits_low all_bits_same mux counter decoder truth_table state_machine (* CTL* Properties *) is_property string_of_property (`!`) (`X`) (* (`G`) (`F`) *) (`&&`) (`^^`) (`||`) (`<->`) (`->`) (`U`) (* (`W`) (`B`) (`V`) *) sequence (* Abstract Data Types *) (* Map Set *) is (* General *) (** Compares any two values for equality. *) component (==) +a +b -is_equal is {prim IsEqual a b is_equal end a b is_equal} end (** Compares any two values for inequality. *) component (!=) +a +b -is_not_equal is is_not_equal = ! (a == b) end (** Raises an error and prevents code generation. *) component error +msg is {prim Error msg end msg} end (** Converts any value to a string. Handles recursive data structures. *) component string_of +value +sofar -str is if {is_component value $} {string_of_component value str} ef {is_integer value $} {string_of_integer value str} ef {is_float value $} {string_of_float value str} ef {is_boolean value $} {string_of_boolean value str} ef {is_vector value $} {string_of_vector value str} ef {is_property value $} {string_of_property value str} ef {List.member sofar value $} str = "rec" ef {is_list value $} {string_of_list value sofar str} ef {is_record value $} {string_of_record value sofar str} ef {is_system value $} {string_of_system value sofar str} else {error "string_of: Unknown type."} end end (** Prints any value to stdout. *) component show +value is {print {string_of value [] $}} end (** Unifies two variables. *) component unify *value_a *value_b is value_a = value_b end (* Components *) (** Checks if value is a component. *) component is_component +value -yes is {prim IsComponent a x end value yes} end (** Converts a component to a string. *) component string_of_component +comp_value -str is if !{is_component comp_value $} {error "string_of_component: Value is not a component."} else str = "" end end (* Systems *) (** Checks if value is a system. *) component is_system +value -yes is {prim IsSystem a x end value yes} end (** Returns the record of a system's ports. *) component ports_of_system system port_record is {prim SystemPorts a x end system port_record} end (** Converts a system to a string. *) component string_of_system +system +sofar -str is if !{is_system system $} {error "string_of_system: Value is not a system."} else str = "" end end (* Numbers *) (** Less than comparison of integers or floats. *) component (<) +a +b -yes is if {is_integer a $} && {is_integer b $} {prim IntegerLt a b x end a b yes} ef {is_float a $} && {is_float b $} {prim FloatLt a b x end a b yes} else {error "(<): Values are not integers or floats."} end end (** Greater than comparison of integers or floats. *) component (>) +a +b -yes is if {is_integer a $} && {is_integer b $} || {is_float a $} && {is_float b $} yes = ! (a < b || a == b) else {error "(>): Values are not integers or floats."} end end (** Less than or equal comparison of integers or floats. *) component (<=) +a +b -yes is if {is_integer a $} && {is_integer b $} || {is_float a $} && {is_float b $} yes = a < b || a == b else {error "(<=): Values are not integers or floats."} end end (** Greater than or equal comparison of integers or floats. *) component (>=) +a +b -yes is if {is_integer a $} && {is_integer b $} || {is_float a $} && {is_float b $} yes = ! (a < b) else {error "(>=): Values are not integers or floats."} end end (** Integer or float addition. *) component (+) +a +b -x is if {is_integer a $} && {is_integer b $} {prim IntegerAdd a b x end a b x} ef {is_float a $} && {is_float b $} {prim FloatAdd a b x end a b x} else {error "(+): Values are not integers or floats."} end end (** Integer or float subtraction. *) component (-) +a +b -x is if {is_integer a $} && {is_integer b $} {prim IntegerSub a b x end a b x} ef {is_float a $} && {is_float b $} {prim FloatSub a b x end a b x} else {error "(-): Values are not integers or floats."} end end (** Integer or float multiplication. *) component (*) +a +b -x is if {is_integer a $} && {is_integer b $} {prim IntegerMul a b x end a b x} ef {is_float a $} && {is_float b $} {prim FloatMul a b x end a b x} else {error "(*): Values are not integers or floats."} end end (** Integer or float division. *) component (/) +a +b -x is if {is_integer a $} && {is_integer b $} {prim IntegerDiv a b x end a b x} ef {is_float a $} && {is_float b $} {prim FloatDiv a b x end a b x} else {error "(/): Values are not integers or floats."} end end (** Integer or float power. *) component (**) +a +b -x is if {is_integer a $} && {is_integer b $} {prim IntegerPow a b x end a b x} ef {is_float a $} && {is_float b $} {prim FloatPow a b x end a b x} else {error "(**): Values are not integers or floats."} end end (* Integers *) (** Checks if value is an integer. *) component is_integer +value -yes is {prim IsInteger a x end value yes} end (** Converts and integer to a string. *) component string_of_integer +integer -str is {prim IntegerToString a x end integer str} end (** Converts a string to an integer. *) component integer_of_string +str -integer is {prim StringToInteger a x end str integer} end (** Converts an integer to a float. *) component float_of_integer +integer -float is {prim IntegerToFloat a x end integer float} end (** Integer modulo. *) component (%) +a +b -x is {prim IntegerMod a b x end a b x} end (** Integer bitwise NOT. *) component (~) +a -x is {prim IntegerNot a x end a x} end (** Integer bitwise AND. *) component (&) +a +b -x is {prim IntegerAnd a b x end a b x} end (** Integer bitwise XOR. *) component (^) +a +b -x is {prim IntegerXor a b x end a b x} end (** Integer bitwise OR. *) component (|) +a +b -x is {prim IntegerOr a b x end a b x} end (** Integer bitwise shift left. *) component (<<) +a +b -x is {prim IntegerShiftLeft a b x end a b x} end (** Integer bitwise shift right. *) component (>>) +a +b -x is {prim IntegerShiftRight a b x end a b x} end (** Returns a list of integers between a certain range (inclusive). *) component range +a +b -x is x = a == b then [a] else a < b then a :: {range (a + 1) b $} else a :: {range (a - 1) b $} end (:) = range (** Returns the number of bits required to represent a number of items. *) component bits_required +tally -bits is if tally < 0 {error "bits_required: tally must be >= 0."} ef tally == 0 bits = 0 ef tally == 1 bits = 1 else bits = {integer_of_float {ceil ({log {float_of_integer tally $} $} / {log 2.0 $}) $} $} end end local binary_of_integer0 is component binary_of_integer0 +value +width_ +bin_in -bin_out is if width_ <= 0 bin_out = bin_in else bin_out = {binary_of_integer0 (value / 2) (width_ - 1) ((value % 2 == 1 then "1" else "0") ++ bin_in) $} end end (** Converts an integer into a binary string. *) component binary_of_integer +value +width_ -binary is if width_ < 0 {error "binary_of_integer: width_ must be >= 0."} else {binary_of_integer0 value width_ "" binary} end end end local integer_of_binary0 is component integer_of_binary0 +binary +factor +value_in -value_out is if binary == "" value_out = value_in else value_out = {integer_of_binary0 (tail binary) (factor * 2) (head binary == @1 then value_in + factor else value_in) $} end end (** Converts a binary string into an integer. *) component integer_of_binary +binary -integer is {integer_of_binary0 {List.reverse binary $} 1 0 integer} end end (* Floats *) (** Checks if value is a float. *) component is_float +value -yes is {prim IsFloat a x end value yes} end (** Converts a float to a string. *) component string_of_float +float -str is {prim FloatToString a x end float str} end (** Converts a string to a flost. *) component float_of_string +str -float is {prim StringToFloat a x end str float} end (** Converts a float to an integer. *) component integer_of_float +float -integer is {prim FloatToInteger a x end float integer} end (** Rounds a float up to the nearest integer (float type returned). *) component ceil +a -x is {prim FloatCeil a x end a x} end (** Rounds a float down to the nearest integer (float type returned). *) component floor +a -x is {prim FloatFloor a x end a x} end (** Rounds a float to the nearest integer (float type returned). *) component round +a -x with t is {floor a t} x = a - t <= 0.5 then t else {ceil a $} end (** Exponent. *) component exp +a -x is {prim FloatExp a x end a x} end (** Natural log. *) component log +a -x is {prim FloatLog a x end a x} end (** Square root. *) component sqrt +a -x is x = a ** 0.5 end (** Sine of radians. *) component sin +a -x is {prim FloatSin a x end a x} end (** Cosine of radians. *) component cos +a -x is {prim FloatCos a x end a x} end (** Tangent of radians. *) component tan +a -x is {prim FloatTan a x end a x} end (** Arc sine. *) component asin +a -x is {prim FloatAsin a x end a x} end (** Arc cosine. *) component acos +a -x is {prim FloatAcos a x end a x} end (** Arc tangent. *) component atan +a -x is {prim FloatAtan a x end a x} end (** Arc tangent2. *) component atan2 +rise +run -x is {prim FloatAtan2 a b x end rise run x} end (* Exponent e. *) e = {exp 1.0 $} (* PI. *) pi = {acos -1.0 $} (* Booleans *) (** Checks if value is a boolean. *) component is_boolean +value -yes is {prim IsBoolean a x end value yes} end (** Converts a boolean to a string. *) component string_of_boolean +boolean -str is if !{is_boolean boolean $} {error "string_of_boolean: Value is not a boolean."} else str = boolean then "true" else "false" end end (** Boolean negation. *) component (!) +a -x is {prim BooleanNot a x end a x} end (* Records *) (** Checks if value is a record. *) component is_record +value -yes is {prim IsRecord a x end value yes} end (** Record information. A list of (name: value:). *) component record_info +record -info is {prim RecordInfo a x end record info} end (** Converts a record to a string. *) component string_of_record +record +sofar -str with f sofar0 is sofar0 = record :: sofar component f +pairs -str is if pairs == [] str = "" else with h t is h :: t = pairs str = h.name ++ ":" ++ {string_of h.value sofar0 $} ++ (t == [] then "" else " " ++ {f t $}) end end str = "(" ++ {f {record_info record $} $} ++ ")" end (* Lists *) (** Checks if value is a list. *) component is_list +value -yes is {prim IsList a x end value yes} end (** Converts a list to a string. *) component string_of_list +list +sofar -str with sofar0 string_of_elements is sofar0 = list :: sofar component string_of_elements +es -str is if es == [] str = [] ef tail es == [] str = {string_of (head es) sofar0 $} else str = {string_of (head es) sofar0 $} ++ " " ++ {string_of_elements (tail es) $} end end str = "[" ++ {string_of_elements list $} ++ "]" end (** Prints a string to stdout. *) component print +str is {prim ListPrint a end str} end (* Command line arguments. *) argv = {prim ListArgv -Args end $} (** Returns the first element of a list (head). *) component (head) +list -hd is hd = list.hd end (** Returns the list without the first element (tail). *) component (tail) +list -tl is tl = list.tl end (** Returns the length of a list. *) component (length) +list -len is {List.fold_left comp +count +ele +total is total = count + 1 end 0 list len} end (** Creates a new list by added an element in front of an existing list (cons). *) component (::) *hd *tl *list is list = (hd:hd tl:tl) end (** Concatenates two lists together. *) component (++) +a +b -x is if a == [] x = b else x = head a :: {(++) (tail a) b $} end end (** Repeated list concatenation. *) component (#) +list_in +count -list_out with f is component f +list +count -list_out is if count <= 0 list_out = list else list_out = {f (list ++ list_in) (count - 1) $} end end {f [] count list_out} end (* Common list functions. *) List = import "list.cf" (* Vectors *) (** Checks if value is a vector. *) component is_vector +value -yes is {prim IsVector a x end value yes} end (** Converts a vector to a string. Width information included. *) component string_of_vector +vec -str is if !{is_vector vec $} {error "string_of_vector: Value is not a vector."} else str = "" end end local f is component f +str +vec_in -vec_out is if str == "" vec_out = vec_in else vec_out = {f (tail str) (vec_in '++' {const 8 (head str) $}) $} end end (** Converts a string to an ASCII encoded vector. *) component vector_of_string +str -vec is {f str '' vec} end end (** Converts a vector into a ASCII bin vector. *) component bin_of_vector +vec -vec_bin is if width vec <= 0 vec_bin = '' else vec_bin = ('msb' vec 'then' {const 8 @1 $} 'else' {const 8 @0 $}) '++' {bin_of_vector ('lsbs' vec) $} end end local hex_of_nib is component hex_of_nib +nib -hex is hex = nib '==' '0000' 'then' {const 8 @0 $} 'else' nib '==' '0001' 'then' {const 8 @1 $} 'else' nib '==' '0010' 'then' {const 8 @2 $} 'else' nib '==' '0011' 'then' {const 8 @3 $} 'else' nib '==' '0100' 'then' {const 8 @4 $} 'else' nib '==' '0101' 'then' {const 8 @5 $} 'else' nib '==' '0110' 'then' {const 8 @6 $} 'else' nib '==' '0111' 'then' {const 8 @7 $} 'else' nib '==' '1000' 'then' {const 8 @8 $} 'else' nib '==' '1001' 'then' {const 8 @9 $} 'else' nib '==' '1010' 'then' {const 8 @A $} 'else' nib '==' '1011' 'then' {const 8 @B $} 'else' nib '==' '1100' 'then' {const 8 @C $} 'else' nib '==' '1101' 'then' {const 8 @D $} 'else' nib '==' '1110' 'then' {const 8 @E $} 'else' {const 8 @F $} end (** Converts a vector into a ASCII hex vector. *) component hex_of_vector +vec -vec_hex is if width vec <= 0 vec_hex = '' ef width vec < 4 vec_hex = {hex_of_nib ('0' '#' (4 - width vec) '++' vec) $} ef width vec == 4 vec_hex = {hex_of_nib vec $} else vec_hex = {hex_of_vector vec'[((width vec) - 1) : 4] $} '++' {hex_of_nib vec'[3 : 0] $} end end end (** Returns the integer width of a vector. *) component (width) +vec -width_ is {prim VectorWidth a x end vec width_} end (** Clocks a subsystem. Clock must be a string. *) component clock +clock_name +system is {prim VectorClock a b end clock_name system} end (** Resets a subsystem. *) component reset +vec_reset +system is {prim VectorReset a b end vec_reset system} end (** Enables a subsystem. *) component enable +vec_enable +system is {prim VectorEnable a b end vec_enable system} end (** Posts assertion violation message with test vector drops low. *) (* XXX component assert +message +test is {prim VectorAssert a b end message test} end *) (** Creates a top level input, given a port name and width. *) component input +name +width_ -vec is {prim VectorInput a b x end name width_ vec} end (** Creates a top level output, given a port name and vector. *) component output +name +vec is {prim VectorOutput a b end name vec} end (** Displays an ASCII encoded vector, provided enable is high. *) (* XXX component display +enable +message is {prim VectorPrint a b end enable message} end *) (** Creates a vector constant given a width and value. *) component const +width_ +value -vec is {prim VectorConst a b x end value width_ vec} end (** Creates a vector constant of ...0001. *) component one +width_ -vec is {const width_ 1 vec} end (** Creates a vector constant of ...1111. *) component ones +width_ -vec is {const width_ -1 vec} end (** Creates a vector constant of ...0000. *) component zero +width_ -vec is {const width_ 0 vec} end (** Creates a register given a width and an input vector. *) component reg +width_ +in -out is {prim VectorReg a b x end width_ in out} end (** Creates a register chain given a width, a delay length, and an input vector. *) component regs +width_ +depth +in -out is if depth <= 0 in = out else {regs width_ (depth - 1) {reg width_ in $} out} end end (** Creates a black box. *) component bbox +name +wid +params +in -out is {prim VectorBbox a b c d x end name wid params in out} end (** Creates a ROM given a data width, list of values, and an address vector. *) (* XXX Implemented with registers. *) component rom +width_ +values +addr -data with rom_consts is {List.map comp a x is x = width_'a end values rom_consts} {reg width_ {mux addr rom_consts $} data} end (** Creates a read-before-write RAM. *) component ram_rbw +data_width +write_enable +write_addr +write_data +read_addr -read_data with reg_enables reg_data is {decoder write_enable write_addr reg_enables} {List.map comp +reg_enable -reg_data is {enable reg_enable {reg data_width write_data reg_data}} end {list_of_bits reg_enables $} reg_data} {reg data_width {mux read_addr reg_data $} read_data} end (** Creates a write-before-read RAM. *) component ram_wbr +data_width +write_enable +write_addr +write_data +read_addr -read_data with reg_enables reg_data is {decoder write_enable write_addr reg_enables} {List.map comp +reg_enable -reg_data is {enable reg_enable {reg data_width write_data reg_data}} end {list_of_bits reg_enables $} reg_data} {mux {reg (width read_addr) read_addr $} reg_data read_data} end (** Vector bitwise NOT. *) component ('~') +a -x is {prim VectorNot a x end a x} end (** Vector bitwise AND. *) component ('&') +a +b -x is {prim VectorAnd a b x end a b x} end (** Vector bitwise XOR. *) component ('^') +a +b -x is {prim VectorXor a b x end a b x} end (** Vector bitwise OR. *) component ('|') +a +b -x is {prim VectorOr a b x end a b x} end (** 2 input mux: ctrl 'then' high 'else' low *) component ('then') +ctrl +high +low -result is {prim VectorMux a b c x end ctrl high low result} end (** Vector concatenation. *) component ('++') +a +b -x is {prim VectorConcat a b x end a b x} end (** Vector repeated concatenation. *) component ('#') +vec +count -vec_out is if count <= 0 vec_out = '' else vec_out = vec '++' {('#') vec (count - 1) $} end end (** Vector bit select or constant declaration. For selection, bits is a list of integers, where head of list becomes MSB. For constant declartion, in is the width and bits is the value. *) component (') +in +bits -out is if {is_integer in $} {const in bits out} ef bits == [] {prim VectorZero x end out} else out = {prim VectorSelect a b x end in (head bits) $} '++' {(') in (tail bits) $} end end (** Vector equality comparison. *) component ('==') +a +b -is_equal is {prim VectorEqu a b x end a b is_equal} end (** Vector inequality comparison. *) component ('!=') +a +b -is_not_equal is is_not_equal = '~' (a '==' b) end (** Vector unsigned less than comparison. *) component ('<') +a +b -yes is {prim VectorLt a b yes end a b yes} end (** Vector unsigned greater than comparison. *) component ('>') +a +b -yes is {('<') b a yes} end (** Vector unsigned less than or equal comparison. *) component ('<=') +a +b -yes is yes = '~' (a '>' b) end (** Vector unsigned greater than or equal comparison. *) component ('>=') +a +b -yes is yes = '~' (a '<' b) end (** Vector signed less than comparison. *) component ('<+') +a +b -yes is yes = ('~' 'msb' a '++' 'lsbs' a) '<' ('~' 'msb' b '++' 'lsbs' b) end (** Vector signed greater than comparison. *) component ('>+') +a +b -yes is yes = ('~' 'msb' a '++' 'lsbs' a) '>' ('~' 'msb' b '++' 'lsbs' b) end (** Vector signed less than or equal comparison. *) component ('<=+') +a +b -yes is yes = ('~' 'msb' a '++' 'lsbs' a) '<=' ('~' 'msb' b '++' 'lsbs' b) end (** Vector signed greater than or equal comparison. *) component ('>=+') +a +b -yes is yes = ('~' 'msb' a '++' 'lsbs' a) '>=' ('~' 'msb' b '++' 'lsbs' b) end (** Vector addition. *) component ('+') +a +b -x is {prim VectorAdd a b x end a b x} end (** Vector subtraction. *) component ('-') +a +b -x is {prim VectorSub a b x end a b x} end (** Vector unsigned multiplication. *) component ('*') +a +b -x is if width a == 0 || width b == 0 {error "('*'): Vectors require width greater than 0."} end {prim VectorMul a b x end ({zero (width b) $} '++' a) ({zero (width a) $} '++' b) x} end (** Vector signed multiplication. *) component ('*+') +a +b -x is if width a == 0 || width b == 0 {error "('*+'): Vectors require width greater than 0."} end {prim VectorMul a b x end ('msb' a '#' width b '++' a) ('msb' b '#' width a '++' b) x} end (** Vector shift right. Shift amount must be a positive integer. *) component ('<<') +vec_a +shift -vec_x is (* XXX Add support for vector '<<' vector. *) if shift < 0 {error "('<<'): Shift amount must be >= 0."} else with width_ is width_ = width vec_a if shift >= width_ vec_x = '0' '#' width_ else vec_x = vec_a'[(width_ - 1 - shift) : 0] '++' '0' '#' shift end end end (** Vector unsigned shift left. Shift amount must be a positive integer. *) component ('>>') +vec_a +shift -vec_x is (* XXX Add support for vector '>>' vector. *) if shift < 0 {error "('>>'): Shift amount must be >= 0."} else with width_ is width_ = width vec_a if shift >= width_ vec_x = '0' '#' width_ else vec_x = '0' '#' shift '++' vec_a'[(width_ - 1) : shift] end end end (** Vector signed shift left. Shift amount must be a positive integer. *) component ('>>+') +vec_a +shift -vec_x is (* XXX Add support for vector '>>+' vector. *) if shift < 0 {error "('>>+'): Shift amount must be >= 0."} else with width_ is width_ = width vec_a if shift >= width_ vec_x = 'msb' vec_a '#' width_ else vec_x = 'msb' vec_a '#' shift '++' vec_a'[(width_ - 1) : shift] end end end (** ('/') operator is not supported. *) component ('/') +vec_a +vec_b -vec_x is {error "('/'): Operator not supported."} (* XXX *) end (** ('%') operator is not supported. *) component ('%') +vec_a +vec_b -vec_x is {error "('%'): Operator not supported."} (* XXX *) end (** ('**') operator is not supported. *) component ('**') +vec_a +vec_b -vec_x is {error "('**'): Operator not supported."} (* XXX *) end (** Returns the least signficant bit of a vector. *) component ('lsb') +vec_a -vec_x is vec_x = vec_a'[0] end (** Returns the most signficant bit of a vector. *) component ('msb') +vec_a -vec_x is vec_x = vec_a'[(width vec_a - 1)] end (** Returns a vector without the most signficant bit. *) component ('lsbs') +vec_a -vec_x is if width vec_a == 0 {error "('lsbs'): Width must be > 0."} ef width vec_a == 1 vec_x = '' else vec_x = vec_a'[(width vec_a - 2) : 0] end end (** Returns a vector without the least signficant bit. *) component ('msbs') +vec_a -vec_x is if width vec_a == 0 {error "('msbs'): Width must be > 0."} ef width vec_a == 1 vec_x <- '' else vec_x <- vec_a'[(width vec_a - 1) : 1] end end (* (** External combinatorial component. *) component external_combinatorial +name +params +in +width_out -out is {prim VectorExtComb a b c d x end name params in width_out out} end (** External sequential component. *) component external_sequential +name +params +in +width_out -out is {prim VectorExtSequ a b c d x end name params in width_out out} end (** External soft component. *) component external_softvector +name +params +width_ *data is {prim VectorExtSoft a b c x end name params width_ data} end *) (** Splits of a vector into a list of 1-bit vectors. Head of list is MSB. *) component list_of_bits +vec -bits is if width vec == 0 bits = [] else bits = 'msb' vec :: {list_of_bits ('lsbs' vec) $} end end (** Returns '1' when all bits in a vector are high. *) component all_bits_high +vec -yes is {List.tree ('&') unify {list_of_bits vec $} yes} end (** Returns '1' when all bits in a vector are low. *) component all_bits_low +vec -yes is yes = '~' {List.tree ('|') unify {list_of_bits vec $} $} end (** Returns '1' when all bits in a vector are the same. *) component all_bits_same +vec -yes is yes = {all_bits_high vec $} '|' {all_bits_low vec $} end local mux_down_row is component mux_down_row +sel +ins -outs is if ins == [] || length ins == 1 outs = ins else outs = (sel 'then' head tail ins 'else' head ins) :: {mux_down_row sel (tail tail ins) $} end end (** Vector multiplexer. Select of '000' selects head of options. *) component mux +select +options -out is if options == [] {error "mux: Option list must have at least 1 element."} ef length options == 1 out = head options ef width select == 0 {error "mux: Not enough select bits to select all options."} else out = {mux ('msbs' select) {mux_down_row ('lsb' select) options $} $} end end end (** Given a width, creates an up counter reset to 0. *) component counter +width_ -count with next is next = count '+' {one width_ $} {reg width_ next count} end (** Decoder with an enable. *) component decoder +enable +addr -decode with addr_width number table_rows is addr_width = width addr number = 2 ** addr_width component table_rows +count -rows is if count >= number rows = [] else rows = [("1" ++ {binary_of_integer count addr_width $}) (("0" # (number - count - 1)) ++ "1" ++ ("0" # count))] :: {table_rows (count + 1) $} end end {truth_table ([("0" ++ ("-" # addr_width)) ("0" # number)] :: {table_rows 0 $}) (enable '++' addr) decode} end local validate_input_bit validate_output_bit check_table build_outputs select build_logic is component validate_input_bit +bit is if ! (bit == @0 || bit == @1 || bit == @-) {error "truth_table: Invalid bit string."} end end component validate_output_bit +bit is if ! (bit == @0 || bit == @1) {error "truth_table: Invalid bit string."} end end component check_table +table +input_width +output_width is if table != [] with row input output is row = head table {List.nth row 0 input} {List.nth row 1 output} if input_width != length input {error "truth_table: Input width does not match." } end if output_width != length output {error "truth_table: Output width does not match."} end {List.iterate validate_input_bit input} {List.iterate validate_output_bit output} {check_table (tail table) input_width output_width} end end component build_outputs +outputs +assoc_in -assoc_out is if outputs == [] assoc_out = assoc_in else with output is output = head outputs if {List.Assoc.member assoc_in output $} {build_outputs (tail outputs) assoc_in assoc_out} else {build_outputs (tail outputs) {List.Assoc.add assoc_in output {const (length output) {integer_of_binary output $} $} $} assoc_out} end end end component select +input +bit -bit_string -bit_select is if input == [] bit_string = "" bit_select = [] else if head input == @- {select (tail input) (bit - 1) bit_string bit_select} else with bit_string_0 bit_select_0 is {select (tail input) (bit - 1) bit_string_0 bit_select_0} bit_string = head input :: bit_string_0 bit_select = bit :: bit_select_0 end end end component build_logic +table +input +input_width +output_vectors -output with row input_string output_string is row = head table {List.nth row 0 input_string} {List.nth row 1 output_string} if length table == 1 {List.Assoc.find output_vectors {List.nth row 1 $} output} else with bit_string bit_select vector_comp is {select input_string (input_width - 1) bit_string bit_select} {const (length bit_string) {integer_of_binary bit_string $} vector_comp} if length bit_string == input_width output = input '==' vector_comp 'then' {List.Assoc.find output_vectors output_string $} 'else' {build_logic (tail table) input input_width output_vectors $} else output = input'bit_select '==' vector_comp 'then' {List.Assoc.find output_vectors output_string $} 'else' {build_logic (tail table) input input_width output_vectors $} end end end (** Constructs a truth-table given an input and a table. Example: [["00" "11"] ["01" "10"] ["1-" "00"]] *) component truth_table +table +input -output with outputs is {check_table table (length head head table) (length head tail head table)} {build_outputs {List.nth {List.transpose table $} 1 $} [] outputs} {build_logic table input (width input) outputs output} end end (** Constructs a state-machine given a state transition table. Inputs (i) and current states (s) may use dontcare bits ("-01"). Outputs (o) and next states (s) must only use true bits ("01"). Example: [(i:"0-" s:"0" n:"1" o:"11") (i:"11" s:"1" n:"0" o:"00")] *) component state_machine +table +input -output with first_row i_width s_width o_width validate_row tt_table state next_state next_state_output is first_row = head table i_width = length first_row.i o_width = length first_row.o s_width = length first_row.s component validate_row row is if length row.i != i_width {error "state-machine: Inconsistant input widths."} end if length row.o != o_width {error "state-machine: Inconsistant output widths."} end if length row.s != s_width {error "state-machine: Inconsistant state widths."} end if length row.n != s_width {error "state-machine: Inconsistant next-state widths."} end end {List.iterate validate_row table} {List.map comp row_sm row_tt is row_tt = [(row_sm.i ++ row_sm.s) (row_sm.n ++ row_sm.o)] end table tt_table} {reg s_width next_state state} {truth_table tt_table (input '++' state) next_state_output} next_state = next_state_output'[(s_width + o_width - 1) : o_width] output = next_state_output'[(o_width - 1) : 0] end (* Properties *) (** Checks if value is a property. *) component is_property +value -yes is {prim IsProperty a x end value yes} end (** Converts a property to a string. *) component string_of_property +prop -str is if ! {is_property prop $} {error "string_of_property: Value is not a property."} else str = "" end end (** Property logical negation. *) component (`!`) +prop_a -prop_x is {prim PropertyNot a x end prop_a prop_x} end (** Property temporal next. *) component (`X`) +prop_a -prop_x is {prim PropertyNext a x end prop_a prop_x} end (** Property logical AND. *) component (`&&`) +prop_a +prop_b -prop_x is prop_x = `!` (`!` prop_a `||` `!` prop_b) end (** Property logical XOR. *) component (`^^`) +prop_a +prop_b -prop_x is prop_x = (prop_a `&&` `!` prop_b) `||` (`!` prop_a `&&` prop_b) end (** Property logical OR. *) component (`||`) +prop_a +prop_b -prop_x is {prim PropertyOr a b x end prop_a prop_b prop_x} end (** Property logical equivalence. *) component (`<->`) +prop_a +prop_b -prop_x is prop_x = `!` (prop_a `^^` prop_b) end (** Propeprty logical implication. *) component (`->`) +prop_a +prop_b -prop_x is prop_x = `!` (prop_a `&&` `!` prop_b) end (** Property temporal until. *) component (`U`) +prop_a +prop_b -prop_x is {prim PropertyUntil a b x end prop_a prop_b prop_x} end (** Property sequence. *) component sequence +prop_list -prop_x is if prop_list == [] {error "sequence: Requires one or more properties."} ef length prop_list == 1 prop_x = head prop_list else prop_x = head prop_list `->` `X` {sequence (tail prop_list) $} end end confluence-0.10.6/lib/list.cf0100644002340600244710000002160310266541654015367 0ustar hawkit1cadgrp(* Confluence System Design Library Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) environment "base.cf" nth take drop reverse flatten isolate transpose map map2 fold_left fold_right tree iterate Assoc (* find member add remove replace *) member satisfy_and satisfy_or find filter partition sort is (* List queries, selections, and transformations. *) (** Returns the nth element of a list. Index starts at 0. *) component nth +list +n -ele is if n < 0 {error "nth: List is too short."} ef n == 0 ele = head list else ele = {nth (tail list) (n - 1) $} end end (** Takes the first n elements of a list. *) component take +list +n -taken is if n < 0 || list == [] && n > 0 {error "take: List is too short."} ef n == 0 taken = [] else taken = head list :: {take (tail list) (n - 1) $} end end (** Drops the first n elements of a list. *) component drop +list +n -remaining is if n < 0 || list == [] && n > 0 {error "drop: List is too short."} ef n == 0 remaining = list else remaining = {drop (tail list) (n - 1) $} end end (** Reverses the order of a list. *) component reverse +list -rev is {fold_left comp +sofar +ele -new is new = ele :: sofar end [] list rev} end (** Flattens a list into a single list of non-list elements. *) component flatten +list_a -list_x is if list_a == [] list_x = [] else with head_ tail_ is head_ = head list_a tail_ = {flatten (tail list_a) $} if {is_list head_ $} list_x = {flatten head_ $} ++ tail_ else list_x = head_ :: tail_ end end end (** Isolates each element of a list into a list of one element. *) component isolate +list_a -list_x is if list_a == [] list_x = [] else list_x = [(head list_a)] :: {isolate (tail list_a) $} end end (** Matrix transpose (a matrix is a list of equal length lists). *) component transpose +list_a -list_x is if length list_a == 0 {error "transpose: Requires non empty list."} else with tail_ is tail_ = tail list_a if tail_ == [] list_x = {isolate (head list_a) $} else list_x = {map2 (::) (head list_a) {transpose tail_ $} $} end end end (* List iteration. *) (** Applies a unary operation across a list of elements. *) component map +unary_op +list_a -list_x is if list_a == [] list_x = [] else list_x = {unary_op (head list_a) $} :: {map unary_op (tail list_a) $} (* XXX Make tail recursive. *) end end (** Applies a binary operation across two lists of equal length. *) component map2 +binary_op +list_a +list_b -list_x is if list_a == [] || list_b == [] list_x = [] else list_x = {binary_op (head list_a) (head list_b) $} :: {map2 binary_op (tail list_a) (tail list_b) $} (* XXX Make tail recursive. *) end end (** Folds a binary operation across a list, from left to right. Tail recursive. *) component fold_left +binary_op +start +elements -result is if elements == [] result = start else result = {fold_left binary_op {binary_op start (head elements) $} (tail elements) $} end end (** Folds a binary operation across a list, from right to left. Not tail recursive. *) component fold_right +binary_op +elements +start -result is if elements == [] result = start else result = {binary_op (head elements) {fold_right binary_op (tail elements) start $} $} end end (** Applies a binary operation to a list of elements in a binary tree pattern. When the list has an odd number of elements, the unary operation is applied. *) component tree +binary_op +unary_op +elements -result with rank tree0 is component rank +a -x is if a == [] x = a ef length a == 1 x = {unary_op (head a) $} :: [] else x = {binary_op {nth a 0 $} {nth a 1 $} $} :: {rank {drop a 2 $} $} end end component tree0 +elements -result is if elements == [] {error "tree: Input list needs at least one element."} ef length elements == 1 result = head elements else result = {tree0 {rank elements $} $} end end {tree0 elements result} end (** Applies a unit operation across a list of elements. *) component iterate +unit_op +elements is if elements != [] {unit_op (head elements)} {iterate unit_op (tail elements)} end end (* Association lists. *) local find member add remove replace is (** Finds a key, then returns a value of an association table. *) component find +table +key -value is if table == [] {error ("Assoc.find: Key not found: " ++ {string_of key [] $} ++ {string_of table [] $})} else with row is row = head table if key == head row {nth row 1 value} else {find (tail table) key value} end end end (** Checks if key is in association table. *) component member +table +key -yes is if table == [] yes = false else with row is row = head table if key == head row yes = true else {member (tail table) key yes} end end end (** Adds a key value pair to an association table. *) component add +table +key +value -table_new is table_new = [key value] :: table end (** Removes a key value pair from an association table. *) component remove +table +key -table_new is if table == [] table_new = [] else with row is row = head table if key == head row table_new = tail table else table_new = row :: {remove (tail table) key $} (* XXX Make tail recursive. *) end end end (** Replaces a key value pair in an association table. *) component replace +table +key +value -table_new is if table == [] table_new = [[key value]] else with row is row = head table if key == head row table_new = [key value] :: tail table (* XXX Make tail recursive. *) else table_new = row :: {replace (tail table) key value $} end end end Assoc = (find:find member:member add:add remove:remove replace:replace) end (* List scanning. *) (** Checks if a list contains an element. *) component member +list +element -yes is yes = {satisfy_or comp +a -x is x = a == element end list $} end (** Returns true iff all elements in the list satisfy the predicate. *) component satisfy_and +unary_predicate +list -yes is if list == [] yes = true else yes = {unary_predicate (head list) $} && {satisfy_and unary_predicate (tail list) $} end end (** Returns true iff any element in the list satisfies the predicate. *) component satisfy_or +unary_predicate +list -yes is if list == [] yes = false else yes = {unary_predicate (head list) $} || {satisfy_or unary_predicate (tail list) $} end end (* List searching, filtering, and sorting. *) (** Returns the first element in a list that satifies the predicate. *) component find +unary_predicate +list -element is if list == [] {error "find: Element not found in list."} else with hd is hd = head list element = {unary_predicate hd $} then hd else {find unary_predicate (tail list) $} end end (** Returns a list of elements that satisfy the predicate. *) component filter +unary_predicate +list_a -list_x is if list_a == [] list_x = [] else with hd tl is hd = head list_a tl = {filter unary_predicate (tail list_a) $} list_x = {unary_predicate hd $} then hd :: tl else tl end end (** Paritions a list into two lists: elements that do, and do not satisfy the predicate. *) component partition +unary_predicate +list_a -list_true -list_false is if list_a == [] list_true = list_false = [] else with hd tl_true tl_false is hd = head list_a {partition unary_predicate (tail list_a) tl_true tl_false} if {unary_predicate hd $} list_true = hd :: tl_true list_false = tl_false else list_true = tl_true list_false = hd :: tl_false end end end (** Sorts a list given a comparison function. *) component sort +compare +list_a -list_x is if list_a == [] list_x = [] else with hd tl top bottom is hd = head list_a tl = tail list_a {partition comp +a -x is {compare a hd x} end tl top bottom} list_x = {sort compare top $} ++ (hd :: {sort compare bottom $}) end end confluence-0.10.6/lib/common/0040755002340600244710000000000010312276326015364 5ustar hawkit1cadgrpconfluence-0.10.6/lib/common/common.cf0100644002340600244710000001311410266541655017173 0ustar hawkit1cadgrp(* Confluence System Design Library Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) -latch_moore_set -latch_moore_reset -latch_mealy_set -latch_mealy_reset -toggle_moore -toggle_mealy -timer -interleaver -sequence -sim_start is (* BsdLic = " Copyright (C) 2003-2004 Tom Hawkins All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. " *) component latch_moore_set +s +r -q is {state_machine [(i:"00" s:"0" n:"0" o:"0") (i:"01" s:"0" n:"0" o:"0") (i:"10" s:"0" n:"1" o:"0") (i:"11" s:"0" n:"1" o:"0") (i:"00" s:"1" n:"1" o:"1") (i:"01" s:"1" n:"0" o:"1") (i:"10" s:"1" n:"1" o:"1") (i:"11" s:"1" n:"1" o:"1")] (s '++' r) q} end component latch_moore_reset +s +r -q is {state_machine [(i:"00" s:"0" n:"0" o:"0") (i:"01" s:"0" n:"0" o:"0") (i:"10" s:"0" n:"1" o:"0") (i:"11" s:"0" n:"0" o:"0") (i:"00" s:"1" n:"1" o:"1") (i:"01" s:"1" n:"0" o:"1") (i:"10" s:"1" n:"1" o:"1") (i:"11" s:"1" n:"0" o:"1")] (s '++' r) q} end component latch_mealy_set +s +r -q is {state_machine [(i:"00" s:"0" n:"0" o:"0") (i:"01" s:"0" n:"0" o:"0") (i:"10" s:"0" n:"1" o:"1") (i:"11" s:"0" n:"1" o:"1") (i:"00" s:"1" n:"1" o:"1") (i:"01" s:"1" n:"0" o:"0") (i:"10" s:"1" n:"1" o:"1") (i:"11" s:"1" n:"1" o:"1")] (s '++' r) q} end component latch_mealy_reset +s +r -q is {state_machine [(i:"00" s:"0" n:"0" o:"0") (i:"01" s:"0" n:"0" o:"0") (i:"10" s:"0" n:"1" o:"1") (i:"11" s:"0" n:"0" o:"0") (i:"00" s:"1" n:"1" o:"1") (i:"01" s:"1" n:"0" o:"0") (i:"10" s:"1" n:"1" o:"1") (i:"11" s:"1" n:"0" o:"0")] (s '++' r) q} end component toggle_moore +t -q is {state_machine [(i:"0" s:"0" n:"0" o:"0") (i:"1" s:"0" n:"1" o:"0") (i:"0" s:"1" n:"1" o:"1") (i:"1" s:"1" n:"0" o:"1")] t q} end component toggle_mealy +t -q is {state_machine [(i:"0" s:"0" n:"0" o:"0") (i:"1" s:"0" n:"1" o:"1") (i:"0" s:"1" n:"1" o:"1") (i:"1" s:"1" n:"0" o:"0")] t q} end component timer +time +width_ +start -count -active -last with c match pre_active is c = {counter width_ count} match = count '==' {const width_ (time - 1) $} {latch_mealy_set start match pre_active} {reset start c} {enable pre_active c} active = {reg 1 pre_active $} last = active '&' match end component interleaver +DataWidth +Swap +Write +Addr +DataIn -SyncPrimary -SyncSecondary -DataOut -Mem0 -Mem1 with AddrWidth AddrOut LoadMem0 LoadMem1 is AddrWidth = width Addr {reset Swap {counter AddrWidth AddrOut}} {toggle_moore Swap LoadMem1} LoadMem0 = '~' LoadMem1 SyncPrimary = {reg 1 Swap $} SyncSecondary = AddrOut '==' {zero AddrWidth $} Mem0 = {ram_rbw DataWidth (Write '&' LoadMem0) Addr DataIn AddrOut _} Mem1 = {ram_rbw DataWidth (Write '&' LoadMem1) Addr DataIn AddrOut _} DataOut = {reg 1 LoadMem0 $} 'then' Mem1.read_data 'else' Mem0.read_data end component sequence +width_ +values +start -data with elements addr_width addr active is elements = length values {bits_required elements addr_width} {timer elements addr_width start addr active _} data = {reg 1 active $} 'then' {rom width_ values addr $} 'else' {zero width_ $} end component sim_start -start_flag is start_flag = '~' {reg 1 '1' $} end confluence-0.10.6/lib/common/__cfdoc__0100644002340600244710000000011310266541655017161 0ustar hawkit1cadgrpDirectory of common components that have not made their way into base.cf. confluence-0.10.6/lib/common/sync.cf0100644002340600244710000000307310266541655016662 0ustar hawkit1cadgrp(* Confluence System Design Library Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) (** Cross clock domain synchronization. *) synchronizer is (** See link for more info: http://www.e-insite.net/ednmag/index.asp?layout=article&articleid=CA276202 *) component synchronizer +clk_src +clk_dst +start -take_it -got_it with take_it_1 take_it_2 take_it_3 got_it_1 got_it_2 got_it_3 is (* start to take_it. *) {clock clk_src {reg 1 (start '^' take_it_1) take_it_1}} {clock clk_dst {regs 1 2 take_it_1 take_it_2}} {clock clk_dst {reg 1 take_it_2 take_it_3}} take_it = take_it_2 '^' take_it_3 (* take_it back to got_it. *) {clock clk_dst {reg 1 (take_it '^' got_it_1) got_it_1}} {clock clk_src {regs 1 2 got_it_1 got_it_2}} {clock clk_src {reg 1 got_it_2 got_it_3}} got_it = got_it_2 '^' got_it_3 end confluence-0.10.6/lib/common/unit_test.cf0100644002340600244710000000310110266541655017714 0ustar hawkit1cadgrp(* Confluence System Design Library Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) -run_test -assert_equal -assert_boolean -assert_logic is component run_test +parent_name +test_name +test_suite is {test_suite (parent_name ++ "/" ++ test_name)} end component assert_equal +test_name +assert_name +a +b is if a != b {print ("** assert_equal violation: " ++ test_name ++ "/" ++ assert_name ++ " -> " ++ {string_of a [] $} ++ " != " ++ {string_of b [] $})} end end component assert_boolean +test_name +assert_name +a is if ! a {print ("** assert_boolean violation: " ++ test_name ++ "/" ++ assert_name)} end end component assert_logic +test_name +assert_name +a is (* XXX {assert ("** assert_logic violation: " ++ test_name ++ "/" ++ assert_name) a} {output (test_name ++ "/" ++ assert_name) a} *) end confluence-0.10.6/lib/doc/0040755002340600244710000000000010312276326014641 5ustar hawkit1cadgrpconfluence-0.10.6/lib/doc/README0100644002340600244710000000006510266541655015527 0ustar hawkit1cadgrpDirectory of cfdoc generated library documentation. confluence-0.10.6/INSTALL0100644002340600244710000000271310266541652014364 0ustar hawkit1cadgrpConfluence Logic Design Language, Compiler, and Standard Library Copyright (C) 2003-2005 Tom Hawkins -------------------------- Installation Instructions: -------------------------- 1. Extract the installation: $ tar -xzf confluence-0.10.0.tar.gz 2. Set the CF_LIB and CF_ENV environment variables (add the following lines to .bashrc or .bash_profile): export CF_LIB=/lib # if binary distribution export CF_LIB=<$PREFIX>/lib/confluence # if installing from source export CF_ENV=$CF_LIB/base.cf 3. Install OCaml (http://caml.inria.fr/ocaml/distrib.html). 4. Compile and install the tools. Set the PREFIX location: $ make PREFIX=/usr install 5. To compile and install the FNF Icarus code generator, see src/ivl/Makefile. ------------------- Directory Contents: ------------------- INSTALL : This file. LICENSE_GPL : License covering Confluence compiler. LICENSE_LGPL : License covering Confluence standard libraries. NEWS : Release notes. Makefile : The top level makefile to build the compiler and documentation. lib/ : Confluence base libraries and test suites. misc/confluence.vim : Vim syntax file for highlighting Confluence programs. src/ : Confluence compiler source. src/doc : Source code documentation. confluence-0.10.6/LICENSE_GPL0100644002340600244710000004310610266541652015043 0ustar hawkit1cadgrp GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. confluence-0.10.6/LICENSE_LGPL0100644002340600244710000006347610266541652015173 0ustar hawkit1cadgrp GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! confluence-0.10.6/Makefile0100644002340600244710000000161010266541652014766 0ustar hawkit1cadgrpSHELL=/bin/sh PREFIX=/usr/local .PHONY : all all : cd src && $(MAKE) PREFIX=$(PREFIX) .PHONY : install install : cd src && $(MAKE) PREFIX=$(PREFIX) install install -D lib/base.cf $(PREFIX)/lib/confluence/base.cf install -D lib/list.cf $(PREFIX)/lib/confluence/list.cf install -D lib/base_test/base_test.cf $(PREFIX)/lib/confluence/base_test/base_test.cf install -D lib/base_test/run_test $(PREFIX)/lib/confluence/base_test/run_test install -D lib/common/common.cf $(PREFIX)/lib/confluence/common/common.cf install -D lib/common/sync.cf $(PREFIX)/lib/confluence/common/sync.cf install -D lib/common/unit_test.cf $(PREFIX)/lib/confluence/common/unit_test.cf .PHONY : uninstall uninstall : cd src && $(MAKE) PREFIX=$(PREFIX) uninstall -rm -r $(PREFIX)/lib/confluence .PHONY : clean clean : cd src && $(MAKE) PREFIX=$(PREFIX) clean confluence-0.10.6/NEWS0100644002340600244710000007320610312275627014035 0ustar hawkit1cadgrpConfluence Logic Design Language and Compiler Copyright (C) 2003-2005 Tom Hawkins Release Notes * Denotes changes that impact backward compatibility. ------------------------------------------------------------------------ Confluence 0.10.6 -- 09/15/2005 - FNF VHDL bug fix: output inversion. ------------------------------------------------------------------------ Confluence 0.10.5 -- 04/26/2005 - Blackbox support in Confluence and FNF: {bbox module_name output_width param_list in out} ------------------------------------------------------------------------ Confluence 0.10.4 -- 03/23/2005 - The FNF NuSMV code generator turns output vectors into assertions. - FNF NuSMV code generator adds support for multipliers. ------------------------------------------------------------------------ Confluence 0.10.3 -- 02/17/2005 - Changed FNF select primitive to select a single bit, rather than a sequence of bits. Updated all the FNF generators and the Icarus FNF writer. - Completed the initial FNF C model generator: $ fnf -read_fnf model.fnf -write_c model ------------------------------------------------------------------------ Confluence 0.10.2 -- 02/01/2005 - Added JHDL FNF code generator. (Contributed by Nathan Cain) ------------------------------------------------------------------------ Confluence 0.10.1 -- 01/19/2005 - New syntax for naming local namespaces: my_system = local a b c is (* ... *) end - New syntax for naming instantiations. The following are equivalent: my_value = {my_system : my_component arg1 arg2 $} my_system = {my_component arg1 ang2 _} my_value = my_system.3 - FNF supports VHDL code generation. - Outdated examples removed from distribution. ------------------------------------------------------------------------ Confluence 0.10.0 -- 01/07/2005 * Number of instantiation arguments must match number of component arguments. Use _ to fill in the blanks: {reg data_width _ _} * FNF combined with Confluence installation. Nls and Lp modules are removed. CF now produces an FNF netlist. Use FNF to generate C, Verilog, etc. * Most command line options have changed or have been removed. * The following primitives have been removed: ram, rom, inout, tristate, join, header, assert, display * ram_wbr, ram_rbw, and rom components are implemented with registers, decoders, and muxes. * No support for VHDL or C code generation (temporary). - Happy New Year! Please share your good forturne with the tsunami victims. Donate today! ------------------------------------------------------------------------ Confluence 0.9.3 -- 10/12/2004 - The (') operater can be now used to create vector constants: wid'val - The new -p option has been added to control port order. - Added a new processor design (lib/designs/cpu/ttp). Comes with an assembler and integrated memory model (in Python). TTP is written in the pre 0.9 syntax, however. ------------------------------------------------------------------------ Confluence 0.9.2 -- 08/16/2004 - Updated lib/designs/arith to new syntax. (Contribution by James Gilb) * Added soft vectors. Changes to inout, and added tristate and external_softvector. - Added command line options (-o -m -g -t) to specify output code. (Contribution by Aneesh Dalvi) - Added "header" component to set header documentation. * Removed "set" compiler directive component. * Removed _c, _i, _o, and _b from generated port names. * input, output, and inout no longer specifies port position. Ports are sorted first by inputs, outputs, and inouts then they are sorted alphabetically. * Removed the older Base.cf standard library. - Fixed the bug affecting large multipliers in the C code generator. ------------------------------------------------------------------------ Confluence 0.9.1 -- 07/21/2004 - Started adding command line options to cf. Initial options include -help, -base_env, -compile_only, -error_limit. cf -h # For more info. * The argv variable now contains only the arguments after the main program file. For example: cf -compile_only program.cf one two three argv = ["one" "two" "three"] * Changed documentation comments from (# #) to (** *). * Discontinued cfdoc. - Updated error reporting of free variables. Reduces the error logging in most cases. Also provides a free variable dependency graph that is useful for debugging. - Minor adjustments to runtime error reporting. Fixed a bug that reports a false error location during an unusual evaluation order. - Removed hierarchical code generation to simplify the internal representation in preparation for new optimizations. The compiler directive "LevelDensity" has been disabled. - Recoded NuSMV XOR expressions to be compatible with SMV. - Restructured primitive compilation. Fixed bug with recursive records. - Updated tutorial. - Started aligning coding conventions with OCaml. - Added constant propagation optimization for add and subtract. ------------------------------------------------------------------------ Confluence 0.9.0 -- 03/20/2004 - Confluence is Open Source The Confluence compiler is now licensed under GNU GPL and The standard libraries are licensed under GNU LGPL. - New Distribution Format See INSTALL for the new installation instructions. - New Base Environment (base.cf) The new base environment (base.cf) conforms to the new coding conventions. Base.cf, still distributed in lib, is depreciated. - New Digital Logic Simulator The C code generator includes a wrapper around the standard Confluence C API to produce implement simulation executables. External verification environments communicate with the simulator using Unix pipes (stdin, stdout). A simple command language provides means to initialize models, set and query port signals, cycle clock domains, and control VCD recording. The following is an example of the simulator command language: # Comments are part of the command language. ! # Initialize model. [ vcd_file.dmp # Start recording to VCD. $ input_1_i 011A # Set input_1 to 0x011A. @ # Perform combinatorial calculation. ? output_2_o # Query the value of output_2_o. ~ clock_c # Cycle the clock_c domain. | # Sample the port data to VCD. ] # Close the dump file. Queried port values come back on stdout; one hex value per line. The new directive {set "CompileC" true} compiles the resulting C code for you, so a post GCC step is not needed. The simulator is compatible with the "EmbeddedC" directive. - Python and Java Code Generation Discontinued Due to the power and flexibility of the new simulator, there is no longer a need for multiple general purpose programming language targets. The simulation command language makes it trivial to connect Python, Java, Perl, or any other high level language to a Confluence simulator. And unlike generated Python or Java models, you get simulation performance of compiled C. - cfdoc: Confluence Auto-Documentation Cfdoc generates HTML documentation from CF source code comments. Cfdoc searches a directory tree for CF source code and assembles a network of hyperlinked pages documenting the directory structure and the CF source code. Source code documentation comments are valid at the beginning of every file and before each named component definition. A documentation comment has the form: (# This is a doc comment. #) In addition to doc comments, special doc files ("__cfdoc__") may be placed in each directory to comment particular nodes in the source tree. Cfdoc synopsis: cfdoc [-h] [-i ] NOTE: and /doc must already exist. Cfdoc must be invoked in the parent directory of . - Referencing System Environment Variables for Imports New syntax for import and environment strings provides means to access system environment variables. This enables users to make absolute path reference across a source tree, regardless of where the source tree is installed in the file system. For example, if the environment variable DSP_PROJECT is set to "/home/joe/dsp_project", the following import: import "$DSP_PROJECT/common/fir_filter.cf" actually references "/home/joe/dsp_project/common/fir_filter.cf". Environment variables may only be used at the beginning of a reference string. The environment variable must be an absolute path. - New RAM Model The new ram component produces independent write and read port components. Example: {ram +data_width +data_values -write_port -read_port} {write_port +write_addr +write_data} {read_port +read_before_write +read_addr -read_data} Notice the write_port does not have an explicit write_enable -- it uses the implicit enable. data_values is a list of integers that specify the RAM's initial conditions. NOTE: RAM initialization may not be supported by synthesis. Check with your EDA vendor. - New Property Datatype Properties will enable designers to specify system properties in the form of propositional temporal logic, for formal verification and simulation monitoring. Several linear-time temporal logic (LTL) operators have been introduced, with more to follow. Property assertions will be supported in a future release. Example: "a implies b on the next clock cycle" property = a `->` `X` b - Promela Code Generation Discontinued Symbolic model checking is superior to explicit state model checking for digital logic verification. NuSMV, an open-source symbolic model checking language, has continued support. - Variable names may begin with a lower case letter. - ASCII encoded characters are now specified with @A. cA is no longer supported due to potential conflicts with lowercase variable names. - Assertions no longer have severity levels. {assert "Check a == a." (a '==' b)} - Generated C sends assertions and print messages to stderr. - Digital Signal Recorder (dsr) has been discontinued. - Removed (ports) unary operator. Use ports_of_system to retrieve system port records. - Bug fix in addition and subtraction primitives. - The CF_BASE_ENVIRONMENT environment variable has been renamed to CF_ENV. CF_LIB is an optional environment variable used for absolute references to the standard library: import "$CF_LIB/base.cf" - Removed (\) operator. - Strings may span multiple lines. ------------------------------------------------------------------------ Confluence 0.8.0 -- 01/17/04 - New NuSMV code generator. Enable with {Set "GenNuSmv" true}. NuSMV is a state of the art open source symbolic model checker for formal verification. Symbolic model checking is more efficient for digital logic verification than explicit model checking (SPIN). NuSMV can verify stand-alone models. Therefore "GenTestBench" has no effect for NuSMV model generation. NuSMV is licensed under LGPL and can be downloaded at: http://nusmv.irst.itc.it/ - New XML netlist generator. Enable with {Set "GenXml" true}. XML netlists are used for building custom back-end Confluence code generators for analysis tools, alternative output languages, visulatization, or synthesis. The Confluence netlist DTD is located at: http://www.launchbird.com/misc/confluence_netlist.dtd - New C coding style to limit use of multiplications for improved embedded performance. - SystemToString in Base.cf now includes port record information. ------------------------------------------------------------------------ Confluence 0.7.7 -- 12/22/03 - New record data structure to map names to values. Records are created with the following syntax: NewRecord = (Name1:Value1 Name2:Value2) EmptyRecord = () Names must be unique within a record. Also, name order determines type. For example: (A:1 B:2) == (A:1 B:2) (A:1 B:2) != (B:2 A:1) Like system ports, record fields can be accessed either by name or position using the (.) operator: Record.Name Record.1 IsRecord and RecordInfo are two new primitives added to Base.cf for records. Given a record, RecordInfo returns a list of records detailing the input record: {RecordInfo (A:1 B:2) $} == [(Name:"A" Value:1) (Name:"B" Value:2)] Base.cf also includes RecordToString with a tie-in to ToString and Show for printing and debugging record values. - New prefix operator (ports), returns a record of a system's port values. PortRecord = ports SomeSystem - Lists are no longer a built in type. Instead, they are built from records. For example: [] == () [1 2] == 1 :: 2 :: [] == (Head:1 Tail:(Head:2 Tail:())) - Depreciated syntax for conditional operator (? :) and vector switch operator ('?' ':'). New syntax is as follows: Predicate then TrueExpr else FalseExpr SelectBit 'then' TrueVector 'else' FalseVector - New Confluence distribution with OCaml bytecode executables allowing Confluence to run on any system supported by Objective Caml (Unix, Mac, Windows, Cygwin). Download OCaml, including the abstract machine, at: http://www.ocaml.org/ Also, removed deep recursion in compiler that caused stack overflows in the OCaml abstract machine. - Bug fix effecting type error reporting of a recursive data structures. - Direction markers (+ - *) can prefix instantiation arguments. - Renamed "VcdSupport" code generation constraint to "EmbeddedC". When "EmbeddedC" is set, C code is generated for embedded applications, i.e. no VCD support or printfs from assertions or vector prints. "EmbeddedC" defaults to false. - VectorPrint primitive now supported in Java models. Fixed comparison bugs in Java models. Though VCD is still not supported, Java test-benches make correct use of the limited Java model API. ------------------------------------------------------------------------ Confluence 0.7.6 -- 12/09/03 - The compiler now implements unification for all variable binding. Any pair of values can be unified. However, unifying two systems or two vectors will result in a unification error unless the instances are the same. - New unification operator (=). (=) has the same semantics as (<-) and (->). The follow are equivalent: A <- B (* Direction is ignored by compiler. *) A -> B A = B - Lists can be constructed with free variables. Example: local A B C is [A B C] = [1 2 3] {Show A} (* 1 *) {Show B} (* 2 *) {Show C} (* 3 *) end List = [List] (* Data structures can be recursive. *) - Free variables can be created anywhere using _. - Component port direction markers (+ - *) are optional. The markers should indicate the following: +Port : All information produced outside component. -Port : All information produced inside component. *Port : Information produced both inside and outside component. - Commas in instantiations are depreciated and will be removed from future releases. - To support direction markers with instantiation arguments, argument expressions and bracketed list elements are restricted to non-operator expressions. For example: {SomeComp A B C + D} (* Invalid. *) {SomeComp A B (C + D)} (* Valid. *) {Print head List} (* Invalid. *) {Print (head List)} (* Valid. *) [A B C + D] (* Invalid. *) [A B (C + D)] (* Valid. *) The exceptions to the rule are (.) and ('): {SomeComp Sys.Port Vector'Bits} The current compiler does not accept direction markers with arguments due to possible ambiguities with legacy Confluence code. Argument direction markers will be supported in the next release. For example: {SomeComp +Input1 +Input2 -Output3 +Input4 *Multi5} - The dot operator (.) now references ports by either name or position. For position references, the right side must be an integer. The at operator (@) has been removed. Sys.PortName (* By name. *) Sys.1 (* By position. *) - Keyword "is" is required at the top of a file between the external ports and statements. - Removed ListHead and ListTail primitives from Base.cf. - New VCD utility: Digital Signal Recorder (DSR). DSR generates VCD from a simplified input language. DSR is intended to be used with C, Java, Python, or other models to record simulation waveforms. $ dsr -h # For more information. ------------------------------------------------------------------------ Confluence 0.7.5 -- 12/01/03 - Implemented free variable error reporting that provides complete visibility. No more "combinatorial loop" errors. - New Java code generator. Enable with {Set, "GenJava" true}. Currently does not support VecPrint, VecExtSequ, or VecExtComb primitives. Currently no VCD methods. - Added association list components to Base.cf. Association lists are lists of Key/Value pairs. - Updated TruthTable implementation to make efficient use of input dont-cares. - Replaced `operator syntax with (operator) for better legibility. - Removed optional "then" keyword from "if ef else" statements. - Added "with" and "is" keywords and new syntax for components and namespaces. Component Definitions: component Add +A +B -X is X <- A + B end comp +A +B -X is X <- A + B end Explicit Namespace: local Tmp1 Tmp2 is (* ... *) end Implicit Namespace: component Comp +A -X with Tmp1 Tmp2 is (* ... *) end comp +A -X with Tmp1 Tmp2 is (* ... *) end if Check1 with Tmp1 Tmp2 is (* ... *) ef Check2 with Tmp3 Tmp4 is (* ... *) else with Tmp5 Tmp6 is (* ... *) end Colon syntax (:Name) and component definitions without "is" are depreciated and will not be supported in future releases. ------------------------------------------------------------------------ Confluence 0.7.4 -- 11/14/03 - The new primitive VectorRam implements true multi-port memories. Given an address and data width, VectorRam returns a component (RamPort) to implement the RAM's port interface. RamPort my be instantiated multiple times and across separate clock domains. VectorRamRbw and VectorRamWbr have been redefined in terms of VectorRam. Their prior interfaces and semantics have been maintained. - Fixed a corner case bug in the pre-runtime compiler. The bug prevented the completion of computation in the case when an output instantiation expression is a source for that system's output. ------------------------------------------------------------------------ Confluence 0.7.3 -- 10/31/03 - Bug fix to VectorReg in C code generator. ------------------------------------------------------------------------ Confluence 0.7.2 -- 10/28/03 - Added the capability to instantiate external components into Confluence for such tasks as 3rd party IP integration, building custom logic primitives, and instantiating FPGA specific blocks. Two new logic primitives are added to the language to support external component instantiation. Given a component name, an integer list of parameters, an input vector, and an output width, VectorExtComb and VectorExtSequ instantiates external combinatorial and sequential components. Base.cf also defines ExternalCombinatorialComponent and ExternalSequentialComponent built on top of VectorExtComb and VectorExtSequ to package and deliver reusable components. External instantiations are supported in Confluence generated Verilog, VHDL, C, and Python. - Added "ExternalC" and "ExternalPython" code generation constraints. Both constraints are used to insert custom C and Python code, primarily to support external component instances, i.e., including external header files and import statements. - Changed VHDL coding of VectorMul. Uses ieee.numeric_std.resize to truncate most significant bits. ------------------------------------------------------------------------ Confluence 0.7.1 -- 10/23/03 - Consolidated List.cf and Logic.cf into Base.cf. Program files no longer need to specify an environment if Base.cf, List.cf, or Logic.cf was previously referenced. The path to the implicit base environment is specified by the system environment variable CF_BASE_ENVIRONMENT. The new keyword "rootenvironment", when used at the top of a program file, tells the compiler the file has no parent environment. - Simplified installation to a basic tarball (confluence-X.X.X-pc-linux.tar.gz). The Cygwin version can be downloaded using Internet Explorer. - No longer uses a license server daemon; cfld removed from installation. ------------------------------------------------------------------------ Confluence 0.7.0 -- 10/10/03 - Confluence now compiles into the Promela language for formal verification and random simulation using the open-source SPIN Model Checker. Promela code generation is enabled by setting {Set, "GenPromela" true}. In addition, Promela test-benches are also generated with {Set, "GenTestBench" PosNum}. Unlike Verilog, VHDL, C, and Python test-benches, Promela test-benches may include 0, 1, or more clock domains, and may also include input and inout ports. The "examples/spin" directory includes a demonstration of Confluence + SPIN that performs equivalence checking between a golden and faulty model. See the Confluence reference manual for the Promela API. For more info on SPIN see http://spinroot.com/. - Redefined semantics of VectorMul logic primitive so input operands and result have same width. Removed VectorMulS primitive. Defined operators '*' and '*+' in terms of VectorMul so they have their prior semantics (inputs may have different widths, result width is sum of input widths). - To ease code coverage requirements for hard-real-time software, removed all if statements, conditional operators (?:), and short circuit operators (&&, ||) from computation part of generated C code. - Moved VectorConst calculation into initialization functions in generated C/Python to improve execution time. - Added -c switch to ba2cf to generate coverage metrics. ------------------------------------------------------------------------ Confluence 0.6.5 -- 09/16/03 - ba2cf completed. Generates CF StateMachines for assertion based verification. - Bug fix to VectorToHex. ------------------------------------------------------------------------ Confluence 0.6.4 -- 09/08/03 - Prevents free variable output error message if other error were produced. - ROMs are extended with 0s to fill complete address space. - RAMs are initialized to 0 in Verilog and VHDL. - Created VectorPrint for printing vectors as ASCII encoded string in output code. - Added StringToVector, VectorToBin, and VectorToHex, vector string manipulation components. ------------------------------------------------------------------------ Confluence 0.6.3 -- 08/26/03 - Introduced free variable output port counter to catch combinatorial loops. - Bug fix in error reporting. Now traps invalid input names for Dot sink expressions. - Added "#ifdef __cplusplus" guard to output C header file. - Added "VcdSupport" code generation constraint. Controls if VCD functions are added to output C code. - Updated tutorial and example documentation to current language syntax. ------------------------------------------------------------------------ Confluence 0.6.2 -- 08/07/03 - cf defaults the license server ip address to 127.0.0.1 if CF_LICENSE_SERVER is not available. - Bug fix for Switch logic primitive in VHDL generator. ------------------------------------------------------------------------ Confluence 0.6.1 -- 08/06/03 - All component inputs no longer required at instantiation time. If inputs are left unconnected inputs must be bound using @ or . system operators. - Dot (Sys.PortName) and At (Sys.PortNum) expressions are now valid at sink expression position. - New error reporting provides unconnected inputs information including port name, component location, and instantiation location. ------------------------------------------------------------------------ Confluence 0.6.0 -- 08/04/03 - New documentation. Includes XML source. - Complete redefinition of operators. See language reference manual for details. - Added integer bitwise operations (<< >> ~ & ^ |). - Updated UnitTest.cf unit testing framework. - Added unit test suites for base libraries. See lib/unit_testing. - Renamed "signal" data-type to "vector". Renaming and redefinition of several vector components. See language reference manual and Base.cf for details. - Additional integer constant syntax (0b101, 1b001). - Additional vector constant syntax ('0b01', '1b00'). - New component definition statement. See language reference manual for details. - New Compile-time connection analysis and run-time checking prevents "Free variables" and "Suspended threads" errors. - Updated cf.vim with new syntax. - All examples up to date. - Removed keywords endif, endcomp, endprim, and endlocal. - Redefined Assert for consistency with UnitTest.cf. ------------------------------------------------------------------------ Confluence 0.5.6 -- 07/19/03 - Integers now have arbitrary (infinitely large) precision. - New hexadecimal notation for integer constants: 0xE = 14 : bits (inf,8] = 0 1xE = ~1 : bits (inf,8] = 1 (negative integer) - Signal constants now accept hexadecimal notation: '00110101' = '0x35' = '1x35' (sign bit has no affect) Signal constants created with hex will have a width with a multiple of 4. - Variable names now may include underscores. cf.vim: - Updated to support new integer and signal constants and variable names. ------------------------------------------------------------------------ Confluence 0.5.5 -- 07/17/03 cf: - Removed "RegisterStyle" code generation constraint. - Removed "VerilogVersion" code generation constraint. All generated Verilog now conforms to Verilog-1995. - Removed Optant logic primitive. - Added Switch logic primitive (?:). - Added "fileloc" keyword that returns a string with file location information. Base.cf: - Removed "Length" name. Use "length" operator for calculating the length of lists. - Removed "Optant" component. - Switch operator (?:) implemented with a Switch rather than an Optant. Logic.cf: - Mux and TruthTable implemented with Switches rather than Optants. cf.vim: - Added new "fileloc" keyword. ------------------------------------------------------------------------ Confluence 0.5.4 -- 07/02/03 ltl2ba: - New binary translates linear-time temporal logics (LTL) to Promela Buchi automata. See opensrc/ltl2ba-1.0. ba2cf: - New binary parses results from ltl2ba. Will eventually generate Confluence logic to implement non-deterministic finite automata produced from ltl2ba. ------------------------------------------------------------------------ Confluence 0.5.3 -- 06/26/03 cf: - Raised precedence of list prefix operators (head, tail, length) to the same level as signal prefix operators (not, msb, lsb, msbs, lsbs, and width). Base.cf: - Added and defined `length operator. cf.vim: - Added "length" for keyword highlighting. ------------------------------------------------------------------------ Confluence 0.5.2 -- 06/19/03 cf: - Increased compile-time debugging resolution and improved error messages. - Changed Assert semantics to {Assert, TestSignal SeverityLevel Message}. Assertion posts Message when TestSignal is low and halts simulation if SeverityLevel is less than or equal to 0. - Changed register primitives to have reset-over-enable priority. Subsystem resets and enables follow the equations: subsystem reset = supersystem reset OR (OR accumulation of local resets) subsystem enable = supersystem enable AND (AND accumulation of local enables) Note: Code generation constraint "RegisterStyle" currently does not affect register coding. Base.cf: - Updated Assert primitive. ------------------------------------------------------------------------ Confluence 0.5.1 -- 06/17/03 cfld: - Bug fixes affecting Cygwin versions. (Errors on stop action). - Increased error reporting and license file status. ------------------------------------------------------------------------ Confluence 0.5.0 -- 06/10/03 cf: - Bug fix to HDL code generators for assertions. - Bug fix to VHDL assertion coding. - Run-time error reporting returns instantiation locations instead of component locations. - Old HDL code generators have been removed. - New signal map generator links HDL signal names to Confluence file locations. Enabled with "GenSignalMap" constraint. cfld: - Completely rebuilt license manager. Type "cfld" and see above for usage information. No update necessary, but highly recommended. confluence-0.10.6/misc/0040755002340600244710000000000010312276326014261 5ustar hawkit1cadgrpconfluence-0.10.6/misc/confluence.vim0100644002340600244710000001225010266541655017124 0ustar hawkit1cadgrp" Vim syntax file " Copyright (c) 2003, 2004 Tom Hawkins " Language: Confluence " Maintainer: Tom Hawkins " Last Change: " URL: http://www.launchbird.com/misc/cf.vim if exists("b:current_syntax") finish endif " Special syn match cfSpecial "_" " Identifiers syn match cfIdentifier /\<\(\u\|\l\)\w*\>/ " Errors syn match cfBraceErr "}" syn match cfBrackErr "\]" syn match cfParenErr ")" syn match cfCommentErr "\*)" " Some convenient clusters syn cluster cfAllErrs contains=cfBraceErr,cfBrackErr,cfParenErr,cfCommentErr syn cluster cfContained contains=cfTodo " Enclosing delimiters syn region cfEncl transparent matchgroup=cfKeyword start="(" matchgroup=cfKeyword end=")" contains=ALLBUT,@cfContained,cfParenErr syn region cfEncl transparent matchgroup=cfKeyword start="{" matchgroup=cfKeyword end="}" contains=ALLBUT,@cfContained,cfBraceErr syn region cfEncl transparent matchgroup=cfKeyword start="\[" matchgroup=cfKeyword end="\]" contains=ALLBUT,@cfContained,cfBrackErr " Comments syn region cfComment start="(\*" end="\*)" contains=cfComment,cfTodo syn region cfDocComment start="(#" end="#)" contains=cfDocComment,cfTodo syn keyword cfTodo contained TODO FIXME XXX syn keyword cfKeyword comp prim if ef else end with is syn keyword cfKeyword local component syn keyword cfKeyword environment import rootenvironment fileloc syn keyword cfBoolean true false syn match cfOperator "'" syn match cfOperator "\." syn match cfOperator "-" syn match cfOperator "'-'" syn region cfString start=+"+ skip=+\\\\\|\\"+ end=+"+ syn match cfNil "\[]" syn match cfEmpty "()" syn match cfInteger "\<\=\-\?\d\+\>" syn match cfInteger "\<[0|1]x\x\+\>" syn match cfInteger "\<[0|1]b[0|1]\+\>" syn match cfInteger "@\S" syn match cfFloat "\<\=\-\?\d\+\.\d*\([eE][\-]\=\d\+\)*\>" syn match cfConst "'\([0|1]*\|[0|1]x\x*\|[0|1]b[0|1]*\)'" syn match cfSpecial "\$" syn match cfSpecial "=" syn match cfSpecial ":" syn match cfOperator "`!`" syn match cfOperator "`X`" syn match cfOperator "`G`" syn match cfOperator "`F`" syn match cfOperator "`&&`" syn match cfOperator "`^^`" syn match cfOperator "`||`" syn match cfOperator "`<->`" syn match cfOperator "`->`" syn match cfOperator "`U`" syn match cfOperator "`W`" syn match cfOperator "`B`" syn match cfOperator "`V`" syn keyword cfOperator then syn match cfOperator "'then'" syn match cfOperator "'else'" syn match cfOperator "||" syn match cfOperator "&&" syn match cfOperator "|" syn match cfOperator "'|'" syn match cfOperator "\^" syn match cfOperator "'\^'" syn match cfOperator "&" syn match cfOperator "'&'" syn match cfOperator "!" syn match cfOperator "==" syn match cfOperator "!=" syn match cfOperator "'=='" syn match cfOperator "'!='" syn match cfOperator "++" syn match cfOperator "'++'" syn match cfOperator "::" syn match cfOperator "#" syn match cfOperator "'#'" syn match cfOperator "<" syn match cfOperator ">" syn match cfOperator "<=" syn match cfOperator ">=" syn match cfOperator "'<'" syn match cfOperator "'>'" syn match cfOperator "'<='" syn match cfOperator "'>='" syn match cfOperator "'<+'" syn match cfOperator "'>+'" syn match cfOperator "'<=+'" syn match cfOperator "'>=+'" syn match cfOperator "<<" syn match cfOperator ">>" syn match cfOperator "'<<'" syn match cfOperator "'>>'" syn match cfOperator "'>>+'" syn match cfOperator "+" syn match cfOperator "'+'" syn match cfOperator "\*" syn match cfOperator "/" syn match cfOperator "%" syn match cfOperator "'\*'" syn match cfOperator "'/'" syn match cfOperator "'%'" syn match cfOperator "'\*+'" syn match cfOperator "\*\*" syn match cfOperator "'\*\*'" syn match cfOperator "\~" syn keyword cfOperator head syn keyword cfOperator tail syn keyword cfOperator length syn keyword cfOperator width syn match cfOperator "'\~'" syn match cfOperator "'msb'" syn match cfOperator "'msbs'" syn match cfOperator "'lsb'" syn match cfOperator "'lsbs'" syn match cfOperator "(\*)" syn match cfOperator "(\*\*)" syn match cfOperator "(#)" syn match cfSpecial "<-" syn match cfSpecial "->" " Synchronization syn sync minlines=50 syn sync maxlines=500 " Define the default highlighting. " For version 5.7 and earlier: only when not done already " For version 5.8 and later: only when an item doesn't have highlighting yet if version >= 508 || !exists("did_cf_syntax_inits") if version < 508 let did_cf_syntax_inits = 1 command -nargs=+ HiLink hi link else command -nargs=+ HiLink hi def link endif " HiLink cfIdentifier Identifier HiLink cfBraceErr Error HiLink cfBrackErr Error HiLink cfParenErr Error HiLink cfCommentErr Error HiLink cfComment Comment HiLink cfDocComment Comment HiLink cfKeyword Keyword HiLink cfOperator Keyword HiLink cfNil Constant HiLink cfEmpty Constant HiLink cfBoolean Boolean HiLink cfInteger Number HiLink cfFloat Float HiLink cfConst Constant HiLink cfString String HiLink cfTodo Todo HiLink cfEncl Keyword HiLink cfSpecial Type HiLink cfSeperator Special delcommand HiLink endif let b:current_syntax = "confluence" confluence-0.10.6/src/0040755002340600244710000000000010312276326014115 5ustar hawkit1cadgrpconfluence-0.10.6/src/cfeval/0040755002340600244710000000000010312276326015355 5ustar hawkit1cadgrpconfluence-0.10.6/src/cfeval/cfAst.ml0100644002340600244710000001603610266541655016762 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) exception CfAstError;; type expr = Apply of Loc.loc * string * expr * expr list (* location, annotation, comp, arg list. *) | Connect of Loc.loc * expr * expr (* location, sink expr, source expr. *) | Cond of Loc.loc * expr * expr * expr (* location, predicate, true, false *) | Name of Loc.loc * string | Comp of Loc.loc * string * string list * stmt list (* location, annotation, ports, statements *) | Prim of Loc.loc * string * string list (* location, primitive name, ports *) | DotName of Loc.loc * expr * string | DotPosition of Loc.loc * expr * Intbig.intbig | Integer of Loc.loc * Intbig.intbig | Float of Loc.loc * float | Boolean of Loc.loc * bool | Vector of Loc.loc * string | Record of Loc.loc * (string * expr) list | Free of Loc.loc and stmt = ApplyStmt of expr | ConnectStmt of expr ;; let expr_loc expr = match expr with Apply (loc, _, _, _) | Connect (loc, _, _) | Cond (loc, _, _, _) | Name (loc, _) | Comp (loc, _, _, _) | Prim (loc, _, _) | DotName (loc, _, _) | DotPosition (loc, _, _) | Integer (loc, _) | Float (loc, _) | Boolean (loc, _) | Vector (loc, _) | Record (loc, _) | Free loc -> loc ;; let stmt_loc stmt = match stmt with ApplyStmt apply -> expr_loc apply | ConnectStmt connect -> expr_loc connect ;; let add_sub_env apply_parent apply_sub sub_name = let loc = expr_loc apply_sub in match apply_parent with Apply (app_loc, sys_ann, Comp (comp_loc, comp_ann, ports, l), free_args) -> Apply (app_loc, sys_ann, Comp (comp_loc, comp_ann, ports, (l @ [ConnectStmt (Connect (loc, Name (loc, sub_name), apply_sub))])), free_args) | _ -> Report.fatal "Invalid file application."; raise CfAstError;; (* Apply Ast to Channel. *) let write_channel = ref stdout;; let write str = output_string !write_channel str;; let id i = i ^ " ";; let rec write_exprs exprs i = match exprs with [] -> () | expr :: exprs -> write_expr expr i; write (i ^ ";\n"); write_exprs exprs i and writeStringList names = match names with [] -> write ("[]") | name :: names -> write ("\"" ^ String2.replace_meta_chars name ^ "\" :: "); writeStringList names and write_expr a i = match a with Apply (l, _, e, ports) -> write (i ^ "CfAst.Apply (\n"); write_loc l (id i); write (",\n"); write_expr e (id i); write (id i ^ ",\n"); write (id i ^ "[\n"); write_exprs ports (id i); write (id i ^ "],\n"); write (i ^ ")\n") | Connect (l, e1, e2) -> write (i ^ "CfAst.Connect ("); write_loc l (id i); write (",\n"); write_expr e1 (id i); write ((id i) ^ ",\n"); write_expr e2 (id i); write (i ^ ")\n") | Cond (l, p, t, f) -> write (i ^ "CfAst.Cond (\n"); write_loc l (id i); write (",\n"); write_expr p (id i); write ((id i) ^ ",\n"); write_expr t (id i); write ((id i) ^ ",\n"); write_expr f (id i); write (i ^ ")\n") | Name (l, b) -> write (i ^ "CfAst.Name (\n"); write_loc l (id i); write (",\n"); write ((id i) ^ "\"" ^ String2.replace_meta_chars b ^ "\"\n"); write (i ^ ")\n") | Comp (l, _, ports, s) -> write (i ^ "CfAst.Comp (\n"); write_loc l (id i); write (",\n"); write (id i); writeStringList ports; write (",\n"); write (id i ^ "[\n"); write_stmts s (id i); write (id i ^ "]\n"); write (i ^ ")\n") | Prim (l, n, ports) -> write (i ^ "CfAst.Prim (\n"); write_loc l (id i); write (",\n"); write ((id i) ^ "\"" ^ n ^ "\",\n"); write (id i); writeStringList ports; write (",\n"); write (i ^ ")\n") | DotName (l, e1, name) -> write (i ^ "CfAst.DotName (\n"); write_loc l (id i); write (",\n"); write_expr e1 (id i); write (id i ^ ",\n"); write (id i ^ "\"" ^ name ^ "\"\n"); write (i ^ ")\n") | DotPosition (l, e1, position) -> write (i ^ "CfAst.DotPosition (\n"); write_loc l (id i); write (",\n"); write_expr e1 (id i); write (id i ^ ",\n"); write (id i ^ Intbig.string_of_intbig position ^ "\n"); write (i ^ ")\n") | Integer (l, n) -> write (i ^ "CfAst.Integer ("); write_loc l ""; write (", Intbig.intbig_of_string \"" ^ Intbig.string_of_intbig n ^ "\")\n") | Float (l, n) -> write (i ^ "CfAst.Float ("); write_loc l ""; write (", " ^ string_of_float n ^ ")\n") | Boolean (l, b) -> write (i ^ "CfAst.Boolean ("); write_loc l ""; write (", " ^ string_of_bool b ^ ")\n") | Vector (l, s) -> write (i ^ "CfAst.Vector ("); write_loc l ""; write (", \"" ^ s ^ "\")\n") | Record (l, fields) -> write (i ^ "CfAst.Record ("); write_loc l ""; List.iter (function (label, value) -> write (i ^ " " ^ label ^ " :\n"); write_expr value (i ^ " ") ) fields; write (i ^ ")\n") | Free l -> write (i ^ "CfAst.Free ("); write_loc l ""; write (")\n") and write_stmt a i = match a with ApplyStmt b -> write (i ^ "CfAst.ApplyStmt (\n"); write_expr b (id i); write (i ^ ");\n") | ConnectStmt b -> write (i ^ "CfAst.ConnectStmt (\n"); write_expr b (id i); write (i ^ ");\n") and write_stmts stmts i = match stmts with [] -> () | stmt :: stmts -> write_stmt stmt i; write_stmts stmts i; and write_loc loc i = match loc with Loc.Unify (s, i0, i1) -> write (i ^ "Loc.Unify (\"" ^ s ^ "\", " ^ string_of_int i0 ^ ", " ^ string_of_int i1 ^ ")") | Loc.Argument (s, i0, i1, i2) -> write (i ^ "Loc.Argument (\"" ^ s ^ "\", " ^ string_of_int i0 ^ ", " ^ string_of_int i1 ^ ", " ^ string_of_int i2 ^ ")") | Loc.Unknown s -> write (i ^ "Loc.Unknown \"" ^ s ^ "\"") ;; let write_apply a i channel = write_channel := channel; write_expr a i;; confluence-0.10.6/src/cfeval/cf.ml0100644002340600244710000001134210266541655016305 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) let help () = print_string (" NAME cf - Confluence compiler SYNOPSIS cf [options] [file] [arguments] DESCRIPTION Confluence is a functional programming language for reactive system design, including digital logic systems (ASIC, FPGA) and control oriented hard real-time software. The Confluence compiler (cf) translates a Confluence description into Verilog and VHDL (for digital logic synthesis), C (for simulation and software targets), and NuSMV (for formal verification, via model checking). OPTIONS -h OR -help Prints this information then exits. -b filename OR -base_env filename Sets the base environment for the compilation. Overrides the CF_ENV environment variable. If CF_ENV not defined and -base_env option not set, the base environment defaults to /usr/lib/confluence/base.cf. -e integer OR -error_limit integer Sets the maximum number of reported errors. A negative number reports all errors. -c OR -compile_only Parses and compiles, but does not evaluate a program. -o name Sets the output file name. Default is out.fnf. -test Run the built in unit tests. ENVIRONMENT VARIABLES CF_ENV A filename that specifies the base environment (commonly base.cf). CF_LIB The directory location of the Confluence standard library (optional). VERSION " ^ Version.version ^ " AUTHOR Tom Hawkins (tomahawkins@yahoo.com) SEE ALSO http://www.confluent.org/ COPYRIGHT Copyright (C) 2003-2005 Tom Hawkins "); print_newline (); exit 0 ;; let parse_cmd_args () = let argv = Sys.argv in let argc = Array.length argv in if argc = 1 then help (); let parsing = ref true in let i = ref 0 in let base_env = ref "" in let compile_only = ref false in let program = ref "" in let output = ref "out.fnf" in while !parsing do incr i; if argc = !i then Report.fatal ("** Invalid Argument: Expecting program filename."); match argv.(!i) with | "-h" | "-help" -> help () | "-b" | "-base_env" -> if argc = !i + 1 then Report.fatal ("** Invalid Argument: Expecting base environment filename."); base_env := argv.(!i + 1); incr i | "-c" | "-compile_only" -> compile_only := true | "-e" | "-error_limit" -> if argc = !i + 1 then Report.fatal ("** Invalid Argument: Expecting error limit number."); (try Report.set_error_limit (int_of_string argv.(!i + 1)) with _ -> Report.fatal ("** Invalid Argument: Expecting integer error limit.")); incr i | "-o" -> if argc = !i + 1 then Report.fatal ("** Invalid Argument: Expecting output filename."); output := argv.(!i + 1); incr i | "-test" -> Test_suite.run (); exit 0 | file -> program := file; parsing := false done; incr i; CfPrims.set_argv_position !i; if !base_env = "" then base_env := (try Sys.getenv "CF_ENV" with Not_found -> "/usr/lib/confluence/base.cf"); CfParserUtil.set_base_env !base_env; !program, !compile_only, !output ;; let open_out filename = try open_out filename with Sys_error _ -> Report.fatal ("** Error: Could not open file " ^ filename ^ " for writing."); raise (Invalid_argument "no file") ;; let main () = let (program, compile_only, output_name) = parse_cmd_args () in let ast = CfParserUtil.parse_program program CfLexer.token CfParser.file in let task = CfCompiler.compileApplication ast in if not compile_only then begin CfTypes.readyTask task; CfTypes.executeTasks (); CfTypes.checkAllPortsDetermined (); if Report.errorReported () then Report.fatal "Errors reported. Exiting."; let channel = open_out output_name in Cf_fnf.output_fnf channel; close_out channel end; exit 0 ;; Printexc.print main ();; confluence-0.10.6/src/cfeval/cfParser.mly0100644002340600244710000004240510266541656017660 0ustar hawkit1cadgrp/* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ %{ (* Pre Code *) let parse_error s = CfParserUtil.error ("Unexpected token: '" ^ (CfParserUtil.get_current_token ()) ^ "'");; %} %token IDENTIFIER %token INTEGER %token FLOAT %token STRING %token BOOLEAN %token VECTOR %token FREE %token END %token COMP %token COMPONENT %token PRIM %token IF %token EF %token ELSE %token WITH %token IS %token LOCAL %token IMPORT %token ENVIRONMENT %token ROOTENVIRONMENT %token BRACE_LEFT %token BRACE_RIGHT %token PAREN_LEFT %token PAREN_RIGHT %token BRACKET_LEFT %token BRACKET_RIGHT %token DOLLAR %token COLON %token EOF %token LexerError /* Operators */ %token OP_UNIFY %token OP_CONNECT_LEFT %token OP_CONNECT_RIGHT %token OP_THEN OP_VEC_THEN OP_VEC_ELSE %token OP_PROP_U %token OP_PROP_IMPLY %token OP_PROP_EQUIV %token OP_OR OP_PROP_OR %token OP_PROP_XOR %token OP_AND OP_PROP_AND %token OP_BW_OR OP_VEC_OR %token OP_BW_XOR OP_VEC_XOR %token OP_BW_AND OP_VEC_AND %token OP_EQU OP_NEQ OP_VEC_EQU OP_VEC_NEQ %token OP_CONCAT OP_RETURN OP_VEC_CONCAT %token OP_CONS %token OP_REPEAT OP_VEC_REPEAT %token OP_LT OP_GT OP_LE OP_GE OP_VEC_LT OP_VEC_GT OP_VEC_LE OP_VEC_GE OP_VEC_LT_S OP_VEC_GT_S OP_VEC_LE_S OP_VEC_GE_S %token OP_LSHIFT OP_RSHIFT OP_VEC_LSHIFT OP_VEC_RSHIFT OP_VEC_RSHIFT_S %token OP_ADD OP_SUB OP_VEC_ADD OP_VEC_SUB %token OP_MUL OP_DIV OP_MOD OP_VEC_MUL OP_VEC_DIV OP_VEC_MOD OP_VEC_MUL_S %token OP_POW OP_VEC_POW %token OP_NOT OP_BW_NOT OP_HEAD OP_TAIL OP_LENGTH OP_WIDTH OP_VEC_NOT OP_VEC_MSB OP_VEC_MSBS OP_VEC_LSB OP_VEC_LSBS OP_PROP_NOT OP_PROP_X %token OP_DOT OP_VEC_SELECT %right OP_UNIFY %right OP_CONNECT_LEFT %left OP_CONNECT_RIGHT %right OP_THEN ELSE OP_VEC_THEN OP_VEC_ELSE %left OP_PROP_U %left OP_PROP_IMPLY %left OP_PROP_EQUIV %left OP_OR OP_PROP_OR %left OP_PROP_XOR %left OP_AND OP_PROP_AND %left OP_BW_OR OP_VEC_OR %left OP_BW_XOR OP_VEC_XOR %left OP_BW_AND OP_VEC_AND %left OP_EQU OP_NEQ OP_VEC_EQU OP_VEC_NEQ %right OP_CONCAT OP_RETURN OP_VEC_CONCAT %right OP_CONS %left OP_REPEAT OP_VEC_REPEAT %left OP_LT OP_GT OP_LE OP_GE OP_VEC_LT OP_VEC_GT OP_VEC_LE OP_VEC_GE OP_VEC_LT_S OP_VEC_GT_S OP_VEC_LE_S OP_VEC_GE_S %left OP_LSHIFT OP_RSHIFT OP_VEC_LSHIFT OP_VEC_RSHIFT OP_VEC_RSHIFT_S %left OP_ADD OP_SUB OP_VEC_ADD OP_VEC_SUB %left OP_MUL OP_DIV OP_MOD OP_VEC_MUL OP_VEC_DIV OP_VEC_MOD OP_VEC_MUL_S %right OP_POW OP_VEC_POW %nonassoc OP_NOT OP_BW_NOT OP_HEAD OP_TAIL OP_LENGTH OP_WIDTH OP_VEC_NOT OP_VEC_MSB OP_VEC_MSBS OP_VEC_LSB OP_VEC_LSBS OP_PROP_NOT OP_PROP_X %left OP_DOT OP_VEC_SELECT %start file %type file %% file : file_application EOF { CfParserUtil.set_env ""; (snd $1) } | ENVIRONMENT STRING file_application EOF { CfParserUtil.set_env (CfParserUtil.format_string (snd $2)); (snd $3) } | ROOTENVIRONMENT file_application EOF { (snd $2) } ; file_application : component_ports IS statements { ($1, CfAst.Apply (CfParserUtil.current_file_loc (), "", CfAst.Comp (CfParserUtil.current_file_loc (), "", $1, $3), CfParserUtil.free_arg_list (CfParserUtil.current_file_loc ()) $1)) } | component_ports name_space_sugar { ($1, CfAst.Apply (CfParserUtil.current_file_loc (), "", CfAst.Comp (CfParserUtil.current_file_loc (), "", $1, $2), CfParserUtil.free_arg_list (CfParserUtil.current_file_loc ()) $1)) } ; statements : { [] } | statements statement { $1 @ [$2] } ; statement : name_space { CfAst.ApplyStmt $1 } | ifelse { $1 } | component_named { $1 } | application { CfAst.ApplyStmt $1 } | connect { CfAst.ConnectStmt $1 } ; name_space : LOCAL locals IS statements END { CfParserUtil.application_expr_of_namespace (fst $1) "" $2 $4 } /* XXX annotate namespace */ ; name_space_sugar : WITH locals IS statements { [CfParserUtil.application_of_namespace (fst $1) "" $2 $4] } /* XXX annotate namespace */ ; locals : local { [$1] } | locals local { $1 @ [$2] } ; local : IDENTIFIER { snd $1 } ; ifelse : IF expression statements ifelse_else { CfParserUtil.conditional_of_ifelse (fst $1) $2 $3 $4 } | IF expression name_space_sugar ifelse_else { CfParserUtil.conditional_of_ifelse (fst $1) $2 $3 $4 } ; ifelse_else : END { [] } | ELSE statements END { $2 } | ELSE name_space_sugar END { $2 } | EF expression statements ifelse_else { [CfParserUtil.conditional_of_ifelse (fst $1) $2 $3 $4] } | EF expression name_space_sugar ifelse_else { [CfParserUtil.conditional_of_ifelse (fst $1) $2 $3 $4] } ; component_named : COMPONENT IDENTIFIER component_ports IS statements END { CfParserUtil.stmt_of_comp_named (fst $1) $2 $3 $5 } | COMPONENT IDENTIFIER component_ports name_space_sugar END { CfParserUtil.stmt_of_comp_named (fst $1) $2 $3 $4 } ; expression : expression_nonop { $1 } | expression_op { $1 } ; expression_nonop : PAREN_LEFT expression PAREN_RIGHT { $2 } | STRING { CfParserUtil.application_of_string (fst $1) (CfParserUtil.format_string (snd $1)) } | INTEGER { CfAst.Integer (fst $1, snd $1) } | FLOAT { CfAst.Float (fst $1, snd $1) } | BOOLEAN { CfAst.Boolean (fst $1, snd $1) } | VECTOR { CfAst.Vector (fst $1, snd $1) } | IDENTIFIER { CfAst.Name (fst $1, snd $1) } | FREE { CfAst.Free (fst $1) } | list_sugar { $1 } | dot { $1 } | vector_select { $1 } | import_file { $1 } | component_anon { $1 } | primitive { $1 } | name_space { $1 } | application { $1 } | func { $1 } | record { $1 } | nil { $1 } ; expression_op : connect { $1 } | prefix { $1 } | infix { $1 } | trifix { $1 } | conditional { $1 } ; list_sugar : BRACKET_LEFT list_sugar_items BRACKET_RIGHT { $2 } ; dot : expression_nonop OP_DOT IDENTIFIER { CfAst.DotName (fst $2, $1, snd $3) } | expression_nonop OP_DOT INTEGER { CfAst.DotPosition (fst $2, $1, snd $3) } ; vector_select : expression_nonop OP_VEC_SELECT expression_nonop { CfParserUtil.application_of_infix $2 $1 $3 } ; import_file : IMPORT STRING { CfAst.Name (fst $1, CfParserUtil.add_import (CfParserUtil.format_string (snd $2))) } ; record : PAREN_LEFT record_fields PAREN_RIGHT { CfAst.Record (fst $1, List.rev $2) } | PAREN_LEFT PAREN_RIGHT { CfAst.Record (fst $1, []) } ; record_fields : IDENTIFIER COLON expression_nonop { [(snd $1, $3)] } | record_fields IDENTIFIER COLON expression_nonop { (snd $2, $4) :: $1 } ; nil : BRACKET_LEFT BRACKET_RIGHT { CfAst.Record (fst $1, []) } ; component_anon : COMP component_ports IS statements END { CfAst.Comp (fst $1, "", $2, $4) } | COMP component_ports name_space_sugar END { CfAst.Comp (fst $1, "", $2, $3) } ; component_ports : { [] } | component_ports direction_marker IDENTIFIER { $1 @ [snd $3] } ; primitive : PRIM IDENTIFIER component_ports END { CfAst.Prim (fst $1, snd $2, $3) } ; application : BRACE_LEFT expression_nonop arguments BRACE_RIGHT { CfAst.Apply (fst $1, "", $2, $3) } | BRACE_LEFT IDENTIFIER COLON expression_nonop arguments BRACE_RIGHT { CfParserUtil.connect_name (fst $3) $2 (CfAst.Apply (fst $1, snd $2, $4, $5)) } ; func : BRACE_LEFT expression_nonop arguments direction_marker DOLLAR arguments BRACE_RIGHT { CfParserUtil.select_position (fst $5) (CfAst.Apply (fst $1, "", $2, ($3 @ (CfAst.Free (fst $5) :: $6)))) (List.length $3 + 1) } | BRACE_LEFT IDENTIFIER COLON expression_nonop arguments direction_marker DOLLAR arguments BRACE_RIGHT { CfParserUtil.select_position (fst $7) (CfParserUtil.connect_name (fst $3) $2 (CfAst.Apply (fst $1, snd $2, $4, ($5 @ (CfAst.Free (fst $7) :: $8))))) (List.length $5 + 1) } ; arguments : { [] } | arguments direction_marker expression_nonop { $1 @ [$3] } ; direction_marker : { () } | OP_ADD { () } | OP_SUB { () } | OP_MUL { () } ; connect : expression OP_UNIFY expression { CfAst.Connect (fst $2, $1, $3) } | expression OP_CONNECT_LEFT expression { CfAst.Connect (fst $2, $1, $3) } | expression OP_CONNECT_RIGHT expression { CfAst.Connect (fst $2, $3, $1) } ; prefix : OP_NOT expression { CfParserUtil.application_of_prefix $1 $2 } | OP_BW_NOT expression { CfParserUtil.application_of_prefix $1 $2 } | OP_HEAD expression { CfParserUtil.application_of_prefix $1 $2 } | OP_TAIL expression { CfParserUtil.application_of_prefix $1 $2 } | OP_LENGTH expression { CfParserUtil.application_of_prefix $1 $2 } | OP_WIDTH expression { CfParserUtil.application_of_prefix $1 $2 } | OP_VEC_NOT expression { CfParserUtil.application_of_prefix $1 $2 } | OP_VEC_MSB expression { CfParserUtil.application_of_prefix $1 $2 } | OP_VEC_MSBS expression { CfParserUtil.application_of_prefix $1 $2 } | OP_VEC_LSB expression { CfParserUtil.application_of_prefix $1 $2 } | OP_VEC_LSBS expression { CfParserUtil.application_of_prefix $1 $2 } | OP_PROP_NOT expression { CfParserUtil.application_of_prefix $1 $2 } | OP_PROP_X expression { CfParserUtil.application_of_prefix $1 $2 } ; infix : expression OP_BW_OR expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_OR expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_BW_XOR expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_XOR expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_BW_AND expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_AND expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_EQU expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_NEQ expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_EQU expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_NEQ expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_CONCAT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_RETURN expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_CONCAT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_CONS expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_REPEAT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_REPEAT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_LT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_GT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_LE expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_GE expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_LT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_GT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_LE expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_GE expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_LT_S expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_GT_S expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_LE_S expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_GE_S expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_LSHIFT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_RSHIFT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_LSHIFT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_RSHIFT expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_RSHIFT_S expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_ADD expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_SUB expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_ADD expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_SUB expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_MUL expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_DIV expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_MOD expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_MUL expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_DIV expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_MOD expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_MUL_S expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_POW expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_VEC_POW expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_PROP_AND expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_PROP_XOR expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_PROP_OR expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_PROP_EQUIV expression { CfParserUtil.application_of_infix $2 $1 $3 } | expression OP_PROP_IMPLY expression { CfParserUtil.application_of_infix $2 $1 $3 } ; trifix : expression OP_VEC_THEN expression OP_VEC_ELSE expression { CfParserUtil.application_of_trifix $2 $1 $3 $5 } ; conditional : expression OP_AND expression { CfAst.Cond (fst $2, $1, $3, $1) } | expression OP_OR expression { CfAst.Cond (fst $2, $1, $1, $3) } | expression OP_THEN expression ELSE expression { CfAst.Cond (fst $2, $1, $3, $5) } ; list_sugar_items : expression_nonop { CfParserUtil.application_of_infix (CfAst.expr_loc $1, "::") $1 (CfAst.Record (CfAst.expr_loc $1, [])) } | expression_nonop list_sugar_items { CfParserUtil.application_of_infix (CfAst.expr_loc $1, "::") $1 $2 } | expression_nonop COLON expression_nonop { CfParserUtil.application_of_infix $2 $1 $3 } | expression_nonop COLON expression_nonop list_sugar_items { CfParserUtil.application_of_infix (fst $2, "++") (CfParserUtil.application_of_infix $2 $1 $3) $4 } ; %% (* Post Code *) confluence-0.10.6/src/cfeval/cfAst.mli0100644002340600244710000000420410266541655017125 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) exception CfAstError;; type expr = Apply of Loc.loc * string * expr * expr list (* location, annotation, comp, arg list. *) | Connect of Loc.loc * expr * expr (* location, sink expr, source expr. *) | Cond of Loc.loc * expr * expr * expr (* location, predicate, true, false *) | Name of Loc.loc * string | Comp of Loc.loc * string * string list * stmt list (* location, annotation, ports, statements *) | Prim of Loc.loc * string * string list (* location, primitive name, ports *) | DotName of Loc.loc * expr * string | DotPosition of Loc.loc * expr * Intbig.intbig | Integer of Loc.loc * Intbig.intbig | Float of Loc.loc * float | Boolean of Loc.loc * bool | Vector of Loc.loc * string | Record of Loc.loc * (string * expr) list | Free of Loc.loc and stmt = ApplyStmt of expr | ConnectStmt of expr ;; val expr_loc : expr -> Loc.loc;; val stmt_loc : stmt -> Loc.loc;; val add_sub_env : expr -> expr -> string -> expr;; val write_apply : expr -> string -> out_channel -> unit;; confluence-0.10.6/src/cfeval/cfCompiler.ml0100644002340600244710000002467510266541656020016 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) exception Error of string;; (* Compilation error handling. *) let lastLocation = ref (Loc.unknown "Report Default");; let setLocation loc = if Loc.isKnown loc then lastLocation := loc;; let error msg = Report.fatal( "** Compilation Error\n\n" ^ " May Be Near --> " ^ Loc.toString !lastLocation ^ "\n\n" ^ msg);; (** Compiler environment. *) type cenv = Env of cenv * string list (* Parent env, port names. *) | EnvRoot ;; let rec checkUniqueNames1 name names = match names with [] -> () | n :: names -> if name = n then raise (Error ("Name duplicated in lexical scope: " ^ name ^ ".")); checkUniqueNames1 name names ;; let rec checkUniqueNames names = match names with [] -> () | name :: names -> checkUniqueNames1 name names; checkUniqueNames names ;; let extendEnv cenv names = checkUniqueNames names; Env (cenv, names) ;; let rec findIndex count name names = match names with [] -> raise Not_found | n :: names -> if n = name then count else findIndex (count + 1) name names;; let rec findName cenv name = (* Returns (frameIndex, portIndex). frameIndex starts at 0, portIndex starts at 0. *) match cenv with EnvRoot -> raise (Error ("Name not found in lexical scope: " ^ name)) | Env (parent, names) -> try (0, findIndex 0 name names) with Not_found -> begin match findName parent name with (frameIndex, portIndex) -> (frameIndex + 1, portIndex) end ;; (** Runtime helpers. *) (** Evaluations and connects instance arguments. *) let rec evalArgs argExprs renv portValues index = match argExprs with [] -> () | argExpr :: argExprs -> argExpr renv portValues.(index); evalArgs argExprs renv portValues (index + 1) ;; (** Applies a new instance. *) let applyComponent appRenv appLoc system_name comp argCount argExprs = (* XXX Clean this up. *) let compRenv, compLoc, arity, component_name, portNames, compStmts = CfTypes.getCompInfo comp in if argCount <> arity then raise (CfTypes.Error ("Number of instantiation arguments (" ^ string_of_int argCount ^ ") does not match number of component ports (" ^ string_of_int arity ^ ").\n\n Instance Location: " ^ Loc.toString appLoc ^ "\n\n Component Location: " ^ Loc.toString compLoc)); let subRenv = CfTypes.extendEnv appRenv appLoc (compRenv, compLoc, arity, component_name, portNames, compStmts) system_name in evalArgs argExprs appRenv (CfTypes.getRenvValues subRenv) 0; compStmts subRenv; subRenv ;; (** Recursive compilation functions. *) (* stmt(s) : renv -> unit expr : renv -> variable -> unit *) let rec compExpr cenv ast = let expr = match ast with | CfAst.Apply (loc, ann, comp, args) -> compApply cenv loc ann comp args | CfAst.Connect (loc, expr0, expr1) -> compConnect cenv loc expr0 expr1 | CfAst.Cond (loc, p, t, f) -> compCond cenv loc p t f | CfAst.Name (loc, name) -> compName cenv loc name | CfAst.DotName (loc, sys, name) -> compDotName cenv loc sys name | CfAst.DotPosition (loc, sys, position) -> compDotPosition cenv loc sys position | CfAst.Comp (loc, ann, ports, stmts) -> compComponent cenv loc ann ports stmts | CfAst.Prim (loc, name, ports) -> compPrimitive cenv loc name ports | CfAst.Integer (loc, i) -> compInteger cenv loc i | CfAst.Float (loc, f) -> compFloat cenv loc f | CfAst.Boolean (loc, b) -> compBoolean cenv loc b | CfAst.Vector (loc, s) -> compVector cenv loc s | CfAst.Record (loc, fields) -> compRecord cenv loc fields | CfAst.Free loc -> compFree cenv loc in let taskedExpr renv variable = CfTypes.readyTask (renv, fun () -> expr renv variable) in taskedExpr and compStmt cenv astStmt = match astStmt with CfAst.ApplyStmt astApply -> let exprApply = compExpr cenv astApply in let stmt renv = exprApply renv (CfTypes.newFree ()) in stmt | CfAst.ConnectStmt astConnect -> let exprConnect = compExpr cenv astConnect in let stmt renv = exprConnect renv (CfTypes.newFree ()) in stmt and compStmts cenv astStmts = match astStmts with [] -> (fun renv -> ()) | astStmt :: astStmts -> let stmt = compStmt cenv astStmt and stmts = compStmts cenv astStmts in (fun renv -> stmt renv; stmts renv) and compApply cenv loc system_name astComp astArgs = setLocation loc; let exprComp = compExpr cenv astComp in let exprArgs = List.map (function astArg -> compExpr cenv astArg) astArgs in let argCount = List.length astArgs in let expr renv system = CfTypes.setLocation loc; let comp = CfTypes.newFreeWithTask renv (fun comp -> CfTypes.unify system (CfTypes.newSystem (applyComponent renv loc system_name comp argCount exprArgs)) ) in exprComp renv comp in expr and compConnect cenv loc astExpr0 astExpr1 = setLocation loc; let expr0 = compExpr cenv astExpr0 in let expr1 = compExpr cenv astExpr1 in let expr renv result = CfTypes.setLocation loc; expr0 renv result; expr1 renv result in expr and compCond cenv loc astPred astTrue astFalse = setLocation loc; let exprPred = compExpr cenv astPred in let exprTrue = compExpr cenv astTrue in let exprFalse = compExpr cenv astFalse in let expr renv result = CfTypes.setLocation loc; let pred = CfTypes.newFreeWithTask renv (fun pred -> (* XXX How to assign variable dependency? *) if CfTypes.getBoolean pred then exprTrue renv result else exprFalse renv result ) in exprPred renv pred in expr and compName cenv loc name = setLocation loc; let (envIndex, valueIndex) = findName cenv name in let expr renv result = CfTypes.setLocation loc; CfTypes.unify result (CfTypes.getRenvValues (CfTypes.getRelativeEnv renv envIndex)).(valueIndex) in expr and compDotName cenv loc astSysOrRec name = setLocation loc; let exprSysOrRec = compExpr cenv astSysOrRec in let expr renv result = CfTypes.setLocation loc; let sysOrRec = CfTypes.newFreeWithTask renv (fun sysOrRec -> CfTypes.unify result (CfTypes.getFieldByName (if CfTypes.isSystem sysOrRec then (CfTypes.getPorts sysOrRec) else sysOrRec) name) ) in exprSysOrRec renv sysOrRec in expr and compDotPosition cenv loc astSysOrRec position = setLocation loc; let exprSysOrRec = compExpr cenv astSysOrRec in let index = Intbig.int_of_intbig position - 1 in let expr renv result = CfTypes.setLocation loc; let sysOrRec = CfTypes.newFreeWithTask renv (fun sysOrRec -> CfTypes.unify result (CfTypes.getFieldByIndex (if CfTypes.isSystem sysOrRec then (CfTypes.getPorts sysOrRec) else sysOrRec) index) ) in exprSysOrRec renv sysOrRec in expr and compComponent cenv loc component_name ports astStmts = setLocation loc; let subCenv = extendEnv cenv ports in let ports = Array.of_list ports in let stmts = compStmts subCenv astStmts in let arity = Array.length ports in let expr renv result = CfTypes.setLocation loc; CfTypes.unify result (CfTypes.newComp (renv, loc, arity, component_name, ports, stmts)) in expr and compPrimitive cenv loc name ports = setLocation loc; let subCenv = extendEnv cenv ports in let ports = Array.of_list ports in let arity = Array.length ports in let stmts = try CfPrims.compilePrimitive name arity with CfTypes.Error msg -> raise (Error msg) in let expr renv result = CfTypes.setLocation loc; CfTypes.unify result (CfTypes.newComp (renv, loc, arity, name, ports, stmts)) in expr and compInteger cenv loc i = setLocation loc; let i = CfTypes.newInteger i in let expr renv result = CfTypes.setLocation loc; CfTypes.unify result i in expr and compFloat cenv loc f = setLocation loc; let f = CfTypes.newFloat f in let expr renv result = CfTypes.setLocation loc; CfTypes.unify result f in expr and compBoolean cenv loc b = setLocation loc; let b = CfTypes.newBoolean b in let expr renv result = CfTypes.setLocation loc; CfTypes.unify result b in expr and compVector cenv loc s = setLocation loc; CfTypes.checkBits s; let value = Intbig.intbig_of_binary_string s in let width = Intbig.intbig_of_int (String.length s) in let vector = CfTypes.newVectorConst value width in let expr renv result = CfTypes.setLocation loc; CfTypes.unify result (vector (CfTypes.getEnvId renv)) in expr and compRecord cenv loc fields = setLocation loc; let arity = List.length fields in let (names, values) = List.split fields in checkUniqueNames names; let names = Array.of_list names in let exprs = Array.of_list (List.map (fun value -> compExpr cenv value) values) in let expr renv result = CfTypes.setLocation loc; let values = Array.make arity (CfTypes.newFree ()) in for i = 0 to arity - 1 do let var = CfTypes.newFree () in values.(i) <- var; exprs.(i) renv var done; CfTypes.unify result (CfTypes.newRecord arity names values) in expr and compFree cenv loc = setLocation loc; let free = CfTypes.newFreeLoc loc "_" in let expr renv result = CfTypes.unify result (free renv) in expr ;; let compileApplication astApply = try let expr = compExpr EnvRoot astApply in let renv = CfTypes.newEnvRoot () in let run () = expr renv (CfTypes.newFree ()) in (renv, run) with Error msg -> error msg; raise (Error "") ;; confluence-0.10.6/src/cfeval/cfCompiler.mli0100644002340600244710000000161710266541656020156 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) val compileApplication : CfAst.expr -> CfTypes.renv * (unit -> unit);; confluence-0.10.6/src/cfeval/cfLexer.mll0100644002340600244710000003324410266541656017467 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) { (* Pre Code *) exception Error of string;; let commentDepth = ref 0;; let buildInteger (loc, s) = CfParser.INTEGER (loc, Intbig.intbig_of_string s);; let buildChar (loc, s) = CfParser.INTEGER (loc, Intbig.intbig_of_char s.[1]);; let buildFloat (loc, s) = CfParser.FLOAT (loc, float_of_string s);; let buildBoolean (loc, s) = CfParser.BOOLEAN (loc, s = "true");; let hexCharToBits hex = match hex with '0' -> "0000" | '1' -> "0001" | '2' -> "0010" | '3' -> "0011" | '4' -> "0100" | '5' -> "0101" | '6' -> "0110" | '7' -> "0111" | '8' -> "1000" | '9' -> "1001" | 'A' | 'a' -> "1010" | 'B' | 'b' -> "1011" | 'C' | 'c' -> "1100" | 'D' | 'd' -> "1101" | 'E' | 'e' -> "1110" | 'F' | 'f' -> "1111" | _ -> raise (Error "Lex Error: Invalid hex character.");; let rec hexToBits hex = if hex = "" then "" else hexCharToBits (String2.left_char hex) ^ hexToBits (String2.right_string hex);; let buildVector (loc, s) = let tmp = CfParser.VECTOR (loc, String.sub s 1 (String.length s - 2)) in if String.length s >= 3 then match String2.take_left s 3 with "'0x" | "'1x" -> CfParser.VECTOR (loc, hexToBits (String.sub s 3 (String.length s - 4))) | "'0b" | "'1b" -> CfParser.VECTOR (loc, String.sub s 3 (String.length s - 4)) | _ -> tmp else tmp;; } (* Whitespace *) let lineTerminator = '\r' | '\n' | "\r\n" let inputCharacter = [^ '\r' '\n'] let whiteSpace = lineTerminator | [' ' '\t'] (* Other stuff. *) let escape = ['\\' '"' 'n' 't' 'r'] let stringChar = [^ '\\' '"'] let pseudoChar = '\\' escape let string = '"' (stringChar | pseudoChar)* '"' let dec = ['0' - '9'] let hex = ['0' - '9' 'A' - 'F' 'a' - 'f'] let bin = ['0' '1'] let int = '-'? dec+ | "0x" hex+ | "1x" hex+ | "0b" bin+ | "1b" bin+ let vector = '\'' (bin* | ("0x" hex* | "1x" hex*) | ("0b" bin* | "1b" bin*)) '\'' let float = '-'? dec+ '.' dec+ ('e' '-'? dec+ )? let letter = ['A' - 'Z' 'a' - 'z' '_' '0' - '9'] let firstLetter = ['A' - 'Z' 'a' - 'z'] let name = firstLetter letter* let char = '@' [^ ' ' '\r' '\n' '\t'] let identifier = name | "(')" | "(!)" | "(~)" | "(head)" | "(tail)" | "(length)" | "(width)" | "('~')" | "('msb')" | "('msbs')" | "('lsb')" | "('lsbs')" | "(`!`)" | "(`X`)" | "(**)" | "('**')" | "(*)" | "(/)" | "(%)" | "('*')" | "('/')" | "('%')" | "('*+')" | "(+)" | "(-)" | "('+')" | "('-')" | "(<<)" | "(>>)" | "('<<')" | "('>>')" | "('>>+')" | "(<)" | "(>)" | "(<=)" | "(>=)" | "('<')" | "('>')" | "('<=')" | "('>=')" | "('<+')" | "('>+')" | "('<=+')" | "('>=+')" | "(#)" | "('#')" | "(::)" | "(++)" | "('++')" | "(==)" | "(!=)" | "('==')" | "('!=')" | "(&)" | "('&')" | "(^)" | "('^')" | "(|)" | "('|')" | "(&&)" | "(||)" | "(`&&`)" | "(`^^`)" | "(`||`)" | "(`<->`)" | "(`->`)" | "(`U`)" | "(:)" | "('then')" rule token = parse | int { buildInteger (CfParserUtil.next_lex lexbuf) } | char { buildChar (CfParserUtil.next_lex lexbuf) } | float { buildFloat (CfParserUtil.next_lex lexbuf) } | string { CfParser.STRING (CfParserUtil.next_lex lexbuf) } | vector { buildVector (CfParserUtil.next_lex lexbuf) } | "true" { buildBoolean (CfParserUtil.next_lex lexbuf) } | "false" { buildBoolean (CfParserUtil.next_lex lexbuf) } | "_" { CfParser.FREE (CfParserUtil.next_lex lexbuf) } | "end" { CfParser.END (CfParserUtil.next_lex lexbuf) } | "component" { CfParser.COMPONENT (CfParserUtil.next_lex lexbuf) } | "comp" { CfParser.COMP (CfParserUtil.next_lex lexbuf) } | "prim" { CfParser.PRIM (CfParserUtil.next_lex lexbuf) } | "if" { CfParser.IF (CfParserUtil.next_lex lexbuf) } | "ef" { CfParser.EF (CfParserUtil.next_lex lexbuf) } | "else" { CfParser.ELSE (CfParserUtil.next_lex lexbuf) } | "with" { CfParser.WITH (CfParserUtil.next_lex lexbuf) } | "is" { CfParser.IS (CfParserUtil.next_lex lexbuf) } | "local" { CfParser.LOCAL (CfParserUtil.next_lex lexbuf) } | "import" { CfParser.IMPORT (CfParserUtil.next_lex lexbuf) } | "environment" { CfParser.ENVIRONMENT (CfParserUtil.next_lex lexbuf) } | "rootenvironment" { CfParser.ROOTENVIRONMENT (CfParserUtil.next_lex lexbuf) } | "fileloc" { let (l, _) = CfParserUtil.next_lex lexbuf in CfParser.STRING (l, "\"" ^ Loc.toString l ^ "\"") } | "{" { CfParser.BRACE_LEFT (CfParserUtil.next_lex lexbuf) } | "}" { CfParser.BRACE_RIGHT (CfParserUtil.next_lex lexbuf) } | "(" { CfParser.PAREN_LEFT (CfParserUtil.next_lex lexbuf) } | ")" { CfParser.PAREN_RIGHT (CfParserUtil.next_lex lexbuf) } | "[" { CfParser.BRACKET_LEFT (CfParserUtil.next_lex lexbuf) } | "]" { CfParser.BRACKET_RIGHT (CfParserUtil.next_lex lexbuf) } | "$" { CfParser.DOLLAR (CfParserUtil.next_lex lexbuf) } | ":" { CfParser.COLON (CfParserUtil.next_lex lexbuf) } | eof { CfParser.EOF (CfParserUtil.next_lex lexbuf) } | "(*" { let _ = CfParserUtil.next_lex lexbuf in incr commentDepth; comment lexbuf; token lexbuf } | whiteSpace { let _ = CfParserUtil.next_lex lexbuf in token lexbuf } | "." { CfParser.OP_DOT (CfParserUtil.next_lex lexbuf) } | "'" { CfParser.OP_VEC_SELECT (CfParserUtil.next_lex lexbuf) } | "!" { CfParser.OP_NOT (CfParserUtil.next_lex lexbuf) } | "~" { CfParser.OP_BW_NOT (CfParserUtil.next_lex lexbuf) } | "head" { CfParser.OP_HEAD (CfParserUtil.next_lex lexbuf) } | "tail" { CfParser.OP_TAIL (CfParserUtil.next_lex lexbuf) } | "length" { CfParser.OP_LENGTH (CfParserUtil.next_lex lexbuf) } | "width" { CfParser.OP_WIDTH (CfParserUtil.next_lex lexbuf) } | "'~'" { CfParser.OP_VEC_NOT (CfParserUtil.next_lex lexbuf) } | "'msb'" { CfParser.OP_VEC_MSB (CfParserUtil.next_lex lexbuf) } | "'msbs'" { CfParser.OP_VEC_MSBS (CfParserUtil.next_lex lexbuf) } | "'lsb'" { CfParser.OP_VEC_LSB (CfParserUtil.next_lex lexbuf) } | "'lsbs'" { CfParser.OP_VEC_LSBS (CfParserUtil.next_lex lexbuf) } | "`!`" { CfParser.OP_PROP_NOT (CfParserUtil.next_lex lexbuf) } | "`X`" { CfParser.OP_PROP_X (CfParserUtil.next_lex lexbuf) } | "**" { CfParser.OP_POW (CfParserUtil.next_lex lexbuf) } | "'**'" { CfParser.OP_VEC_POW (CfParserUtil.next_lex lexbuf) } | "*" { CfParser.OP_MUL (CfParserUtil.next_lex lexbuf) } | "/" { CfParser.OP_DIV (CfParserUtil.next_lex lexbuf) } | "%" { CfParser.OP_MOD (CfParserUtil.next_lex lexbuf) } | "'*'" { CfParser.OP_VEC_MUL (CfParserUtil.next_lex lexbuf) } | "'/'" { CfParser.OP_VEC_DIV (CfParserUtil.next_lex lexbuf) } | "'%'" { CfParser.OP_VEC_MOD (CfParserUtil.next_lex lexbuf) } | "'*+'" { CfParser.OP_VEC_MUL_S (CfParserUtil.next_lex lexbuf) } | "+" { CfParser.OP_ADD (CfParserUtil.next_lex lexbuf) } | "-" { CfParser.OP_SUB (CfParserUtil.next_lex lexbuf) } | "'+'" { CfParser.OP_VEC_ADD (CfParserUtil.next_lex lexbuf) } | "'-'" { CfParser.OP_VEC_SUB (CfParserUtil.next_lex lexbuf) } | "<<" { CfParser.OP_LSHIFT (CfParserUtil.next_lex lexbuf) } | ">>" { CfParser.OP_RSHIFT (CfParserUtil.next_lex lexbuf) } | "'<<'" { CfParser.OP_VEC_LSHIFT (CfParserUtil.next_lex lexbuf) } | "'>>'" { CfParser.OP_VEC_RSHIFT (CfParserUtil.next_lex lexbuf) } | "'>>+'" { CfParser.OP_VEC_RSHIFT_S (CfParserUtil.next_lex lexbuf) } | "<" { CfParser.OP_LT (CfParserUtil.next_lex lexbuf) } | ">" { CfParser.OP_GT (CfParserUtil.next_lex lexbuf) } | "<=" { CfParser.OP_LE (CfParserUtil.next_lex lexbuf) } | ">=" { CfParser.OP_GE (CfParserUtil.next_lex lexbuf) } | "'<'" { CfParser.OP_VEC_LT (CfParserUtil.next_lex lexbuf) } | "'>'" { CfParser.OP_VEC_GT (CfParserUtil.next_lex lexbuf) } | "'<='" { CfParser.OP_VEC_LE (CfParserUtil.next_lex lexbuf) } | "'>='" { CfParser.OP_VEC_GE (CfParserUtil.next_lex lexbuf) } | "'<+'" { CfParser.OP_VEC_LT_S (CfParserUtil.next_lex lexbuf) } | "'>+'" { CfParser.OP_VEC_GT_S (CfParserUtil.next_lex lexbuf) } | "'<=+'" { CfParser.OP_VEC_LE_S (CfParserUtil.next_lex lexbuf) } | "'>=+'" { CfParser.OP_VEC_GE_S (CfParserUtil.next_lex lexbuf) } | "#" { CfParser.OP_REPEAT (CfParserUtil.next_lex lexbuf) } | "'#'" { CfParser.OP_VEC_REPEAT (CfParserUtil.next_lex lexbuf) } | "::" { CfParser.OP_CONS (CfParserUtil.next_lex lexbuf) } | "++" { CfParser.OP_CONCAT (CfParserUtil.next_lex lexbuf) } | "'++'" { CfParser.OP_VEC_CONCAT (CfParserUtil.next_lex lexbuf) } | "\\" { CfParser.OP_RETURN (CfParserUtil.next_lex lexbuf) } | "==" { CfParser.OP_EQU (CfParserUtil.next_lex lexbuf) } | "!=" { CfParser.OP_NEQ (CfParserUtil.next_lex lexbuf) } | "'=='" { CfParser.OP_VEC_EQU (CfParserUtil.next_lex lexbuf) } | "'!='" { CfParser.OP_VEC_NEQ (CfParserUtil.next_lex lexbuf) } | "&" { CfParser.OP_BW_AND (CfParserUtil.next_lex lexbuf) } | "'&'" { CfParser.OP_VEC_AND (CfParserUtil.next_lex lexbuf) } | "^" { CfParser.OP_BW_XOR (CfParserUtil.next_lex lexbuf) } | "'^'" { CfParser.OP_VEC_XOR (CfParserUtil.next_lex lexbuf) } | "|" { CfParser.OP_BW_OR (CfParserUtil.next_lex lexbuf) } | "'|'" { CfParser.OP_VEC_OR (CfParserUtil.next_lex lexbuf) } | "&&" { CfParser.OP_AND (CfParserUtil.next_lex lexbuf) } | "||" { CfParser.OP_OR (CfParserUtil.next_lex lexbuf) } | "`&&`" { CfParser.OP_PROP_AND (CfParserUtil.next_lex lexbuf) } | "`^^`" { CfParser.OP_PROP_XOR (CfParserUtil.next_lex lexbuf) } | "`||`" { CfParser.OP_PROP_OR (CfParserUtil.next_lex lexbuf) } | "`<->`" { CfParser.OP_PROP_EQUIV (CfParserUtil.next_lex lexbuf) } | "`->`" { CfParser.OP_PROP_IMPLY (CfParserUtil.next_lex lexbuf) } | "`U`" { CfParser.OP_PROP_U (CfParserUtil.next_lex lexbuf) } | "then" { CfParser.OP_THEN (CfParserUtil.next_lex lexbuf) } | "'then'" { CfParser.OP_VEC_THEN (CfParserUtil.next_lex lexbuf) } | "'else'" { CfParser.OP_VEC_ELSE (CfParserUtil.next_lex lexbuf) } | "<-" { CfParser.OP_CONNECT_LEFT (CfParserUtil.next_lex lexbuf) } | "->" { CfParser.OP_CONNECT_RIGHT (CfParserUtil.next_lex lexbuf) } | "=" { CfParser.OP_UNIFY (CfParserUtil.next_lex lexbuf) } | identifier { CfParser.IDENTIFIER (CfParserUtil.next_lex lexbuf) } | _ { CfParserUtil.error ("Unrecognized character: '" ^ (snd (CfParserUtil.next_lex lexbuf)) ^ "'"); CfParser.LexerError (CfParserUtil.next_lex lexbuf) } and comment = parse | "(*" { let _ = CfParserUtil.next_lex lexbuf in incr commentDepth; comment lexbuf } | "*)" { let _ = CfParserUtil.next_lex lexbuf in decr commentDepth; if !commentDepth <> 0 then comment lexbuf else () } | string { let _ = CfParserUtil.next_lex lexbuf in comment lexbuf } | eof { CfParserUtil.error ("End of file without closing comment.") } | _ { let _ = CfParserUtil.next_lex lexbuf in comment lexbuf } { (* Post Code *) } confluence-0.10.6/src/cfeval/cf_fnf.ml0100644002340600244710000002431510266541660017136 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; (* Types *) type producer = cell;; type scope_holder = No_scope of string * string | Scope of scope;; type system = System of system * (* Parent system. *) int * (* SysId. *) scope_holder ref * (* FNF scope. *) bool ref * (* Cre determined. *) string ref * (* Clock domain. *) producer ref * (* Reset. *) producer ref * (* Enable. *) Loc.loc list (* Call path. *) | System_root of int * (* SysId. *) scope * (* FNF scope. *) string * (* Clock domain. *) producer * (* Reset. *) producer (* Enable. *) ;; type stateful = Reg of system * port * port * port;; (* system, clock_port, reset_port, enable_port *) (** Local Stateful Data *) let sub_clocks = Hashtbl.create 64;; (* Clock name to producing cell. *) let sub_resets = Hashtbl.create 64;; (* SysId to producer IdSet. *) let sub_enables = Hashtbl.create 64;; (* SysId to producer IdSet. *) let next_system_id = ref 0;; (* Next SysId. *) let statefuls = ref [];; (* list of stateful components. *) let fnf = create_root_scope "top";; (* XXX *) let zero = create_const fnf "0";; let one = create_const fnf "1";; (** System Functions *) let rec scope_of_system system = match system with | System_root (_, scope, _, _, _) -> scope | System (parent, _, scope, _, _, _, _, _) -> (match !scope with | No_scope (module_name, instance_name) -> (* let new_scope = create_sub_scope (scope_of_system parent) module_name instance_name in *) let new_scope = fnf in scope := Scope new_scope; new_scope | Scope scope -> scope) ;; let id_of_system system = match system with | System_root (id, _, _, _, _) | System (_, id, _, _, _, _, _, _) -> id ;; let locs_of_system system = match system with | System_root _ -> [] | System (_, _, _, _, _, _, _, locs) -> locs ;; let new_root_system () = let id = !next_system_id in incr next_system_id; System_root (id, fnf, "clock", zero, one) ;; let new_sub_system parent module_name instance_name instance_locs component_loc = let id = !next_system_id in incr next_system_id; System (parent, id, ref (No_scope (module_name, instance_name)), ref false, ref "", ref zero, ref one, instance_locs) ;; (** Determine the clock, reset, and enable for a system. *) let rec determine_cre system = (* clock = pClock when clock = "" else clock reset = parentReset OR localResets enable = parentEnable AND (parentReset OR localResets) *) match system with | System_root (_, _, clock, reset, enable) -> clock, reset, enable | System (parent, id, space, cre_determined, clock, reset, enable, locs) -> if not !cre_determined then begin cre_determined := true; let parent_clock, parent_reset, parent_enable = determine_cre parent in let pid = id_of_system parent in let parent_scope = scope_of_system parent in let fold_or a b = let cell, pa, pb = create_or parent_scope 1 in connect a pa; connect b pb; cell in let fold_and a b = let cell, pa, pb = create_and parent_scope 1 in connect a pa; connect b pb; cell in if !clock = "" then clock := parent_clock; if not (Hashtbl.mem sub_resets id) then reset := parent_reset else reset := List.fold_left fold_or parent_reset (Hashtbl.find sub_resets id); if not (Hashtbl.mem sub_enables id) then enable := parent_enable else enable := List.fold_left fold_and parent_enable (Hashtbl.find sub_enables id); end; !clock, !reset, !enable ;; (** Signal width. *) let width_of_producer = width_of_cell;; (** Synchronization Functions *) let set_clock_domain system clock_name error = match system with | System_root _ -> error "System error. Can not set clock domain for root system." | System (_, _, _, _, clock, _, _, _) -> if !clock <> "" then error ("System error. System already assigned clock domain \"" ^ !clock ^ "\". Can not be set to \"" ^ clock_name ^ "\"."); clock := clock_name ;; let add_sub_reset system producer error = match system with | System_root _ -> error "System error. Can not reset root system." | System (_, id, _, _, _, _, _, _) -> if Hashtbl.mem sub_resets id then Hashtbl.replace sub_resets id (producer :: (Hashtbl.find sub_resets id)) else Hashtbl.add sub_resets id [producer] ;; let add_sub_enable system producer error = match system with | System_root _ -> error "System error. Can not enable root system." | System (_, id, _, _, _, _, _, _) -> if Hashtbl.mem sub_enables id then Hashtbl.replace sub_enables id (producer :: (Hashtbl.find sub_enables id)) else Hashtbl.add sub_enables id [producer] ;; (** Post Evaluation Functions *) (** A running list of required clocks. *) let clocks = Hashtbl.create 64;; (** Connects clocks, resets, and enables to stateful primitives. *) let connect_stateful stateful = match stateful with Reg (system, clock_port, reset_port, enable_port) -> let clock, reset, enable = determine_cre system in if not (Hashtbl.mem clocks clock) then Hashtbl.add clocks clock (create_input fnf clock 1); connect (Hashtbl.find clocks clock) clock_port; connect reset reset_port; connect enable enable_port ;; (** Generates and FNF netlist. *) let output_fnf channel = List.iter connect_stateful !statefuls; Fnf_out.output_fnf channel fnf ;; (** Logic Primitive Constructors *) let new_input system name width = create_input (scope_of_system system) name width ;; let new_output system name producer = let cell, a = create_output (scope_of_system system) name (width_of_cell producer) in connect producer a ;; let new_const system value = create_const (scope_of_system system) value ;; let new_buf system p0 = let cell, a = create_buf (scope_of_system system) (width_of_cell p0) in connect p0 a; cell ;; let new_not system p0 = let cell, a = create_not (scope_of_system system) (width_of_cell p0) in connect p0 a; cell ;; let new_and system p0 p1 = let cell, a, b = create_and (scope_of_system system) (width_of_cell p0) in connect p0 a; connect p1 b; cell ;; let new_xor system p0 p1 = let cell, a, b = create_xor (scope_of_system system) (width_of_cell p0) in connect p0 a; connect p1 b; cell ;; let new_or system p0 p1 = let cell, a, b = create_or (scope_of_system system) (width_of_cell p0) in connect p0 a; connect p1 b; cell ;; let new_concat system p0 p1 = let cell, a, b = create_concat (scope_of_system system) (width_of_cell p0) (width_of_cell p1) in connect p0 a; connect p1 b; cell ;; let new_select system p0 bit = let cell, a = create_select (scope_of_system system) (width_of_cell p0) bit in connect p0 a; cell ;; let new_equ system p0 p1 = let cell, a, b = create_eq (scope_of_system system) (width_of_cell p0) in connect p0 a; connect p1 b; cell ;; let new_lt system p0 p1 = let cell, a, b = create_lt (scope_of_system system) (width_of_cell p0) in connect p0 a; connect p1 b; cell ;; let new_add system p0 p1 = let cell, a, b = create_add (scope_of_system system) (width_of_cell p0) in connect p0 a; connect p1 b; cell ;; let new_sub system p0 p1 = let cell, a, b = create_sub (scope_of_system system) (width_of_cell p0) in connect p0 a; connect p1 b; cell ;; let new_mul system p0 p1 = let cell, a, b = create_mul (scope_of_system system) (width_of_cell p0) in connect p0 a; connect p1 b; cell ;; let new_mux system pred t f = let cell, a, b, c = create_mux (scope_of_system system) (width_of_cell t) in connect pred a; connect f b; connect t c; cell ;; (** Stateful logic primitives. *) let new_state system width = let cell, _ = create_buf (scope_of_system system) width in cell ;; let new_reg system data_in data_out = let scope = scope_of_system system in let width = width_of_cell data_in in let reg, clk, data = create_ff scope width in let rmux, rst, r0, r1 = create_mux scope width in let emux, enb, e0, e1 = create_mux scope width in let zero = create_const scope (String.make width '0') in connect data_in e1; connect emux r0; connect zero r1; connect rmux data; connect reg e0; connect reg (port_of_cell data_out 0); statefuls := Reg (system, clk, rst, enb) :: !statefuls ;; let new_bbox system name params data_in data_out = let scope = scope_of_system system in let width_in = width_of_cell data_in in let ecat, enb, ecat_data = create_concat scope 1 width_in in let rcat, rst, rcat_data = create_concat scope 1 (width_in + 1) in let ccat, clk, ccat_data = create_concat scope 1 (width_in + 2) in let bbox, bbox_data = create_bbox scope name (width_of_cell data_out) (width_in + 3) params in connect data_in ecat_data; connect ecat rcat_data; connect rcat ccat_data; connect ccat bbox_data; connect bbox (port_of_cell data_out 0); statefuls := Reg (system, clk, rst, enb) :: !statefuls; ;; confluence-0.10.6/src/cfeval/cfParserUtil.ml0100644002340600244710000002064010266541656020322 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Stateful Parser Data *) let to_parse = Queue.create ();; (* Fifo of file names to parse. *) let asts = Hashtbl.create 8;; (* File name => ast. *) let subs = Hashtbl.create 8;; (* File name => subenvs. *) let top_files = ref [];; let (files : string list ref) = ref [];; let base_env = ref "/usr/lib/confluence/base.cf";; let set_base_env file = base_env := file ;; (* Position information. *) let parent = ref "";; let error_file = ref "";; let error_line = ref 0;; let error_col = ref 0;; let current_file = ref "";; let current_line = ref 0;; let current_col = ref 0;; let current_token = ref "";; (* Clear stateful information. *) let clear_stateful () = Hashtbl.clear asts; Hashtbl.clear subs; top_files := []; files := []; ;; (* Parsing error reporting. *) let error msg = Report.fatal ( "** Syntax Error\n\n" ^ " May Be Near --> " ^ Loc.toString (Loc.create !error_file !error_line !error_col) ^ "\n\n" ^ msg);; (* Main parser helpers. *) let format_name new_name = let format_path () = try let i = String.rindex !current_file '/' in String.sub !current_file 0 (i + 1) with Not_found -> "" in if new_name = "" then error "File reference is an empty string."; if new_name.[0] = '/' then new_name else if new_name.[0] = '$' then begin let (env, path) = try let i = String.index new_name '/' in (String.sub new_name 1 (i - 1), String.sub new_name i (String.length new_name - i)) with Not_found -> (String.sub new_name 1 (String.length new_name - 1), "") in try let env_val = Sys.getenv env in if String.length env_val = 0 || env_val.[0] <> '/' then error ("Environment variable is not an absolute path: " ^ env ^ " = " ^ env_val); env_val ^ path with Not_found -> error ("Environment variable not found: " ^ env); "" end else format_path () ^ new_name ;; let set_sub_env file = if !parent = "" then top_files := file :: !top_files else begin try Hashtbl.replace subs !parent (file :: (Hashtbl.find subs !parent)) with Not_found -> Hashtbl.add subs !parent [file] end;; let rec parse_all_files parse_channel = if not (Queue.is_empty to_parse) then let file = Queue.take to_parse in if not (Hashtbl.mem asts file) then begin files := file :: !files; parent := ""; current_file := file; current_line := 1; current_col := 1; error_file := file; error_line := 1; error_col := 1; try let channel = open_in file in Hashtbl.add asts file (parse_channel channel); close_in channel; set_sub_env file with Sys_error _ -> error ("File not found: " ^ file) end; parse_all_files parse_channel; ;; let rec insert_sub_asts ast_apply files = match files with [] -> ast_apply | file :: files -> insert_sub_asts (CfAst.add_sub_env ast_apply (build_sub_ast file) ("_file_" ^ file)) files and build_sub_ast file = let ast = Hashtbl.find asts file in let subFiles = try Hashtbl.find subs file with Not_found -> [] in insert_sub_asts ast subFiles;; let rec build_file_names files = match files with [] -> [] | file :: files -> ("_file_" ^ file) :: build_file_names files;; let free_arg_list loc names = List2.make (List.length names) (CfAst.Free loc) ;; (** Main parser. *) let parse_program main_file lexer parser = let parse_channel channel = parser lexer (Lexing.from_channel channel) in let loc = Loc.create main_file 0 0 in Queue.add main_file to_parse; parse_all_files parse_channel; let file_names = build_file_names !files in let main_ast = insert_sub_asts (CfAst.Apply (loc, "", CfAst.Comp (loc, "", file_names, []), free_arg_list loc file_names)) !top_files in clear_stateful (); main_ast ;; (* Misc Parser and Lexer functions. *) let current_file_loc () = Loc.create !current_file 0 0;; let set_env env_file = if env_file = "" then begin parent := !base_env; Queue.add !base_env to_parse; end else begin let new_file = format_name env_file in parent := new_file; Queue.add new_file to_parse; end;; let add_import new_import = let new_file = format_name new_import in Queue.add new_file to_parse; "_file_" ^ new_file;; let update_positions c = if c == '\n' then begin current_line := !current_line + 1; current_col := 1 end else current_col := !current_col + 1;; let next_lex lexbuf = error_file := !current_file; error_line := !current_line; error_col := !current_col; let loc = Loc.create !current_file !current_line !current_col in let token = Lexing.lexeme lexbuf in current_token := token; String.iter update_positions token; (loc, token);; let get_current_token () = !current_token;; (* Parser Transformations *) (** Transforms a namespace in an expression. *) let application_expr_of_namespace loc annotation names stmts = CfAst.Apply (loc, annotation, CfAst.Comp (loc, annotation, names, stmts), free_arg_list loc names) ;; (** Transforms a namespace in a statement. *) let application_of_namespace loc annotation names stmts = CfAst.ApplyStmt (application_expr_of_namespace loc annotation names stmts) ;; (** Selects position from system or record expression. *) let select_position loc expr position = CfAst.DotPosition (loc, expr, Intbig.intbig_of_int position) ;; (** Connects a name to an expression. *) let connect_name loc (name_loc, name) expr = CfAst.Connect (loc, CfAst.Name (name_loc, name), expr) ;; (** Creates a statement from a named component. *) let stmt_of_comp_named comp_loc (name_loc, name) ports stmts = CfAst.ConnectStmt (connect_name comp_loc (name_loc, name) (CfAst.Comp (comp_loc, name, ports, stmts))) ;; let application_of_prefix (op_loc, op_name) a = select_position op_loc (CfAst.Apply (op_loc, "", CfAst.Name (op_loc, "(" ^ op_name ^ ")"), [a; CfAst.Free op_loc])) 2 ;; let application_of_infix (op_loc, op_name) a b = select_position op_loc (CfAst.Apply (op_loc, "", CfAst.Name (op_loc, "(" ^ op_name ^ ")"), [a; b; CfAst.Free op_loc])) 3 ;; let application_of_trifix (op_loc, op_name) a b c = select_position op_loc (CfAst.Apply (op_loc, "", CfAst.Name (op_loc, "(" ^ op_name ^ ")"), [a; b; c; CfAst.Free op_loc])) 4 ;; let conditional_of_ifelse loc p ts fs = (* _ <- p ? {comp ts end} : {comp fs end} *) CfAst.ConnectStmt (CfAst.Connect (loc, CfAst.Free loc, (CfAst.Cond (loc, p, (CfAst.Apply (loc, "", CfAst.Comp (loc, "", [], ts), [])), (CfAst.Apply (loc, "", CfAst.Comp (loc, "", [], fs), [])) ))));; let format_string s = (* Remove quotes. Convert \ charaters. *) let rec f i s1 = if i == (String.length s) - 1 then s1 else if String.get s i == '\\' then match String.get s (i + 1) with '\\' -> f (i + 2) (s1 ^ "\\") | '"' -> f (i + 2) (s1 ^ "\"") | 'n' -> f (i + 2) (s1 ^ "\n") | 'r' -> f (i + 2) (s1 ^ "\r") | 't' -> f (i + 2) (s1 ^ "\t") | _ -> begin error "Invalid String"; "" end else f (i + 1) (s1 ^ String.make 1 (String.get s i)) in f 1 "";; let rec application_of_string loc s = (* "abc" -> {`:: a {`:: b {`:: c [] $} $} $} *) if String.length s == 0 then CfAst.Record (loc, []) else select_position loc (CfAst.Apply (loc, "", CfAst.Name (loc, "(::)"), [CfAst.Integer (loc, Intbig.intbig_of_char (String.get s 0)); application_of_string loc (String.sub s 1 (String.length s - 1)); CfAst.Free loc] )) 3 ;; confluence-0.10.6/src/cfeval/cfParserUtil.mli0100644002340600244710000000527110266541657020477 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Parsing Transformations and Management *) (** Setting the base environment. *) val set_base_env : string -> unit;; (** Main parsing. *) val parse_program : string -> 'a -> ('a -> Lexing.lexbuf -> CfAst.expr) -> CfAst.expr;; (** Error Reporting *) val error : string -> unit;; (** Parser and Lexer Functions *) val current_file_loc : unit -> Loc.loc;; val set_env : string -> unit;; val add_import : string -> string;; val next_lex : Lexing.lexbuf -> (Loc.loc * string);; val get_current_token : unit -> string;; (** Parser Transformations *) val free_arg_list : Loc.loc -> string list -> CfAst.expr list;; val application_expr_of_namespace : Loc.loc -> string -> string list -> CfAst.stmt list -> CfAst.expr;; val application_of_namespace : Loc.loc -> string -> string list -> CfAst.stmt list -> CfAst.stmt;; (* location, names, stmts *) val select_position : Loc.loc -> CfAst.expr -> int -> CfAst.expr;; val connect_name : Loc.loc -> (Loc.loc * string) -> CfAst.expr -> CfAst.expr;; val stmt_of_comp_named : Loc.loc -> (Loc.loc * string) -> string list -> CfAst.stmt list -> CfAst.stmt;; val application_of_prefix : (Loc.loc * string) -> CfAst.expr -> CfAst.expr;; (* name, expr *) val application_of_infix : (Loc.loc * string) -> CfAst.expr -> CfAst.expr -> CfAst.expr;; (* name, expr, expr *) val application_of_trifix : (Loc.loc * string) -> CfAst.expr -> CfAst.expr -> CfAst.expr -> CfAst.expr;; (* name, expr, expr, expr *) val conditional_of_ifelse : Loc.loc -> CfAst.expr -> CfAst.stmt list -> CfAst.stmt list -> CfAst.stmt;; val format_string : string -> string;; val application_of_string : Loc.loc -> string -> CfAst.expr;; confluence-0.10.6/src/cfeval/cfPrims.ml0100644002340600244710000011735410266541657017334 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) exception CfPrimsError;; (** Compiler of primitives. *) (** Strict primitive builders. *) let stmt_of_prim_l prim = fun renv -> let ports = CfTypes.getRenvValues renv in let slot = CfTypes.newSlot renv 1 (fun () -> prim ports.(0)) in CfTypes.slotVariableLenient slot ports.(0) ;; let stmt_of_prim_s prim = fun renv -> let ports = CfTypes.getRenvValues renv in let slot = CfTypes.newSlot renv 1 (fun () -> prim ports.(0)) in CfTypes.slotVariableStrict slot ports.(0) ;; let stmt_of_prim_ll prim = fun renv -> let ports = CfTypes.getRenvValues renv in let slot = CfTypes.newSlot renv 2 (fun () -> prim ports.(0) ports.(1)) in CfTypes.slotVariableLenient slot ports.(0); CfTypes.slotVariableLenient slot ports.(1) ;; let stmt_of_prim_ss prim = fun renv -> let ports = CfTypes.getRenvValues renv in let slot = CfTypes.newSlot renv 2 (fun () -> prim ports.(0) ports.(1)) in CfTypes.slotVariableStrict slot ports.(0); CfTypes.slotVariableStrict slot ports.(1) ;; let stmt_of_prim_sl prim = fun renv -> let ports = CfTypes.getRenvValues renv in let slot = CfTypes.newSlot renv 2 (fun () -> prim ports.(0) ports.(1)) in CfTypes.slotVariableStrict slot ports.(0); CfTypes.slotVariableLenient slot ports.(1) ;; let stmt_of_prim_x prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.unify ports.(0) (prim ()) ;; let stmt_of_prim_lx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(1) [ports.(0)]; let slot = CfTypes.newSlot renv 1 (fun () -> CfTypes.unify ports.(1) (prim ports.(0))) in CfTypes.slotVariableLenient slot ports.(0) ;; let stmt_of_prim_sx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(1) [ports.(0)]; let slot = CfTypes.newSlot renv 1 (fun () -> CfTypes.unify ports.(1) (prim ports.(0))) in CfTypes.slotVariableStrict slot ports.(0) ;; let stmt_of_prim_llx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(2) [ports.(0); ports.(1)]; let slot = CfTypes.newSlot renv 2 (fun () -> CfTypes.unify ports.(2) (prim ports.(0) ports.(1))) in CfTypes.slotVariableLenient slot ports.(0); CfTypes.slotVariableLenient slot ports.(1) ;; (** Vector primitive builders. *) let stmt_of_prim_rll prim = fun renv -> let ports = CfTypes.getRenvValues renv in let slot = CfTypes.newSlot renv 2 (fun () -> prim (CfTypes.getEnvId renv) ports.(0) ports.(1)) in CfTypes.slotVariableLenient slot ports.(0); CfTypes.slotVariableLenient slot ports.(1) ;; let stmt_of_prim_rsl prim = fun renv -> let ports = CfTypes.getRenvValues renv in let slot = CfTypes.newSlot renv 2 (fun () -> prim (CfTypes.getEnvId renv) ports.(0) ports.(1)) in CfTypes.slotVariableStrict slot ports.(0); CfTypes.slotVariableLenient slot ports.(1) ;; let stmt_of_prim_rlx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(1) [ports.(0)]; let slot = CfTypes.newSlot renv 1 (fun () -> CfTypes.unify ports.(1) (prim (CfTypes.getEnvId renv) ports.(0))) in CfTypes.slotVariableLenient slot ports.(0) ;; let stmt_of_prim_rllx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(2) [ports.(0); ports.(1)]; let slot = CfTypes.newSlot renv 2 (fun () -> CfTypes.unify ports.(2) (prim (CfTypes.getEnvId renv) ports.(0) ports.(1))) in CfTypes.slotVariableLenient slot ports.(0); CfTypes.slotVariableLenient slot ports.(1) ;; let stmt_of_prim_rlsx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(2) [ports.(0); ports.(1)]; let slot = CfTypes.newSlot renv 2 (fun () -> CfTypes.unify ports.(2) (prim (CfTypes.getEnvId renv) ports.(0) ports.(1))) in CfTypes.slotVariableLenient slot ports.(0); CfTypes.slotVariableStrict slot ports.(1) ;; let stmt_of_prim_rlllx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(3) [ports.(0); ports.(1); ports.(2)]; let slot = CfTypes.newSlot renv 3 (fun () -> CfTypes.unify ports.(3) (prim (CfTypes.getEnvId renv) ports.(0) ports.(1) ports.(2))) in CfTypes.slotVariableLenient slot ports.(0); CfTypes.slotVariableLenient slot ports.(1); CfTypes.slotVariableLenient slot ports.(2) ;; let stmt_of_prim_rslx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(2) [ports.(0); ports.(1)]; let slot = CfTypes.newSlot renv 2 (fun () -> CfTypes.unify ports.(2) (prim (CfTypes.getEnvId renv) ports.(0) ports.(1) )) in CfTypes.slotVariableStrict slot ports.(0); CfTypes.slotVariableLenient slot ports.(1) ;; let stmt_of_prim_rsslx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(3) [ports.(0); ports.(1); ports.(2)]; let slot = CfTypes.newSlot renv 3 (fun () -> CfTypes.unify ports.(3) (prim (CfTypes.getEnvId renv) ports.(0) ports.(1) ports.(2))) in CfTypes.slotVariableStrict slot ports.(0); CfTypes.slotVariableStrict slot ports.(1); CfTypes.slotVariableLenient slot ports.(2) ;; let stmt_of_prim_rssllx prim = fun renv -> let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(4) [ports.(0); ports.(1); ports.(2); ports.(3)]; let slot = CfTypes.newSlot renv 4 (fun () -> CfTypes.unify ports.(4) (prim (CfTypes.getEnvId renv) ports.(0) ports.(1) ports.(2) ports.(3))) in CfTypes.slotVariableStrict slot ports.(0); CfTypes.slotVariableStrict slot ports.(1); CfTypes.slotVariableLenient slot ports.(2); CfTypes.slotVariableLenient slot ports.(3) ;; (* Primitive information. *) type prim = | Error | IsEqual | IsComponent | IsSystem | SystemPorts | IsInteger | IntegerToString | StringToInteger | IntegerToFloat | IntegerLt | IntegerGt (* XXX *) | IntegerLe (* XXX *) | IntegerGe (* XXX *) | IntegerAdd | IntegerSub | IntegerMul | IntegerDiv | IntegerMod | IntegerPow | IntegerNot | IntegerAnd | IntegerXor | IntegerOr | IntegerShiftLeft | IntegerShiftRight | IsFloat | FloatToString | StringToFloat | FloatToInteger | FloatLt | FloatGt (* XXX *) | FloatLe (* XXX *) | FloatGe (* XXX *) | FloatAdd | FloatSub | FloatMul | FloatDiv | FloatPow | FloatCeil | FloatFloor | FloatExp | FloatLog | FloatSqrt (* XXX *) | FloatSin | FloatCos | FloatTan | FloatAsin | FloatAcos | FloatAtan | FloatAtan2 | IsBoolean | BooleanNot | IsRecord | RecordInfo | IsList | ListPrint | ListArgv | IsVector | VectorWidth | VectorClock | VectorEnable | VectorReset | VectorInput | VectorOutput (* | VectorAssert | VectorPrint *) | VectorConst | VectorAnd | VectorOr | VectorXor | VectorNot | VectorConcat | VectorZero | VectorSelect | VectorEqu | VectorLt | VectorAdd | VectorSub | VectorMul | VectorMux (* | VectorTristate | VectorExtComb | VectorExtSequ | VectorExtSoft *) | VectorReg | VectorBbox (* | VectorRom | VectorRam *) | IsProperty | PropertyNot | PropertyOr | PropertyNext | PropertyUntil ;; let totalArity prim = match prim with | Error -> 1 | IsEqual -> 3 | IsComponent -> 2 | IsSystem -> 2 | SystemPorts -> 2 | IsInteger -> 2 | IntegerToString -> 2 | StringToInteger -> 2 | IntegerToFloat -> 2 | IntegerLt -> 3 | IntegerGt -> 3 | IntegerLe -> 3 | IntegerGe -> 3 | IntegerAdd -> 3 | IntegerSub -> 3 | IntegerMul -> 3 | IntegerDiv -> 3 | IntegerMod -> 3 | IntegerPow -> 3 | IntegerNot -> 2 | IntegerAnd -> 3 | IntegerXor -> 3 | IntegerOr -> 3 | IntegerShiftLeft -> 3 | IntegerShiftRight -> 3 | IsFloat -> 2 | FloatToString -> 2 | StringToFloat -> 2 | FloatToInteger -> 2 | FloatLt -> 3 | FloatGt -> 3 | FloatLe -> 3 | FloatGe -> 3 | FloatAdd -> 3 | FloatSub -> 3 | FloatMul -> 3 | FloatDiv -> 3 | FloatPow -> 3 | FloatCeil -> 2 | FloatFloor -> 2 | FloatExp -> 2 | FloatLog -> 2 | FloatSqrt -> 2 | FloatSin -> 2 | FloatCos -> 2 | FloatTan -> 2 | FloatAsin -> 2 | FloatAcos -> 2 | FloatAtan -> 2 | FloatAtan2 -> 3 | IsBoolean -> 2 | BooleanNot -> 2 | IsRecord -> 2 | RecordInfo -> 2 | IsList -> 2 | ListPrint -> 1 | ListArgv -> 1 | IsVector -> 2 | VectorWidth -> 2 | VectorClock -> 2 | VectorEnable -> 2 | VectorReset -> 2 | VectorInput -> 3 | VectorOutput -> 2 (* | VectorAssert -> 2 | VectorPrint -> 2 *) | VectorConst -> 3 | VectorAnd -> 3 | VectorOr -> 3 | VectorXor -> 3 | VectorNot -> 2 | VectorConcat -> 3 | VectorZero -> 1 | VectorSelect -> 3 | VectorEqu -> 3 | VectorLt -> 3 | VectorAdd -> 3 | VectorSub -> 3 | VectorMul -> 3 | VectorMux -> 4 (* | VectorTristate -> 3 | VectorExtComb -> 5 | VectorExtSequ -> 5 | VectorExtSoft -> 4 *) | VectorReg -> 3 | VectorBbox -> 5 (* | VectorRom -> 4 | VectorRam -> 4 *) | IsProperty -> 2 | PropertyNot -> 2 | PropertyOr -> 3 | PropertyNext -> 2 | PropertyUntil -> 3 ;; let toString prim = match prim with | Error -> "Error" | IsEqual -> "IsEqual" | IsComponent -> "IsComponent" | IsSystem -> "IsSystem" | SystemPorts -> "SystemPorts" | IsInteger -> "IsInteger" | IntegerToString -> "IntegerToString" | StringToInteger -> "StringToInteger" | IntegerToFloat -> "IntegerToFloat" | IntegerLt -> "IntegerLt" | IntegerGt -> "IntegerGt" | IntegerLe -> "IntegerLe" | IntegerGe -> "IntegerGe" | IntegerAdd -> "IntegerAdd" | IntegerSub -> "IntegerSub" | IntegerMul -> "IntegerMul" | IntegerDiv -> "IntegerDiv" | IntegerMod -> "IntegerMod" | IntegerPow -> "IntegerPow" | IntegerNot -> "IntegerNot" | IntegerAnd -> "IntegerAnd" | IntegerXor -> "IntegerXor" | IntegerOr -> "IntegerOr" | IntegerShiftLeft -> "IntegerShiftLeft" | IntegerShiftRight -> "IntegerShiftRight" | IsFloat -> "IsFloat" | FloatToString -> "FloatToString" | StringToFloat -> "StringToFloat" | FloatToInteger -> "FloatToInteger" | FloatLt -> "FloatLt" | FloatGt -> "FloatGt" | FloatLe -> "FloatLe" | FloatGe -> "FloatGe" | FloatAdd -> "FloatAdd" | FloatSub -> "FloatSub" | FloatMul -> "FloatMul" | FloatDiv -> "FloatDiv" | FloatPow -> "FloatPow" | FloatCeil -> "FloatCeil" | FloatFloor -> "FloatFloor" | FloatExp -> "FloatExp" | FloatLog -> "FloatLog" | FloatSqrt -> "FloatSqrt" | FloatSin -> "FloatSin" | FloatCos -> "FloatCos" | FloatTan -> "FloatTan" | FloatAsin -> "FloatAsin" | FloatAcos -> "FloatAcos" | FloatAtan -> "FloatAtan" | FloatAtan2 -> "FloatAtan2" | IsBoolean -> "IsBoolean" | BooleanNot -> "BooleanNot" | IsRecord -> "IsRecord" | RecordInfo -> "RecordInfo" | IsList -> "IsList" | ListPrint -> "ListPrint" | ListArgv -> "ListArgv" | IsVector -> "IsVector" | VectorWidth -> "VectorWidth" | VectorClock -> "VectorClock" | VectorEnable -> "VectorEnable" | VectorReset -> "VectorReset" | VectorInput -> "VectorInput" | VectorOutput -> "VectorOutput" (* | VectorAssert -> "VectorAssert" | VectorPrint -> "VectorPrint" *) | VectorConst -> "VectorConst" | VectorAnd -> "VectorAnd" | VectorOr -> "VectorOr" | VectorXor -> "VectorXor" | VectorNot -> "VectorNot" | VectorConcat -> "VectorConcat" | VectorZero -> "VectorZero" | VectorSelect -> "VectorSelect" | VectorEqu -> "VectorEqu" | VectorLt -> "VectorLt" | VectorAdd -> "VectorAdd" | VectorSub -> "VectorSub" | VectorMul -> "VectorMul" | VectorMux -> "VectorMux" (* | VectorTristate -> "VectorTristate" | VectorExtComb -> "VectorExtComb" | VectorExtSequ -> "VectorExtSequ" | VectorExtSoft -> "VectorExtSoft" *) | VectorReg -> "VectorReg" | VectorBbox -> "VectorBbox" (* | VectorRom -> "VectorRom" | VectorRam -> "VectorRam" *) | IsProperty -> "IsProperty" | PropertyNot -> "PropertyNot" | PropertyOr -> "PropertyOr" | PropertyNext -> "PropertyNext" | PropertyUntil -> "PropertyUntil" ;; let fromString name = match name with | "Error" -> Error | "IsEqual" -> IsEqual | "IsComponent" -> IsComponent | "IsSystem" -> IsSystem | "SystemPorts" -> SystemPorts | "IsInteger" -> IsInteger | "IntegerToString" -> IntegerToString | "StringToInteger" -> StringToInteger | "IntegerToFloat" -> IntegerToFloat | "IntegerLt" -> IntegerLt | "IntegerGt" -> IntegerGt | "IntegerLe" -> IntegerLe | "IntegerGe" -> IntegerGe | "IntegerAdd" -> IntegerAdd | "IntegerSub" -> IntegerSub | "IntegerMul" -> IntegerMul | "IntegerDiv" -> IntegerDiv | "IntegerMod" -> IntegerMod | "IntegerPow" -> IntegerPow | "IntegerNot" -> IntegerNot | "IntegerAnd" -> IntegerAnd | "IntegerXor" -> IntegerXor | "IntegerOr" -> IntegerOr | "IntegerShiftLeft" -> IntegerShiftLeft | "IntegerShiftRight" -> IntegerShiftRight | "IsFloat" -> IsFloat | "FloatToString" -> FloatToString | "StringToFloat" -> StringToFloat | "FloatToInteger" -> FloatToInteger | "FloatLt" -> FloatLt | "FloatGt" -> FloatGt | "FloatLe" -> FloatLe | "FloatGe" -> FloatGe | "FloatAdd" -> FloatAdd | "FloatSub" -> FloatSub | "FloatMul" -> FloatMul | "FloatDiv" -> FloatDiv | "FloatPow" -> FloatPow | "FloatCeil" -> FloatCeil | "FloatFloor" -> FloatFloor | "FloatExp" -> FloatExp | "FloatLog" -> FloatLog | "FloatSqrt" -> FloatSqrt | "FloatSin" -> FloatSin | "FloatCos" -> FloatCos | "FloatTan" -> FloatTan | "FloatAsin" -> FloatAsin | "FloatAcos" -> FloatAcos | "FloatAtan" -> FloatAtan | "FloatAtan2" -> FloatAtan2 | "IsBoolean" -> IsBoolean | "BooleanNot" -> BooleanNot | "IsRecord" -> IsRecord | "RecordInfo" -> RecordInfo | "IsList" -> IsList | "ListPrint" -> ListPrint | "ListArgv" -> ListArgv | "IsVector" -> IsVector | "VectorWidth" -> VectorWidth | "VectorClock" -> VectorClock | "VectorEnable" -> VectorEnable | "VectorReset" -> VectorReset | "VectorInput" -> VectorInput | "VectorOutput" -> VectorOutput (* | "VectorAssert" -> VectorAssert | "VectorPrint" -> VectorPrint *) | "VectorConst" -> VectorConst | "VectorAnd" -> VectorAnd | "VectorOr" -> VectorOr | "VectorXor" -> VectorXor | "VectorNot" -> VectorNot | "VectorConcat" -> VectorConcat | "VectorZero" -> VectorZero | "VectorSelect" -> VectorSelect | "VectorEqu" -> VectorEqu | "VectorLt" -> VectorLt | "VectorAdd" -> VectorAdd | "VectorSub" -> VectorSub | "VectorMul" -> VectorMul | "VectorMux" -> VectorMux (* | "VectorTristate" -> VectorTristate | "VectorExtComb" -> VectorExtComb | "VectorExtSequ" -> VectorExtSequ | "VectorExtSoft" -> VectorExtSoft *) | "VectorReg" -> VectorReg | "VectorBbox" -> VectorBbox (* | "VectorRom" -> VectorRom | "VectorRam" -> VectorRam *) | "IsProperty" -> IsProperty | "PropertyNot" -> PropertyNot | "PropertyOr" -> PropertyOr | "PropertyNext" -> PropertyNext | "PropertyUntil" -> PropertyUntil | _ -> raise CfPrimsError ;; (* Remote error handling. *) let remoteError msg = raise (CfTypes.Error msg);; (* Helpers. *) let rec checkBits msg values = let checkBit bit = if not (bit = '1' || bit = '0') then raise (CfTypes.Error (msg ^ " Invalid bit (not 0 nor 1).")); in match values with [] -> () | value :: values -> String.iter checkBit value; checkBits msg values;; (* General primitives. *) let isEqual renv = let ports = CfTypes.getRenvValues renv in CfTypes.setVariableDependence ports.(2) [ports.(0); ports.(1)]; CfTypes.isEqual renv ports.(0) ports.(1) ports.(2) ;; let error msg = raise (CfTypes.Error ("Raised Error: " ^ CfTypes.listToString msg)) ;; (** Component primitives. *) let isComponent a = CfTypes.newBoolean (CfTypes.isComp a) ;; (** System primtitives. *) let isSystem a = CfTypes.newBoolean (CfTypes.isSystem a) ;; let systemPorts system = CfTypes.getPorts system ;; (** Integer primitives. *) let isInteger a = CfTypes.newBoolean (CfTypes.isInteger a);; let integerToString a = CfTypes.stringToList (Intbig.string_of_intbig (CfTypes.getInteger a));; let stringToInteger str = CfTypes.newInteger (Intbig.intbig_of_string (CfTypes.listToString str)) ;; let integerToFloat a = CfTypes.newFloat (Intbig.float_of_intbig (CfTypes.getInteger a));; let integerLt a b = CfTypes.newBoolean (Intbig.lt (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerGt a b = CfTypes.newBoolean (Intbig.gt (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerLe a b = CfTypes.newBoolean (Intbig.le (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerGe a b = CfTypes.newBoolean (Intbig.ge (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerAdd a b = CfTypes.newInteger (Intbig.add (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerSub a b = CfTypes.newInteger (Intbig.sub (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerMul a b = CfTypes.newInteger (Intbig.mul (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerDiv a b = CfTypes.newInteger (Intbig.div (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerMod a b = CfTypes.newInteger (Intbig.modu (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerPow a b = CfTypes.newInteger (Intbig.pow (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerNot a = CfTypes.newInteger (Intbig.bw_not (CfTypes.getInteger a));; let integerAnd a b = CfTypes.newInteger (Intbig.bw_and (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerXor a b = CfTypes.newInteger (Intbig.bw_xor (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerOr a b = CfTypes.newInteger (Intbig.bw_or (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerShiftLeft a b = CfTypes.newInteger (Intbig.shift_left (CfTypes.getInteger a) (CfTypes.getInteger b));; let integerShiftRight a b = CfTypes.newInteger (Intbig.shift_right (CfTypes.getInteger a) (CfTypes.getInteger b));; (** Float primitives. *) let isFloat a = CfTypes.newBoolean (CfTypes.isFloat a);; let floatToString a = let s = string_of_float (CfTypes.getFloat a) in let s = if String2.right_char s = '.' then s ^ "0" else s in CfTypes.stringToList s ;; let stringToFloat str = CfTypes.newFloat (float_of_string (CfTypes.listToString str)) ;; let floatToInteger a = CfTypes.newInteger (Intbig.intbig_of_float (CfTypes.getFloat a));; let floatLt a b = CfTypes.newBoolean (CfTypes.getFloat a < CfTypes.getFloat b);; let floatGt a b = CfTypes.newBoolean (CfTypes.getFloat a > CfTypes.getFloat b);; let floatLe a b = CfTypes.newBoolean (CfTypes.getFloat a <= CfTypes.getFloat b);; let floatGe a b = CfTypes.newBoolean (CfTypes.getFloat a >= CfTypes.getFloat b);; let floatAdd a b = CfTypes.newFloat (CfTypes.getFloat a +. CfTypes.getFloat b);; let floatSub a b = CfTypes.newFloat (CfTypes.getFloat a -. CfTypes.getFloat b);; let floatMul a b = CfTypes.newFloat (CfTypes.getFloat a *. CfTypes.getFloat b);; let floatDiv a b = CfTypes.newFloat (CfTypes.getFloat a /. CfTypes.getFloat b);; let floatPow a b = CfTypes.newFloat (CfTypes.getFloat a ** CfTypes.getFloat b);; let floatCeil a = CfTypes.newFloat (ceil (CfTypes.getFloat a));; let floatFloor a = CfTypes.newFloat (floor (CfTypes.getFloat a));; let floatExp a = CfTypes.newFloat (exp (CfTypes.getFloat a));; let floatLog a = CfTypes.newFloat (log (CfTypes.getFloat a));; let floatSqrt a = CfTypes.newFloat (sqrt (CfTypes.getFloat a));; let floatSin a = CfTypes.newFloat (sin (CfTypes.getFloat a));; let floatCos a = CfTypes.newFloat (cos (CfTypes.getFloat a));; let floatTan a = CfTypes.newFloat (tan (CfTypes.getFloat a));; let floatAsin a = CfTypes.newFloat (asin (CfTypes.getFloat a));; let floatAcos a = CfTypes.newFloat (acos (CfTypes.getFloat a));; let floatAtan a = CfTypes.newFloat (atan (CfTypes.getFloat a));; let floatAtan2 a b = CfTypes.newFloat (atan2 (CfTypes.getFloat a) (CfTypes.getFloat b));; (** Boolean primtives. *) let isBoolean a = CfTypes.newBoolean (CfTypes.isBoolean a);; let booleanNot a = CfTypes.newBoolean (not (CfTypes.getBoolean a));; (** Record primitives. *) let isRecord a = CfTypes.newBoolean (CfTypes.isRecord a) ;; let recordInfo r = CfTypes.recordInfo r ;; (** List primitives. *) let isList a = CfTypes.newBoolean (CfTypes.isList a) ;; let listPrint l = print_string (CfTypes.listToString l); print_newline () ;; let argv_position = ref 0;; let set_argv_position pos = argv_position := pos ;; let listArgv () = let rec f args = match args with [] -> CfTypes.newRecord 0 [||] [||] | arg :: args -> CfTypes.newRecord 2 [|"hd"; "tl"|] [|(CfTypes.stringToList arg); (f args)|] in f (List2.drop (Array.to_list Sys.argv) !argv_position) ;; (** Vector primitives. *) let isVector a = CfTypes.newBoolean (CfTypes.isVector a);; let vectorWidth a = CfTypes.newInteger (Intbig.intbig_of_int (CfTypes.getWidth a));; let vectorClock clockName system = Cf_fnf.set_clock_domain (CfTypes.getEnvId (CfTypes.getRenv system)) (CfTypes.listToString clockName) remoteError ;; let vectorEnable enableVector system = CfTypes.checkWidthIs enableVector 1; Cf_fnf.add_sub_enable (CfTypes.getEnvId (CfTypes.getRenv system)) (CfTypes.getProducer enableVector) remoteError;; let vectorReset resetVector system = CfTypes.checkWidthIs resetVector 1; Cf_fnf.add_sub_reset (CfTypes.getEnvId (CfTypes.getRenv system)) (CfTypes.getProducer resetVector) remoteError;; let vectorInput sysId name width = if CfTypes.getInt width <= 0 then raise (CfTypes.Error "Vector error. Input width must be greater than 0."); let s = CfTypes.newVector (Cf_fnf.new_input sysId (CfTypes.listToString name) (CfTypes.getInt width)) in CfTypes.checkWidth s; s ;; let vectorOutput sysId name output = CfTypes.checkWidthNotZero output; Cf_fnf.new_output sysId (CfTypes.listToString name) (CfTypes.getProducer output) ;; (* let vectorAssert sysId msg test = CfTypes.checkWidthIs test 1; Cf_fnf.new_assert sysId (CfTypes.getProducer test) (CfTypes.listToString msg) ;; let vectorPrint sysId enable msg = CfTypes.checkWidthIs enable 1; CfTypes.checkWidthNotZero msg; Cf_fnf.new_print sysId (CfTypes.getProducer enable) (CfTypes.getProducer msg);; *) let vectorConst sysId value width = CfTypes.newVectorConst (CfTypes.getInteger value) (CfTypes.getInteger width) sysId;; let vectorBuf sysId a = CfTypes.checkWidthNotZero a; CfTypes.newVector (Cf_fnf.new_buf sysId (CfTypes.getProducer a));; let vectorNot sysId a = CfTypes.checkWidthNotZero a; CfTypes.newVector (Cf_fnf.new_not sysId (CfTypes.getProducer a));; let vectorAnd sysId a b = CfTypes.checkWidthNotZero a; CfTypes.checkWidthsAreSame a b; CfTypes.newVector (Cf_fnf.new_and sysId (CfTypes.getProducer a) (CfTypes.getProducer b));; let vectorOr sysId a b = CfTypes.checkWidthNotZero a; CfTypes.checkWidthsAreSame a b; CfTypes.newVector (Cf_fnf.new_or sysId (CfTypes.getProducer a) (CfTypes.getProducer b));; let vectorXor sysId a b = CfTypes.checkWidthNotZero a; CfTypes.checkWidthsAreSame a b; CfTypes.newVector (Cf_fnf.new_xor sysId (CfTypes.getProducer a) (CfTypes.getProducer b));; let vectorConcat sysId a b = if CfTypes.is_zero_width_vector a then b else if CfTypes.is_zero_width_vector b then a else CfTypes.newVector (Cf_fnf.new_concat sysId (CfTypes.getProducer a) (CfTypes.getProducer b)) ;; let vectorZero () = CfTypes.zero_width_vector ;; let vectorSelect sysId input bit = let bit = CfTypes.getInt bit in let width = CfTypes.getWidth input in if bit < 0 then raise (CfTypes.Error "Vector error. Bit selection requires positive integers."); if bit >= width then raise (CfTypes.Error "Vector error. Bit selection requires integers < width - 1."); CfTypes.newVector (Cf_fnf.new_select sysId (CfTypes.getProducer input) bit) ;; let vectorEqu sysId a b = CfTypes.checkWidthNotZero a; CfTypes.checkWidthsAreSame a b; CfTypes.newVector (Cf_fnf.new_equ sysId (CfTypes.getProducer a) (CfTypes.getProducer b)) ;; let vectorLt sysId a b = CfTypes.checkWidthNotZero a; CfTypes.checkWidthsAreSame a b; CfTypes.newVector (Cf_fnf.new_lt sysId (CfTypes.getProducer a) (CfTypes.getProducer b)) ;; let vectorAdd sysId a b = CfTypes.checkWidthNotZero a; CfTypes.checkWidthsAreSame a b; CfTypes.newVector (Cf_fnf.new_add sysId (CfTypes.getProducer a) (CfTypes.getProducer b));; let vectorSub sysId a b = CfTypes.checkWidthNotZero a; CfTypes.checkWidthsAreSame a b; CfTypes.newVector (Cf_fnf.new_sub sysId (CfTypes.getProducer a) (CfTypes.getProducer b));; let vectorMul sysId a b = CfTypes.checkWidthNotZero a; CfTypes.checkWidthNotZero b; CfTypes.checkWidthsAreSame a b; CfTypes.newVector (Cf_fnf.new_mul sysId (CfTypes.getProducer a) (CfTypes.getProducer b));; let vectorMux sysId pred t f = CfTypes.checkWidthIs pred 1; CfTypes.checkWidthsAreSame t f; CfTypes.checkWidthNotZero t; CfTypes.newVector (Cf_fnf.new_mux sysId (CfTypes.getProducer pred) (CfTypes.getProducer t) (CfTypes.getProducer f));; (* let vectorExtComb sysId name params dataIn widthOut = CfTypes.checkWidthNotZero dataIn; if CfTypes.getInt widthOut <= 0 then raise (CfTypes.Error ("VectorExtComb error. External combinatorial component requires output width > 0.")); CfTypes.newVector (Cf_fnf.new_ExtComb sysId (CfTypes.listToString name) (CfTypes.listToIntList params) (CfTypes.getProducer dataIn) (CfTypes.getInt widthOut)) ;; let vectorExtSequ sysId name params dataIn widthOut = CfTypes.checkWidthNotZero dataIn; if CfTypes.getInt widthOut <= 0 then raise (CfTypes.Error ("VectorExtSequ error. External sequential component requires output width > 0.")); CfTypes.newVector (Cf_fnf.new_ExtSequ sysId (CfTypes.listToString name) (CfTypes.listToIntList params) (CfTypes.getProducer dataIn) (CfTypes.getInt widthOut)) ;; let vectorExtSoft sysId name params width = if CfTypes.getInt width <= 0 then raise (CfTypes.Error ("VectorExtSoft error. External soft component requires width > 0.")); CfTypes.newVector (Cf_fnf.new_ExtSoft sysId (CfTypes.listToString name) (CfTypes.listToIntList params) (CfTypes.getInt width)) ;; *) (* Stateful logic primitives. *) let vectorRegStmt renv = let sysId = CfTypes.getEnvId renv in let ports = CfTypes.getRenvValues renv in let width = ports.(0) in let dataIn = ports.(1) in let dataOut = ports.(2) in CfTypes.setVariableDependence dataOut [width; dataIn]; let slot = CfTypes.newSlot renv 1 (fun () -> let width = CfTypes.getInt width in CfTypes.unify dataOut (CfTypes.newVector (Cf_fnf.new_state sysId width)); CfTypes.checkWidthNotZero dataOut; let slot = CfTypes.newSlot renv 1 (fun () -> CfTypes.checkWidthsAreSame dataIn dataOut; Cf_fnf.new_reg sysId (CfTypes.getProducer dataIn) (CfTypes.getProducer dataOut); ) in CfTypes.slotVariableStrict slot dataIn ) in CfTypes.slotVariableStrict slot width ;; let vectorBboxStmt renv = let sysId = CfTypes.getEnvId renv in let ports = CfTypes.getRenvValues renv in let name = ports.(0) in let width = ports.(1) in let params = ports.(2) in let dataIn = ports.(3) in let dataOut = ports.(4) in CfTypes.setVariableDependence dataOut [name; width; params; dataIn]; let slot = CfTypes.newSlot renv 1 (fun () -> let width = CfTypes.getInt width in CfTypes.unify dataOut (CfTypes.newVector (Cf_fnf.new_state sysId width)); CfTypes.checkWidthNotZero dataOut; let slot = CfTypes.newSlot renv 3 (fun () -> CfTypes.checkWidthNotZero dataIn; Cf_fnf.new_bbox sysId (CfTypes.listToString name) (CfTypes.listToIntList params) (CfTypes.getProducer dataIn) (CfTypes.getProducer dataOut); ) in CfTypes.slotVariableStrict slot name; CfTypes.slotVariableStrict slot params; CfTypes.slotVariableStrict slot dataIn ) in CfTypes.slotVariableStrict slot width ;; (* let bits a = if a < 0 then raise (CfTypes.Error "Bits: Count must be >= 0.") else if a = 0 then 0 else if a = 1 then 1 else int_of_float (ceil (log (float_of_int a) /. log 2.0)) ;; let vectorRomStmt renv = let sysId = CfTypes.getEnvId renv in let ports = CfTypes.getRenvValues renv in let width = ports.(0) in let values = ports.(1) in let addr = ports.(2) in let data = ports.(3) in CfTypes.setVariableDependence data [width; values; addr]; let slot = CfTypes.newSlot renv 1 (fun () -> let width = CfTypes.getInt width in CfTypes.unify data (CfTypes.newVector (Cf_fnf.new_State sysId width)); CfTypes.checkWidthNotZero data; let slot = CfTypes.newSlot renv 2 (fun () -> let values = CfTypes.listToIntegerList values in let depth = List.length values in let addrWidth = CfTypes.getWidth addr in let dataWidth = CfTypes.getWidth data in if addrWidth < bits depth then raise (CfTypes.Error ("VectorRom error. Expecting address width of greater than or equal to " ^ string_of_int (bits depth) ^ ". Got " ^ string_of_int addrWidth ^ ".")); let values = values @ List2.make (int_of_float (2.0 ** float_of_int addrWidth -. float_of_int depth)) Intbig.zero in CfTypes.checkWidthNotZero addr; Cf_fnf.new_Rom sysId dataWidth values (CfTypes.getProducer addr) (CfTypes.getProducer data) ) in CfTypes.slotVariableStrict slot values; CfTypes.slotVariableStrict slot addr; ) in CfTypes.slotVariableStrict slot width ;; let vectorRamStmt renv = let sysId = CfTypes.getEnvId renv in let ports = CfTypes.getRenvValues renv in let width = ports.(0) in let values = ports.(1) in let write = ports.(2) in let read = ports.(3) in CfTypes.setVariableDependence write [width; values]; CfTypes.setVariableDependence read [width; values]; let slot = CfTypes.newSlot renv 2 (fun () -> let width = CfTypes.getInt width in let values = CfTypes.listToIntegerList values in let depth = List.length values in let addrWidth = bits depth in let values = values @ List2.make (int_of_float (2.0 ** float_of_int addrWidth -. float_of_int depth)) Intbig.zero in let memory = Cf_fnf.new_RamMem sysId width values in let writeStmt renv = let sysId = CfTypes.getEnvId renv in let ports = CfTypes.getRenvValues renv in let addr = ports.(0) in let data = ports.(1) in CfTypes.setVariableDependence data [addr]; let slot = CfTypes.newSlot renv 2 (fun () -> CfTypes.checkWidthIs addr addrWidth; CfTypes.checkWidthIs data width; let addr = CfTypes.getProducer addr in let data = CfTypes.getProducer data in Cf_fnf.new_RamWrite sysId memory addr data; ) in CfTypes.slotVariableStrict slot addr; CfTypes.slotVariableStrict slot data; in let readStmt renv = let sysId = CfTypes.getEnvId renv in let ports = CfTypes.getRenvValues renv in let rbw = ports.(0) in let addr = ports.(1) in let data = ports.(2) in CfTypes.setVariableDependence data [rbw; addr]; CfTypes.unify data (CfTypes.newVector (Cf_fnf.new_State sysId width)); let slot = CfTypes.newSlot renv 2 (fun () -> CfTypes.checkWidthIs addr addrWidth; CfTypes.checkWidthIs data width; let rbw = CfTypes.getBoolean rbw in let addr = CfTypes.getProducer addr in let data = CfTypes.getProducer data in Cf_fnf.new_RamRead sysId memory rbw addr data; ) in CfTypes.slotVariableStrict slot rbw; CfTypes.slotVariableStrict slot addr; in CfTypes.unify write (CfTypes.newComp (renv, Loc.unknown "Internal RamWrite", 2, [|"addr"; "data"|], writeStmt)); CfTypes.unify read (CfTypes.newComp (renv, Loc.unknown "Internal RamRead", 3, [|"read_before_write"; "addr"; "data"|], readStmt)) ) in CfTypes.slotVariableStrict slot width; CfTypes.slotVariableStrict slot values; ;; *) (** Properties. *) let property p = if CfTypes.isVector p then CfTypes.newPropertyVector p else p ;; let isProperty p = CfTypes.newBoolean (CfTypes.isVector p && CfTypes.getWidth p = 1 || CfTypes.isProperty p) ;; let propertyNot p = CfTypes.newPropertyNot (property p) ;; let propertyOr p0 p1 = CfTypes.newPropertyOr (property p0) (property p1) ;; let propertyNext p = CfTypes.newPropertyNext (property p) ;; let propertyUntil p0 p1 = CfTypes.newPropertyUntil (property p0) (property p1) ;; (* Primitive selector. *) let compilePrimitive primName arity = try let prim = fromString primName in if arity <> totalArity prim then raise (CfTypes.Error ("Illegal number of primitive ports. " ^ primName ^ " needs " ^ string_of_int (totalArity prim) ^ ", not " ^ string_of_int arity)); begin match prim with | IsEqual -> isEqual | Error -> stmt_of_prim_s error | IsComponent -> stmt_of_prim_lx isComponent | IsSystem -> stmt_of_prim_lx isSystem | SystemPorts -> stmt_of_prim_lx systemPorts | IsInteger -> stmt_of_prim_lx isInteger | IntegerToString -> stmt_of_prim_lx integerToString | StringToInteger -> stmt_of_prim_sx stringToInteger | IntegerToFloat -> stmt_of_prim_lx integerToFloat | IntegerLt -> stmt_of_prim_llx integerLt | IntegerGt -> stmt_of_prim_llx integerGt | IntegerLe -> stmt_of_prim_llx integerLe | IntegerGe -> stmt_of_prim_llx integerGe | IntegerAdd -> stmt_of_prim_llx integerAdd | IntegerSub -> stmt_of_prim_llx integerSub | IntegerMul -> stmt_of_prim_llx integerMul | IntegerDiv -> stmt_of_prim_llx integerDiv | IntegerMod -> stmt_of_prim_llx integerMod | IntegerPow -> stmt_of_prim_llx integerPow | IntegerNot -> stmt_of_prim_lx integerNot | IntegerAnd -> stmt_of_prim_llx integerAnd | IntegerXor -> stmt_of_prim_llx integerXor | IntegerOr -> stmt_of_prim_llx integerOr | IntegerShiftLeft -> stmt_of_prim_llx integerShiftLeft | IntegerShiftRight -> stmt_of_prim_llx integerShiftRight | IsFloat -> stmt_of_prim_lx isFloat | FloatToString -> stmt_of_prim_lx floatToString | StringToFloat -> stmt_of_prim_sx stringToFloat | FloatToInteger -> stmt_of_prim_lx floatToInteger | FloatLt -> stmt_of_prim_llx floatLt | FloatGt -> stmt_of_prim_llx floatGt | FloatLe -> stmt_of_prim_llx floatLe | FloatGe -> stmt_of_prim_llx floatGe | FloatAdd -> stmt_of_prim_llx floatAdd | FloatSub -> stmt_of_prim_llx floatSub | FloatMul -> stmt_of_prim_llx floatMul | FloatDiv -> stmt_of_prim_llx floatDiv | FloatPow -> stmt_of_prim_llx floatPow | FloatCeil -> stmt_of_prim_lx floatCeil | FloatFloor -> stmt_of_prim_lx floatFloor | FloatExp -> stmt_of_prim_lx floatExp | FloatLog -> stmt_of_prim_lx floatLog | FloatSqrt -> stmt_of_prim_lx floatSqrt | FloatSin -> stmt_of_prim_lx floatSin | FloatCos -> stmt_of_prim_lx floatCos | FloatTan -> stmt_of_prim_lx floatTan | FloatAsin -> stmt_of_prim_lx floatAsin | FloatAcos -> stmt_of_prim_lx floatAcos | FloatAtan -> stmt_of_prim_lx floatAtan | FloatAtan2 -> stmt_of_prim_llx floatAtan2 | IsBoolean -> stmt_of_prim_lx isBoolean | BooleanNot -> stmt_of_prim_lx booleanNot | IsRecord -> stmt_of_prim_lx isRecord | RecordInfo -> stmt_of_prim_sx recordInfo | IsList -> stmt_of_prim_lx isList | ListPrint -> stmt_of_prim_s listPrint | ListArgv -> stmt_of_prim_x listArgv | IsVector -> stmt_of_prim_lx isVector | VectorWidth -> stmt_of_prim_lx vectorWidth | VectorClock -> stmt_of_prim_sl vectorClock | VectorEnable -> stmt_of_prim_ll vectorEnable | VectorReset -> stmt_of_prim_ll vectorReset | VectorInput -> stmt_of_prim_rslx vectorInput | VectorOutput -> stmt_of_prim_rsl vectorOutput (* | VectorAssert -> stmt_of_prim_rsl vectorAssert | VectorPrint -> stmt_of_prim_rll vectorPrint *) | VectorConst -> stmt_of_prim_rllx vectorConst | VectorAnd -> stmt_of_prim_rllx vectorAnd | VectorOr -> stmt_of_prim_rllx vectorOr | VectorXor -> stmt_of_prim_rllx vectorXor | VectorNot -> stmt_of_prim_rlx vectorNot | VectorConcat -> stmt_of_prim_rllx vectorConcat | VectorZero -> stmt_of_prim_x vectorZero | VectorSelect -> stmt_of_prim_rlsx vectorSelect | VectorEqu -> stmt_of_prim_rllx vectorEqu | VectorLt -> stmt_of_prim_rllx vectorLt | VectorAdd -> stmt_of_prim_rllx vectorAdd | VectorSub -> stmt_of_prim_rllx vectorSub | VectorMul -> stmt_of_prim_rllx vectorMul | VectorMux -> stmt_of_prim_rlllx vectorMux (* | VectorTristate -> stmt_of_prim_rllx vectorTristate | VectorExtComb -> stmt_of_prim_rssllx vectorExtComb | VectorExtSequ -> stmt_of_prim_rssllx vectorExtSequ | VectorExtSoft -> stmt_of_prim_rsslx vectorExtSoft *) | VectorReg -> vectorRegStmt | VectorBbox -> vectorBboxStmt (* | VectorRom -> vectorRomStmt | VectorRam -> vectorRamStmt *) | IsProperty -> stmt_of_prim_lx isProperty | PropertyNot -> stmt_of_prim_lx propertyNot | PropertyOr -> stmt_of_prim_llx propertyOr | PropertyNext -> stmt_of_prim_lx propertyNext | PropertyUntil -> stmt_of_prim_llx propertyUntil end with CfPrimsError -> raise (CfTypes.Error ("Unknown primitive: " ^ primName));; confluence-0.10.6/src/cfeval/cfPrims.mli0100644002340600244710000000166110266541657017476 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) val set_argv_position : int -> unit;; val compilePrimitive : string -> int -> (CfTypes.renv -> unit);; confluence-0.10.6/src/cfeval/cfTypes.ml0100644002340600244710000006214410266541660017334 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Exceptions *) (** General runtime error exception. *) exception Error of string;; (** Main types. *) type renv = { renvId : Cf_fnf.system; renvParent : renv; renvCompLoc : Loc.loc; renvAppLocs : Loc.loc list; renvPorts : variable; } and variable = value ref and value = Free of slot list ref * variable list ref | Integer of Intbig.intbig | Float of float | Boolean of bool | Vector of Cf_fnf.producer | Vector0 | Record of int * string array * variable array | System of renv | Comp of renv * Loc.loc * int * string * string array * (renv -> unit) | Property of property and property = PropertyVector of Cf_fnf.producer | PropertyNot of property | PropertyOr of property * property | PropertyNext of property | PropertyUntil of property * property and slot = renv * int ref * (unit -> unit) ;; (** Root environment. *) let rec rootRenv = { renvId = Cf_fnf.new_root_system (); renvParent = rootRenv; renvCompLoc = Loc.unknown "Root environment."; renvAppLocs = []; renvPorts = ref (Record (0, [||], [||])); } ;; (** Runtime error reporting. *) let lastLocation = ref (Loc.unknown "Report Default");; let lastRenv = ref rootRenv;; let setLocation loc = if Loc.isKnown loc then lastLocation := loc ;; let rec instanceTrace locs = match locs with | [] -> "" | loc :: locs -> instanceTrace locs ^ " " ^ Loc.toString loc ^ "\n" ;; let error msg = Report.error ( "** Runtime Error\n\n" ^ msg ^ "\n\n" ^ " Error May Be Near:\n\n " ^ Loc.toString !lastLocation ^ "\n\n" ^ " Instantiation Trace:\n\n" ^ instanceTrace !lastRenv.renvAppLocs ^ "\n") ;; (** Helpers. *) let rec typeToString v = match !v with | Free (t, f) -> "Free(slots:" ^ string_of_int (List.length !t) ^ " frees:" ^ string_of_int (List.length !f) ^ ")" | Integer i -> "Integer(" ^ Intbig.string_of_intbig i ^ ")" | Float f -> "Float(" ^ string_of_float f ^ ")" | Boolean b -> "Boolean(" ^ (if b then "true" else "false") ^ ")" | Vector p -> "Vector(" ^ string_of_int (Cf_fnf.width_of_producer p) ^ ")" | Vector0 -> "Vector(0)" | Record (a, n, v) -> "Record(" ^ List.fold_left2 (fun a n v -> a ^ " " ^ n ^ ":" (*^ typeToString v*)) "" (Array.to_list n) (Array.to_list v) ^ " )" | System s -> "System(" ^ typeToString s.renvPorts ^ ")" | Comp _ -> "Component" | Property p -> "Property(" ^ propertyToString p ^ ")" (* and renvToString renv = "renv: CompLoc = " ^ Loc.toString renv.renvCompLoc ^ " Names = ( " ^ List.fold_left (fun s n -> s ^ n ^ " ") "" (Array.to_list renv.renvNames) ^ ")" (* ^ " Values = ( " ^ List.fold_left (fun s n -> s ^ typeToString n ^ " ") "" (Array.to_list renv.renvValues) ^ ")" *) *) and propertyToString p = match p with | PropertyVector prod -> typeToString (ref (Vector prod)) | PropertyNot p -> "(! " ^ propertyToString p ^ ")" | PropertyOr (p0, p1) -> "(" ^ propertyToString p0 ^ " || " ^ propertyToString p1 ^ ")" | PropertyNext p -> "(X " ^ propertyToString p ^ ")" | PropertyUntil (p0, p1) -> "(" ^ propertyToString p0 ^ " U " ^ propertyToString p1 ^ ")" ;; let typeError v exp = "Type error. Expecting " ^ exp ^ ". Got " ^ typeToString v ^ ".";; (** Free variable monitor. *) let freeVariableMemory = ref [];; let freeVariableDepend = ref [];; let freeVariableDeterminedThreshold = 10000;; let freeVariableDeterminedCounter = ref freeVariableDeterminedThreshold;; let freeVariableClean () = freeVariableMemory := List.fold_left (fun mem varData -> let (_, _, _, var) = varData in match !var with | Free _ -> varData :: mem | _ -> mem ) [] !freeVariableMemory; freeVariableDepend := List.fold_left (fun dep_mem (var, deps) -> match !var with | Free _ -> (var, deps) :: dep_mem | _ -> dep_mem ) [] !freeVariableDepend; ;; let freeVariableAdd (renv, loc, name, var) = freeVariableMemory := (renv, loc, name, var) :: !freeVariableMemory ;; let setVariableDependence var depvars = freeVariableDepend := (var, depvars) :: !freeVariableDepend ;; let freeVariableDetermined () = decr freeVariableDeterminedCounter; if !freeVariableDeterminedCounter = 0 then begin freeVariableDeterminedCounter := freeVariableDeterminedThreshold; freeVariableClean () end ;; (** Task queue. *) let taskList = ref [];; let readyTask (renv, task) = taskList := (renv, task) :: !taskList ;; let executeTasks () = while !taskList <> [] do let (renv, task) = List.hd !taskList in taskList := List.tl !taskList; try lastRenv := renv; task () with Error msg -> error msg done ;; (** Sync slots. *) let newSlot renv count task = (renv, ref count, task) ;; let sync slot = let (renv, count, task) = slot in decr count; if !count <= 0 then readyTask (renv, task) ;; let incrSlot slot = let (renv, count, task) = slot in incr count ;; (** Variable unification. *) (** Unification error. *) let unifyError var0 var1 = raise (Error ("Unification Error: " ^ typeToString var0 ^ " != " ^ typeToString var1)) ;; (** Recursive unification. *) let rec unify var0 var1 upSet = (* upSet can go to a set if O(n) lookup is too expensive. *) let (val0, val1) = (!var0, !var1) in if not (val0 == val1 || List.exists (function (a, b) -> (a == val0 && b == val1) || (a == val1 && b == val0)) upSet) then let upSet = (val0, val1) :: upSet in match (val0, val1) with (Free (slots0, frees0), Free (slots1, frees1)) -> let slotsNew = List.rev_append !slots0 !slots1 in let freesNew = List.rev_append !frees0 !frees1 in let valNew = Free (ref slotsNew, ref freesNew) in List.iter (fun var -> var := valNew) freesNew | (Free (slots, frees), value) | (value, Free (slots, frees)) -> List.iter (fun var -> var := value; freeVariableDetermined ()) !frees; List.iter (fun slot -> sync slot) !slots | (Record (arity0, names0, variables0), Record (arity1, names1, variables1)) -> if arity0 <> arity1 || names0 <> names1 then unifyError var0 var1; for i = 0 to arity0 - 1 do unify variables0.(i) variables1.(i) upSet done | (Integer i0, Integer i1) -> if Intbig.ne i0 i1 then unifyError var0 var1; | (Float f0, Float f1) -> if f0 <> f1 then unifyError var0 var1; | (Boolean b0, Boolean b1) -> if b0 <> b1 then unifyError var0 var1; | (Vector p0, Vector p1) -> unifyError var0 var1 | (Vector0, Vector0) -> unifyError var0 var1 | (Property _, Property _) -> unifyError var0 var1 | (System _, System _) -> unifyError var0 var1 | (Comp _, Comp _) -> unifyError var0 var1 | (_, _) -> unifyError var0 var1 ;; (** Unification front end. *) let unify v0 v1 = unify v0 v1 [] ;; (** Adds a slot to a variable. If free, variable stores slot. If record, all elements must be determined before sync. Else slot is synced. *) let rec slotVariableStrict slot var varSet = if List.exists (fun var0 -> !var == !var0) varSet then sync slot else match !var with Free (slots, frees) -> let (renv, count, task) = slot in let slotNew = (renv, ref 1, (fun () -> slotVariableStrict slot var varSet)) in let slotsNew = slotNew :: !slots in List.iter (fun var -> match !var with Free (slots, _) -> slots := slotsNew | _ -> raise (Error "CfTypes.slotVariableStrict: Should not get here. Free variable references a non free variable. (1)") ) !frees | Record (arity, names, values) -> let varSet = var :: varSet in for i = 0 to arity - 1 do incrSlot slot; slotVariableStrict slot values.(i) varSet done; sync slot | _ -> sync slot ;; (** SlotVariable front end. *) let slotVariableStrict slot var = slotVariableStrict slot var [] ;; (** SlotVariable partial. Syncs slot if not type is not free. Will sync even if type is a record that is not fully determined. *) let slotVariableLenient slot var = match !var with | Free (slots, frees) -> let slotsNew = slot :: !slots in List.iter (fun var -> match !var with Free (slots, _) -> slots := slotsNew | _ -> raise (Error "CfTypes.slotVariableLenient: Should not get here. Free variable references a non free variable. (1)") ) !frees | _ -> sync slot ;; (** Free Variables Functions *) (** Creates a new free variable. *) let newFree () = let rec var = ref (Free (ref [], ref [var])) in var ;; (** Creates a new free variable with a location. *) let newFreeLoc loc name renv = let var = newFree () in freeVariableAdd (renv, loc, name, var); var ;; (** Assigns a slot of a new free variable. *) let newFreeWithTask renv task = let rec var = ref (Free (ref [(renv, ref 1, fun () -> task var)], ref [var])) in var ;; let isFree v = match !v with Free _ -> true | _ -> false ;; (** Boolean Variable Functions *) let newBoolean b = ref (Boolean b);; let isBoolean v = match !v with Boolean _ -> true | _ -> false;; let getBoolean v = match !v with Boolean i -> i | _ -> raise (Error (typeError v "Boolean"));; (** Recursive comparision. *) let rec isEqual renv var0 var1 varBool upSet = let (val0, val1) = (!var0, !var1) in if val0 == val1 || List.exists (function (a, b) -> (a == val0 && b == val1) || (a == val1 && b == val0)) upSet then unify varBool (ref (Boolean true)) else let upSet = (val0, val1) :: upSet in match (val0, val1) with (Free _, _) -> slotVariableLenient (renv, ref 1, fun () -> isEqual renv var0 var1 varBool upSet) var0 | (_, Free _) -> slotVariableLenient (renv, ref 1, fun () -> isEqual renv var0 var1 varBool upSet) var1 | (Integer i0, Integer i1) -> if Intbig.eq i0 i1 then unify varBool (newBoolean true) else unify varBool (newBoolean false) | (Float f0, Float f1) -> if f0 = f1 then unify varBool (newBoolean true) else unify varBool (newBoolean false) | (Boolean b0, Boolean b1) -> if b0 = b1 then unify varBool (newBoolean true) else unify varBool (newBoolean false) | (Vector _, Vector _) -> unify varBool (newBoolean false) | (Vector0, Vector0) -> unify varBool (newBoolean false) | (Record (arity0, names0, values0), Record (arity1, names1, values1)) -> if arity0 <> arity1 || names0 <> names1 then unify varBool (newBoolean false) else let bools = Array.make arity0 (newFree ()) in let slot = (renv, ref (arity0 + 1), fun () -> unify varBool (newBoolean (List.for_all getBoolean (Array.to_list bools)))) in sync slot; (* In case arity is 0. *) for i = 0 to arity0 - 1 do let free = newFree () in bools.(i) <- free; slotVariableLenient slot free; isEqual renv values0.(i) values1.(i) free upSet done | (System _, System _) -> unify varBool (newBoolean false) | (Comp _, Comp _) -> unify varBool (newBoolean false) | (_, _) -> unify varBool (newBoolean false) ;; (** Comparision front end. *) let isEqual renv var0 var1 varBool = isEqual renv var0 var1 varBool [] ;; (* Integer Variable Functions *) let newInteger i = ref (Integer i);; let isInteger v = match !v with Integer _ -> true | _ -> false;; let getInteger v = match !v with Integer i -> i | _ -> raise (Error (typeError v "Integer"));; let getInt v = let i = getInteger v in try Intbig.int_of_intbig i with Failure _ -> raise (Error ("Integer is too big to convert to fixed width integer: " ^ Intbig.string_of_intbig i));; (* Float Variable Functions *) let newFloat f = ref (Float f);; let isFloat v = match !v with Float _ -> true | _ -> false;; let getFloat v = match !v with Float i -> i | _ -> raise (Error (typeError v "Float"));; (* Vector Variable Functions *) let zero_width_vector = ref Vector0;; let is_zero_width_vector v = match !v with | Vector0 -> true | Vector _ -> false | _ -> raise (Error (typeError v "Vector")) ;; let checkBits bitStr = let checkBit c = match c with '0' -> () | '1' -> () | a -> raise (Error "Vector constant requires string containing only 1's and 0's.") in String.iter checkBit bitStr;; let newVector producer = ref (Vector producer) ;; let newVectorConst value width system = (* System is last argument for partial application in compiler. *) if Intbig.eq width Intbig.zero then ref Vector0 else ref (Vector (Cf_fnf.new_const system (Intbig.binary_string_of_intbig value width))) ;; let isVector v = match !v with | Vector _ | Vector0 -> true | _ -> false ;; let getWidth v = match !v with | Vector p -> Cf_fnf.width_of_producer p | Vector0 -> 0 | _ -> raise (Error (typeError v "Vector")) ;; let getProducer v = match !v with | Vector p -> p | Vector0 -> raise (Error "Zero width vector does not have a producer.") | _ -> raise (Error (typeError v "Vector")) ;; let checkWidth v = if getWidth v < 0 then raise (Error "Invalid vector width. Width less than zero.");; let checkWidthNotZero v = if getWidth v <= 0 then raise (Error "Invalid vector width. Vector instance requires width greater than zero.");; let checkWidthIs v w = if getWidth v <> w || w < 0 then raise (Error ("Invalid vector width. Expecting " ^ string_of_int w ^ ", not " ^ string_of_int (getWidth v) ^ "."));; let checkWidthsAreSame v1 v2 = checkWidth v1; if getWidth v1 <> getWidth v2 then raise (Error "Invalid vector width. Vector pairs must have matching widths.");; (** Property Variable Functions *) let isProperty v = match !v with | Vector _ -> getWidth v = 1 | Property _ -> true | _ -> false ;; let newPropertyVector v = match !v with | Vector prod -> checkWidthIs v 1; ref (Property (PropertyVector prod)) | _ -> raise (Error (typeError v "Vector")) ;; let newPropertyNot v = match !v with | Property p -> ref (Property (PropertyNot p)) | _ -> raise (Error (typeError v "Property")) ;; let newPropertyOr v0 v1 = match !v0, !v1 with | Property p0, Property p1 -> ref (Property (PropertyOr (p0, p1))) | _, Property _ -> raise (Error (typeError v0 "Property")) | Property _, _ -> raise (Error (typeError v1 "Property")) | _, _ -> raise (Error (typeError v0 "Property")) ;; let newPropertyNext v = match !v with | Property p -> ref (Property (PropertyNext p)) | _ -> raise (Error (typeError v "Property")) ;; let newPropertyUntil v0 v1 = match !v0, !v1 with | Property p0, Property p1 -> ref (Property (PropertyUntil (p0, p1))) | _, Property _ -> raise (Error (typeError v0 "Property")) | Property _, _ -> raise (Error (typeError v1 "Property")) | _, _ -> raise (Error (typeError v0 "Property")) ;; (** Record functions. *) let newRecord arity names values = ref (Record (arity, names, values)) ;; let isRecord v = match !v with Record _ -> true | _ -> false ;; let newNil () = newRecord 0 [||] [||] ;; let newPair head tail = newRecord 2 [|"hd"; "tl"|] [|head; tail|] ;; let rec findNameIndex index name names = if names.(index) = name then index else findNameIndex (index + 1) name names ;; let getFieldByName v name = match !v with Record (_, names, values) -> (try values.(findNameIndex 0 name names) with Invalid_argument _ -> raise (Error ("Record error. Record has no field named \"" ^ name ^ "\"."))) | _ -> raise (Error (typeError v "Record")) ;; let getFieldByIndex v index = match !v with Record (arity, _, values) -> if index < 0 then raise (Error "Record error. Index is less than or equal to zero (references start at 1)."); if index >= arity then raise (Error "Record error. Index exceeds arity."); values.(index) | _ -> raise (Error (typeError v "Record")) ;; (* List Functions *) let isList v = match !v with Record (arity, names, _) -> arity = 0 || names = [| "hd"; "tl" |] | _ -> false ;; let rec listToString v = if not (isList v) then raise (Error (typeError v "List")); match !v with Record (arity, _, values) -> if arity = 0 then "" else (match !(values.(0)) with Integer i -> begin try String.make 1 (Intbig.char_of_intbig i) with _ -> raise (Error "Type error. List contains non printable characters. Integers outside ascii range.") end | _ -> raise (Error "Type error. List contains non printable characters. Non integer list elements.") ) ^ listToString values.(1) | _ -> raise (Error (typeError v "List")) ;; let rec stringToList a = match a with "" -> newNil () | _ -> newPair (newInteger (Intbig.intbig_of_char a.[0])) (stringToList (String2.right_string a)) ;; let rec recordInfo0 pairs = match pairs with [] -> newNil () | (name, value) :: pairs -> newPair (newRecord 2 [|"name"; "value"|] [|stringToList name; value|]) (recordInfo0 pairs) ;; let recordInfo v = match !v with Record (arity, names, values) -> recordInfo0 (List.combine (Array.to_list names) (Array.to_list values)) | _ -> raise (Error (typeError v "Record")) ;; let rec listToIntegerList v = if not (isList v) then raise (Error (typeError v "List")); match !v with Record (arity, _, values) -> if arity = 0 then [] else getInteger values.(0) :: listToIntegerList values.(1) | _ -> raise (Error (typeError v "List")) ;; let rec listToIntList v = if not (isList v) then raise (Error (typeError v "List")); match !v with Record (arity, _, values) -> if arity = 0 then [] else getInt values.(0) :: listToIntList values.(1) | _ -> raise (Error (typeError v "List")) ;; (* Component (and Primitive) Functions *) let newComp (defRenv, compLoc, arity, component_name, portNames, stmt) = ref (Comp (defRenv, compLoc, arity, component_name, portNames, stmt)) ;; let isComp v = match !v with Comp _ -> true | _ -> false ;; let getCompInfo v = match !v with Comp (defRenv, compLoc, arity, component_name, portNames, stmt) -> (defRenv, compLoc, arity, component_name, portNames, stmt) | _ -> raise (Error (typeError v "Component")) ;; (** System Functions *) let newSystem renv = ref (System renv) ;; let isSystem v = match !v with System _ -> true | _ -> false ;; let getRenv v = match !v with System renv -> renv | _ -> raise (Error (typeError v "System")) ;; let getPorts v = match !v with System renv -> renv.renvPorts | _ -> raise (Error (typeError v "System")) ;; (** Environment Functions *) let getEnvId renv = renv.renvId ;; let newEnvRoot () = rootRenv ;; let extendEnv appRenv appLoc (compRenv, compLoc, arity, component_name, portNames, _) system_name = let portValues = Array.make arity (newFree ()) in let appLocs = appLoc :: appRenv.renvAppLocs in let renv = { renvId = Cf_fnf.new_sub_system (getEnvId appRenv) component_name system_name appLocs compLoc; renvParent = compRenv; renvCompLoc = compLoc; renvAppLocs = appLocs; renvPorts = newRecord arity portNames portValues; } in Array.iteri (fun i portName -> portValues.(i) <- newFreeLoc compLoc portName renv) portNames; renv ;; let rec getRelativeEnv renv index = if index <= 0 then renv else getRelativeEnv renv.renvParent (index - 1) ;; let getRenvValues renv = match !(renv.renvPorts) with Record (_, _, values) -> values | _ -> raise (Error "System error. System ports is not a record. Should not get here.") ;; (* Check all port variables are determined. *) let sortCompare var0 var1 = match (var0, var1) with ((renv0, _, _, _), (renv1, _, _, _)) -> compare (List.length renv0.renvAppLocs) (List.length renv1.renvAppLocs) ;; let rec consolidateResiduals residuals sofar = match residuals with [] -> sofar | (renv, _, _, var) as varData :: residuals -> let (group, other) = List.partition (function (renv0, _, _, var0) -> !var == !var0) residuals in begin match !var with Free (slots, _) -> if !slots = [] then consolidateResiduals other sofar else consolidateResiduals other (List.sort sortCompare (varData :: group) :: sofar) | _ -> consolidateResiduals other sofar end ;; let buildRootDependencyList () = List.fold_left (fun sofar (_, vars) -> List.fold_left (fun sofar var -> if not (isFree var) || List.exists (fun listvar -> !listvar == !var) sofar then sofar else var :: sofar ) sofar vars ) [] !freeVariableDepend ;; let buildDependencyGraph freeVariableDepend = let t1 = List.map (fun (var, depvars) -> var, List.filter isFree depvars) freeVariableDepend in let t2 = List.fold_left (fun sofar (_, depvars) -> List.fold_left (fun sofar depvar -> if List.exists (fun (var, _) -> !var == !depvar) t1 then sofar else (depvar, []) :: sofar ) sofar depvars ) [] t1 in let t3 = t2 @ t1 in let i_of_var var = List2.indexf (fun (listvar, _) -> !listvar == !var) t3 0 in let freevars = Array.make (List.length t3) (ref (Boolean true)) in List2.iteri (fun i (var, _) -> freevars.(i) <- var) t3; let connect = Array.make (List.length t3) [||] in List2.iteri (fun i (var, depvars) -> connect.(i) <- Array.make (List.length depvars) 0; List2.iteri (fun j depvar -> connect.(i).(j) <- i_of_var depvar) depvars ) t3; freevars, connect ;; let printValueDependencies graph = let (_, connect) = graph in print_string "** Free Value Dependencies\n\n : ...)\n\n"; Array.iteri (fun i deps -> print_string (" " ^ string_of_int i ^ " :"); Array.iter (fun j -> print_string (" " ^ string_of_int j)) deps; print_string "\n" ) connect; print_newline (); ;; let reportFreeVariableSet msg set id_of_freevar = let (_, _, _, a_var) = List.hd set in Report.error ("** Free Variable Error\n\n" ^ msg ^ "\n\n" ^ (try " Value id: " ^ string_of_int (id_of_freevar a_var) ^ "\n\n" with Not_found -> "") ^ List.fold_left (fun a varData -> let (renv, loc, name, var) = varData in a ^ " " ^ name ^ " " ^ Loc.toString loc ^ "\n" ) "" set ^ "\n Instantiation Trace:\n\n" ^ instanceTrace (let (renv, _, _, _) = List.hd set in renv.renvAppLocs) ^ "\n") ;; let freeVariableReport () = freeVariableClean (); let freeSets = consolidateResiduals !freeVariableMemory [] in let rootDepends = buildRootDependencyList () in let errorFound = ref false in let graph = buildDependencyGraph !freeVariableDepend in let id_of_freevar var = let freevars, _ = graph in let found = ref false in let i = ref 0 in while not !found do if !i >= Array.length freevars then raise Not_found; if !(freevars.(!i)) == !var then found := true else incr i done; !i in (* Checking unset root vars. *) let freevar, connect = graph in Array.iteri (fun i deps -> if Array.length deps = 0 then try let set = List.find (fun set -> List.exists (fun (_, _, _, setvar) -> !(freevar.(i)) == !setvar) set) freeSets in errorFound := true; reportFreeVariableSet "The following unified variables are required (root dependence):" set id_of_freevar with Not_found -> Report.error "** Free Variable Error\n\nRequired variable not in free set list. (should not get here)\n\n" ) connect; (* XXX Add cyclic checking here. *) if not !errorFound then begin List.iter (fun freeSet -> reportFreeVariableSet "The following unified variables are required (single dependence):" freeSet id_of_freevar) freeSets; end; if List.length freeSets > 0 then printValueDependencies graph; ;; let checkAllPortsDetermined () = if not (Report.errorReported ()) then freeVariableReport (); ;; confluence-0.10.6/src/cfeval/cfTypes.mli0100644002340600244710000001166710266541660017511 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Datatypes and Runtime Tools *) (** Exceptions *) exception Error of string;; (** Types *) type variable;; type renv;; (** Runtime Error Reporting *) (** Sets current location and environment. *) val setLocation : Loc.loc -> unit;; (** Specifies a variable dependency. *) val setVariableDependence : variable -> variable list -> unit;; (** Reports an error with an instantiation trace. *) val error : string -> unit;; val typeToString : variable -> string;; (** Task Queue *) (** Sends a task into the ready queue. *) val readyTask : renv * (unit -> unit) -> unit;; (** Executues tasks in queue. *) val executeTasks : unit -> unit;; (** Sync slots. *) type slot;; (** Creates a new slot. *) val newSlot : renv -> int -> (unit -> unit) -> slot;; (** Syncs a slot. *) val sync : slot -> unit;; (** Increments slots counter. *) val incrSlot : slot -> unit;; (** Slots a variable. Records must me complete. *) val slotVariableStrict : slot -> variable -> unit;; (** Slots a variable. Records may be incomplete. *) val slotVariableLenient : slot -> variable -> unit;; (** Unifies two variables. *) val unify : variable -> variable -> unit;; (** Compares two variables. *) val isEqual : renv -> variable -> variable -> variable -> unit;; (** Free Values *) val newFree : unit -> variable;; val newFreeLoc : Loc.loc -> string -> renv -> variable;; val newFreeWithTask : renv -> (variable -> unit) -> variable;; (** Integers *) val newInteger : Intbig.intbig -> variable;; val isInteger : variable -> bool;; val getInteger : variable -> Intbig.intbig;; val getInt : variable -> int;; (** Floats *) val newFloat : float -> variable;; val isFloat : variable -> bool;; val getFloat : variable -> float;; (** Booleans *) val newBoolean : bool -> variable;; val isBoolean : variable -> bool;; val getBoolean : variable -> bool;; (** Vectors *) val zero_width_vector : variable;; val is_zero_width_vector : variable -> bool;; val checkBits : string -> unit;; val newVector : Cf_fnf.producer -> variable;; val newVectorConst : Intbig.intbig -> Intbig.intbig -> Cf_fnf.system -> variable;; val isVector : variable -> bool;; val getWidth : variable -> int;; val getProducer : variable -> Cf_fnf.producer;; val checkWidth : variable -> unit;; val checkWidthNotZero : variable -> unit;; val checkWidthIs : variable -> int -> unit;; val checkWidthsAreSame : variable -> variable -> unit;; (** Properties *) val isProperty : variable -> bool;; val newPropertyVector : variable -> variable;; val newPropertyNot : variable -> variable;; val newPropertyOr : variable -> variable -> variable;; val newPropertyNext : variable -> variable;; val newPropertyUntil : variable -> variable -> variable;; (** Records *) val newRecord : int -> string array -> variable array -> variable;; val isRecord : variable -> bool;; val recordInfo : variable -> variable;; val getFieldByName : variable -> string -> variable;; val getFieldByIndex : variable -> int -> variable;; (** Lists *) val isList : variable -> bool;; val listToString : variable -> string;; val stringToList : string -> variable;; val listToIntegerList : variable -> Intbig.intbig list;; val listToIntList : variable -> int list;; (** Components *) val newComp : (renv * Loc.loc * int * string * string array * (renv -> unit)) -> variable;; val isComp : variable -> bool;; val getCompInfo : variable -> (renv * Loc.loc * int * string * string array * (renv -> unit)) (** Systems *) val newSystem : renv -> variable;; val isSystem : variable -> bool;; val getRenv : variable -> renv;; val getPorts : variable -> variable;; (** Runtime environment (renv). *) val getEnvId : renv -> Cf_fnf.system;; val newEnvRoot : unit -> renv;; val extendEnv : renv -> Loc.loc -> (renv * Loc.loc * int * string * string array * 'a) -> string -> renv;; val getRelativeEnv : renv -> int -> renv;; val getRenvValues : renv -> variable array;; (** Check all ports determined. *) val checkAllPortsDetermined : unit -> unit;; confluence-0.10.6/src/cfeval/cf_fnf.mli0100644002340600244710000000530110266541660017301 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Confluence to FNF Interface Functions *) (** Types *) type producer;; type system;; (** Synchronization *) val width_of_producer : producer -> int;; val new_root_system : unit -> system;; val new_sub_system : system -> string -> string -> Loc.loc list -> Loc.loc -> system;; val set_clock_domain : system -> string -> (string -> unit) -> unit;; val add_sub_enable : system -> producer -> (string -> unit) -> unit;; val add_sub_reset : system -> producer -> (string -> unit) -> unit;; (** Combinatorial Primitives *) val new_input : system -> string -> int -> producer;; val new_output : system -> string -> producer -> unit;; val new_const : system -> string -> producer;; val new_buf : system -> producer -> producer;; val new_not : system -> producer -> producer;; val new_and : system -> producer -> producer -> producer;; val new_or : system -> producer -> producer -> producer;; val new_xor : system -> producer -> producer -> producer;; val new_concat : system -> producer -> producer -> producer;; val new_select : system -> producer -> int -> producer;; val new_equ : system -> producer -> producer -> producer;; val new_lt : system -> producer -> producer -> producer;; val new_add : system -> producer -> producer -> producer;; val new_sub : system -> producer -> producer -> producer;; val new_mul : system -> producer -> producer -> producer;; val new_mux : system -> producer -> producer -> producer -> producer;; (** Stateful Primitives: First call new_state, then call specific. *) val new_state : system -> int -> producer;; val new_reg : system -> producer -> producer -> unit;; val new_bbox : system -> string -> int list -> producer -> producer -> unit;; (** Code Generator *) val output_fnf : out_channel -> unit;; confluence-0.10.6/src/Makefile0100644002340600244710000000715610266541655015573 0ustar hawkit1cadgrpSHELL=/bin/bash .SUFFIXES: .ml .mli .cmo .cmi .cmx PREFIX=/usr/local OCAMLC=ocamlc.opt OCAMLOPT=ocamlopt.opt OCAMLDEP=ocamldep OCAMLDOC=ocamldoc OCAMLLIB= $(shell $(OCAMLC) -where) INCLUDES= -I misc -I cfeval -I fnflib OCAMLFLAGS=$(INCLUDES) # add other options for ocamlc here OCAMLOPTFLAGS=$(INCLUDES) # add other options for ocamlopt here .PHONY : all all : cf fnf doc .PHONY : doc doc : $(OCAMLDOC) -html $(INCLUDES) -d doc \ misc/*.ml misc/*.mli \ cfeval/*.ml cfeval/*.mli \ fnflib/*.ml fnflib/*.mli check: cf cf -test .PHONY : install install : all install -D cf $(PREFIX)/bin/cf install -D fnf $(PREFIX)/bin/fnf .PHONY : uninstall uninstall : -rm $(PREFIX)/bin/cf -rm $(PREFIX)/bin/fnf CF_CMX=\ $(OCAMLLIB)/unix.cmxa \ $(OCAMLLIB)/nums.cmxa \ misc/ut.cmx \ misc/list2.cmx \ misc/string2.cmx \ misc/intbig.cmx \ misc/loc.cmx \ misc/report.cmx \ misc/version.cmx \ fnflib/fnf_core.cmx \ fnflib/fnf_out.cmx \ cfeval/cf_fnf.cmx \ cfeval/cfAst.cmx \ cfeval/cfParserUtil.cmx \ cfeval/cfParser.cmx \ cfeval/cfLexer.cmx \ cfeval/cfTypes.cmx \ cfeval/cfPrims.cmx \ cfeval/cfCompiler.cmx \ misc/test_suite.cmx \ cfeval/cf.cmx FNF_CMX=\ misc/ut.cmx \ misc/string2.cmx \ misc/version.cmx \ fnflib/parser_util.cmx \ fnflib/fnf_core.cmx \ fnflib/fnf_parser.cmx \ fnflib/fnf_lexer.cmx \ fnflib/fnf_out.cmx \ fnflib/fnf_verilog.cmx \ fnflib/fnf_vhdl.cmx \ fnflib/fnf_jhdl.cmx \ fnflib/fnf_nusmv.cmx \ fnflib/fnf_c.cmx \ fnflib/ltl.cmx \ fnflib/psl_ast.cmx \ fnflib/psl_parser.cmx \ fnflib/psl_lexer.cmx \ fnflib/fnf.cmx cf : $(CF_CMX) $(OCAMLOPT) -o cf $(OCAMLOPTFLAGS) $(CF_CMX) fnf : $(FNF_CMX) $(OCAMLOPT) -o fnf $(OCAMLOPTFLAGS) $(FNF_CMX) .ml.cmo: $(OCAMLC) $(OCAMLFLAGS) -c $< .mli.cmi: $(OCAMLC) $(OCAMLFLAGS) -c $< .ml.cmx: $(OCAMLOPT) $(OCAMLOPTFLAGS) -c $< clean: -rm depend -rm cf -rm fnf -rm cfeval/cfParser.ml -rm cfeval/cfParser.mli -rm cfeval/cfParser.output -rm cfeval/cfLexer.ml -rm fnflib/fnf_parser.ml -rm fnflib/fnf_parser.mli -rm fnflib/fnf_parser.output -rm fnflib/fnf_lexer.ml -rm fnflib/psl_parser.ml -rm fnflib/psl_parser.mli -rm fnflib/psl_parser.output -rm fnflib/psl_lexer.ml -rm fnflib/*.cm[iox] fnflib/*.o -rm cfeval/*.cm[iox] cfeval/*.o -rm misc/*.cm[iox] misc/*.o -rm doc/*.html doc/*.css depend : \ cfeval/cfParser.ml \ cfeval/cfParser.mli \ cfeval/cfLexer.ml \ fnflib/psl_parser.ml \ fnflib/psl_parser.mli \ fnflib/psl_lexer.ml \ fnflib/fnf_parser.ml \ fnflib/fnf_parser.mli \ fnflib/fnf_lexer.ml $(OCAMLDEP) $(INCLUDES) \ misc/*.ml misc/*.mli \ cfeval/*.ml cfeval/*.mli \ fnflib/*.ml fnflib/*.mli \ > depend include depend cfeval/cfParser.ml cfeval/cfParser.mli: cfeval/cfParser.mly cd cfeval && ocamlyacc -v cfParser.mly cfeval/cfLexer.ml: cfeval/cfLexer.mll cd cfeval && ocamllex cfLexer.mll fnflib/fnf_parser.ml fnflib/fnf_parser.mli: fnflib/fnf_parser.mly cd fnflib && ocamlyacc -v fnf_parser.mly fnflib/fnf_lexer.ml: fnflib/fnf_lexer.mll cd fnflib && ocamllex fnf_lexer.mll fnflib/psl_parser.ml fnflib/psl_parser.mli: fnflib/psl_parser.mly cd fnflib && ocamlyacc -v psl_parser.mly fnflib/psl_lexer.ml: fnflib/psl_lexer.mll cd fnflib && ocamllex psl_lexer.mll confluence-0.10.6/src/doc/0040755002340600244710000000000010312276326014662 5ustar hawkit1cadgrpconfluence-0.10.6/src/doc/README0100644002340600244710000000006710266541655015552 0ustar hawkit1cadgrpDocumentation generated by ocamldoc. See index.html. confluence-0.10.6/src/fnflib/0040755002340600244710000000000010312276326015355 5ustar hawkit1cadgrpconfluence-0.10.6/src/fnflib/fnf_c.mli0100644002340600244710000000157710266541661017147 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; val output_c : out_channel -> out_channel -> scope -> unit;; confluence-0.10.6/src/fnflib/fnf.ml0100644002340600244710000001411010266541661016457 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) let help () = print_string (" NAME fnf SYNOPSIS fnf [options] DESCRIPTION FNF (Free Netlist Format) is an elaborated, hierarchical, register transfer level (RTL) netlist format used to communicate design information between frontend EDA tools. The FNF tool translates an FNF netlist to Verilog, VHDL, C, and NuSMV. OPTIONS Options are processed in the order they are received. -h OR -help Prints this information then exits. -read_fnf file Read in an FNF netlist. -write_fnf file Write out an FNF netlist. -write_nusmv file Write out an NuSMV description. -write_verilog file Write out a Verilog netlist. -write_vhdl file Write out a VHDL netlist. -write_c file Write out a C model. Appends '.c' and '.h' to file name. -write_jhdl class Write out a JHDL netlist. Appends .java to class name. EXAMPLES Building an FNF netlist from Verilog using Icarus: $ iverilog -Wall -t fnf -o my_netlist.fnf my_verilog.v Use FNF to produce a Verilog and C model: $ fnf -read_fnf my_netlist.fnf -write_verilog my_netlist.v -write_c my_netlist Use FNF to produce an NuSMV model: $ fnf -read_fnf my_netlist.fnf -write_nusmv my_netlist.smv Use FNF to produce another FNF netlist: $ fnf -read_fnf my_netlist.fnf -write_fnf my_netlist2.fnf KNOWN LIMITATIONS General - No tristate support. - No memory support. - No division or modulo operators. Icarus Verilog FNF Code Generator - Assumes ports and named signals have [n:0] ordering. - \"always\" blocks are constrained to the Icarus Verilog synthesizable subset. - All register clocks and asynchronous resets must be senitive on the rising edge. WARNING: No errors will be issued if a design contains \"negedge\". - All arithmetic operations must be unsigned. WARNING: No errors will be issued if a design contains signed operations. - Multipliers can not be embbeded in concatenations. Verilog and VHDL Model Writer - Netlist is flat. NuSMV Model Writer - 2-value model. No X's or Z's. - Inputs assumed to init to 0. - Registers are initialized to 0. VERSION " ^ Version.version ^ " AUTHOR Tom Hawkins SEE ALSO FNF and Confluence : http://www.confluent.org/ Icarus Verilog : http://www.icarus.com/eda/verilog/ NuSMV : http://nusmv.irst.itc.it/ COPYRIGHT Copyright (C) 2004-2005 Tom Hawkins "); print_newline (); exit 0 ;; type current_scope = None | Scope of Fnf_core.scope;; let main () = let argv = Sys.argv in let argc = Array.length argv in if argc = 1 then help (); let i = ref 1 in let error msg = prerr_string ("** ERROR: " ^ msg); prerr_newline (); exit 1 in let debug msg = print_string msg; print_newline () in let open_out filename = try open_out filename with Sys_error _ -> error ("Could not open file " ^ filename ^ " for writing."); raise (Invalid_argument "no file") in let open_in filename = try open_in filename with Sys_error _ -> error ("Could not open file " ^ filename ^ " for reading."); raise (Invalid_argument "no file") in let next_arg arg_type = if !i >= argc then error ("Invalid Argument. Expecting " ^ arg_type ^ "."); let arg = argv.(!i) in incr i; arg in let scope = ref None in let get_scope () = match !scope with | None -> error ("No netlist currently loaded.") | Scope scope -> scope in while !i < argc do match next_arg "command option" with | "-h" | "-help" -> help () | "-read_fnf" -> let file = next_arg "write_fnf file" in let channel = open_in file in scope := Scope (try Parser_util.parse_channel channel file Fnf_lexer.token Fnf_parser.netlist with Parser_util.Error msg -> error msg); close_in channel | "-write_fnf" -> let file = next_arg "write_fnf file" in let channel = open_out file in Fnf_out.output_fnf channel (get_scope ()); close_out channel | "-write_verilog" -> let file = next_arg "verilog file" in let channel = open_out file in Fnf_verilog.output_verilog channel (get_scope ()); close_out channel | "-write_vhdl" -> let file = next_arg "vhdl file" in let channel = open_out file in Fnf_vhdl.output_vhdl channel (get_scope ()); close_out channel | "-write_jhdl" -> let file = next_arg "jhdl file" in let channel = open_out (file ^ ".java") in Fnf_jhdl.output_jhdl file channel (get_scope ()); close_out channel | "-write_nusmv" -> let file = next_arg "nusmv file" in let channel = open_out file in Fnf_nusmv.output_nusmv channel (get_scope ()); close_out channel | "-write_c" -> let file = next_arg "nusmv file" in let channel_c = open_out (file ^ ".c") in let channel_h = open_out (file ^ ".h") in Fnf_c.output_c channel_c channel_h (get_scope ()); close_out channel_c; close_out channel_h | arg -> error ("Invalid argument: " ^ arg) done ;; Printexc.print main ();; confluence-0.10.6/src/fnflib/fnf_c.ml0100644002340600244710000004412010266541661016765 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; let debug msg = print_string msg; print_newline () ;; let words_of_width bits = (bits - 1) / 32 + 1 ;; let cell_index_table = Hashtbl.create 1024;; let next_index = ref 0;; let add_cell_index cell index = Hashtbl.add cell_index_table (id_of_cell cell) index ;; let index_of_cell cell = Hashtbl.find cell_index_table (id_of_cell cell) ;; let reset () = Hashtbl.clear cell_index_table; next_index := 0 ;; let allocate_cell cell = let input num = let cell = producer_of_port (port_of_cell cell num) in (match info_of_cell cell with Dangle -> raise (Invalid_argument "encountered unconnected cell") | _ -> ()); cell in match info_of_cell cell with | Input (_, w) | Not w | And w | Xor w | Or w | Add w | Sub w | Mul w | Mux w -> add_cell_index cell !next_index; next_index := !next_index + (words_of_width w) | Output (_, w) | Name (_, w) | Buf w -> add_cell_index cell (index_of_cell (input 0)) | Const value -> let w = String.length value in add_cell_index cell !next_index; next_index := !next_index + (words_of_width w) | Concat (wl, wr) -> let w = wl + wr in add_cell_index cell !next_index; next_index := !next_index + (words_of_width w) | Select (_, bit) -> add_cell_index cell !next_index; next_index := !next_index + 1 | Eq _ | Lt _ -> add_cell_index cell !next_index; next_index := !next_index + 1 | Ff w -> add_cell_index cell !next_index; next_index := !next_index + (words_of_width w * 2 + 1) | Ffc w -> add_cell_index cell !next_index; next_index := !next_index + (words_of_width w * 2 + 2) | Dangle -> add_cell_index cell 0 (* So it doesn't raise an error it the calc phase. *) | Bbox _ -> raise (Invalid_argument "Black-boxes not supported in C code generation.") ;; let channel_c = ref stdout;; let channel_h = ref stdout;; let write_string string = output_string !channel_c string ;; let write line = output_string !channel_c line; output_char !channel_c '\n' ;; let write_h line = output_string !channel_h line; output_char !channel_h '\n' ;; (** Builds the simulation data structure. *) let output_sim_struct scope cells = let indent = ref 0 in let write line = for i = 1 to !indent do output_string !channel_h " "; output_string !channel_c " "; done; output_string !channel_h line; output_string !channel_c line; output_char !channel_h '\n'; output_char !channel_c '\n' in let rec declare_names scope_item = match scope_item with | Scope scope -> write "struct {"; incr indent; List.iter declare_names (items_of_scope scope); decr indent; write ("} " ^ instance_name_of_scope scope ^ ";") | Cell cell -> (match info_of_cell cell with | Input (name, w) -> write ("unsigned long * " ^ name ^ "; // input " ^ name ^ " : " ^ string_of_int w ^ " bits, " ^ string_of_int (words_of_width w) ^ " words") | Output (name, w) -> write ("unsigned long * " ^ name ^ "; // output " ^ name ^ " : " ^ string_of_int w ^ " bits, " ^ string_of_int (words_of_width w) ^ " words") | Name (name, w) -> write ("unsigned long * " ^ name ^ ";") | _ -> () ) in write ""; write "// Simulator Data Type"; write "struct simulator_s {"; incr indent; write "struct {"; incr indent; declare_names (Scope (root_of_scope scope)); decr indent; write "} signals;"; write ("unsigned long memory[" ^ string_of_int !next_index ^ "];"); decr indent; write "};"; write ""; write "typedef struct simulator_s *simulator_t;"; write "" ;; (** Creates the "new" and "delete" functions. *) let output_new_delete () = write_h "// Simulator Constructor"; write_h "simulator_t new_simulator();\n"; write_h "// Simulator Destructor"; write_h "void delete_simulator(simulator_t);\n"; write_string ("simulator_t new_simulator() { simulator_t simulator; simulator = (simulator_t) malloc(sizeof(*simulator)); return simulator; } void delete_simulator(simulator_t simulator) { free ((void*) simulator); } ") ;; (** Creates the primitive functions. *) let output_primitive_functions () = write_string " void fnf_mask(int words, unsigned long mask, unsigned long* x) { x[words - 1] = x[words - 1] & mask; } void fnf_not(int words, unsigned long mask, unsigned long* a, unsigned long* x) { int i; for (i = 0; i < words; i++) x[i] = ~ a[i]; fnf_mask(words, mask, x); } void fnf_and(int words, unsigned long mask, unsigned long* a, unsigned long* b, unsigned long* x) { int i; for (i = 0; i < words; i++) x[i] = a[i] & b[i]; fnf_mask(words, mask, x); } void fnf_xor(int words, unsigned long mask, unsigned long* a, unsigned long* b, unsigned long* x) { int i; for (i = 0; i < words; i++) x[i] = a[i] ^ b[i]; fnf_mask(words, mask, x); } void fnf_or(int words, unsigned long mask, unsigned long* a, unsigned long* b, unsigned long* x) { int i; for (i = 0; i < words; i++) x[i] = a[i] | b[i]; fnf_mask(words, mask, x); } void fnf_concat_over(int words_a, int words_b, int shift_left, int shift_right, unsigned long* a, unsigned long* b, unsigned long* x) { int i; int j; for (i = 0; i < words_b; i++) x[i] = b[i]; for (i = 0, j = words_b - 1; i < words_a; i++, j++) { x[j] = x[j] | (0xFFFFFFFF & (a[i] << shift_left)); x[j + 1] = a[i] >> shift_right; } } void fnf_concat_under(int words_a, int words_b, int shift_left, int shift_right, unsigned long* a, unsigned long* b, unsigned long* x) { int i; int j; for (i = 0; i < words_b; i++) x[i] = b[i]; for (i = 0, j = words_b - 1; i < words_a - 1; i++, j++) { x[j] = x[j] | (0xFFFFFFFF & (a[i] << shift_left)); x[j + 1] = a[i] >> shift_right; } x[j] = x[j] | (0xFFFFFFFF & (a[i] << shift_left)); } void fnf_concat_simple(int words_a, int words_b, unsigned long* a, unsigned long* b, unsigned long* x) { int i; int j; for (i = 0; i < words_b; i++) x[i] = b[i]; for (i = 0, j = words_b; i < words_a; i++, j++) x[j] = a[i]; } void fnf_select(int word, int bit, unsigned long* a, unsigned long* x) { x[0] = 1 & (a[word] >> bit); } void fnf_eq(int words, unsigned long* a, unsigned long* b, unsigned long* x) { int i; x[0] = 1; for (i = 0; i < words; i++) x[0] = x[0] && a[i] == b[i]; } void fnf_lt(int words, unsigned long* a, unsigned long* b, unsigned long* x) { int i; x[0] = 0; for (i = words - 1; i >= 0; i--) { if (a[i] < b[i]) { x[0] = 1; return; } else if (a[i] > b[i]) { return; } } } void fnf_add(int words, unsigned long mask, unsigned long* a, unsigned long* b, unsigned long* x) { int i; unsigned long long tmp = 0; for (i = 0; i < words; i++) { tmp = (unsigned long long) a[i] + (unsigned long long) b[i] + tmp; x[i] = (unsigned long) (tmp & 0xFFFFFFFF); tmp = (tmp >> 32) & 1; } fnf_mask(words, mask, x); } void fnf_sub(int words, unsigned long mask, unsigned long* a, unsigned long* b, unsigned long* x) { int i; unsigned long long tmp = 0; for (i = 0; i < words; i++) { tmp = (unsigned long long) a[i] - (unsigned long long) b[i] - tmp; x[i] = (unsigned long) (tmp & 0xFFFFFFFF); tmp = (tmp >> 32) & 1; } fnf_mask(words, mask, x); } void fnf_mul(int words, unsigned long mask, unsigned long* a, unsigned long* b, unsigned long* x) { int i, ia, ib, ic; unsigned long long tmp; for (i = 0; i < words; i++) x[i] = 0; for (i = 0; i < words; i++) { for (ia = i, ib = 0; ia >= 0; ia--, ib++) { tmp = (unsigned long long) (a[ia]) * (unsigned long long) (b[ib]); for (ic = i; ic < words; ic++) { tmp = tmp + (unsigned long long) x[ic]; x[ic] = (unsigned long) (tmp & 0xFFFFFFFF); tmp = (tmp >> 8); } } } fnf_mask(words, mask, x); } void fnf_mux(int words, unsigned long* select, unsigned long* on_0, unsigned long* on_1, unsigned long* x) { int i; for (i = 0; i < words; i++) x[i] = select[0] ? on_1[i] : on_0[i]; } void fnf_ff(int words, unsigned long* clk, unsigned long* q) { int i; unsigned long* state_clk = & q[words]; unsigned long* state_d = & q[words + 1]; if (clk[0] && ! state_clk[0]) for (i = 0; i < words; i++) q[i] = state_d[i]; state_clk[0] = clk[0]; } void fnf_ff_update(int words, unsigned long* data, unsigned long* q) { int i; unsigned long* state_d = & q[words + 1]; for (i = 0; i < words; i++) state_d[i] = data[i]; } void fnf_ffc(int words, unsigned long* clr, unsigned long* clk, unsigned long* q) { int i; unsigned long* state_clr = & q[words]; unsigned long* state_clk = & q[words + 1]; unsigned long* state_d = & q[words + 2]; if (clr[0] && ! state_clr[0]) for (i = 0; i < words; i++) q[i] = 0; else if (clk[0] && ! state_clk[0]) for (i = 0; i < words; i++) q[i] = state_d[i]; state_clr[0] = clr[0]; state_clk[0] = clk[0]; } void fnf_ffc_update(int words, unsigned long* data, unsigned long* q) { int i; unsigned long* state_d = & q[words + 2]; for (i = 0; i < words; i++) state_d[i] = data[i]; } " ;; (** Misc Helpers *) let hex_of_bin bin = let m = String.length bin mod 4 in let bin = if m = 0 then bin else String.make (4 - m) '0' ^ bin in let rec f sofar bin = if bin = "" then sofar else f (sofar ^ match String.sub bin 0 4 with | "0000" -> "0" | "0001" -> "1" | "0010" -> "2" | "0011" -> "3" | "0100" -> "4" | "0101" -> "5" | "0110" -> "6" | "0111" -> "7" | "1000" -> "8" | "1001" -> "9" | "1010" -> "A" | "1011" -> "B" | "1100" -> "C" | "1101" -> "D" | "1110" -> "E" | "1111" -> "F" | _ -> raise (Invalid_argument "Invalid binary string.") ) (String.sub bin 4 (String.length bin - 4)) in "0x" ^ f "" bin ;; let mask_of_width width = let remainder = width mod 32 in if remainder = 0 then "0xFFFFFFFF" else hex_of_bin (String.make remainder '1') ;; (** Cell Initialization *) let init_cell cell = let id = id_of_cell cell in let input num = let cell = producer_of_port (port_of_cell cell num) in (match info_of_cell cell with Dangle -> raise (Invalid_argument "encountered unconnected cell") | _ -> ()); id_of_cell cell in match info_of_cell cell with | Input (name, w) | Output (name, w) | Name (name, w) -> write (" simulator->signals." ^ String2.join (path_of_cell cell) "." ^ "." ^ name ^ " = &(memory[" ^ string_of_int (index_of_cell cell) ^ "]);") | Const value -> let rec f value index = let len = String.length value in if len <= 32 then write (" memory[" ^ string_of_int index ^ "] = " ^ hex_of_bin value ^ ";") else begin write (" memory[" ^ string_of_int index ^ "] = " ^ hex_of_bin (String.sub value (len - 32) 32) ^ ";"); f (String.sub value 0 (len - 32)) (index + 1) end in f value (index_of_cell cell) | Ff w -> write (" memory[" ^ string_of_int (index_of_cell cell + words_of_width w) ^ "] = 1;") | Ffc w -> write (" memory[" ^ string_of_int (index_of_cell cell + words_of_width w ) ^ "] = 1;"); write (" memory[" ^ string_of_int (index_of_cell cell + words_of_width w + 1) ^ "] = 1;"); | _ -> () ;; let words_of_width width = string_of_int (words_of_width width) ;; (** Define the init function. *) let output_init scope cells = write_h "// Simulator Initialization"; write_h "void init_simulator(simulator_t);"; write_h ""; write_string ("void init_simulator(simulator_t simulator) { int i; unsigned long *memory; memory = simulator->memory; for (i = 0; i < " ^ string_of_int !next_index ^ "; i++) simulator->memory[i] = 0; "); List.iter init_cell cells; write "}\n"; ;; (** Cell Calculation *) let calc_cell cell = let index = index_of_cell cell in let input num = let cell = producer_of_port (port_of_cell cell num) in (match info_of_cell cell with Dangle -> raise (Invalid_argument "encountered unconnected cell") | _ -> ()); index_of_cell cell in let mem_index = "& memory[" ^ string_of_int index ^ "]" in let mem_input num = "& memory[" ^ string_of_int (input num) ^ "]" in let write_fnf_func name args = write (" " ^ name ^ "(" ^ String2.join args ", " ^ ");") in match info_of_cell cell with | Input (_, w) -> write_fnf_func "fnf_mask" [words_of_width w; mask_of_width w; mem_index] | Output _ | Name _ | Dangle | Const _ | Buf _ -> () | Not w -> write_fnf_func "fnf_not" [words_of_width w; mask_of_width w; mem_input 0; mem_index] | And w -> write_fnf_func "fnf_and" [words_of_width w; mask_of_width w; mem_input 0; mem_input 1; mem_index] | Xor w -> write_fnf_func "fnf_xor" [words_of_width w; mask_of_width w; mem_input 0; mem_input 1; mem_index] | Or w -> write_fnf_func "fnf_or" [words_of_width w; mask_of_width w; mem_input 0; mem_input 1; mem_index] | Concat (wl, wr) -> let shift_left = wr mod 32 in let shift_right = 32 - shift_left in if shift_left = 0 then write_fnf_func "fnf_concat_simple" [words_of_width wl; words_of_width wr; mem_input 0; mem_input 1; mem_index] else if shift_right > wl mod 32 then write_fnf_func "fnf_concat_under" [words_of_width wl; words_of_width wr; string_of_int shift_left; string_of_int shift_right; mem_input 0; mem_input 1; mem_index] else write_fnf_func "fnf_concat_over" [words_of_width wl; words_of_width wr; string_of_int shift_left; string_of_int shift_right; mem_input 0; mem_input 1; mem_index] | Select (w, bit) -> write_fnf_func "fnf_select" [string_of_int (bit / 32); string_of_int (bit mod 32); mem_input 0; mem_index] | Eq w -> write_fnf_func "fnf_eq" [words_of_width w; mem_input 0; mem_input 1; mem_index] | Lt w -> write_fnf_func "fnf_lt" [words_of_width w; mem_input 0; mem_input 1; mem_index] | Add w -> write_fnf_func "fnf_add" [words_of_width w; mask_of_width w; mem_input 0; mem_input 1; mem_index] | Sub w -> write_fnf_func "fnf_sub" [words_of_width w; mask_of_width w; mem_input 0; mem_input 1; mem_index] | Mul w -> write_fnf_func "fnf_mul" [words_of_width w; mask_of_width w; mem_input 0; mem_input 1; mem_index] | Mux w -> write_fnf_func "fnf_mux" [words_of_width w; mem_input 0; mem_input 1; mem_input 2; mem_index] | Ff w -> write_fnf_func "fnf_ff" [words_of_width w; mem_input 0; mem_index] | Ffc w -> write_fnf_func "fnf_ffc" [words_of_width w; mem_input 0; mem_input 1; mem_index] | Bbox _ -> raise (Invalid_argument "Black-boxes not supported in C code generation.") ;; let reg_update_cell cell = let input num = let cell = producer_of_port (port_of_cell cell num) in (match info_of_cell cell with Dangle -> raise (Invalid_argument "encountered unconnected cell") | _ -> ()); index_of_cell cell in let mem_index = "& memory[" ^ string_of_int (index_of_cell cell) ^ "]" in let mem_input num = "& memory[" ^ string_of_int (input num) ^ "]" in let write_fnf_func name args = write (" " ^ name ^ "(" ^ String2.join args ", " ^ ");") in match info_of_cell cell with | Ff w -> write_fnf_func "fnf_ff_update" [words_of_width w; mem_input 1; mem_index] | Ffc w -> write_fnf_func "fnf_ffc_update" [words_of_width w; mem_input 2; mem_index] | _ -> () ;; (** Define the calc function. *) let output_calc cells = write_h "// Simulator Cycle Calculation"; write_h "void calc_simulator(simulator_t);"; write_h ""; write "void calc_simulator(simulator_t simulator)"; write "{"; write " unsigned long *memory;"; write " memory = simulator->memory;"; List.iter calc_cell cells; List.iter reg_update_cell cells; write "}"; write ""; ;; (** Orders the cells for execution. *) let order_cells scope = let rec order remaining computed = if remaining = [] then List.rev computed else let is_ready ports = List.for_all (fun port -> let id = id_of_cell (producer_of_port port) in List.exists (fun cell -> id = id_of_cell cell) computed ) ports in let is_ready cell = match info_of_cell cell with | Dangle | Input _ | Const _ -> true | Ff _ -> is_ready [port_of_cell cell 0] | Ffc _ -> is_ready [port_of_cell cell 0; port_of_cell cell 1] | _ -> is_ready (ports_of_cell cell) in let ready, not_ready = List.partition is_ready remaining in if ready = [] then raise (Invalid_argument "No cells can be scheduled. Suspecting a combinational or Q-to-D loop."); order not_ready (ready @ computed) in order (all_cells scope) [] ;; (** Output a C model given a scope. [output_c c_channer h_channel scope] *) let output_c out_channel_c out_channel_h scope = channel_c := out_channel_c; channel_h := out_channel_h; let cells = order_cells scope in List.iter allocate_cell cells; write_h "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"; write "#include "; output_sim_struct scope cells; output_new_delete (); output_primitive_functions (); output_init scope cells; output_calc cells; write_h "#ifdef __cplusplus\n}\n#endif\n"; reset () ;; confluence-0.10.6/src/fnflib/parser_util.mli0100644002340600244710000000232010266541663020412 0ustar hawkit1cadgrp(* InFormal Digital Logic Verification Environment Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Error exception. *) exception Error of string;; (** Parsing error reporting. *) val error : string -> unit;; (** Handles next token. *) val next_lex : Lexing.lexbuf -> string * (string * int * int);; (** Gets the current token. *) val get_current_token : unit -> string;; (** Parses an channel. *) val parse_channel : in_channel -> string -> 'a -> ('a -> Lexing.lexbuf -> 'b) -> 'b;; confluence-0.10.6/src/fnflib/fnf_core.ml0100644002340600244710000003446210266541661017503 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** General error reporting. *) exception Error of string;; exception Invalid_port_number;; let debug msg = print_string msg; print_newline () ;; (** The netlist is the global conection matrix. *) type netlist = { root : scope; mutable cells : cell_netlist_info array; mutable next_cell : int } (** Cell type and connectivity information. *) and cell_netlist_info = { scope : scope; info : cell_info; producers : cell array; mutable consumers : port list } (** A scope is a hierarchical object that contains cells, properties, and subscopes. *) and scope = { netlist : netlist; module_ : string; instance : string; is_root : bool; parent : scope; mutable items : item list } (** A scope item can be either a subscope, a cell, or a property. *) and item = Scope of scope | Cell of cell (** A cell is a primitive logic operation. *) and cell = netlist * int (** A port is an input to a cell. *) and port = cell * int (** A property is temporal relation of states in a design. Supports CTL, LTL, and CTL*. *) and property = int (* XXX *) (** Cell info gives the netlist user visability to cell information. *) and cell_info = Input of string * int | Output of string * int | Name of string * int | Dangle | Const of string | Buf of int | Not of int | And of int | Xor of int | Or of int | Concat of int * int | Select of int * int | Eq of int | Lt of int | Add of int | Sub of int | Mul of int | Mux of int | Ff of int | Ffc of int | Bbox of string * int * int * int list ;; (* Internal netlist operations. *) (** Netlist containing cell. *) let netlist_of_cell (netlist, _) = netlist ;; (** Netlist containing port. *) let netlist_of_port ((netlist, _), _) = netlist ;; (** Cell id of cell. *) let id_of_cell (_, id) = id ;; (** Cell id of port. *) let id_of_port ((_, id), _) = id ;; (** Number of port. *) let num_of_port ((_, _), n) = n ;; (** Cell of port. *) let cell_of_port (cell, _) = cell ;; (** Check that a port and a cell belong to the same netlist. *) let assert_same_netlist cell port = if netlist_of_cell cell != netlist_of_port port then raise (Error "Cell and port do not belong to the same netlist.") ;; (** Adds a consumer reference to producer. *) let add_consumer cell port = assert_same_netlist cell port; let consumer_info = (netlist_of_cell cell).cells.(id_of_cell cell) in consumer_info.consumers <- port :: consumer_info.consumers ;; let is_ports_same ((_, c1), p1) ((_, c2), p2) = (c1, p1) = (c2, p2) ;; (** Removes a consumer reference from producer. *) let remove_consumer cell port = let consumer_cell_id = id_of_port port in let port_num = num_of_port port in assert_same_netlist cell port; let consumer_info = (netlist_of_cell cell).cells.(id_of_cell cell) in consumer_info.consumers <- List.filter (fun p -> not (is_ports_same p port)) consumer_info.consumers ;; (** Adds a new cell to the netlist. *) let add_new_cell scope info arity = let netlist = scope.netlist in let dangle = netlist, 0 in (* Allocate memory if needed. *) if netlist.next_cell >= Array.length netlist.cells then netlist.cells <- Array.append netlist.cells (Array.make 1024 netlist.cells.(0)); let cell_id = netlist.next_cell in netlist.next_cell <- netlist.next_cell + 1; let cell = netlist, cell_id in netlist.cells.(cell_id) <- { scope = scope; info = info; producers = Array.make arity dangle; consumers = [] }; scope.items <- Cell cell :: scope.items; for i = 0 to arity - 1 do add_consumer dangle (cell, i) done; cell ;; (** Cleans up the netlist. *) let collect_garbage scope = () (* XXX *) ;; (* Scope Manipulation *) (** Creates a root scope and global netlist. *) let create_root_scope module_name = let rec netlist = { root = scope; cells = [| dangle |]; next_cell = 1 } and scope = { netlist = netlist; module_ = module_name; instance = module_name; is_root = true; parent = scope; items = [ Cell (netlist, 0) ] } and dangle = { scope = scope; info = Dangle; producers = [||]; consumers = [] } in scope ;; (** Creates a sub scope. *) let create_sub_scope parent_scope module_name instance_name = let scope = { netlist = parent_scope.netlist; module_ = module_name; instance = instance_name; is_root = false; parent = parent_scope; items = [] } in parent_scope.items <- Scope scope :: parent_scope.items; scope ;; (** Returns the parent of a scope. If the scope is root, it returns itself. *) let parent_of_scope scope = scope.parent ;; (** Returns the root scope. *) let root_of_scope scope = scope.netlist.root ;; (** Returns the items of a scope. *) let items_of_scope scope = List.rev scope.items ;; (** Returns the module name of a scope. *) let module_name_of_scope scope = scope.module_ ;; (** Returns the module name of a scope. *) let instance_name_of_scope scope = scope.instance ;; (** Returns a list of all cells. *) let all_cells scope = let netlist = scope.netlist in let rec f sofar index = if index < 0 then sofar else f ((netlist, index) :: sofar) (index - 1) in f [] (netlist.next_cell - 1) ;; (** Returns the enclosing scope of a cell. *) let scope_of_cell (netlist, cell_id) = netlist.cells.(cell_id).scope ;; let rec revpath_of_scope scope = if scope.is_root then [scope.instance] else scope.instance :: revpath_of_scope scope.parent ;; (** Retuns the hierarchical scope path of a scope. *) let path_of_scope scope = List.rev (revpath_of_scope scope) ;; (** Retuns the hierarchical scope path of a cell. *) let path_of_cell cell = path_of_scope (scope_of_cell cell) ;; (** Cell Manipulation *) (** Returns cell information. *) let info_of_cell cell = let netlist, cell_id = cell in netlist.cells.(cell_id).info ;; (** String name of cell. *) let name_of_cell cell = match info_of_cell cell with | Input _ -> "input" | Output _ -> "output" | Name _ -> "name" | Dangle -> "dangle" | Const _ -> "const" | Buf _ -> "buf" | Not _ -> "not" | And _ -> "and" | Xor _ -> "xor" | Or _ -> "or" | Concat _ -> "concat" | Select _ -> "select" | Eq _ -> "eq" | Lt _ -> "lt" | Add _ -> "add" | Sub _ -> "sub" | Mul _ -> "mul" | Mux _ -> "mux" | Ff _ -> "ff" | Ffc _ -> "ffc" | Bbox _ -> "bbox" ;; (** Output width of a cell. *) let width_of_cell cell = match info_of_cell cell with | Dangle -> raise (Error "Dangle cell does not have an output width.") | Input (_, w) -> w | Output _ -> raise (Error "Output cell does not have an output width.") | Name _ -> raise (Error "Name cell does not have an output width.") | Const s -> String.length s | Buf w | Not w | And w | Xor w | Or w -> w | Concat (a, b) -> a + b | Select _ -> 1 | Eq w | Lt w -> 1 | Add w | Sub w | Mul w | Mux w | Ff w | Ffc w -> w | Bbox (_, w, _, _) -> w ;; (** Input width of a cell port. *) let width_of_port (cell, port_num) = match info_of_cell cell with | Dangle -> raise (Invalid_argument "Dangle has no input port.") | Input _ -> raise (Invalid_argument "Input has no input port.") | Const _ -> raise (Invalid_argument "Const has no input port.") | Output (_, w) | Name (_, w) | Buf w | Not w | Select (w, _) -> if port_num = 0 then w else raise Invalid_port_number | And w | Xor w | Or w | Eq w | Lt w | Add w | Sub w | Mul w -> if port_num = 0 || port_num = 1 then w else raise Invalid_port_number | Concat (a, b) -> if port_num = 0 then a else if port_num = 1 then b else raise Invalid_port_number | Mux w -> if port_num = 0 then 1 else if port_num = 1 || port_num = 2 then w else raise Invalid_port_number | Ff w -> if port_num = 0 then 1 else if port_num = 1 then w else raise Invalid_port_number | Ffc w -> if port_num = 0 || port_num = 1 then 1 else if port_num = 2 then w else raise Invalid_port_number | Bbox (_, _, w, _) -> if port_num = 0 then w else raise Invalid_port_number ;; (** The number of input ports of a cell. *) let arity_of_cell cell = match info_of_cell cell with | Dangle | Input _ | Const _ -> 0 | Output _ | Name _ | Buf _ | Not _ | Select _ -> 1 | And _ | Xor _ | Or _ | Concat _ | Eq _ | Lt _ | Add _ | Sub _ | Mul _ -> 2 | Mux _ -> 3 | Ff _ -> 2 | Ffc _ -> 3 | Bbox _ -> 1 ;; (** Checks if port is dangling. *) let is_port_dangling ((netlist, cell_id), port_id) = let _, producer_id = netlist.cells.(cell_id).producers.(port_id) in producer_id = 0 ;; (** Checks if cell is a valid producer, i.e., not a dangle, output, or a name. *) let is_cell_producer cell = match info_of_cell cell with | Output _ | Name _ -> false | _ -> true ;; (** Ports of a cell. *) let ports_of_cell cell = let arity = arity_of_cell cell in let rec f i = if i = arity then [] else (cell, i) :: f (i + 1) in f 0 ;; (** One port of a cell. *) let port_of_cell cell num = if num >= arity_of_cell cell then raise Invalid_port_number; cell, num ;; (** Producing cell of port. *) let producer_of_port port = (netlist_of_port port).cells.(id_of_port port).producers.(num_of_port port) ;; (** Consuming ports of a cell. *) let consumers_of_cell cell = (netlist_of_cell cell).cells.(id_of_cell cell).consumers ;; (** Reconnects a cell to a port. *) let reconnect cell port = if not (is_cell_producer cell) then raise (Error ("Can not connect to a non producer cell: " ^ string_of_int (id_of_cell cell) ^ " -> " ^ string_of_int (id_of_port port) ^ "," ^ string_of_int (num_of_port port))); remove_consumer (producer_of_port port) port; add_consumer cell port; (netlist_of_port port).cells.(id_of_port port).producers.(num_of_port port) <- cell ;; (** Connects a cell to a port. Port must be dangling prior to connection. *) let connect cell port = if not (is_port_dangling port) then raise (Error "Cell port is already connected."); reconnect cell port ;; (* Cell Creation *) (** The special cell that represents unconnected inputs. *) let dangle scope = scope.netlist, 0;; (** Creates a new input cell. *) let create_input scope name width = add_new_cell scope (Input (name, width)) 0 ;; (** Creates a new output cell. *) let create_output scope name width = let cell = add_new_cell scope (Output (name, width)) 1 in cell, (cell, 0) ;; (** Creates a new signal name cell. *) let create_name scope name width = let cell = add_new_cell scope (Name (name, width)) 1 in cell, (cell, 0) ;; (** Creates a constant cell. *) let create_const scope bits = add_new_cell scope (Const bits) 0 ;; (** Creates a buffer cell. *) let create_buf scope width = let cell = add_new_cell scope (Buf width) 1 in cell, (cell, 0) ;; (** Creates a NOT gate. *) let create_not scope width = let cell = add_new_cell scope (Not width) 1 in cell, (cell, 0) ;; (** Creates a AND gate. *) let create_and scope width = let cell = add_new_cell scope (And width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates a XOR gate. *) let create_xor scope width = let cell = add_new_cell scope (Xor width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates a OR gate. *) let create_or scope width = let cell = add_new_cell scope (Or width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates a concatenation. *) let create_concat scope width_left width_right = let cell = add_new_cell scope (Concat (width_left, width_right)) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates a bit selection. *) let create_select scope width bit = if bit >= width || bit < 0 then raise (Error "Invalid bit select."); let cell = add_new_cell scope (Select (width, bit)) 1 in cell, (cell, 0) ;; (** Creates a equal comparison. *) let create_eq scope width = let cell = add_new_cell scope (Eq width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates a less than comparison. *) let create_lt scope width = let cell = add_new_cell scope (Lt width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates an adder. *) let create_add scope width = let cell = add_new_cell scope (Add width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates a subtractor. *) let create_sub scope width = let cell = add_new_cell scope (Sub width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates a multiplier. *) let create_mul scope width = let cell = add_new_cell scope (Mul width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates a mux. *) let create_mux scope width = let cell = add_new_cell scope (Mux width) 3 in cell, (cell, 0), (cell, 1), (cell, 2) ;; (** Creates an ff. *) let create_ff scope width = let cell = add_new_cell scope (Ff width) 2 in cell, (cell, 0), (cell, 1) ;; (** Creates an ffc. *) let create_ffc scope width = let cell = add_new_cell scope (Ffc width) 3 in cell, (cell, 0), (cell, 1), (cell, 2) ;; (** Creates an black box. *) let create_bbox scope name width_out width_in parameters = let cell = add_new_cell scope (Bbox (name, width_out, width_in, parameters)) 1 in cell, (cell, 0) ;; confluence-0.10.6/src/fnflib/fnf_core.mli0100644002340600244710000001062410266541661017646 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Free Netlist Format (FNF) Core Functions *) (** {2 Netlist Exceptions} *) exception Error of string;; (** {2 Netlist Types} *) type scope;; type cell;; type port;; type cell_info = Input of string * int | Output of string * int | Name of string * int | Dangle | Const of string | Buf of int | Not of int | And of int | Xor of int | Or of int | Concat of int * int | Select of int * int | Eq of int | Lt of int | Add of int | Sub of int | Mul of int | Mux of int | Ff of int | Ffc of int | Bbox of string * int * int * int list ;; type item = Scope of scope | Cell of cell;; (** {2 Scope Manipulation} *) val create_root_scope : string -> scope;; val create_sub_scope : scope -> string -> string -> scope;; (* parent, module, instance *) val parent_of_scope : scope -> scope;; val root_of_scope : scope -> scope;; val items_of_scope : scope -> item list;; val all_cells : scope -> cell list;; val module_name_of_scope : scope -> string;; val instance_name_of_scope : scope -> string;; val scope_of_cell : cell -> scope;; val path_of_scope : scope -> string list;; val path_of_cell : cell -> string list;; (** {2 Cell Manipulation} *) val info_of_cell : cell -> cell_info;; val name_of_cell : cell -> string;; val width_of_cell : cell -> int;; val width_of_port : port -> int;; val arity_of_cell : cell -> int;; val is_port_dangling : port -> bool;; val is_cell_producer : cell -> bool;; (* Not output or name. *) val id_of_cell : cell -> int;; val cell_of_port : port -> cell;; val ports_of_cell : cell -> port list;; val port_of_cell : cell -> int -> port;; val connect : cell -> port -> unit;; (* Check that source cell is not an output or a name. Raise exception if not connected to dangle. *) val reconnect : cell -> port -> unit;; (* Check that source cell is not an output or a name. *) val consumers_of_cell : cell -> port list;; val producer_of_port : port -> cell;; (* val delete_cell : cell -> unit;; val move_cell : cell -> scope;; (* Move cell to other scope. *) *) (** {2 Cell Creation} *) val dangle : scope -> cell;; val create_input : scope -> string -> int -> cell;; val create_output : scope -> string -> int -> cell * port;; val create_name : scope -> string -> int -> cell * port;; val create_const : scope -> string -> cell;; val create_buf : scope -> int -> cell * port;; val create_not : scope -> int -> cell * port;; val create_and : scope -> int -> cell * port * port;; val create_xor : scope -> int -> cell * port * port;; val create_or : scope -> int -> cell * port * port;; val create_concat : scope -> int -> int -> cell * port * port;; val create_select : scope -> int -> int -> cell * port;; val create_eq : scope -> int -> cell * port * port;; val create_lt : scope -> int -> cell * port * port;; val create_add : scope -> int -> cell * port * port;; val create_sub : scope -> int -> cell * port * port;; val create_mul : scope -> int -> cell * port * port;; val create_mux : scope -> int -> cell * port * port * port;; val create_ff : scope -> int -> cell * port * port;; val create_ffc : scope -> int -> cell * port * port * port;; val create_bbox : scope -> string -> int -> int -> int list -> cell * port;; confluence-0.10.6/src/fnflib/fnf_jhdl.ml0100644002340600244710000001770010266541662017471 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (* JHDL generator adapted from VHDL generator by Nathan Cain *) open Fnf_core;; let channel = ref stdout;; let write line = output_string !channel line; output_char !channel '\n' ;; let id_of_cell cell = "n" ^ string_of_int (id_of_cell cell) ;; let debug msg = print_string msg; print_newline () ;; let rec find_io sofar scope_item = match scope_item with | Scope scope -> List.fold_left find_io sofar (items_of_scope scope) | Cell cell -> (match info_of_cell cell with | Input _ | Output _ -> cell :: sofar | _ -> sofar ) ;; (*******************************************************) (**** Note: May not correctly support tristate values in const! ****) let output_cellinterface cell term = match info_of_cell cell with | Input (name, w) -> write (" in(\"" ^ name ^ "\", " ^ string_of_int(w) ^ ")" ^ term) | Output (name, w) -> write (" out(\"" ^ name ^ "\", " ^ string_of_int(w) ^ ")" ^ term) | _ -> raise (Invalid_argument "encountered a non-port cell") ;; let rec output_cellinterfaces cells = match cells with | [] -> () | [cell] -> output_cellinterface cell "" | cell :: cells -> output_cellinterface cell ","; output_cellinterfaces cells ;; let output_parameter cell term = match info_of_cell cell with | Input (name, w) | Output (name, w) -> write (" Wire " ^ name ^ term) | _ -> raise (Invalid_argument "encountered a non-port cell") ;; let rec output_parameters cells = match cells with | [] -> () | [cell] -> output_parameter cell "" | cell :: cells -> output_parameter cell ","; output_parameters cells ;; let output_connect cell = match info_of_cell cell with | Input (name, w) | Output (name, w) -> write (" connect(\"" ^ name ^ "\", " ^ name ^ ");") | _ -> raise (Invalid_argument "encountered a non-port cell") ;; let rec output_connects cells = match cells with | [] -> () | [cell] -> output_connect cell | cell :: cells -> output_connect cell; output_connects cells ;; let rec output_localwires scope_item = match scope_item with | Scope scope -> List.iter output_localwires (items_of_scope scope); | Cell cell -> (match info_of_cell cell with | Output _ | Name _ | Dangle -> () | _ -> write (" Wire " ^ id_of_cell cell ^ " = wire(" ^ string_of_int (width_of_cell cell) ^ ", \"" ^ id_of_cell cell ^ "\");") ) ;; let assign cell expr = write (" " ^ id_of_cell cell ^ " <= " ^ expr ^ ";") ;; let rec output_logic scope_item = match scope_item with | Scope scope -> List.iter output_logic (items_of_scope scope); | Cell cell -> let id = id_of_cell cell in let input num = let cell = producer_of_port (port_of_cell cell num) in (match info_of_cell cell with Dangle -> raise (Invalid_argument "encountered unconnected cell") | _ -> ()); id_of_cell cell in (match info_of_cell cell with | Input (name, w) -> write (" //Input: " ^ id); write (" buf_o(" ^ name ^ ", " ^ id ^ ", \"Input_" ^ id ^ "\");") | Output (name, w) -> write (" //Output: " ^ id); write (" buf_o(" ^ input 0 ^ ", " ^ name ^ ", \"Output_" ^ id ^ "\");") | Name (name, w) -> write (" //Name: " ^ id) | Dangle -> write (" //Dangle: " ^ id) | Const value -> write (" //Const: " ^ id); write (" constant_o(" ^ id ^ ", new BV(\"0b" ^ value ^ "\"), \"Const_" ^ id ^ "\");") | Buf w -> write (" //Buf: " ^ id); write (" buf_o(" ^ input 0 ^ ", " ^ id ^ ", \"Buf_" ^ id ^ "\");") | Not w -> write (" //Not: " ^ id); write (" not_o(" ^ input 0 ^ ", " ^ id ^ ", \"Not_" ^ id ^ "\");") | And w -> write (" //And: " ^ id); write (" and_o(" ^ input 0 ^ ", " ^ input 1 ^ ", " ^ id ^ ", \"And_" ^ id ^ "\");") | Xor w -> write (" //Xor: " ^ id); write (" xor_o(" ^ input 0 ^ ", " ^ input 1 ^ ", " ^ id ^ ", \"Xor_" ^ id ^ "\");") | Or w -> write (" //Or: " ^ id); write (" or_o(" ^ input 0 ^ ", " ^ input 1 ^ ", " ^ id ^ ", \"Or_" ^ id ^ "\");") | Concat (wl, wr) -> write (" //Concat: " ^ id); write (" concat_o(" ^ input 0 ^ ", " ^ input 1 ^ ", " ^ id ^ ", \"Concat_" ^ id ^ "\");") | Select (w, bit) -> write (" //Select: " ^ id); write (" WireList " ^ id ^ "_temp = new WireList();"); write (" " ^ id ^ "_temp.append( " ^ input 0 ^ ".gw(" ^ string_of_int bit ^ "));"); write (" concat_o(" ^ id ^ "_temp, " ^ id ^ ", \"Select_" ^ id ^ "\");") | Eq w -> write (" //Eq: " ^ id); write (" new eq(this, " ^ input 0 ^ ", " ^ input 1 ^ ", " ^ id ^ ", \"Eq_" ^ id ^ "\");") | Lt w -> write (" //Lt: " ^ id); write (" new lt(this, " ^ input 0 ^ ", " ^ input 1 ^ ", false, " ^ id ^ ", \"Lt_" ^ id ^ "\");") | Add w -> write (" //Add: " ^ id); write (" add_o(" ^ input 0 ^ ", " ^ input 1 ^ ", " ^ id ^ ", \"Add_" ^ id ^ "\");") | Sub w -> write (" //Sub: " ^ id); write (" sub_o(" ^ input 0 ^ ", " ^ input 1 ^ ", " ^ id ^ ", \"Sub_" ^ id ^ "\");") | Mul w -> write (" //Mul: " ^ id); write (" new arrayMult(this, " ^ input 0 ^ ", " ^ input 1 ^ ", null, " ^ id ^ ", false, 0, \"Mul_" ^ id ^ "\");") | Mux w -> write (" //Mux: " ^ id); write (" mux_o(" ^ input 1 ^ ", " ^ input 2 ^ ", " ^ input 0 ^ ", " ^ id ^ ", \"Mux_" ^ id ^ "\");") | Ff w -> write (" //Ff: " ^ id); write (" regc_o(" ^ input 0 ^ ", " ^ input 1 ^ ", " ^ id ^ ", \"Ff_" ^ id ^ "\");") | Ffc w -> write (" //Ffc: " ^ id); write (" regr_o(" ^ input 1 ^ ", " ^ input 2 ^ ", " ^ input 0 ^ ", " ^ id ^ ", \"Ffc_" ^ id ^ "\");") | Bbox _ -> raise (Invalid_argument "Black-boxes not supported in JHDL code generation.") ) ;; let output_jhdl file out_channel scope = channel := out_channel; let scope_item = Scope (root_of_scope scope) in let ports = find_io [] scope_item in write ("import byucc.jhdl.base.*;"); write ("import byucc.jhdl.Logic.*;"); write ("import byucc.jhdl.Logic.Modules.*;"); write (" "); write ("public class " ^ file ^ " extends Logic"); write ("{"); write (" "); write (" public static CellInterface[] cell_interface = {"); output_cellinterfaces ports; write (" };"); write (""); (* Note: generation of the constructor's parameter list requires at least 1 port... can/will there be an fnf with no ports? Only if there's no system instantiated in the cf.... but what good is that?*) write (" public " ^ file); write (" ("); write (" Node parent,"); output_parameters ports; write (" )"); write (" {"); write (" "); write (" super(parent);"); write (" "); output_connects ports; write (" "); output_localwires scope_item; write (" "); write (" "); output_logic scope_item; write (" "); write (" }"); write ("}"); ;; confluence-0.10.6/src/fnflib/fnf_jhdl.mli0100644002340600244710000000170310266541662017636 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (* JHDL generator adapted from VHDL generator by Nathan Cain *) open Fnf_core;; val output_jhdl : string -> out_channel -> scope -> unit;; confluence-0.10.6/src/fnflib/fnf_lexer.mll0100644002340600244710000000763010266541662020044 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) { (* Pre code. *) } (* Whitespace *) let white_space = [' ' '\t' '\r' '\n'] (* Comments *) let comment = ';' [^ '\n']* '\n' (* Integers *) let dec_digit = ['0' - '9'] let integer = dec_digit+ (* Strings *) let string_char = [^'"' '\\'] | ('\\' _) let string = '"' string_char* '"' rule token = parse | "(" { Fnf_parser.Parenl (Parser_util.next_lex lexbuf) } | ")" { Fnf_parser.Parenr (Parser_util.next_lex lexbuf) } | "scope" { Fnf_parser.Scope (Parser_util.next_lex lexbuf) } | "input" { Fnf_parser.Input (Parser_util.next_lex lexbuf) } | "output" { Fnf_parser.Output (Parser_util.next_lex lexbuf) } | "name" { Fnf_parser.Name (Parser_util.next_lex lexbuf) } | "dangle" { Fnf_parser.Dangle (Parser_util.next_lex lexbuf) } | "const" { Fnf_parser.Const (Parser_util.next_lex lexbuf) } | "buf" { Fnf_parser.Buf (Parser_util.next_lex lexbuf) } | "not" { Fnf_parser.Not (Parser_util.next_lex lexbuf) } | "and" { Fnf_parser.And (Parser_util.next_lex lexbuf) } | "xor" { Fnf_parser.Xor (Parser_util.next_lex lexbuf) } | "or" { Fnf_parser.Or (Parser_util.next_lex lexbuf) } | "concat" { Fnf_parser.Concat (Parser_util.next_lex lexbuf) } | "select" { Fnf_parser.Select (Parser_util.next_lex lexbuf) } | "eq" { Fnf_parser.Eq (Parser_util.next_lex lexbuf) } | "lt" { Fnf_parser.Lt (Parser_util.next_lex lexbuf) } | "add" { Fnf_parser.Add (Parser_util.next_lex lexbuf) } | "sub" { Fnf_parser.Sub (Parser_util.next_lex lexbuf) } | "mul" { Fnf_parser.Mul (Parser_util.next_lex lexbuf) } | "mux" { Fnf_parser.Mux (Parser_util.next_lex lexbuf) } | "ff" { Fnf_parser.Ff (Parser_util.next_lex lexbuf) } | "ffc" { Fnf_parser.Ffc (Parser_util.next_lex lexbuf) } | "bbox" { Fnf_parser.Bbox (Parser_util.next_lex lexbuf) } | integer { Fnf_parser.Integer (Parser_util.next_lex lexbuf) } | string { Fnf_parser.String (Parser_util.next_lex lexbuf) } | eof { Fnf_parser.EOF (Parser_util.next_lex lexbuf) } | comment { let _ = Parser_util.next_lex lexbuf in token lexbuf } | white_space { let _ = Parser_util.next_lex lexbuf in token lexbuf } | _ { let token = Parser_util.next_lex lexbuf in Parser_util.error ("Unrecognized character: '" ^ (fst token) ^ "'"); Fnf_parser.Lexer_error token } { (* Post code. *) } confluence-0.10.6/src/fnflib/fnf_nusmv.ml0100644002340600244710000002524710266541662017725 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; let debug msg = print_string msg; print_newline () ;; let channel = ref stdout;; let level = ref 0;; let write line = for i = 1 to !level do output_string !channel " " done; output_string !channel line; output_char !channel '\n' ;; let id_of_cell cell = "n" ^ string_of_int (id_of_cell cell) ;; let iter count func = for i = 0 to count - 1 do func ("_" ^ string_of_int i) done ;; let join count func delimiter = let rec f bit str = if bit >= count then str else f (bit + 1) (str ^ delimiter ^ func ("_" ^ string_of_int bit)) in f 1 (func "_0") ;; let if_expr pred on_true on_false = "case " ^ pred ^ " : " ^ on_true ^ "; 1 : " ^ on_false ^ "; esac" ;; (** Adder used for add and mul.*) let add label_x label_a label_b msb lsb = let rec add is_msb bit = if bit < lsb then raise (Invalid_argument "add"); let xout = label_x bit in let cout = label_x bit ^ "_c" in let temp = label_x bit ^ "_t" in let cin = if bit = lsb then "0" else add false (bit - 1) in if is_msb then write ("DEFINE " ^ xout ^ " := " ^ label_a bit ^ " xor " ^ label_b bit ^ " xor " ^ cin ^ ";") else begin write ("DEFINE " ^ temp ^ " := " ^ label_a bit ^ " xor " ^ label_b bit ^ ";"); write ("DEFINE " ^ cout ^ " := (" ^ temp ^ " & " ^ cin ^ ") | (" ^ label_a bit ^ " & " ^ label_b bit ^ ");"); write ("DEFINE " ^ xout ^ " := " ^ temp ^ " xor " ^ cin ^ ";") end; cout in let _ = add true msb in () ;; (** NuSMV Data Representation For 2-value model: _ *) let rec output_scope_item scope_item = match scope_item with | Scope scope -> write ("--(scope " ^ module_name_of_scope scope ^ " " ^ instance_name_of_scope scope); incr level; List.iter output_scope_item (items_of_scope scope); decr level; write ("--)") | Cell cell -> let id = id_of_cell cell in let input num = let cell = producer_of_port (port_of_cell cell num) in (match info_of_cell cell with Dangle -> raise (Invalid_argument "encountered unconnected cell") | _ -> ()); id_of_cell cell in (match info_of_cell cell with | Input (name, w) -> write ("-- input " ^ name); iter w (fun bit -> write ("IVAR " ^ id ^ bit ^ "_input : boolean;"); write ("VAR " ^ id ^ bit ^ " : boolean;"); write ("ASSIGN init(" ^ id ^ bit ^ ") := 0;"); write ("ASSIGN next(" ^ id ^ bit ^ ") := " ^ id ^ bit ^ "_input;"); ) | Output (name, w) -> write ("-- output " ^ name ^ " " ^ input 0); write ("SPEC AG " ^ join w (fun bit -> input 0 ^ bit) " | " ^ ";") | Name (name, w) -> write ("-- name " ^ name ^ " " ^ input 0) | Dangle -> () | Const value -> write ("-- const \"" ^ value ^ "\""); let len = String.length value in for i = 0 to len - 1 do let c = value.[len - 1 - i] in write ("DEFINE " ^ id ^ "_" ^ string_of_int i ^ " := " ^ (if c = '1' then "1" else if c = '0' then "0" else raise (Invalid_argument "invalid constant string")) ^ ";"); done | Buf w -> write ("-- buf"); iter w (fun bit -> write ("DEFINE " ^ id ^ bit ^ " := " ^ input 0 ^ bit ^ ";")) | Not w -> write ("-- not"); iter w (fun bit -> write ("DEFINE " ^ id ^ bit ^ " := ! " ^ input 0 ^ bit ^ ";")) | And w -> write ("-- and"); iter w (fun bit -> write ("DEFINE " ^ id ^ bit ^ " := " ^ input 0 ^ bit ^ " & " ^ input 1 ^ bit ^ ";")) | Xor w -> write ("-- xor"); iter w (fun bit -> write ("DEFINE " ^ id ^ bit ^ " := " ^ input 0 ^ bit ^ " xor " ^ input 1 ^ bit ^ ";")) | Or w -> write ("-- or"); iter w (fun bit -> write ("DEFINE " ^ id ^ bit ^ " := " ^ input 0 ^ bit ^ " | " ^ input 1 ^ bit ^ ";")) | Concat (wl, wr) -> write ("-- concat"); iter wr (fun bit -> write ("DEFINE " ^ id ^ bit ^ " := " ^ input 1 ^ bit ^ ";")); for i = wr to wr + wl - 1 do write ("DEFINE " ^ id ^ "_" ^ string_of_int i ^ " := " ^ input 0 ^ "_" ^ string_of_int (i - wr) ^ ";") done | Select (w, bit) -> write ("-- select"); write ("DEFINE " ^ id ^ "_0 := " ^ input 0 ^ "_" ^ string_of_int bit ^ ";"); | Eq w -> let rec eq bit = if bit < 0 then [] else ("(" ^ input 0 ^ "_" ^ string_of_int bit ^ " <-> " ^ input 1 ^ "_" ^ string_of_int bit ^ ")") :: eq (bit - 1) in write ("-- eq " ^ id ^ " = " ^ input 0 ^ " == " ^ input 1); write ("DEFINE " ^ id ^ "_0 := " ^ String2.join (eq (w - 1)) " & " ^ ";") | Lt w -> let rec lt bit = let expr = id ^ "_" ^ string_of_int bit ^ "_c" in if bit = 0 then write ("DEFINE " ^ expr ^ " := ! " ^ input 0 ^ "_0 & " ^ input 1 ^ "_0;") else begin let c = lt (bit - 1) in let bit = "_" ^ string_of_int bit in write ("DEFINE " ^ expr ^ " := (" ^ input 1 ^ bit ^ " & " ^ c ^ ") | (" ^ input 1 ^ bit ^ " & ! " ^ input 0 ^ bit ^ ") | (" ^ c ^ " & ! " ^ input 0 ^ bit ^ ");") end; expr in write ("-- lt " ^ id ^ " = " ^ input 0 ^ " < " ^ input 1); write ("DEFINE " ^ id ^ "_0 := " ^ lt (w - 1) ^ ";") | Add w -> write ("-- add " ^ id ^ " = " ^ input 0 ^ " + " ^ input 1); add (fun bit -> id ^ "_" ^ string_of_int bit) (fun bit -> (input 0) ^ "_" ^ string_of_int bit) (fun bit -> (input 1) ^ "_" ^ string_of_int bit) (w - 1) 0 | Sub w -> let rec sub bit = let xout = id ^ "_" ^ string_of_int bit in let cout = id ^ "_" ^ string_of_int bit ^ "_c" in let temp = id ^ "_" ^ string_of_int bit ^ "_t" in let cin = if bit = 0 then "0" else sub (bit - 1) in let bit = "_" ^ string_of_int bit in write ("DEFINE " ^ temp ^ " := ! " ^ input 0 ^ bit ^ ";"); write ("DEFINE " ^ cout ^ " := (" ^ input 1 ^ bit ^ " & " ^ cin ^ ") | (" ^ temp ^ " & " ^ input 1 ^ bit ^ ") | (" ^ temp ^ " & " ^ cin ^ ");"); write ("DEFINE " ^ xout ^ " := " ^ input 0 ^ bit ^ " xor " ^ input 1 ^ bit ^ " xor " ^ cin ^ ";"); cout in write ("-- sub " ^ id ^ " = " ^ input 0 ^ " - " ^ input 1); let _ = sub (w - 1) in () | Mul w -> write ("-- mul " ^ id ^ " = " ^ input 0 ^ " * " ^ input 1); let rec f1 a = let rec f2 a b = if a >= 0 then begin write ("DEFINE " ^ id ^ "_bitand_" ^ string_of_int a ^ "_" ^ string_of_int b ^ " := " ^ input 0 ^ "_" ^ string_of_int a ^ " & " ^ input 1 ^ "_" ^ string_of_int b ^ ";"); f2 (a - 1) (b + 1) end in if a >= 0 then begin f2 a 0; f1 (a - 1) end in f1 (w - 1); let rec accum label bit_a = let bit = "_" ^ string_of_int bit_a in write ("DEFINE " ^ id ^ bit ^ " := " ^ label ^ bit ^ ";"); let bit_a = bit_a + 1 in let bit_a_str = "_" ^ string_of_int bit_a in if bit_a < w then begin let new_label = id ^ "_accum" ^ bit_a_str in add (fun bit -> new_label ^ "_" ^ string_of_int bit) (fun bit -> label ^ "_" ^ string_of_int bit) (fun bit -> id ^ "_bitand" ^ bit_a_str ^ "_" ^ string_of_int (bit - bit_a)) (w - 1) bit_a; accum new_label bit_a end in accum (id ^ "_bitand_0") 0 | Mux w -> write ("-- mux"); (* write ("SPEC E [1 U " ^ input 0 ^ "_0] & E [1 U ! " ^ input 0 ^ "_0];"); *) iter w (fun bit -> write ("DEFINE " ^ id ^ bit ^ " := " ^ if_expr (input 0 ^ "_0") (input 2 ^ bit) (input 1 ^ bit) ^ ";")) | Ff w -> let clock = input 0 ^ "_0" in let clock_state = id ^ "_clock_state" in write ("-- ff"); write ("VAR " ^ clock_state ^ " : boolean;"); write ("ASSIGN init(" ^ clock_state ^ ") := 1;"); write ("ASSIGN next(" ^ clock_state ^ ") := " ^ clock ^ ";"); iter w (fun bit -> write ("VAR " ^ id ^ bit ^ " : boolean;"); write ("ASSIGN init(" ^ id ^ bit ^ ") := 0;"); write ("ASSIGN next(" ^ id ^ bit ^ ") := " ^ if_expr (clock ^ " & ! " ^ clock_state) (input 1 ^ bit) (id ^ bit) ^ ";"); ) | Ffc w -> let clear = input 0 ^ "_0" in let clear_state = id ^ "_clear_state" in let clock = input 1 ^ "_0" in let clock_state = id ^ "_clock_state" in write ("-- ffc"); write ("VAR " ^ clear_state ^ " : boolean;"); write ("ASSIGN init(" ^ clear_state ^ ") := 1;"); write ("ASSIGN next(" ^ clear_state ^ ") := " ^ clear ^ ";"); write ("VAR " ^ clock_state ^ " : boolean;"); write ("ASSIGN init(" ^ clock_state ^ ") := 1;"); write ("ASSIGN next(" ^ clock_state ^ ") := " ^ clock ^ ";"); iter w (fun bit -> write ("VAR " ^ id ^ bit ^ " : boolean;"); write ("ASSIGN init(" ^ id ^ bit ^ ") := 0;"); write ("ASSIGN next(" ^ id ^ bit ^ ") := " ^ if_expr (clear ^ " & ! " ^ clear_state) "0" (if_expr (clock ^ " & ! " ^ clock_state) (input 2 ^ bit) (id ^ bit)) ^ ";"); ) | Bbox _ -> raise (Invalid_argument "Black-boxes not supported in NuSMV code generation.") ) ;; let output_nusmv out_channel scope = channel := out_channel; level := 0; let scope_item = Scope (root_of_scope scope) in write ("MODULE main"); output_scope_item scope_item; ;; confluence-0.10.6/src/fnflib/fnf_nusmv.mli0100644002340600244710000000156410266541662020072 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; val output_nusmv : out_channel -> scope -> unit;; confluence-0.10.6/src/fnflib/fnf_out.ml0100644002340600244710000001041410266541662017352 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; let channel = ref stdout;; let is_compact = ref false;; let level = ref 0;; let write line = if not !is_compact then output_string !channel (String.make (!level * 2) ' '); output_string !channel line; output_char !channel '\n' ;; let format_string string = let len = String.length string in let rec r i sofar = if i >= len then sofar else r (i + 1) (sofar ^ (match string.[i] with '\\' -> "\\\\" | '"' -> "\\\"" | c -> String.make 1 c)) in "\"" ^ r 0 "" ^ "\"" ;; let rec output_scope_item scope_item = match scope_item with | Scope scope -> write ("(scope " ^ format_string (module_name_of_scope scope) ^ " " ^ format_string (instance_name_of_scope scope) ^ " ("); incr level; List.iter output_scope_item (items_of_scope scope); decr level; write ("))") | Cell cell -> let id_of_cell cell = string_of_int (id_of_cell cell) in let id = id_of_cell cell ^ " " in let rec inputs i = if i >= arity_of_cell cell then "" else " " ^ id_of_cell (producer_of_port (port_of_cell cell i)) ^ inputs (i + 1) in let inputs = inputs 0 in (match info_of_cell cell with | Input (name, w) -> write ("(input " ^ id ^ format_string name ^ " " ^ string_of_int w ^ ")") | Output (name, w) -> write ("(output " ^ id ^ format_string name ^ " " ^ string_of_int w ^ inputs ^ ")") | Name (name, w) -> write ("(name " ^ id ^ format_string name ^ " " ^ string_of_int w ^ inputs ^ ")") | Dangle -> write ("(dangle " ^ id_of_cell cell ^ ")") | Const value -> write ("(const " ^ id ^ format_string value ^ ")") | Buf w -> write ("(buf " ^ id ^ string_of_int w ^ inputs ^ ")") | Not w -> write ("(not " ^ id ^ string_of_int w ^ inputs ^ ")") | And w -> write ("(and " ^ id ^ string_of_int w ^ inputs ^ ")") | Xor w -> write ("(xor " ^ id ^ string_of_int w ^ inputs ^ ")") | Or w -> write ("(or " ^ id ^ string_of_int w ^ inputs ^ ")") | Concat (wl, wr) -> write ("(concat " ^ id ^ string_of_int wl ^ " " ^ string_of_int wr ^ inputs ^ ")") | Select (w, bit) -> write ("(select " ^ id ^ string_of_int w ^ " " ^ string_of_int bit ^ " " ^ inputs ^ ")") | Eq w -> write ("(eq " ^ id ^ string_of_int w ^ inputs ^ ")") | Lt w -> write ("(lt " ^ id ^ string_of_int w ^ inputs ^ ")") | Add w -> write ("(add " ^ id ^ string_of_int w ^ inputs ^ ")") | Sub w -> write ("(sub " ^ id ^ string_of_int w ^ inputs ^ ")") | Mul w -> write ("(mul " ^ id ^ string_of_int w ^ inputs ^ ")") | Mux w -> write ("(mux " ^ id ^ string_of_int w ^ inputs ^ ")") | Ff w -> write ("(ff " ^ id ^ string_of_int w ^ inputs ^ ")") | Ffc w -> write ("(ffc " ^ id ^ string_of_int w ^ inputs ^ ")") | Bbox (n, wo, wi, p) -> write ("(bbox " ^ id ^ format_string n ^ " " ^ string_of_int wo ^ " " ^ string_of_int wi ^ " (" ^ String2.join (List.map string_of_int p) " " ^ ")" ^ inputs ^ ")") ) ;; let output_fnf out_channel scope = channel := out_channel; is_compact := false; level := 0; output_scope_item (Scope (root_of_scope scope)) ;; let output_fnf_compact out_channel scope = channel := out_channel; is_compact := true; level := 0; output_scope_item (Scope (root_of_scope scope)) ;; confluence-0.10.6/src/fnflib/fnf_out.mli0100644002340600244710000000172310266541662017526 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** {2 FNF Output Functions} *) open Fnf_core;; val output_fnf : out_channel -> scope -> unit;; val output_fnf_compact : out_channel -> scope -> unit;; confluence-0.10.6/src/fnflib/fnf_parser.mly0100644002340600244710000001744510266541662020243 0ustar hawkit1cadgrp/* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ %{ (* Pre Code *) open Fnf_core;; let parse_error s = Parser_util.error ("Unexpected token: '" ^ (Parser_util.get_current_token ()) ^ "'") ;; let debug msg = print_string msg; print_newline () ;; let format_string str = let str = String.sub str 1 (String.length str - 2) in let len = String.length str in let rec format_string sofar i = if i >= len then sofar else match str.[i] with | '\\' -> format_string (sofar ^ String.make 1 '\\' ^ String.make 1 str.[i + 1]) (i + 2) | c -> format_string (sofar ^ String.make 1 c) (i + 1) in format_string "" 0 ;; let scope_stack = ref [];; let current_scope () = List.hd !scope_stack ;; let push_scope scope = scope_stack := scope :: !scope_stack ;; let pop_scope () = scope_stack := List.tl !scope_stack ;; let is_root_scope () = !scope_stack = [] ;; let id_cell_table = Hashtbl.create 1024;; let port_id_table = Hashtbl.create 1024;; let clear_tables () = scope_stack := []; Hashtbl.clear id_cell_table; Hashtbl.clear port_id_table ;; let add_cell id cell = if Hashtbl.mem id_cell_table id then Parser_util.error ("Duplicate cell ID: " ^ string_of_int id) else Hashtbl.add id_cell_table id cell ;; let add_port port id = Hashtbl.add port_id_table port id ;; let connect_ports () = Hashtbl.iter (fun port id -> try connect (Hashtbl.find id_cell_table id) port with Not_found -> Parser_util.error ("Reference cell ID not found: " ^ string_of_int id) ) port_id_table; ;; %} // FNF Keywords and Symbols %token Parenl %token Parenr %token Scope %token Input %token Output %token Name %token Dangle %token Const %token Buf %token Not %token And %token Xor %token Or %token Concat %token Select %token Eq %token Lt %token Add %token Sub %token Mul %token Mux %token Ff %token Ffc %token Bbox %token Integer %token String %token EOF %token Lexer_error %start netlist %type netlist %% netlist : scope { connect_ports (); let scope = current_scope () in clear_tables (); scope } ; scope : Parenl Scope scope_name Parenl scope_items Parenr Parenr { () } ; scope_name : name name { push_scope (if is_root_scope () then create_root_scope $1 else create_sub_scope (current_scope ()) $1 $2) } ; scope_items : { () } | scope_items scope_item { () } ; scope_item : scope { pop_scope () } | cell { () } ; string : String { format_string (fst $1) } ; integer : Integer { int_of_string (fst $1) } ; integers_0 : { [] } | integers_0 integer { $2 :: $1 } ; integers : integers_0 { List.rev $1 } width : integer { $1 } ; name : string { $1 } ; id : integer { $1 } ; bit : integer { $1 } ; cell : Parenl Input id name width Parenr { let cell = create_input (current_scope ()) $4 $5 in add_cell $3 cell } | Parenl Output id name width id Parenr { let cell, data = create_output (current_scope ()) $4 $5 in add_cell $3 cell; add_port data $6 } | Parenl Name id name width id Parenr { let cell, data = create_name (current_scope ()) $4 $5 in add_cell $3 cell; add_port data $6 } | Parenl Dangle id Parenr { add_cell $3 (dangle (current_scope ())) } | Parenl Const id string Parenr { let cell = create_const (current_scope ()) $4 in add_cell $3 cell } | Parenl Buf id width id Parenr { let cell, data = create_buf (current_scope ()) $4 in add_cell $3 cell; add_port data $5 } | Parenl Not id width id Parenr { let cell, data = create_not (current_scope ()) $4 in add_cell $3 cell; add_port data $5 } | Parenl And id width id id Parenr { let cell, left, right = create_and (current_scope ()) $4 in add_cell $3 cell; add_port left $5; add_port right $6 } | Parenl Xor id width id id Parenr { let cell, left, right = create_xor (current_scope ()) $4 in add_cell $3 cell; add_port left $5; add_port right $6 } | Parenl Or id width id id Parenr { let cell, left, right = create_or (current_scope ()) $4 in add_cell $3 cell; add_port left $5; add_port right $6 } | Parenl Concat id width width id id Parenr { let cell, left, right = create_concat (current_scope ()) $4 $5 in add_cell $3 cell; add_port left $6; add_port right $7 } | Parenl Select id width bit id Parenr { let cell, data = create_select (current_scope ()) $4 $5 in add_cell $3 cell; add_port data $6 } | Parenl Eq id width id id Parenr { let cell, left, right = create_eq (current_scope ()) $4 in add_cell $3 cell; add_port left $5; add_port right $6 } | Parenl Lt id width id id Parenr { let cell, left, right = create_lt (current_scope ()) $4 in add_cell $3 cell; add_port left $5; add_port right $6 } | Parenl Add id width id id Parenr { let cell, left, right = create_add (current_scope ()) $4 in add_cell $3 cell; add_port left $5; add_port right $6 } | Parenl Sub id width id id Parenr { let cell, left, right = create_sub (current_scope ()) $4 in add_cell $3 cell; add_port left $5; add_port right $6 } | Parenl Mul id width id id Parenr { let cell, left, right = create_mul (current_scope ()) $4 in add_cell $3 cell; add_port left $5; add_port right $6 } | Parenl Mux id width id id id Parenr { let cell, select, data_0, data_1 = create_mux (current_scope ()) $4 in add_cell $3 cell; add_port select $5; add_port data_0 $6; add_port data_1 $7 } | Parenl Ff id width id id Parenr { let cell, clock, data = create_ff (current_scope ()) $4 in add_cell $3 cell; add_port clock $5; add_port data $6 } | Parenl Ffc id width id id id Parenr { let cell, clear, clock, data = create_ffc (current_scope ()) $4 in add_cell $3 cell; add_port clear $5; add_port clock $6; add_port data $7 } | Parenl Bbox id string width width Parenl integers Parenr id Parenr { let cell, data = create_bbox (current_scope ()) $4 $5 $6 $8 in add_cell $3 cell; add_port data $10 } ; %% (* Post Code *) confluence-0.10.6/src/fnflib/fnf_verilog.ml0100644002340600244710000001147310266541662020220 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; let channel = ref stdout;; let write line = output_string !channel line; output_char !channel '\n' ;; let id_of_cell cell = "n" ^ string_of_int (id_of_cell cell) ;; let debug msg = print_string msg; print_newline () ;; let assign cell expr = write (" assign " ^ id_of_cell cell ^ " = " ^ expr ^ ";") ;; let rec output_scope_item scope_item = match scope_item with | Scope scope -> List.iter output_scope_item (items_of_scope scope); | Cell cell -> let id = id_of_cell cell in let input num = let cell = producer_of_port (port_of_cell cell num) in (match info_of_cell cell with Dangle -> raise (Invalid_argument "encountered unconnected cell") | _ -> ()); id_of_cell cell in (match info_of_cell cell with | Input (name, w) -> assign cell name | Output (name, w) -> write (" assign " ^ name ^ " = " ^ input 0 ^ ";") | Name (name, w) -> () | Dangle -> () | Const value -> assign cell (string_of_int (String.length value) ^ "'b" ^ value) | Buf w -> assign cell (input 0) | Not w -> assign cell ("~ " ^ input 0) | And w -> assign cell (input 0 ^ " & " ^ input 1) | Xor w -> assign cell (input 0 ^ " ^ " ^ input 1) | Or w -> assign cell (input 0 ^ " | " ^ input 1) | Concat (wl, wr) -> assign cell ("{" ^ input 0 ^ ", " ^ input 1 ^ "}") | Select (w, bit) -> if w = 1 then assign cell (input 0) else assign cell (input 0 ^ "[" ^ string_of_int bit ^ "]") | Eq w -> assign cell (input 0 ^ " == " ^ input 1) | Lt w -> assign cell (input 0 ^ " < " ^ input 1) | Add w -> assign cell (input 0 ^ " + " ^ input 1) | Sub w -> assign cell (input 0 ^ " - " ^ input 1) | Mul w -> assign cell (input 0 ^ " * " ^ input 1) | Mux w -> assign cell (input 0 ^ " ? " ^ input 2 ^ " : " ^ input 1) | Ff w -> write (" always @ (posedge " ^ input 0 ^ ") " ^ id ^ " <= " ^ input 1 ^ ";") | Ffc w -> write (" always @ (posedge " ^ input 0 ^ " or posedge " ^ input 1 ^ ") if (" ^ input 0 ^ ") " ^ id ^ " <= {" ^ string_of_int w ^ "{1'b0}}; else " ^ id ^ " <= " ^ input 2 ^ ";") | Bbox (n, wo, wi, p) -> write (" " ^ n ^ " #(" ^ String2.join (List.map string_of_int (wo :: wi :: p)) ", " ^ ") " ^ id ^ "_i (" ^ id ^ ", " ^ input 0 ^ ");") ) ;; let rec find_io sofar scope_item = match scope_item with | Scope scope -> List.fold_left find_io sofar (items_of_scope scope) | Cell cell -> (match info_of_cell cell with | Input (name, _) | Output (name, _) -> name :: sofar | _ -> sofar ) ;; let rec output_io_declarations scope_item = match scope_item with | Scope scope -> List.iter output_io_declarations (items_of_scope scope); | Cell cell -> (match info_of_cell cell with | Input (name, w) -> write (" input " ^ (if w = 1 then "" else "[" ^ string_of_int (w - 1) ^ ":0] ") ^ name ^ ";") | Output (name, w) -> write (" output " ^ (if w = 1 then "" else "[" ^ string_of_int (w - 1) ^ ":0] ") ^ name ^ ";") | _ -> () ) ;; let rec output_local_declarations scope_item = match scope_item with | Scope scope -> List.iter output_local_declarations (items_of_scope scope); | Cell cell -> (match info_of_cell cell with | Output _ | Name _ | Dangle -> () | Ff w | Ffc w -> write (" reg [" ^ string_of_int (w - 1) ^ ":0] " ^ id_of_cell cell ^ ";") | _ -> write (" wire [" ^ string_of_int (width_of_cell cell - 1) ^ ":0] " ^ id_of_cell cell ^ ";") ) ;; let output_verilog out_channel scope = channel := out_channel; let scope_item = Scope (root_of_scope scope) in write ("module " ^ module_name_of_scope scope ^ "(" ^ String2.join (find_io [] scope_item) ", " ^ ");"); output_io_declarations scope_item; output_local_declarations scope_item; output_scope_item scope_item; write ("endmodule") ;; confluence-0.10.6/src/fnflib/fnf_verilog.mli0100644002340600244710000000156610266541662020373 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; val output_verilog : out_channel -> scope -> unit;; confluence-0.10.6/src/fnflib/fnf_vhdl.ml0100644002340600244710000001676610312275627017515 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; let channel = ref stdout;; let write line = output_string !channel line; output_char !channel '\n' ;; let id_of_cell cell = "n" ^ string_of_int (id_of_cell cell) ;; let debug msg = print_string msg; print_newline () ;; let assign cell expr = write (" " ^ id_of_cell cell ^ " <= " ^ expr ^ ";") ;; let rec output_scope_item scope_item = match scope_item with | Scope scope -> List.iter output_scope_item (items_of_scope scope); | Cell cell -> let id = id_of_cell cell in let input num = let cell = producer_of_port (port_of_cell cell num) in (match info_of_cell cell with Dangle -> raise (Invalid_argument "encountered unconnected cell") | _ -> ()); id_of_cell cell in (match info_of_cell cell with | Input (name, w) -> if w = 1 then write (" " ^ id ^ " <= \"1\" when " ^ name ^ " = '1' else \"0\";") else assign cell ("unsigned(" ^ name ^ ")") | Output (name, w) -> if w = 1 then write (" " ^ name ^ " <= '1' when " ^ input 0 ^ " = \"1\" else '0';") else write (" " ^ name ^ " <= std_logic_vector(" ^ input 0 ^ ");") | Name (name, w) -> () | Dangle -> () | Const value -> assign cell ("\"" ^ value ^ "\"") | Buf w -> assign cell (input 0) | Not w -> assign cell ("not " ^ input 0) | And w -> assign cell (input 0 ^ " and " ^ input 1) | Xor w -> assign cell (input 0 ^ " xor " ^ input 1) | Or w -> assign cell (input 0 ^ " or " ^ input 1) | Concat (wl, wr) -> assign cell (input 0 ^ " & " ^ input 1) | Select (w, bit) -> assign cell (input 0 ^ "(" ^ string_of_int bit ^ " downto " ^ string_of_int bit ^ ")") | Eq w -> assign cell ("\"1\" when " ^ input 0 ^ " = " ^ input 1 ^ " else \"0\"") | Lt w -> assign cell ("\"1\" when " ^ input 0 ^ " < " ^ input 1 ^ " else \"0\"") | Add w -> assign cell (input 0 ^ " + " ^ input 1) | Sub w -> assign cell (input 0 ^ " - " ^ input 1) | Mul w -> assign cell ("resize(" ^ input 0 ^ " * " ^ input 1 ^ ", " ^ string_of_int w ^ ")") | Mux w -> assign cell (input 2 ^ " when " ^ input 0 ^ " = \"1\" else " ^ input 1) | Ff w -> write (" " ^ id ^ "_clk <= '1' when " ^ input 0 ^ " = \"1\" else '0';"); write (" process (" ^ id ^ "_clk)"); write (" begin"); write (" if rising_edge(" ^ id ^ "_clk) then"); write (" " ^ id ^ " <= " ^ input 1 ^ ";"); write (" end if;"); write (" end process;") | Ffc w -> write (" " ^ id ^ "_clr <= '1' when " ^ input 0 ^ " = \"1\" else '0';"); write (" " ^ id ^ "_clk <= '1' when " ^ input 1 ^ " = \"1\" else '0';"); write (" process (" ^ id ^ "_clr, " ^ id ^ "_clk)"); write (" begin"); write (" if rising_edge(" ^ id ^ "_clr) then"); write (" " ^ id ^ " <= \"" ^ String.make w '0' ^ "\";"); write (" elseif rising_edge(" ^ id ^ "_clk) then"); write (" " ^ id ^ " <= " ^ input 2 ^ ";"); write (" end if;"); write (" end process;") | Bbox (n, wo, wi, p) -> write (" " ^ id ^ "_i : entity " ^ n ^ " generic map (" ^ String2.join (List.map string_of_int (wo :: wi :: p)) ", " ^ ") port map (" ^ id ^ "_t, unsigned(" ^ input 0 ^ "));"); write (" " ^ id ^ " <= unsigned(" ^ id ^ "_t);") ) ;; let rec find_io sofar scope_item = match scope_item with | Scope scope -> List.fold_left find_io sofar (items_of_scope scope) | Cell cell -> (match info_of_cell cell with | Input _ | Output _ -> cell :: sofar | _ -> sofar ) ;; let output_io_declaration cell term = match info_of_cell cell with | Input (name, w) -> if w = 1 then write (" signal " ^ name ^ " : in std_logic" ^ term) else write (" signal " ^ name ^ " : in std_logic_vector(" ^ string_of_int (w - 1) ^ " downto 0)" ^ term) | Output (name, w) -> if w = 1 then write (" signal " ^ name ^ " : out std_logic" ^ term) else write (" signal " ^ name ^ " : out std_logic_vector(" ^ string_of_int (w - 1) ^ " downto 0)" ^ term) | _ -> raise (Invalid_argument "encountered a non-port cell") ;; let rec output_io_declarations cells = match cells with | [] -> () | [cell] -> output_io_declaration cell "" | cell :: cells -> output_io_declaration cell ";"; output_io_declarations cells ;; let rec output_local_declarations scope_item = match scope_item with | Scope scope -> List.iter output_local_declarations (items_of_scope scope); | Cell cell -> (match info_of_cell cell with | Output _ | Name _ | Dangle -> () | Ff _ -> write (" signal " ^ id_of_cell cell ^ "_clk : std_logic;"); write (" signal " ^ id_of_cell cell ^ " : unsigned(" ^ string_of_int (width_of_cell cell - 1) ^ " downto 0);") | Ffc _ -> write (" signal " ^ id_of_cell cell ^ "_clr : std_logic;"); write (" signal " ^ id_of_cell cell ^ "_clk : std_logic;"); write (" signal " ^ id_of_cell cell ^ " : unsigned(" ^ string_of_int (width_of_cell cell - 1) ^ " downto 0);") | Bbox (_, wo, _, _) -> write (" signal " ^ id_of_cell cell ^ " : unsigned(" ^ string_of_int (width_of_cell cell - 1) ^ " downto 0);"); write (" signal " ^ id_of_cell cell ^ "_t : std_logic_vector(" ^ string_of_int (width_of_cell cell - 1) ^ " downto 0);") | _ -> write (" signal " ^ id_of_cell cell ^ " : unsigned(" ^ string_of_int (width_of_cell cell - 1) ^ " downto 0);") ) ;; let output_vhdl out_channel scope = channel := out_channel; let scope_item = Scope (root_of_scope scope) in let ports = find_io [] scope_item in write ("library ieee;"); write ("use ieee.std_logic_1164.all;"); write ("use ieee.numeric_std.all;"); write ("entity " ^ module_name_of_scope scope ^ " is"); write ("port("); output_io_declarations ports; write (");"); write ("end entity " ^ module_name_of_scope scope ^ ";"); write ("architecture rtl of " ^ module_name_of_scope scope ^ " is"); output_local_declarations scope_item; write ("begin"); output_scope_item scope_item; write ("end architecture rtl;") ;; confluence-0.10.6/src/fnflib/fnf_vhdl.mli0100644002340600244710000000156310266541663017657 0ustar hawkit1cadgrp(* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Fnf_core;; val output_vhdl : out_channel -> scope -> unit;; confluence-0.10.6/src/fnflib/ltl.ml0100644002340600244710000001022310266541663016504 0ustar hawkit1cadgrp(* InFormal Digital Logic Verification Environment Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** LTL Properties *) type ltl = Variable of string | True | Clock of ltl | Posedge of string | Negedge of string | Not of ltl | And of ltl * ltl | Next of ltl (* strong *) | Until of ltl * ltl (* strong *) ;; let variable name = Variable name ;; let not_ a = Not a ;; let and_ a b = And (a, b) ;; let or_ a b = not_ (and_ (not_ a) (not_ b)) ;; let imply a b = or_ (not_ a) b ;; let equivalent a b = and_ (imply a b) (imply b a) ;; let next is_strong a = if is_strong then Next a else not_ (Next (not_ a)) ;; let rec until is_strong a b = if is_strong then Until (a, b) else or_ (until true a b) (always a) and eventually a = until true True a and always a = not_ (eventually (not_ a)) ;; let never a = always (not_ a) ;; let until_overlap is_strong a b = until is_strong a (and_ a b) ;; let before is_strong a b = until is_strong (not_ b) (and_ a (not_ b)) ;; let before_overlap is_strong a b = until is_strong (not_ b) a ;; let rec next_repeat is_strong n a = if n < 0 then raise (Invalid_argument "Ltl.next_repeat: Count is less than 0."); if n = 0 then a else next_repeat is_strong (n - 1) (next is_strong a) ;; let rec next_ae is_strong is_forall n0 n1 a = if n0 > n1 then raise (Invalid_argument "Ltl.next_ae: First count is greater than second."); if n0 = n1 then next_repeat is_strong n0 a else (if is_forall then and_ else or_) (next_repeat is_strong n0 a) (next_ae is_strong is_forall (n0 + 1) n1 a) ;; let next_event is_strong a b = until is_strong (not_ a) (and_ a b) ;; let rec next_event_repeat is_strong n a b = if n < 1 then raise (Invalid_argument "Ltl.next_event_repeat: Count is less than 1."); if n = 1 then next_event is_strong a b else next_event is_strong a (next is_strong (next_event_repeat is_strong (n - 1) a b)) ;; let rec next_event_ae is_strong is_forall n0 n1 a b = if n0 > n1 then raise (Invalid_argument "Ltl.next_event_ae: First count is greater than second."); if n0 = n1 then next_event_repeat is_strong n0 a b else (if is_forall then and_ else or_) (next_event_repeat is_strong n0 a b) (next_event_ae is_strong is_forall (n0 + 1) n1 a b) ;; let rec clock clk a = match a with | Variable _ | True | Clock _ | Posedge _ | Negedge _ -> a | Not a -> not_ (clock clk a) | And (a, b) -> and_ (clock clk a) (clock clk b) | Next a -> until true (not_ clk) (and_ clk (next true (until true (not_ clk) (and_ clk (clock clk a))))) | Until (a, b) -> until true (imply clk (clock clk a)) (and_ clk (clock clk b)) ;; let posedge clk a = Clock (clock (Posedge clk) a) ;; let negedge clk a = Clock (clock (Negedge clk) a) ;; let nusmv_of_ltl ltl name_of_signal name_of_clock = let rec nusmv_of_ltl ltl = match ltl with | Variable name -> name_of_signal name | True -> "1" | Posedge clock -> name_of_clock clock true | Negedge clock -> name_of_clock clock false | Clock a -> nusmv_of_ltl a | Not a -> "(! " ^ nusmv_of_ltl a ^ ")" | And (a, b) -> "(" ^ nusmv_of_ltl a ^ " & " ^ nusmv_of_ltl b ^ ")" | Next a -> "(X " ^ nusmv_of_ltl a ^ ")" | Until (a, b) -> "(" ^ nusmv_of_ltl a ^ " U " ^ nusmv_of_ltl b ^ ")" in "LTLSPEC " ^ nusmv_of_ltl ltl ^ ";" ;; confluence-0.10.6/src/fnflib/parser_util.ml0100644002340600244710000000456610266541663020257 0ustar hawkit1cadgrp(* InFormal Digital Logic Verification Environment Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Generic parser utility functions. *) (** Error exception. *) exception Error of string;; (** Stateful parser data keeps track of file locations. *) let error_line = ref 1;; let error_col = ref 0;; let current_file = ref "channel";; let current_line = ref 1;; let current_col = ref 0;; let current_token = ref "";; let reset_state () = current_file := "channel"; current_line := 1; current_col := 0; current_token := ""; ;; (** Parsing error reporting. *) let error msg = let s = "\n** Syntax Error in " ^ !current_file ^ " at line " ^ string_of_int !error_line ^ "," ^ string_of_int !error_col ^ "\n\n " ^ msg ^ "\n\n" in print_string s; print_newline (); exit 2 ;; (** Updates parser location. *) let update_positions c = if c == '\n' then begin current_line := !current_line + 1; current_col := 1 end else current_col := !current_col + 1;; (** Handles next token. *) let next_lex lexbuf = error_line := !current_line; error_col := !current_col; let token = Lexing.lexeme lexbuf in current_token := token; let position = (!current_file, !current_line, !current_col) in String.iter update_positions token; token, position;; (** Gets the current token. *) let get_current_token () = !current_token;; (** Parses a channel and returns the AST. *) let parse_channel channel channel_name token reduction = reset_state (); current_file := channel_name; try let lexbuf = Lexing.from_channel channel in reduction token lexbuf with Error msg -> error msg ;; confluence-0.10.6/src/fnflib/psl_ast.ml0100644002340600244710000000225710266541663017366 0ustar hawkit1cadgrp(* InFormal Digital Logic Verification Environment Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** PSL Abstract Syntax Tree *) (** Location type. *) type location = string * int * int;; (** Token type for lexer/parser. *) type token = string * location;; (* Abstract Syntax Tree*) type spec = vunit list and vunit = string * vunit_item list (* module, items *) and vunit_item = Assert of location * expression * string and expression = Ltl.ltl ;; confluence-0.10.6/src/fnflib/psl_lexer.mll0100644002340600244710000003005010266541663020062 0ustar hawkit1cadgrp(* InFormal Digital Logic Verification Environment Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) { (* Pre code. *) } (* Whitespace *) let line_terminator = '\r' | '\n' | "\r\n" let white_space = line_terminator | [' ' '\t'] (* Comments *) let comment_eol = "//" [^'\n']* '\n' (* Numbers *) let dec_digit = ['0' - '9'] (* let bin_digit = ['0' - '1'] let hex_digit = ['0' - '9' 'A' - 'F' 'a' - 'f'] let integer = dec_digit+ | dec_digit+ '\'' ['d' 'D'] dec_digit+ | dec_digit+ '\'' ['b' 'B'] bin_digit+ | dec_digit+ '\'' ['h' 'H'] hex_digit+ *) let integer = dec_digit+ (* Identifiers *) let first_letter = ['a' - 'z' 'A' - 'Z' '_'] let letter = ['a' - 'z' 'A' - 'Z' '0' - '9' '_' '$'] let identifier = first_letter letter* let printable = [^' ' '\n' '\r' '\t'] let identifier_esc = '\\' printable+ (* Strings *) let string_char = [^'\n' '\r'] let string = '"' string_char* '"' rule token = parse | "[" { Psl_parser.Brackl (Parser_util.next_lex lexbuf) } | "]" { Psl_parser.Brackr (Parser_util.next_lex lexbuf) } | "(" { Psl_parser.Parenl (Parser_util.next_lex lexbuf) } | ")" { Psl_parser.Parenr (Parser_util.next_lex lexbuf) } | "{" { Psl_parser.Bracel (Parser_util.next_lex lexbuf) } | "}" { Psl_parser.Bracer (Parser_util.next_lex lexbuf) } | "," { Psl_parser.Comma (Parser_util.next_lex lexbuf) } | ";" { Psl_parser.Semicolon (Parser_util.next_lex lexbuf) } | ":" { Psl_parser.Colon (Parser_util.next_lex lexbuf) } | ".." { Psl_parser.Period_period (Parser_util.next_lex lexbuf) } | "=" { Psl_parser.Equal (Parser_util.next_lex lexbuf) } | ":=" { Psl_parser.Colon_equal (Parser_util.next_lex lexbuf) } | "*" { Psl_parser.Aster (Parser_util.next_lex lexbuf) } | "+" { Psl_parser.Plus (Parser_util.next_lex lexbuf) } | "|->" { Psl_parser.Bar_dash_gt (Parser_util.next_lex lexbuf) } | "|=>" { Psl_parser.Bar_equal_gt (Parser_util.next_lex lexbuf) } | "<->" { Psl_parser.Lt_dash_gt (Parser_util.next_lex lexbuf) } | "->" { Psl_parser.Dash_gt (Parser_util.next_lex lexbuf) } | "[*" { Psl_parser.Brackl_aster (Parser_util.next_lex lexbuf) } | "[+]" { Psl_parser.Brackl_plus_brackr (Parser_util.next_lex lexbuf) } | "[->" { Psl_parser.Brackl_dash_gt (Parser_util.next_lex lexbuf) } | "[=" { Psl_parser.Brackl_equal (Parser_util.next_lex lexbuf) } | "&&" { Psl_parser.Amp_amp (Parser_util.next_lex lexbuf) } | "&" { Psl_parser.Amp (Parser_util.next_lex lexbuf) } | "||" { Psl_parser.Bar_bar (Parser_util.next_lex lexbuf) } | "|" { Psl_parser.Bar (Parser_util.next_lex lexbuf) } | "!" { Psl_parser.Bang (Parser_util.next_lex lexbuf) } | "$" { Psl_parser.Dollar (Parser_util.next_lex lexbuf) } | "@" { Psl_parser.At (Parser_util.next_lex lexbuf) } | "." { Psl_parser.Period (Parser_util.next_lex lexbuf) } | "/" { Psl_parser.Slash (Parser_util.next_lex lexbuf) } | "A" { Psl_parser.A (Parser_util.next_lex lexbuf) } | "AG" { Psl_parser.AG (Parser_util.next_lex lexbuf) } | "AF" { Psl_parser.AF (Parser_util.next_lex lexbuf) } | "AX" { Psl_parser.AX (Parser_util.next_lex lexbuf) } | "abort" { Psl_parser.Abort (Parser_util.next_lex lexbuf) } | "always" { Psl_parser.Always (Parser_util.next_lex lexbuf) } | "assert" { Psl_parser.Assert (Parser_util.next_lex lexbuf) } | "assume" { Psl_parser.Assume (Parser_util.next_lex lexbuf) } | "assume_guarantee" { Psl_parser.Assume_guarantee (Parser_util.next_lex lexbuf) } | "before" { Psl_parser.Before (Parser_util.next_lex lexbuf) } | "before!" { Psl_parser.Before_bang (Parser_util.next_lex lexbuf) } | "before!_" { Psl_parser.Before_bang_ (Parser_util.next_lex lexbuf) } | "before_" { Psl_parser.Before_ (Parser_util.next_lex lexbuf) } | "boolean" { Psl_parser.Boolean (Parser_util.next_lex lexbuf) } | "clock" { Psl_parser.Clock (Parser_util.next_lex lexbuf) } | "const" { Psl_parser.Const (Parser_util.next_lex lexbuf) } | "countones" { Psl_parser.Countones (Parser_util.next_lex lexbuf) } | "cover" { Psl_parser.Cover (Parser_util.next_lex lexbuf) } | "default" { Psl_parser.Default (Parser_util.next_lex lexbuf) } | "E" { Psl_parser.E (Parser_util.next_lex lexbuf) } | "EF" { Psl_parser.EF (Parser_util.next_lex lexbuf) } | "EG" { Psl_parser.EG (Parser_util.next_lex lexbuf) } | "EX" { Psl_parser.EX (Parser_util.next_lex lexbuf) } | "endpoint" { Psl_parser.Endpoint (Parser_util.next_lex lexbuf) } | "eventually!" { Psl_parser.Eventually_bang (Parser_util.next_lex lexbuf) } | "F" { Psl_parser.F (Parser_util.next_lex lexbuf) } | "fairness" { Psl_parser.Fairness (Parser_util.next_lex lexbuf) } | "fell" { Psl_parser.Fell (Parser_util.next_lex lexbuf) } | "forall" { Psl_parser.Forall (Parser_util.next_lex lexbuf) } | "G" { Psl_parser.G (Parser_util.next_lex lexbuf) } | "in" { Psl_parser.In (Parser_util.next_lex lexbuf) } | "inf" { Psl_parser.Inf (Parser_util.next_lex lexbuf) } | "inherit" { Psl_parser.Inherit (Parser_util.next_lex lexbuf) } | "isunknown" { Psl_parser.Isunknown (Parser_util.next_lex lexbuf) } | "never" { Psl_parser.Never (Parser_util.next_lex lexbuf) } | "next" { Psl_parser.Next (Parser_util.next_lex lexbuf) } | "next!" { Psl_parser.Next_bang (Parser_util.next_lex lexbuf) } | "next_a" { Psl_parser.Next_a (Parser_util.next_lex lexbuf) } | "next_a!" { Psl_parser.Next_a_bang (Parser_util.next_lex lexbuf) } | "next_e" { Psl_parser.Next_e (Parser_util.next_lex lexbuf) } | "next_e!" { Psl_parser.Next_e_bang (Parser_util.next_lex lexbuf) } | "next_event" { Psl_parser.Next_event (Parser_util.next_lex lexbuf) } | "next_event!" { Psl_parser.Next_event_bang (Parser_util.next_lex lexbuf) } | "next_event_a" { Psl_parser.Next_event_a (Parser_util.next_lex lexbuf) } | "next_event_a!" { Psl_parser.Next_event_a_bang (Parser_util.next_lex lexbuf) } | "next_event_e" { Psl_parser.Next_event_e (Parser_util.next_lex lexbuf) } | "next_event_e!" { Psl_parser.Next_event_e_bang (Parser_util.next_lex lexbuf) } | "onehot" { Psl_parser.Onehot (Parser_util.next_lex lexbuf) } | "onehot0" { Psl_parser.Onehot0 (Parser_util.next_lex lexbuf) } | "property" { Psl_parser.Property (Parser_util.next_lex lexbuf) } | "prev" { Psl_parser.Prev (Parser_util.next_lex lexbuf) } | "report" { Psl_parser.Report (Parser_util.next_lex lexbuf) } | "restrict" { Psl_parser.Restrict (Parser_util.next_lex lexbuf) } | "restrict_guarantee" { Psl_parser.Restrict_guarantee (Parser_util.next_lex lexbuf) } | "rose" { Psl_parser.Rose (Parser_util.next_lex lexbuf) } | "sequence" { Psl_parser.Sequence (Parser_util.next_lex lexbuf) } | "stable" { Psl_parser.Stable (Parser_util.next_lex lexbuf) } | "strong" { Psl_parser.Strong (Parser_util.next_lex lexbuf) } | "U" { Psl_parser.U (Parser_util.next_lex lexbuf) } | "union" { Psl_parser.Union (Parser_util.next_lex lexbuf) } | "until" { Psl_parser.Until (Parser_util.next_lex lexbuf) } | "until!" { Psl_parser.Until_bang (Parser_util.next_lex lexbuf) } | "until!_" { Psl_parser.Until_bang_ (Parser_util.next_lex lexbuf) } | "until_" { Psl_parser.Until_ (Parser_util.next_lex lexbuf) } | "vmode" { Psl_parser.Vmode (Parser_util.next_lex lexbuf) } | "vprop" { Psl_parser.Vprop (Parser_util.next_lex lexbuf) } | "vunit" { Psl_parser.Vunit (Parser_util.next_lex lexbuf) } | "within" { Psl_parser.Within (Parser_util.next_lex lexbuf) } | "X" { Psl_parser.X (Parser_util.next_lex lexbuf) } | "X!" { Psl_parser.X_bang (Parser_util.next_lex lexbuf) } | "posedge" { Psl_parser.Posedge (Parser_util.next_lex lexbuf) } | "negedge" { Psl_parser.Negedge (Parser_util.next_lex lexbuf) } | integer { Psl_parser.Integer (Parser_util.next_lex lexbuf) } | identifier { Psl_parser.Identifier (Parser_util.next_lex lexbuf) } | identifier_esc { Psl_parser.Identifier_esc (Parser_util.next_lex lexbuf) } | string { Psl_parser.String (Parser_util.next_lex lexbuf) } | eof { Psl_parser.EOF (Parser_util.next_lex lexbuf) } | white_space { let _ = Parser_util.next_lex lexbuf in token lexbuf } | comment_eol { let _ = Parser_util.next_lex lexbuf in token lexbuf } | "/*" { let _ = Parser_util.next_lex lexbuf in comment lexbuf } | _ { let token = Parser_util.next_lex lexbuf in Parser_util.error ("Unrecognized character: '" ^ (fst token) ^ "'"); Psl_parser.Lexer_error token } and comment = parse | "*/" { let _ = Parser_util.next_lex lexbuf in token lexbuf } | eof { let token = Parser_util.next_lex lexbuf in Parser_util.error ("End of File without closing comment."); Psl_parser.Lexer_error token } | _ { let _ = Parser_util.next_lex lexbuf in comment lexbuf } { (* Post code. *) } confluence-0.10.6/src/fnflib/psl_parser.mly0100644002340600244710000004653510266541664020274 0ustar hawkit1cadgrp/* InFormal Digital Logic Verification Environment Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ %{ (* Pre Code *) let parse_error s = Parser_util.error ("Unexpected token: '" ^ (Parser_util.get_current_token ()) ^ "'") ;; let debug msg = print_string msg; print_newline () ;; %} // PSL Keywords and Operators %token Brackl %token Brackr %token Parenl %token Parenr %token Bracel %token Bracer %token Comma %token Semicolon %token Colon %token Period_period %token Equal %token Colon_equal %token Aster %token Plus %token Bar_dash_gt %token Bar_equal_gt %token Lt_dash_gt %token Dash_gt %token Brackl_aster %token Brackl_plus_brackr %token Brackl_dash_gt %token Brackl_equal %token Amp_amp %token Amp %token Bar_bar %token Bar %token Bang %token Dollar %token At %token Period %token Slash %token A %token AG %token AF %token AX %token Abort %token Always %token Assert %token Assume %token Assume_guarantee %token Before %token Before_bang %token Before_bang_ %token Before_ %token Boolean %token Clock %token Const %token Countones %token Cover %token Default %token E %token EF %token EG %token EX %token Endpoint %token Eventually_bang %token F %token Fairness %token Fell %token Forall %token G %token In %token Inf %token Inherit %token Isunknown %token Never %token Next %token Next_bang %token Next_a %token Next_a_bang %token Next_e %token Next_e_bang %token Next_event %token Next_event_bang %token Next_event_a %token Next_event_a_bang %token Next_event_e %token Next_event_e_bang %token Onehot %token Onehot0 %token Property %token Prev %token Report %token Restrict %token Restrict_guarantee %token Rose %token Sequence %token Stable %token Strong %token U %token W %token Union %token Until %token Until_bang %token Until_bang_ %token Until_ %token Vmode %token Vprop %token Vunit %token Within %token X %token X_bang // HDL Keywords and Operators %token Negedge %token Posedge %token Bar_bar %token Equal_equal %token Bang_equal %token Lt %token Lt_equal %token Gt %token Gt_equal %token Plus %token Dash %token Tildy %token Carrot // Literals %token Integer %token Integer_width %token Identifier %token Identifier_esc %token String // Misc %token EOF %token Lexer_error // Operator Precedence and Associativity %right Always Never G %right Dash_gt Lt_dash_gt %right Bar_dash_gt Bar_equal_gt %right U W Until Until_bang Until_bang_ Until_ Before Before_bang Before_bang_ Before_ %right X X_bang F Eventually_bang Next Next_bang Next_a Next_a_bang Next_e Next_e_bang Next_event Next_event_bang Next_event_a_bang Next_event_e_bang %left AX AG AF EX EG EF %left Abort %left Semicolon %left Colon %left Bar Bar_bar %left Amp Amp_amp %left Within %left Brackl_aster Brackl_plus_brackr Brackl_equal Brackl_dash_gt %left At %left Union %left Bang // HDL operators have highest precedence. %right Question %left Vl_bar_bar %left Vl_amp_amp %left Vl_bar %left Carrot %left Vl_amp %left Equal_equal Bang_equal %left Lt Lt_equal Gt Gt_equal %left Plus Dash %left Tildy Vl_bang Vl_uplus Vl_uminus %left Brackl %start psl_specification %type psl_specification %% psl_specification : verification_items EOF { List.rev $1 } ; verification_items : { [] } | verification_items verification_unit { $2 :: $1 } ; verification_unit : vunit_type identifier Bracel inherit_specs vunit_items Bracer { raise (Parser_util.Error "Verification unit requires module name.") } | vunit_type identifier Parenl hierarchical_hdl_name Parenr Bracel inherit_specs vunit_items Bracer { List.hd $4, List.rev $8 } ; vunit_type : Vunit { $1 } | Vprop { raise (Parser_util.Error "\"vprop\" not supported.") } | Vmode { raise (Parser_util.Error "\"vmode\" not supported.") } ; hierarchical_hdl_name : identifier hierarchical_hdl_names { fst $1 :: List.rev $2 } ; hierarchical_hdl_names : { [] } | hierarchical_hdl_names path_separator identifier { raise (Parser_util.Error "Hierarchical names are not supported.") } ; path_separator : Period { () } | Slash { () } ; inherit_specs : { [] } | inherit_specs inherit_spec { $2 :: $1 } ; inherit_spec : Inherit identifier comma_identifiers { Parser_util.error "\"inherit\" not supported." } ; vunit_items : { [] } | vunit_items vunit_item { $2 :: $1 } ; vunit_item // XXX : psl_declaration { $1 } : psl_directive { $1 } ; // PSL Declarations /* psl_declaration : Property identifier formal_parameter_list Equal property Semicolon { raise (Parser_util.Error "\"property\" declaration not supported.") } | Sequence identifier formal_parameter_list Equal sequence Semicolon { raise (Parser_util.Error "\"sequence\" declaration not supported.") } | Endpoint identifier formal_parameter_list Equal sequence Semicolon { raise (Parser_util.Error "\"endpoint\" declaration not supported.") } | Default Clock Equal clock_expression Semicolon { raise (Parser_util.Error "\"default clock\" declaration not supported.") } ; formal_parameter_list : | Parenl formal_parameter formal_parameters Parenr { () } ; formal_parameters : | Semicolon formal_parameter { () } ; formal_parameter : param_type identifier comma_identifiers { () } ; param_type : Const { () } | Boolean { () } | Property { () } | Sequence { () } ; actual_parameter_list : property { () } | actual_parameter_list Comma property { () } ; */ // PSL Directives psl_directive : verification_directive { $1 } | identifier Colon verification_directive { $3 } ; verification_directive : Assert property report Semicolon { Psl_ast.Assert (snd $1, $2, $3) } | Assume property Semicolon { raise (Parser_util.Error "\"assume\" directive not supported.") } | Assume_guarantee property report Semicolon { raise (Parser_util.Error "\"assume_guarantee\" directive not supported.") } | Restrict property Semicolon { raise (Parser_util.Error "\"restrict\" directive not supported.") } | Restrict_guarantee property report Semicolon { raise (Parser_util.Error "\"restrict_guarantee\" directive not supported.") } | Cover property report Semicolon { raise (Parser_util.Error "\"cover\" directive not supported.") } | Fairness property Semicolon { raise (Parser_util.Error "\"fairness\" directive not supported.") } | Strong Fairness property Comma property Semicolon { raise (Parser_util.Error "\"strong fairness\" directive not supported.") } ; /* count : number { $1, $1 } | range { $1 } ; finite_count : number { $1, $1 } | finite_range { $1 } ; range : number range_sym number { $1, $3 } | number range_sym Inf { raise (Parser_util.Error "Infintie range not supported.") } ; */ finite_range : number range_sym number { $1, $3 } ; range_sym : Colon { () } | Period_period { () } ; report : { "" } | Report String { let s = fst $2 in String.sub s 1 (String.length s - 2) } ; identifier : Identifier { $1 } | Identifier_esc { $1 } ; comma_identifiers : { () } | Comma identifier comma_identifiers { () } ; /* XXX value_set : Brackl value_range value_ranges Brackr { () } | Boolean { () } ; value_ranges : { () } | value_ranges Comma value_range { () } ; value_range : value { () } | finite_range { () } ; value : boolean { () } | number { () } ; */ /* XXX built_in_function_call : Prev Parenl property Parenr { raise (Parser_util.Error "\"prev\" function not supported.") } | Prev Parenl property Comma number Parenr { raise (Parser_util.Error "\"prev\" function not supported.") } // XXX | Next Parenl property Parenr { raise (Parser_util.Error "\"next\" function not supported.") } | Stable Parenl property Parenr { raise (Parser_util.Error "\"stable\" function not supported.") } | Rose Parenl boolean Parenr { raise (Parser_util.Error "\"rose\" function not supported.") } | Fell Parenl boolean Parenr { raise (Parser_util.Error "\"fell\" function not supported.") } | Isunknown Parenl boolean Parenr { raise (Parser_util.Error "\"isunknown\" function not supported.") } | Countones Parenl boolean Parenr { raise (Parser_util.Error "\"countones\" function not supported.") } | Onehot Parenl boolean Parenr { raise (Parser_util.Error "\"onehot\" function not supported.") } | Onehot0 Parenl boolean Parenr { raise (Parser_util.Error "\"onehot0\" function not supported.") } ; */ number : Integer { int_of_string (fst $1) } ; property //: boolean { $1 } : identifier { Ltl.Variable (fst $1) } | Parenl property Parenr { $2 } // Replicator Properties //| Forall identifier In value_set Colon property { () } //| Forall identifier Brackl finite_range Brackr In value_set Colon property { () } // FL Properties // XXX // | sequence { raise (Parser_util.Error "PSL sequences are not supported.") } // | sequence Bang { raise (Parser_util.Error "PSL sequences are not supported.") } | property At clock_expression { $3 $1 } // XXX // | property Abort property { raise (Parser_util.Error "PSL \"abort\" is not supported.") } | Bang property { Ltl.not_ $2 } | property Amp_amp property { Ltl.and_ $1 $3 } | property Bar_bar property { Ltl.or_ $1 $3 } | property Dash_gt property { Ltl.imply $1 $3 } | property Lt_dash_gt property { Ltl.equivalent $1 $3 } | X property { Ltl.next false $2 } | X_bang property { Ltl.next true $2 } | F property { Ltl.eventually $2 } | G property { Ltl.always $2 } | Brackl property U property Brackr { Ltl.until true $2 $4 } | Brackl property W property Brackr { Ltl.until false $2 $4 } | Always property { Ltl.always $2 } | Never property { Ltl.never $2 } | Next property { Ltl.next false $2 } | Next_bang property { Ltl.next true $2 } | Eventually_bang property { Ltl.eventually $2 } | property Until property { Ltl.until false $1 $3 } | property Until_bang property { Ltl.until true $1 $3 } | property Until_bang_ property { Ltl.until_overlap true $1 $3 } | property Until_ property { Ltl.until_overlap false $1 $3 } | property Before property { Ltl.before false $1 $3 } | property Before_bang property { Ltl.before true $1 $3 } | property Before_bang_ property { Ltl.before_overlap true $1 $3 } | property Before_ property { Ltl.before_overlap false $1 $3 } // Most of the following parametric expressions can not be desugared until evaluation. | X Brackl number Brackr Parenl property Parenr { Ltl.next_repeat false $3 $6 } | X_bang Brackl number Brackr Parenl property Parenr { Ltl.next_repeat true $3 $6 } | Next Brackl number Brackr Parenl property Parenr { Ltl.next_repeat false $3 $6 } | Next_bang Brackl number Brackr Parenl property Parenr { Ltl.next_repeat true $3 $6 } | Next_a Brackl finite_range Brackr Parenl property Parenr { Ltl.next_ae false true (fst $3) (snd $3) $6 } | Next_a_bang Brackl finite_range Brackr Parenl property Parenr { Ltl.next_ae true true (fst $3) (snd $3) $6 } | Next_e Brackl finite_range Brackr Parenl property Parenr { Ltl.next_ae false false (fst $3) (snd $3) $6 } | Next_e_bang Brackl finite_range Brackr Parenl property Parenr { Ltl.next_ae true false (fst $3) (snd $3) $6 } // The first property is really a boolean. | Next_event Parenl property Parenr Parenl property Parenr {Ltl.next_event false $3 $6 } | Next_event_bang Parenl property Parenr Parenl property Parenr {Ltl.next_event true $3 $6 } | Next_event Parenl property Parenr Brackl number Brackr Parenl property Parenr { Ltl.next_event_repeat false $6 $3 $9 } | Next_event_bang Parenl property Parenr Brackl number Brackr Parenl property Parenr { Ltl.next_event_repeat true $6 $3 $9 } | Next_event_a Parenl property Parenr Brackl finite_range Brackr Parenl property Parenr { Ltl.next_event_ae false true (fst $6) (snd $6) $3 $9 } | Next_event_a_bang Parenl property Parenr Brackl finite_range Brackr Parenl property Parenr { Ltl.next_event_ae true true (fst $6) (snd $6) $3 $9 } | Next_event_e Parenl property Parenr Brackl finite_range Brackr Parenl property Parenr { Ltl.next_event_ae false false (fst $6) (snd $6) $3 $9 } | Next_event_e_bang Parenl property Parenr Brackl finite_range Brackr Parenl property Parenr { Ltl.next_event_ae true false (fst $6) (snd $6) $3 $9 } // XXX | Bracel sequence Bracer Parenl property Parenr { () } // XXX | sequence Bar_dash_gt property { raise (Parser_util.Error "PSL sequences are not supported.") } // XXX | sequence Bar_equal_gt property { raise (Parser_util.Error "PSL sequences are not supported.") } // OBE Properties | AX property { raise (Parser_util.Error "PSL OBE properties are not supported.") } | AF property { raise (Parser_util.Error "PSL OBE properties are not supported.") } | AG property { raise (Parser_util.Error "PSL OBE properties are not supported.") } | A Brackl property U property Brackr { raise (Parser_util.Error "PSL OBE properties are not supported.") } | EX property { raise (Parser_util.Error "PSL OBE properties are not supported.") } | EF property { raise (Parser_util.Error "PSL OBE properties are not supported.") } | EG property { raise (Parser_util.Error "PSL OBE properties are not supported.") } | E Brackl property U property Brackr { raise (Parser_util.Error "PSL OBE properties are not supported.") } ; /* sere : boolean { () } | sere Semicolon sere { () } | sere Colon sere { () } | compound_sere { () } ; compound_sere : repeated_sere { () } | braced_sere { () } // XXX | clocked_sere { () } | compound_sere Bar compound_sere { () } | compound_sere Amp compound_sere { () } | compound_sere Amp_amp compound_sere { () } | compound_sere Within compound_sere { () } ; sequence : repeated_sere { () } | braced_sere { () } // XXX | clocked_sere { () } ; repeated_sere : boolean Brackl_aster Brackr { () } | boolean Brackl_aster count Brackr { () } | sequence Brackl_aster Brackr { () } | sequence Brackl_aster count Brackr { () } | Brackl_aster Brackr { () } | Brackl_aster count Brackr { () } | boolean Brackl_plus_brackr { () } | sequence Brackl_plus_brackr { () } | Brackl_plus_brackr { () } | boolean Brackl_equal count Brackr { () } | boolean Brackl_dash_gt Brackr { () } | boolean Brackl_dash_gt count Brackr { () } ; braced_sere : Bracel sere Bracer { () } ; */ /* XXX clocked_sere : braced_sere At clock_expression { () } ; */ clock_expression : Parenl Posedge identifier Parenr { Ltl.posedge (fst $3) } | Parenl Negedge identifier Parenr { Ltl.negedge (fst $3) } | Rose Parenl identifier Parenr { Ltl.posedge (fst $3) } | Fell Parenl identifier Parenr { Ltl.negedge (fst $3) } ; // Boolean, Vector, and Constant Expressions // XXX For now, everything is a property. /* boolean : identifier { () } | boolean Brackl finite_count Brackr { () } | Integer { () } | Integer_width { () } | built_in_function_call { () } | identifier Parenl actual_parameter_list Parenr { () } // Shared property and boolean expressions. // Should account for 12 shift/reduce and 17 reduce/reduce conflicts. | Bang boolean %prec Vl_bang { () } | boolean Amp_amp boolean %prec Vl_amp_amp { () } | boolean Bar_bar boolean %prec Vl_bar_bar { () } | boolean Dash_gt boolean { () } | boolean Lt_dash_gt boolean { () } | Tildy boolean { () } | Plus boolean %prec Vl_uplus { () } | Dash boolean %prec Vl_uminus { () } | boolean Plus boolean { () } | boolean Dash boolean { () } | boolean Lt boolean { () } | boolean Lt_equal boolean { () } | boolean Gt boolean { () } | boolean Gt_equal boolean { () } | boolean Equal_equal boolean { () } | boolean Bang_equal boolean { () } | boolean Amp boolean %prec Vl_amp { () } | boolean Carrot boolean { () } | boolean Bar boolean %prec Vl_bar { () } | boolean Question boolean Colon boolean { () } | boolean Union boolean { () } ; */ %% (* Post Code *) confluence-0.10.6/src/ivl/0040755002340600244710000000000010312276326014707 5ustar hawkit1cadgrpconfluence-0.10.6/src/ivl/fnf.conf0100644002340600244710000000014710266541664016336 0ustar hawkit1cadgrpfunctor:synth2 functor:synth functor:syn-rules functor:cprop functor:nodangle -t:dll flag:DLL=fnf.tgt confluence-0.10.6/src/ivl/Makefile0100644002340600244710000000057110266541664016357 0ustar hawkit1cadgrpSHELL=/bin/bash PREFIX=/usr/local .PHONY : all all : fnf.tgt fnf.tgt : fnf.c ivl_target.h gcc -Wall -O2 -shared -o fnf.tgt fnf.c .PHONY : install install : all install -D fnf.tgt $(PREFIX)/lib/ivl/fnf.tgt install -D fnf.conf $(PREFIX)/lib/ivl/fnf.conf .PHONY : uninstall uninstall : -rm $(PREFIX)/lib/ivl/fnf.tgt -rm $(PREFIX)/lib/ivl/fnf.conf clean: -rm fnf.tgt confluence-0.10.6/src/ivl/fnf.c0100644002340600244710000004000610266541664015631 0ustar hawkit1cadgrp/* FNF: Free Netlist Format Copyright (C) 2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include #include #include #include "ivl_target.h" // Output file. FILE* output = 0; // Design. ivl_design_t design = 0; // Current level of design. unsigned level = 0; // Write indent. void indent() { unsigned i; for (i = 0; i < level; i++) fprintf(output, " "); } // Write quoted string. void quoted_string(const char * string) { int i = 0; fprintf(output, "\""); while (string[i] != '\0') { if (string[i] == '"') fprintf(output, "\\\""); else if (string[i] == '\\') fprintf(output, "\\\\"); else fprintf(output, "%c", string[i]); i++; } fprintf(output, "\""); } // Nexus id table. struct nexus_table_s { ivl_nexus_t nexus; unsigned id; unsigned is_driven; struct nexus_table_s* lt; struct nexus_table_s* gt; } * nexus_table = 0; typedef struct nexus_table_s *nexus_table_t; unsigned next_id = 0; // Create next id. unsigned new_id() { return next_id++; } // Delete the nexus table. Check for dangling nets. void delete_nexus_table(nexus_table_t table) { if (table) { nexus_table_t lt = table->lt; nexus_table_t gt = table->gt; if (! (table->is_driven)) { indent(); fprintf(output, " (dangle %i)\n", table->id); } free((void*) table); delete_nexus_table(lt); delete_nexus_table(gt); } } // Table construction. unsigned id_of_nexus_0(ivl_nexus_t nexus, nexus_table_t table, unsigned is_driven) { if (nexus == table->nexus) { table->is_driven = table->is_driven || is_driven; return table->id; } else if (nexus < table->nexus) if (table->lt) return id_of_nexus_0(nexus, table->lt, is_driven); else { table->lt = (nexus_table_t) (malloc(sizeof(*table))); table->lt->nexus = nexus; table->lt->id = new_id(); table->lt->is_driven = is_driven; table->lt->lt = 0; table->lt->gt = 0; return table->lt->id; } else // nexus > table->nexus if (table->gt) return id_of_nexus_0(nexus, table->gt, is_driven); else { table->gt = (nexus_table_t) (malloc(sizeof(*table))); table->gt->nexus = nexus; table->gt->id = new_id(); table->gt->is_driven = is_driven; table->gt->lt = 0; table->gt->gt = 0; return table->gt->id; } } // Lookup nexus id. unsigned id_of_nexus(ivl_nexus_t nexus, unsigned is_driven) { if (! nexus_table) { nexus_table = (nexus_table_t) (malloc(sizeof(*nexus_table))); nexus_table->nexus = nexus; nexus_table->id = new_id(); nexus_table->is_driven = is_driven; nexus_table->lt = 0; nexus_table->gt = 0; return nexus_table->id; } else return id_of_nexus_0(nexus, nexus_table, is_driven); } // Create single bit select. void create_bit_select(unsigned output_id, unsigned width, unsigned bit, unsigned input_id) { indent(); fprintf(output, " (select %i %i %i %i)\n", output_id, width, bit, input_id); } // Create bit concat. unsigned create_bit_concat(unsigned input_id, unsigned input_width, ivl_nexus_t nexus) { unsigned id = new_id(); indent(); fprintf(output, " (concat %i 1 %i %i %i)\n", id, input_width, id_of_nexus(nexus, 0), input_id); return id; } // Concat lpm_data unsigned create_concat_lpm_data(ivl_lpm_t lpm) { unsigned width = ivl_lpm_width(lpm); unsigned id; unsigned i; id = id_of_nexus(ivl_lpm_data(lpm, 0), 0); for (i = 1; i < width; i++) { id = create_bit_concat(id, i, ivl_lpm_data(lpm, i)); } return id; } // Concat lpm_datab unsigned create_concat_lpm_datab(ivl_lpm_t lpm) { unsigned width = ivl_lpm_width(lpm); unsigned id; unsigned i; id = id_of_nexus(ivl_lpm_datab(lpm, 0), 0); for (i = 1; i < width; i++) { id = create_bit_concat(id, i, ivl_lpm_datab(lpm, i)); } return id; } // Concat lpm_data2 unsigned create_concat_lpm_data2(ivl_lpm_t lpm, unsigned select) { unsigned width = ivl_lpm_width(lpm); unsigned id; unsigned i; id = id_of_nexus(ivl_lpm_data2(lpm, select, 0), 0); for (i = 1; i < width; i++) { id = create_bit_concat(id, i, ivl_lpm_data2(lpm, select, i)); } return id; } // Split lpm_q void create_split_lpm_q(ivl_lpm_t lpm, unsigned id) { unsigned width = ivl_lpm_width(lpm); unsigned i; for (i = 0; i < width; i++) create_bit_select(id_of_nexus(ivl_lpm_q(lpm, i), 1), width, i, id); } // Repeated gates. void create_multi_gate(const char* gate, unsigned id, ivl_net_logic_t logic) { unsigned width = ivl_logic_pins(logic); unsigned id1 = id_of_nexus(ivl_logic_pin(logic, 1), 0); if (width == 2) { indent(); fprintf(output, " (buf %i 1 %i)\n", id, id1); } else { unsigned i; unsigned id2; for (i = 2; i < width; i++) { id2 = (i == width - 1) ? id : new_id(); indent(); fprintf(output, " (%s %i 1 %i %i)\n", gate, id2, id1, id_of_nexus(ivl_logic_pin(logic, i), 0)); id1 = id2; } } } // Mux tree. unsigned create_mux(ivl_lpm_t lpm, unsigned select_width, unsigned select_number) { unsigned id; if (select_width == 0) { id = create_concat_lpm_data2(lpm, select_number); } else { unsigned width = ivl_lpm_width(lpm); unsigned select = id_of_nexus(ivl_lpm_select(lpm, select_width - 1), 0); unsigned data_0 = create_mux(lpm, select_width - 1, select_number << 1); unsigned data_1 = create_mux(lpm, select_width - 1, (select_number << 1) | 1); id = new_id(); indent(); fprintf(output, " (mux %i %i %i %i %i)\n", id, width, select, data_0, data_1); } return id; } // Build the design hierarchy. int build_hierarchy(ivl_scope_t scope, void* cd) { int return_code; unsigned i, j; indent(); fprintf(output, "(scope "); quoted_string(ivl_scope_tname(scope)); fprintf(output, " "); quoted_string(ivl_scope_basename(scope)); fprintf(output, " (\n"); // Constants (root scope only) if (! level) for (i = 0; i < ivl_design_consts(design); i++) { ivl_net_const_t constant = ivl_design_const(design, i); const char* bits = ivl_const_bits(constant); unsigned pins = ivl_const_pins(constant); unsigned id = new_id(); indent(); fprintf(output, " (const %i \"", id); for (j = pins - 1; j < pins; j--) fprintf(output, "%c", bits[j]); fprintf(output, "\")\n"); for (j = 0; j < pins; j++) create_bit_select(id_of_nexus(ivl_const_pin(constant, j), 1), pins, j, id); } // Parameters for (i = 0; i < ivl_scope_params(scope); i++) { ivl_parameter_t param = ivl_scope_param(scope, i); ivl_expr_t param_value = ivl_parameter_expr(param); unsigned width = ivl_expr_width(param_value); const char* bits; unsigned id = new_id(); indent(); fprintf(output, " (const %i \"", id); switch (ivl_expr_type(param_value)) { case IVL_EX_STRING : bits = ivl_expr_string(param_value); break; case IVL_EX_NUMBER : bits = ivl_expr_bits(param_value); break; default : fprintf(output, "** ERROR: Unknown parameter type."); return -1; } for (j = width - 1; j < width; j--) fprintf(output, "%c", bits[j]); fprintf(output, "\")\n"); indent(); fprintf(output, " (name %i ", new_id()); quoted_string(ivl_parameter_basename(param)); fprintf(output, " %i %i)\n", width, id); } // Signals for (i = 0; i < ivl_scope_sigs(scope); i++) { ivl_signal_t sig = ivl_scope_sig(scope, i); unsigned pins = ivl_signal_pins(sig); ivl_signal_port_t type = ivl_signal_port(sig); const char* name = ivl_signal_basename(sig); unsigned id; if (! level && type == IVL_SIP_INPUT) { id = new_id(); fprintf(output, " (input %i \"%s\" %i)\n", id, name, pins); for (j = 0; j < pins; j++) create_bit_select(id_of_nexus(ivl_signal_pin(sig, j), 1), pins, j, id); } else if (! level && type == IVL_SIP_INOUT) { printf("** ERROR: Inout ports not supported.\n"); } else if (! level && type == IVL_SIP_OUTPUT) { id = id_of_nexus(ivl_signal_pin(sig, 0), 0); for (j = 1; j < pins; j++) { id = create_bit_concat(id, j, ivl_signal_pin(sig, j)); } fprintf(output, " (output %i \"%s\" %i %i)\n", new_id(), name, pins, id); } else { id = id_of_nexus(ivl_signal_pin(sig, 0), 0); for (j = 1; j < pins; j++) { id = create_bit_concat(id, j, ivl_signal_pin(sig, j)); } indent(); fprintf(output, " (name %i ", new_id()); //XXX Why is "_s22" getting named? quoted_string(name); fprintf(output, " %i %i)\n", pins, id); } } // Logic for (i = 0; i < ivl_scope_logs(scope); i++) { unsigned id; ivl_net_logic_t log = ivl_scope_log(scope, i); switch (ivl_logic_type(log)) { case IVL_LO_BUF: indent(); fprintf(output, " (buf %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id_of_nexus(ivl_logic_pin(log, 1), 0)); break; case IVL_LO_NOT: indent(); fprintf(output, " (not %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id_of_nexus(ivl_logic_pin(log, 1), 0)); break; case IVL_LO_AND: indent(); create_multi_gate("and ", id_of_nexus(ivl_logic_pin(log, 0), 1), log); break; case IVL_LO_NAND: id = new_id(); indent(); create_multi_gate("and ", id, log); indent(); fprintf(output, " (not %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id); break; case IVL_LO_XOR: indent(); create_multi_gate("xor ", id_of_nexus(ivl_logic_pin(log, 0), 1), log); break; case IVL_LO_XNOR: id = new_id(); indent(); create_multi_gate("xor ", id, log); indent(); fprintf(output, " (not %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id); break; case IVL_LO_OR: indent(); create_multi_gate("or ", id_of_nexus(ivl_logic_pin(log, 0), 1), log); break; case IVL_LO_NOR: id = new_id(); indent(); create_multi_gate("or ", id, log); indent(); fprintf(output, " (not %i 1 %i)\n", id_of_nexus(ivl_logic_pin(log, 0), 1), id); break; default: printf("** ERROR: Unsupported logic type: %i.\n", ivl_logic_type(log)); return -1; } } // LPMs for (i = 0; i < ivl_scope_lpms(scope); i++) { ivl_lpm_t lpm = ivl_scope_lpm(scope, i); ivl_lpm_type_t lpm_t = ivl_lpm_type(lpm); unsigned width = ivl_lpm_width(lpm); unsigned selects; unsigned size; unsigned id, id1, id2, id3; switch (lpm_t) { case IVL_LPM_ADD: id = new_id(); id1 = create_concat_lpm_data(lpm); id2 = create_concat_lpm_datab(lpm); indent(); fprintf(output, " (add %i %i %i %i)\n", id, width, id1, id2); create_split_lpm_q(lpm, id); break; case IVL_LPM_SUB: id = new_id(); id1 = create_concat_lpm_data(lpm); id2 = create_concat_lpm_datab(lpm); indent(); fprintf(output, " (sub %i %i %i %i)\n", id, width, id1, id2); create_split_lpm_q(lpm, id); break; case IVL_LPM_MULT: id = new_id(); id1 = create_concat_lpm_data(lpm); id2 = create_concat_lpm_datab(lpm); indent(); fprintf(output, " (mul %i %i %i %i)\n", id, width, id1, id2); create_split_lpm_q(lpm, id); break; case IVL_LPM_CMP_EQ: id1 = create_concat_lpm_data(lpm); id2 = create_concat_lpm_datab(lpm); indent(); fprintf(output, " (eq %i %i %i %i)\n", id_of_nexus(ivl_lpm_q(lpm, 0), 1), width, id1, id2); break; case IVL_LPM_CMP_NE: id1 = create_concat_lpm_data(lpm); id2 = create_concat_lpm_datab(lpm); id = new_id(); indent(); fprintf(output, " (eq %i %i %i %i)\n", id, width, id1, id2); indent(); fprintf(output, " (not %i 1 %i)\n", id_of_nexus(ivl_lpm_q(lpm, 0), 1), id); break; case IVL_LPM_CMP_GT: // XXX Check for signed. id1 = create_concat_lpm_data(lpm); id2 = create_concat_lpm_datab(lpm); indent(); fprintf(output, " (lt %i %i %i %i)\n", id_of_nexus(ivl_lpm_q(lpm, 0), 1), width, id2, id1); break; case IVL_LPM_CMP_GE: // XXX Check for signed. id1 = create_concat_lpm_data(lpm); id2 = create_concat_lpm_datab(lpm); id = new_id(); indent(); fprintf(output, " (lt %i %i %i %i)\n", id, width, id1, id2); indent(); fprintf(output, " (not %i 1 %i)\n", id_of_nexus(ivl_lpm_q(lpm, 0), 1), id); break; case IVL_LPM_FF: { ivl_nexus_t async_clr = ivl_lpm_async_clr(lpm); ivl_nexus_t async_set = ivl_lpm_async_set(lpm); ivl_nexus_t sync_clr = ivl_lpm_sync_clr(lpm); ivl_nexus_t sync_set = ivl_lpm_sync_set(lpm); ivl_nexus_t clk = ivl_lpm_clk(lpm); ivl_nexus_t enable = ivl_lpm_enable(lpm); if (async_set || sync_set) { perror("** ERROR: Does not support registers with async or sync sets.\n"); return -1; } id = new_id(); id1 = create_concat_lpm_data(lpm); if (enable) { id2 = new_id(); indent(); fprintf(output, " (mux %i %i %i %i %i)\n", id2, width, id_of_nexus(enable, 0), id, id1); id1 = id2; } if (sync_clr) { id2 = new_id(); id3 = new_id(); indent(); fprintf(output, " (const %i \"", id3); for (j = 0; j < width; j++) fprintf(output, "0"); fprintf(output, "\")\n"); indent(); fprintf(output, " (mux %i %i %i %i %i)\n", id2, width, id_of_nexus(sync_clr, 0), id1, id3); id1 = id2; } // XXX Default to posedge sensitivity. if (async_clr) { indent(); fprintf(output, " (ffc %i %i %i %i %i)\n", id, width, id_of_nexus(async_clr, 0), id_of_nexus(clk, 0), id1); } else { indent(); fprintf(output, " (ff %i %i %i %i)\n", id, width, id_of_nexus(clk, 0), id1); } create_split_lpm_q(lpm, id); } break; case IVL_LPM_MUX: { unsigned t = 1; selects = ivl_lpm_selects(lpm); size = ivl_lpm_size(lpm); for (j = 0; j < selects; j++) t = t * 2; assert(t == size); // General case. id = create_mux(lpm, selects, 0); create_split_lpm_q(lpm, id); } break; default: perror("** ERROR: Unsupported LPM type.\n"); return -1; } } level = level + 1; return_code = ivl_scope_children(scope, build_hierarchy, 0); level = level - 1; if (! level) delete_nexus_table(nexus_table); indent(); fprintf(output, "))\n"); return return_code; } /* Ivl entry point. */ int target_design(ivl_design_t des) { design = des; output = fopen(ivl_design_flag(design, "-o"), "w"); if (output == 0) { /* perror("** ERROR: Can not opening output file \"%s\".\n\n", ivl_design_flag(design, "-o")); */ perror(ivl_design_flag(design, "-o")); return -1; } level = 0; build_hierarchy(ivl_design_root(design), 0); design = 0; fclose(output); output = 0; return 0; } confluence-0.10.6/src/ivl/ivl_target.h0100644002340600244710000013671610266541665017244 0ustar hawkit1cadgrp#ifndef __ivl_target_H #define __ivl_target_H /* * Copyright (c) 2000-2003 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT #ident "$Id: ivl_target.h,v 1.1.1.1 2005/07/17 20:46:45 thawk Exp $" #endif #ifdef __cplusplus #define _BEGIN_DECL extern "C" { #define _END_DECL } #else #define _BEGIN_DECL #define _END_DECL #endif _BEGIN_DECL /* * This header file describes the API for the loadable target * module. The main program can load these modules and access the * functions within the loaded module to implement the backend * behavior. * * The interface is divided into two parts: the entry points within * the core that are called by the module, and the entry points in * the module that are called by the core. It is the latter that * causes the module to be invoked in the first place, but most of the * interesting information about the design is accessed through the * various access functions that the modules calls into the core. */ /* * In order to grab onto data in the design, the core passes cookies * to the various functions of the module. These cookies can in turn * be passed to access functions in the core to get more detailed * information. * * The following typedefs list the various cookies that may be passed * around. * * ivl_design_t * This object represents the entire elaborated design. Various * global properties and methods are available from this. * * ivl_event_t * This object represents an event node. An event node stands for * named events written explicitly in the Verilog, and net events * that are implicit when @ statements are used. * * ivl_expr_t * This object represents a node of an expression. If the * expression has sub-expressions, they can be accessed from * various method described below. The ivl_expr_type method in * particular gets the type of the node in the form of an * ivl_expr_type_t enumeration value. * * Objects of this type represent expressions in * processes. Structural expressions are instead treated as logic * gates. * * ivl_lpm_t * This object is the base class for all the various LPM type * device nodes. This object carries a few base properties * (including a type) including a handle to the specific type. * * ivl_net_logic_t * This object represents various built in logic devices. In fact, * this includes just about every directional device that has a * single output, including logic gates and nmos, pmos and cmos * devices. There is also the occasional Icarus Verilog creation. * * ivl_nexus_t * Structural links within an elaborated design are connected * together at each bit. The connection point is a nexus, so pins * of devices refer to an ivl_nexus_t. Furthermore, from a nexus * there are backward references to all the device pins that point * to it. * * ivl_parameter_t * Scopes have zero or more parameter objects that represent * parameters that the source defined. The parameter has a value * that is fully elaborated, with defparams and other parameter * overrides taken care of. * * ivl_process_t * A Verilog process is represented by one of these. A process may * be an "initial" or an "always" process. These come from initial * or always statements from the Verilog source. * * ivl_scope_t * Elaborated scopes within a design are represented by this * type. Objects of this type also act as containers for scoped * objects such as signals. * * ivl_statement_t * Statements within processes are represented by one of these. The * ivl_process_t object holds one of these, but a statement may in * turn contain other statements. * * -- A Note About Bit Sets -- * Some objects hold a value as an array of bits. In these cases there * is some method that retrieves the width of the value and another * that returns a "char*". The latter is a pointer to the least * significant bit value. Bit values are represented by the characters * '0', '1', 'x' and 'z'. Strengths are stored elsewhere. * * -- A Note About Names -- * The names of objects are complete, hierarchical names. That is, * they include the instance name of the module that contains them. * * basenames are the name of the object without the containing * scope. These names are unique within a scope, but not necessarily * throughout the design. */ typedef struct ivl_design_s *ivl_design_t; typedef struct ivl_event_s *ivl_event_t; typedef struct ivl_expr_s *ivl_expr_t; typedef struct ivl_lpm_s *ivl_lpm_t; typedef struct ivl_lval_s *ivl_lval_t; typedef struct ivl_net_const_s*ivl_net_const_t; typedef struct ivl_net_logic_s*ivl_net_logic_t; typedef struct ivl_udp_s *ivl_udp_t; typedef struct ivl_net_probe_s*ivl_net_probe_t; typedef struct ivl_nexus_s *ivl_nexus_t; typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t; typedef struct ivl_parameter_s*ivl_parameter_t; typedef struct ivl_process_s *ivl_process_t; typedef struct ivl_scope_s *ivl_scope_t; typedef struct ivl_signal_s *ivl_signal_t; typedef struct ivl_memory_s *ivl_memory_t; typedef struct ivl_statement_s*ivl_statement_t; typedef struct ivl_variable_s *ivl_variable_t; /* * These are types that are defined as enumerations. These have * explicit values so that the binary API is a bit more resilient to * changes and additions to the enumerations. */ typedef enum ivl_drive_e { IVL_DR_HiZ = 0, IVL_DR_SMALL = 1, IVL_DR_MEDIUM = 2, IVL_DR_WEAK = 3, IVL_DR_LARGE = 4, IVL_DR_PULL = 5, IVL_DR_STRONG = 6, IVL_DR_SUPPLY = 7 } ivl_drive_t; /* This is the type of an ivl_expr_t object. The explicit numbers allow additions to the enumeration without causing values to shift and incompatibilities to be introduced. */ typedef enum ivl_expr_type_e { IVL_EX_NONE = 0, IVL_EX_BITSEL = 1, IVL_EX_BINARY = 2, IVL_EX_CONCAT = 3, IVL_EX_EVENT = 17, IVL_EX_MEMORY = 4, IVL_EX_NUMBER = 5, IVL_EX_SCOPE = 6, IVL_EX_SELECT = 7, IVL_EX_SFUNC = 8, IVL_EX_SIGNAL = 9, IVL_EX_STRING = 10, IVL_EX_TERNARY = 11, IVL_EX_UFUNC = 12, IVL_EX_ULONG = 13, IVL_EX_UNARY = 14, IVL_EX_VARIABLE = 15, IVL_EX_REALNUM = 16 } ivl_expr_type_t; /* This is the type code for an ivl_net_logic_t object. */ typedef enum ivl_logic_e { IVL_LO_NONE = 0, IVL_LO_AND = 1, IVL_LO_BUF = 2, IVL_LO_BUFIF0 = 3, IVL_LO_BUFIF1 = 4, IVL_LO_BUFZ = 5, IVL_LO_NAND = 6, IVL_LO_NMOS = 7, IVL_LO_NOR = 8, IVL_LO_NOT = 9, IVL_LO_NOTIF0 = 10, IVL_LO_NOTIF1 = 11, IVL_LO_OR = 12, IVL_LO_PULLDOWN = 13, IVL_LO_PULLUP = 14, IVL_LO_RNMOS = 15, IVL_LO_RPMOS = 16, IVL_LO_PMOS = 17, IVL_LO_XNOR = 18, IVL_LO_XOR = 19, IVL_LO_EEQ = 20, IVL_LO_UDP = 21 } ivl_logic_t; /* This is the type of an LPM object. */ typedef enum ivl_lpm_type_e { IVL_LPM_ADD = 0, IVL_LPM_CMP_EQ = 10, IVL_LPM_CMP_GE = 1, IVL_LPM_CMP_GT = 2, IVL_LPM_CMP_NE = 11, IVL_LPM_DIVIDE = 12, IVL_LPM_FF = 3, IVL_LPM_MOD = 13, IVL_LPM_MULT = 4, IVL_LPM_MUX = 5, IVL_LPM_SHIFTL = 6, IVL_LPM_SHIFTR = 7, IVL_LPM_SUB = 8, IVL_LPM_RAM = 9, IVL_LPM_UFUNC = 14 } ivl_lpm_type_t; /* Processes are initial or always blocks with a statement. This is the type of the ivl_process_t object. */ typedef enum ivl_process_type_e { IVL_PR_INITIAL = 0, IVL_PR_ALWAYS = 1 } ivl_process_type_t; /* These are the sorts of reasons a scope may come to be. These types are properties of ivl_scope_t objects. */ typedef enum ivl_scope_type_e { IVL_SCT_MODULE = 0, IVL_SCT_FUNCTION= 1, IVL_SCT_TASK = 2, IVL_SCT_BEGIN = 3, IVL_SCT_FORK = 4 } ivl_scope_type_t; /* Signals (ivl_signal_t) that are ports into the scope that contains them have a port type. Otherwise, they are port IVL_SIP_NONE. */ typedef enum ivl_signal_port_e { IVL_SIP_NONE = 0, IVL_SIP_INPUT = 1, IVL_SIP_OUTPUT= 2, IVL_SIP_INOUT = 3 } ivl_signal_port_t; /* This is the type code for an ivl_signal_t object. Implicit types are resolved by the core compiler, and integers are converted into signed registers. */ typedef enum ivl_signal_type_e { IVL_SIT_NONE = 0, IVL_SIT_REG, IVL_SIT_SUPPLY0, IVL_SIT_SUPPLY1, IVL_SIT_TRI, IVL_SIT_TRI0, IVL_SIT_TRI1, IVL_SIT_TRIAND, IVL_SIT_TRIOR } ivl_signal_type_t; /* This is the type code for ivl_statement_t objects. */ typedef enum ivl_statement_type_e { IVL_ST_NONE = 0, IVL_ST_NOOP = 1, IVL_ST_ASSIGN = 2, IVL_ST_ASSIGN_NB = 3, IVL_ST_BLOCK = 4, IVL_ST_CASE = 5, IVL_ST_CASER = 24, /* Case statement with real expressions. */ IVL_ST_CASEX = 6, IVL_ST_CASEZ = 7, IVL_ST_CASSIGN = 8, IVL_ST_CONDIT = 9, IVL_ST_DEASSIGN = 10, IVL_ST_DELAY = 11, IVL_ST_DELAYX = 12, IVL_ST_DISABLE = 13, IVL_ST_FORCE = 14, IVL_ST_FOREVER = 15, IVL_ST_FORK = 16, IVL_ST_RELEASE = 17, IVL_ST_REPEAT = 18, IVL_ST_STASK = 19, IVL_ST_TRIGGER = 20, IVL_ST_UTASK = 21, IVL_ST_WAIT = 22, IVL_ST_WHILE = 23 } ivl_statement_type_t; /* This is the type of a variable, and also used as the type for an expression. */ typedef enum ivl_variable_type_e { IVL_VT_VOID = 0, /* Not used */ IVL_VT_REAL, IVL_VT_VECTOR } ivl_variable_type_t; /* This is the type of the function to apply to a process. */ typedef int (*ivl_process_f)(ivl_process_t net, void*cd); /* This is the type of a function to apply to a scope. The ivl_scope_t parameter is the scope, and the cd parameter is client data that the user passes to the scanner. */ typedef int (ivl_scope_f)(ivl_scope_t net, void*cd); /* Attributes, which can be attached to various object types, have this form. */ typedef enum ivl_attribute_type_e { IVL_ATT_VOID = 0, IVL_ATT_STR, IVL_ATT_NUM } ivl_attribute_type_t; struct ivl_attribute_s { const char*key; ivl_attribute_type_t type; union val_ { const char*str; long num; } val; }; typedef const struct ivl_attribute_s*ivl_attribute_t; /* DESIGN * When handed a design (ivl_design_t) there are a few things that you * can do with it. The Verilog program has one design that carries the * entire program. Use the design methods to iterate over the elements * of the design. * * ivl_design_flag * This function returns the string value of a named flag. Flags * come from the "-fkey=value" options to the iverilog command and * are stored in a map for this function. Given the key, this * function returns the value. * * The special key "-o" is the argument to the -o flag of the * command line (or the default if the -o flag is not used) and is * generally how the target learns the name of the output file. * * ivl_design_process * This function scans the processes (threads) in the design. It * calls the user supplied function on each of the processes until * one of the functors returns non-0 or all the processes are * scanned. This function will return 0, or the non-zero value that * was returned from the last scanned process. * * ivl_design_root * A design has a root named scope that is an instance of the top * level module in the design. This is a hook for naming the * design, or for starting the scope scan. * * ivl_design_time_precision * A design as a time precision. This is the size in seconds (a * signed power of 10) of a simulation tick. */ extern const char* ivl_design_flag(ivl_design_t des, const char*key); extern int ivl_design_process(ivl_design_t des, ivl_process_f fun, void*cd); extern ivl_scope_t ivl_design_root(ivl_design_t des); extern void ivl_design_roots(ivl_design_t des, ivl_scope_t **scopes, unsigned int *nscopes); extern int ivl_design_time_precision(ivl_design_t des); extern unsigned ivl_design_consts(ivl_design_t des); extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx); /* * These methods apply to ivl_net_const_t objects. */ extern const char* ivl_const_bits(ivl_net_const_t net); extern ivl_nexus_t ivl_const_pin(ivl_net_const_t net, unsigned idx); extern unsigned ivl_const_pins(ivl_net_const_t net); extern int ivl_const_signed(ivl_net_const_t net); /* EVENTS * * Events are a unification of named events and implicit events * generated by the @ statements. * * ivl_event_name (Obsolete) * ivl_event_basename * Return the name of the event. The basename is the name within * the scope, as declared by the user. * * ivl_event_edge * Return the edge type for the event. If this is a named event * that has no network input, then the edge is IVL_EDGE_NONE. */ extern const char* ivl_event_name(ivl_event_t net); extern const char* ivl_event_basename(ivl_event_t net); extern unsigned ivl_event_nany(ivl_event_t net); extern ivl_nexus_t ivl_event_any(ivl_event_t net, unsigned idx); extern unsigned ivl_event_nneg(ivl_event_t net); extern ivl_nexus_t ivl_event_neg(ivl_event_t net, unsigned idx); extern unsigned ivl_event_npos(ivl_event_t net); extern ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx); /* EXPRESSIONS * * These methods operate on expression objects from the * design. Expressions mainly exist in behavioral code. The * ivl_expr_type() function returns the type of the expression node, * and the remaining functions access value bits of the expression. * * ivl_expr_signed * This method returns true (!= 0) if the expression node * represents a signed expression. It is possible for sub- * expressions to be unsigned even if a node is signed, but the * IVL core figures all this out for you. At any rate, this method * can be applied to any expression node. * * ivl_expr_type * Get the type of the expression node. Every expression node has a * type, which can affect how some of the other expression methods * operate on the node * * ivl_expr_value * Get the data type of the expression node. This uses the variable * type enum to express the type of the expression node. * * ivl_expr_width * This method returns the bit width of the expression at this * node. It can be applied to any expression node, and returns the * *output* width of the expression node. * * ivl_expr_parameter * This function returns the ivl_parameter_t object that represents * this object, or 0 (nil) if it is not a parameter value. This * function allows the code generator to detect the case where the * expression is a parameter. This will normally only return a * non-nil value for constants. * * ivl_expr_opcode * IVL_EX_BINARY and IVL_EX_UNARY expression nodes include an * opcode from this table: * & -- AND * A -- NAND (~&) * X -- XNOR (~^) */ extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net); extern ivl_variable_type_t ivl_expr_value(ivl_expr_t net); /* IVL_EX_NUMBER */ extern const char* ivl_expr_bits(ivl_expr_t net); /* IVL_EX_UFUNC */ extern ivl_scope_t ivl_expr_def(ivl_expr_t net); /* IVL_EX_REALNUM */ extern double ivl_expr_dvalue(ivl_expr_t net); /* IVL_EX_SIGNAL */ extern unsigned ivl_expr_lsi(ivl_expr_t net); /* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_VARIABLE */ extern const char* ivl_expr_name(ivl_expr_t net); /* IVL_EX_BINARY IVL_EX_UNARY */ extern char ivl_expr_opcode(ivl_expr_t net); /* IVL_EX_BINARY IVL_EX_BITSEL IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_TERNARY */ extern ivl_expr_t ivl_expr_oper1(ivl_expr_t net); /* IVL_EX_BINARY IVL_EX_TERNARY */ extern ivl_expr_t ivl_expr_oper2(ivl_expr_t net); /* IVL_EX_TERNARY */ extern ivl_expr_t ivl_expr_oper3(ivl_expr_t net); /* and expression */ extern ivl_parameter_t ivl_expr_parameter(ivl_expr_t net); /* IVL_EX_CONCAT IVL_EX_UFUNC */ extern ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx); /* IVL_EX_CONCAT IVL_EX_SFUNC IVL_EX_UFUNC */ extern unsigned ivl_expr_parms(ivl_expr_t net); /* IVL_EX_CONCAT */ extern unsigned ivl_expr_repeat(ivl_expr_t net); /* IVL_EX_EVENT */ extern ivl_event_t ivl_expr_event(ivl_expr_t net); /* IVL_EX_SCOPE */ extern ivl_scope_t ivl_expr_scope(ivl_expr_t net); /* IVL_EX_BITSEL */ extern ivl_signal_t ivl_expr_signal(ivl_expr_t net); /* any expression */ extern int ivl_expr_signed(ivl_expr_t net); /* IVL_EX_STRING */ extern const char* ivl_expr_string(ivl_expr_t net); /* IVL_EX_ULONG */ extern unsigned long ivl_expr_uvalue(ivl_expr_t net); /* IVL_EX_VARIABLE */ extern ivl_variable_t ivl_expr_variable(ivl_expr_t net); /* any expression */ extern unsigned ivl_expr_width(ivl_expr_t net); /* * Memory. * * ivl_memory_name (DEPRECATED) * * ivl_memory_basename * This returns the base name of the memory object. The base name * does not include the name of the scopes that contains the object. * * ivl_memory_size * ivl_memory_width * These functions return the dimensions of the memory. The size is * the number of words in the memory, and the width is the number * of bits in each word. * * ivl_memory_scope * This returns the scope that contains the memory. */ extern const char*ivl_memory_basename(ivl_memory_t net); extern int ivl_memory_root(ivl_memory_t net); extern ivl_scope_t ivl_memory_scope(ivl_memory_t net); extern unsigned ivl_memory_size(ivl_memory_t net); extern unsigned ivl_memory_width(ivl_memory_t net); extern ivl_memory_t ivl_expr_memory(ivl_expr_t net); /* LOGIC * These types and functions support manipulation of logic gates. The * ivl_logic_t enumeration identifies the various kinds of gates that * the ivl_net_logic_t can represent. The various functions then * provide access to the bits of information for a given logic device. * * ivl_logic_type * This method returns the type of logic gate that the cookie * represents. * * ivl_logic_name (obsolete) * This method returns the complete name of the logic gate. Every * gate has a complete name (that includes the scope) even if the * Verilog source doesn't include one. The compiler will choose one * if necessary. * * ivl_logic_basename * This is the name of the gate without the scope part. * * ivl_logic_scope * This is the scope that directly contains the logic device. * * ivl_logic_pins * ivl_logic_pin * Return the nexus for the pin. If two pins are connected * together, then these values are the same. Use the nexus * functions to find other pins that are connected to this nexus. * * ivl_logic_attr (obsolete) * Return the value of a specific attribute, given the key name as * a string. If the key is not defined, then return 0 (null). * * ivl_logic_attr_cnt * ivl_logic_attr_val * These support iterating over logic attributes. The _cnt method * returns the number of attributes attached to the gate, and the * ivl_logic_attr_val returns the value of the attribute. */ extern const char* ivl_logic_name(ivl_net_logic_t net); extern const char* ivl_logic_basename(ivl_net_logic_t net); extern ivl_scope_t ivl_logic_scope(ivl_net_logic_t net); extern ivl_logic_t ivl_logic_type(ivl_net_logic_t net); extern ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin); extern unsigned ivl_logic_pins(ivl_net_logic_t net); extern ivl_udp_t ivl_logic_udp(ivl_net_logic_t net); extern unsigned ivl_logic_delay(ivl_net_logic_t net, unsigned transition); /* DEPRECATED */ extern const char* ivl_logic_attr(ivl_net_logic_t net, const char*key); extern unsigned ivl_logic_attr_cnt(ivl_net_logic_t net); extern ivl_attribute_t ivl_logic_attr_val(ivl_net_logic_t net, unsigned idx); /* UDP * */ extern unsigned ivl_udp_sequ(ivl_udp_t net); extern unsigned ivl_udp_nin(ivl_udp_t net); extern unsigned ivl_udp_init(ivl_udp_t net); extern const char* ivl_udp_row(ivl_udp_t net, unsigned idx); extern unsigned ivl_udp_rows(ivl_udp_t net); extern const char* ivl_udp_name(ivl_udp_t net); /* LPM * These functions support access to the properties of LPM * devices. LPM devices are a variety of devices that handle more * complex structural semantics. * * These are the functions that apply to all LPM devices: * * ivl_lpm_name (Obsolete) * ivl_lpm_basename * Return the name of the device. The name is the name of the * device with the scope part, and the basename is without the scope. * * ivl_lpm_scope * LPM devices exist within a scope. Return the scope that contains * this device. * * ivl_lpm_type * Return the ivl_lpm_type_t of the specific LPM device. * * ivl_lpm_width * Return the width of the LPM device. What this means depends on * the LPM type, but it generally has to do with the width of the * output data path. * * * These functions apply to a subset of the LPM devices, or may have * varying meaning depending on the device: * * ivl_lpm_data * Return the input data nexus for device types that have a single * input vector. This is also used to the get nexa of the first * vector for devices that have more inputs. * * ivl_lpm_datab * Return the input data nexus for device types that have a second * input vector. For example, arithmetic devices are like this. * * ivl_lpm_q * Return the output data nexus for device types that have a single * output vector. This is most devices, it turns out. * * ivl_lpm_selects * This is the size of the select input for a LPM_MUX device, or the * address bus width of an LPM_RAM. * * ivl_lpm_signed * Arithmetic LPM devices may be signed or unsigned if there is a * distinction. * * ivl_lpm_size * In addition to a width, some devices have a size. The size is * often the number of inputs per out, i.e., the number of inputs * per bit for a MUX. */ extern const char* ivl_lpm_name(ivl_lpm_t net); /* (Obsolete) */ extern const char* ivl_lpm_basename(ivl_lpm_t net); extern ivl_scope_t ivl_lpm_scope(ivl_lpm_t net); extern int ivl_lpm_signed(ivl_lpm_t net); extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net); extern unsigned ivl_lpm_width(ivl_lpm_t net); /* IVL_LPM_FF */ extern ivl_nexus_t ivl_lpm_async_clr(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_async_set(ivl_lpm_t net); extern ivl_expr_t ivl_lpm_aset_value(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_sync_clr(ivl_lpm_t net); extern ivl_nexus_t ivl_lpm_sync_set(ivl_lpm_t net); extern ivl_expr_t ivl_lpm_sset_value(ivl_lpm_t net); /* IVL_LPM_FF IVL_LPM_RAM */ extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net); /* IVL_LPM_UFUNC */ extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net); /* IVL_LPM_FF IVL_LPM_RAM */ extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net); /* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */ extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx); /* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */ /* IVL_LPM_MUX IVL_LPM_UFUNC */ extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx); extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx); /* IVL_LPM_UFUNC */ extern unsigned ivl_lpm_data2_width(ivl_lpm_t net, unsigned sdx); /* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB IVL_LPM_UFUNC */ extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx); /* IVL_LPM_MUX IVL_LPM_RAM */ extern unsigned ivl_lpm_selects(ivl_lpm_t net); /* IVL_LPM_MUX IVL_LPM_RAM */ extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx); /* IVL_LPM_MUX */ extern unsigned ivl_lpm_size(ivl_lpm_t net); /* IVL_LPM_RAM */ extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net); /* LVAL * The l-values of assignments are concatenation of ivl_lval_t * objects. Each lvi_lval_t object is an assignment to a var or a * memory, through a bit select, part select or word select. * * Var lvals are things like assignments to a part select or a bit * select. Assignment to the whole variable is a special case of a * part select, as is a bit select with a constant expression. The * ivl_lval_pins statement returns the width of the part select for * the lval. The ivl_lval_pin function returns the nexus to the N-th * bit of the part select. The compiler takes care of positioning the * part select so that ivl_lval_pin(net, 0) is the proper bit in the * signal. * * ivl_lval_mux * If the l-value includes a bit select expression, this method * returns an ivl_expr_t that represents that * expression. Otherwise, it returns 0. * * ivl_lval_mem * If the l-value is a memory, this method returns an * ivl_memory_t that represents that memory. Otherwise, it * returns 0. * * ivl_lval_sig * If the l-value is a variable, this method returns the signal * object that is the target of the assign. * * ivl_lval_var * If the l-value is a non-signal variable (i.e. a real) this * method returns the ivl_variable_t object that represents it. * If the lval is this sort of variable, then the part_off, idx and * pin methods do not apply. * * ivl_lval_part_off * The part select of the signal is based here. This is the * canonical index of bit-0 of the part select. * * ivl_lval_idx * If the l-value is a memory, this method returns an * ivl_expr_t that represents the index expression. Otherwise, it * returns 0. * * ivl_lval_pin * Return an ivl_nexus_t for the connection of the ivl_lval_t. * * ivl_lval_pins * Return the number of pins for this object. */ extern ivl_expr_t ivl_lval_mux(ivl_lval_t net); extern ivl_expr_t ivl_lval_idx(ivl_lval_t net); extern ivl_memory_t ivl_lval_mem(ivl_lval_t net); extern ivl_variable_t ivl_lval_var(ivl_lval_t net); extern unsigned ivl_lval_part_off(ivl_lval_t net); extern unsigned ivl_lval_pins(ivl_lval_t net); extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx); extern ivl_signal_t ivl_lval_sig(ivl_lval_t net); /* NEXUS * connections of signals and nodes is handled by single-bit * nexus. These functions manage the ivl_nexus_t object. They also * manage the ivl_nexus_ptr_t objects that are closely related to the * nexus. * * ivl_nexus_name * Each nexus is given a name, typically derived from the signals * connected to it, but completely made up if need be. The name of * every nexus is unique. * * ivl_nexus_ptrs * This function returns the number of pointers that are held by * the nexus. It should always return at least 1. The pointer * proper is accessed by index. * * ivl_nexus_ptr * Return a nexus pointer given the nexus and an index. * * ivl_nexus_set_private * ivl_nexus_get_private * The target module often needs to associate data with a nexus for * later use when the nexus is encountered associated with a * device. These methods allow the code generator to store to or * retrieve from a nexus a void* of private data. This pointer is * guaranteed to be 0 before the target module is invoked. * * Once an ivl_nexus_ptr_t is selected by the ivl_nexus_ptr method, * the properties of the pointer can be accessed by the following * methods: * * ivl_nexus_ptr_pin * This returns the pin number of the device where this nexus * points. It is the bit within the signal or logic device that is * connected to the nexus. * * If the target is an LPM device, then this value is zero, and it * is up to the application to find the pin that refers to this * nexus. The problem is that LPM devices do not have a pinout per * se, the pins all have specific names. * * ivl_nexus_ptr_con * If this is a pointer to a magic constant device, then this * returns the net_const object. * * ivl_nexus_ptr_drive0 * ivl_nexus_ptr_drive1 * These are the 0 and 1 strength values for the devices. For most * devices, these values are fixed by the description in the * original source, with the default as IVL_DR_STRONG. For pins * that are input only, drive0 and drive1 are both IVL_DR_HiZ. * * The strength of strength-aware devices (such as nmos devices) * does not really matter, as long at the output is not * IVL_DR_HiZ. Testing for HiZ drivers is how code generators * detect inputs. * * ivl_nexus_ptr_log * If the target object is an ivl_net_logic_t, this method returns * the object. Otherwise, this method returns 0. * * ivl_nexus_ptr_lpm * If the target object is an ivl_lpm_t, this method returns the * object. Otherwise, this method returns 0. * * ivl_nexus_ptr_sig * If the target object is an ivl_signal_t, this method returns the * object. If the target is not a signal, this method returns 0. */ extern const char* ivl_nexus_name(ivl_nexus_t net); extern unsigned ivl_nexus_ptrs(ivl_nexus_t net); extern ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx); extern void ivl_nexus_set_private(ivl_nexus_t net, void*data); extern void* ivl_nexus_get_private(ivl_nexus_t net); extern ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net); extern ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net); extern unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net); extern ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net); extern ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net); extern ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net); extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net); /* PARAMETER * Parameters are named constants associated with a scope. The user * may set in the Verilog source the value of parameters, and that * leads to ivl_parameter_t objects contained in the ivl_scope_t * objects. * * Parameters are essentially named constants. These constant values * can be accessed by looking at the scope (using ivl_scope_param) or * they can be discovered when they are used, via the * ivl_expr_parameter function. The fact that a constant has a name * (i.e. is a parameter) does not otherwise impose on the value or * interpretation of the constant expression so far as ivl_target is * concerned. The target may need this information, or may choose to * completely ignore it. * * ivl_parameter_basename * return the name of the parameter. * * ivl_parameter_scope * Return the scope of the parameter. The parameter name is only * unique within its scope. * * ivl_parameter_expr * Return the value of the parameter. This should be a simple * constant expression, an IVL_EX_STRING or IVL_EX_NUMBER. */ extern const char* ivl_parameter_basename(ivl_parameter_t net); extern ivl_scope_t ivl_parameter_scope(ivl_parameter_t net); extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net); /* SCOPE * Scopes of various sort have these properties. Use these methods to * access them. Scopes come to exist in the elaborated design * generally when a module is instantiated, though they also come from * named blocks, tasks and functions. * * - module instances (IVL_SCT_MODULE) * A module instance scope may contain events, logic gates, lpm * nodes, signals, and possibly children. The children are further * instances, or function/task scopes. Module instances do *not* * contain a definition. * * - function scopes (IVL_SCT_FUNCTION) * These scopes represent functions. A function may not be a root, * so it is contained within a module instance scope. A function is * required to have a definition (in the form of a statement) and a * signal (IVL_SIG_REG) that is its return value. * * A single function scope is created each time the module with the * definition is instantiated. * * * - task scopes (IVL_SCT_TASK) * [...] * * ivl_scope_attr_cnt * ivl_scope_attr_val * A scope may have attributes attached to it. These functions * allow the target to access the attributes values. * * ivl_scope_children * A scope may in turn contain other scopes. This method iterates * through all the child scopes of a given scope. If the function * returns any value other then 0, the iteration stops and the * method returns that value. Otherwise, iteration continues until * the children run out. * * If the scope has no children, this method will return 0 and * otherwise do nothing. * * ivl_scope_def * Task definition scopes carry a task definition, in the form of * a statement. This method accesses that definition. * * ivl_scope_event * ivl_scope_events * Scopes have 0 or more event objects in them. * * ivl_scope_var * ivl_scope_vars * Scopes have 0 or more variable objects in them. * * ivl_scope_log * ivl_scope_logs * Scopes have 0 or more logic devices in them. A logic device is * represented by ivl_logic_t. * * ivl_scope_lpm * ivl_scope_lpms * Scopes have 0 or more LPM devices in them. These functions access * those devices. * * ivl_scope_name * ivl_scope_basename * Every scope has a hierarchical name. This name is also a prefix * of all the names of objects contained within the scope. The * ivl_scope_basename is the name of the scope without the included * hierarchy. * * ivl_scope_param * ivl_scope_params * A scope has zero or more named parameters. These parameters have * a name and an expression value. * * ivl_scope_parent * If this is a non-root scope, then the parent is the scope that * contains this scope. Otherwise, the parent is nil. * * ivl_scope_port * ivl_scope_ports * Scopes that are functions or tasks have ports defined by * signals. These methods access the ports by name. * * If this scope represents a function, then the ports list * includes the return value, as port 0. The remaining ports are * the input ports in order. * * ivl_scope_sig * ivl_scope_sigs * Scopes have 0 or more signals in them. These signals are * anything that can become and ivl_signal_t, include synthetic * signals generated by the compiler. * * ivl_scope_time_units * Scopes have their own intrinsic time units, typically from the * timescale compiler directive. This method returns the units as a * signed power of 10 value. * * ivl_scope_type * ivl_scope_tname * Scopes have a type and a type name. For example, if a scope is * an instance of module foo, its type is IVL_SCT_MODULE and its * type name is "foo". This is different from the instance name * returned by ivl_scope_name above. */ extern unsigned ivl_scope_attr_cnt(ivl_scope_t net); extern ivl_attribute_t ivl_scope_attr_val(ivl_scope_t net, unsigned idx); extern int ivl_scope_children(ivl_scope_t net, ivl_scope_f func, void*cd); extern ivl_statement_t ivl_scope_def(ivl_scope_t net); extern unsigned ivl_scope_events(ivl_scope_t net); extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_logs(ivl_scope_t net); extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_lpms(ivl_scope_t net); extern ivl_lpm_t ivl_scope_lpm(ivl_scope_t, unsigned idx); extern unsigned ivl_scope_mems(ivl_scope_t net); extern ivl_memory_t ivl_scope_mem(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_vars(ivl_scope_t net); extern ivl_variable_t ivl_scope_var(ivl_scope_t net, unsigned idx); extern const char* ivl_scope_name(ivl_scope_t net); extern const char* ivl_scope_basename(ivl_scope_t net); extern unsigned ivl_scope_params(ivl_scope_t net); extern ivl_parameter_t ivl_scope_param(ivl_scope_t net, unsigned idx); extern ivl_scope_t ivl_scope_parent(ivl_scope_t net); extern unsigned ivl_scope_ports(ivl_scope_t net); extern ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx); extern unsigned ivl_scope_sigs(ivl_scope_t net); extern ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx); extern ivl_scope_type_t ivl_scope_type(ivl_scope_t net); extern const char* ivl_scope_tname(ivl_scope_t net); extern int ivl_scope_time_units(ivl_scope_t net); /* SIGNALS * Signals are named things in the Verilog source, like wires and * regs, and also named things that are created as temporaries during * certain elaboration or optimization steps. A signal may also be a * port of a module or task. * * Signals have a name (obviously) and types. A signal may also be * signed or unsigned. * * ivl_signal_pins * ivl_signal_pin * The ivl_signal_pin function returns the nexus connected to the * signal. If the signal is a vector, the idx can be a non-zero * value, and the result is the nexus for the specified bit. * * ivl_signal_msb * ivl_signal_lsb * These functions return the left and right indices, respectively, * of the signal. If the signal is a scalar, both return 0. However, * it doesn't mean that the signal is a scalar if both return 0, one * can have a vector with 0 as both indices. * * ivl_signal_port * If the signal is a port to a module, this function returns the * port direction. If the signal is not a port, it returns * IVL_SIP_NONE. * * ivl_signal_signed * A signal, which is a vector, may be signed. In Verilog 2000, any * net or variable may be signed. This function returns true if the * signal is signed. * * ivl_signal_local * A signal that was generated by the compiler as a place holder is * marked as local. * * ivl_signal_type * Return the type of the signal, i.e., reg, wire, tri0, etc. * * ivl_signal_name (DEPRECATED) * This function returns the fully scoped hierarchical name for the * signal. The name refers to the entire vector that is the signal. * * NOTE: This function is deprecated. The hierarchical name is too * vague a construct when escaped names can have . characters in * them. Do no use this function in new code, it will disappear. * * ivl_signal_basename * This function returns the name of the signal, without the scope * information. This is the tail of the signal name. Since Verilog * has an escape syntax, this name can contain any ASCII * characters, except NULL or white space. The leading \ and * trailing ' ' of escaped names in Verilog source are not part of * the name, so not included here. * * ivl_signal_attr * Icarus Verilog supports attaching attributes to signals, with * the attribute value (a string) associated with a key. This * function returns the attribute value for the given key. If the * key does not exist, the function returns 0. */ extern ivl_nexus_t ivl_signal_pin(ivl_signal_t net, unsigned idx); extern unsigned ivl_signal_pins(ivl_signal_t net); extern int ivl_signal_msb(ivl_signal_t net); extern int ivl_signal_lsb(ivl_signal_t net); extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net); extern int ivl_signal_signed(ivl_signal_t net); extern int ivl_signal_integer(ivl_signal_t net); extern int ivl_signal_local(ivl_signal_t net); extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net); extern const char* ivl_signal_name(ivl_signal_t net); extern const char* ivl_signal_basename(ivl_signal_t net); extern const char* ivl_signal_attr(ivl_signal_t net, const char*key); extern unsigned ivl_signal_attr_cnt(ivl_signal_t net); extern ivl_attribute_t ivl_signal_attr_val(ivl_signal_t net, unsigned idx); /* * These functions get information about a process. A process is * an initial or always block within the original Verilog source, that * is translated into a type and a single statement. (The statement * may be a compound statement.) * * The ivl_process_type function gets the type of the process, * an "initial" or "always" statement. * * A process is placed in a scope. The statement within the process * operates within the scope of the process unless there are calls * outside the scope. * * The ivl_process_stmt function gets the statement that forms the * process. See the statement related functions for how to manipulate * statements. * * Processes can have attributes attached to them. the attr_cnt and * attr_val methods return those attributes. */ extern ivl_process_type_t ivl_process_type(ivl_process_t net); extern ivl_scope_t ivl_process_scope(ivl_process_t net); extern ivl_statement_t ivl_process_stmt(ivl_process_t net); extern unsigned ivl_process_attr_cnt(ivl_process_t net); extern ivl_attribute_t ivl_process_attr_val(ivl_process_t net, unsigned idx); /* * These functions manage statements of various type. This includes * all the different kinds of statements (as enumerated in * ivl_statement_type_t) that might occur in behavioral code. * * The ivl_statement_type() function returns the type code for the * statement. This is the major type, and implies which of the later * functions are applicable to the statement. */ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net); /* * The following functions retrieve specific single values from the * statement. These values are the bits of data and parameters that * make up the statement. Many of these functions apply to more then * one type of statement, so the comment in front of them tells which * statement types can be passed to the function. * * ivl_stmt_block_scope * If the block is named, then there is a scope associated with * this. The code generator may need to know this in order to * handle disable statements. */ /* IVL_ST_BLOCK, IVL_ST_FORK */ extern unsigned ivl_stmt_block_count(ivl_statement_t net); /* IVL_ST_BLOCK, IVL_ST_FORK */ extern ivl_scope_t ivl_stmt_block_scope(ivl_statement_t net); /* IVL_ST_BLOCK, IVL_ST_FORK */ extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i); /* IVL_ST_UTASK IVL_ST_DISABLE */ extern ivl_scope_t ivl_stmt_call(ivl_statement_t net); /* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */ extern unsigned ivl_stmt_case_count(ivl_statement_t net); /* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */ extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i); /* IVL_ST_CASE,IVL_ST_CASER,IVL_ST_CASEX,IVL_ST_CASEZ */ extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i); /* IVL_ST_CONDIT IVL_ST_CASE IVL_ST_REPEAT IVL_ST_WHILE */ extern ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net); /* IVL_ST_CONDIT */ extern ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net); /* IVL_ST_CONDIT */ extern ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_DELAYX */ extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net); /* IVL_ST_DELAY */ extern unsigned long ivl_stmt_delay_val(ivl_statement_t net); /* IVL_ST_WAIT IVL_ST_TRIGGER */ extern unsigned ivl_stmt_nevent(ivl_statement_t net); extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN IVL_ST_FORCE IVL_ST_RELEASE */ extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN IVL_ST_FORCE IVL_ST_RELEASE */ extern unsigned ivl_stmt_lvals(ivl_statement_t net); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */ extern unsigned ivl_stmt_lwidth(ivl_statement_t net); /* IVL_ST_STASK */ extern const char* ivl_stmt_name(ivl_statement_t net); /* IVL_ST_CASSIGN IVL_ST_FORCE */ extern ivl_nexus_t ivl_stmt_nexus(ivl_statement_t net, unsigned idx); extern unsigned ivl_stmt_nexus_count(ivl_statement_t net); /* IVL_ST_STASK */ extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx); /* IVL_ST_STASK */ extern unsigned ivl_stmt_parm_count(ivl_statement_t net); /* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */ extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net); /* IVL_ST_DELAY, IVL_ST_DELAYX, IVL_ST_FOREVER, IVL_ST_REPEAT IVL_ST_WAIT, IVL_ST_WHILE */ extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net); /* * These functions manipulate variable objects. * * ivl_variable_name * Return the base name of the variable. * * ivl_variable_type * Return the type of the variable. The ivl_variable_type_t is an * enumeration that is defined earlier. */ extern const char* ivl_variable_name(ivl_variable_t net); extern ivl_variable_type_t ivl_variable_type(ivl_variable_t net); #if defined(__MINGW32__) || defined (__CYGWIN32__) # define DLLEXPORT __declspec(dllexport) #else # define DLLEXPORT #endif extern DLLEXPORT int target_design(ivl_design_t des); /* target_design The "target_design" function is called once after the whole design is processed and available to the target. The target doesn't return from this function until it is finished with the design. This function is implemented in the loaded target, and not in the ivl core. This function is how the target module is invoked. */ typedef int (*target_design_f)(ivl_design_t des); _END_DECL /* * $Log: ivl_target.h,v $ * Revision 1.1.1.1 2005/07/17 20:46:45 thawk * * * Revision 1.1.1.1 2005/07/17 20:42:27 thawk * * * Revision 1.1 2004/12/28 15:13:38 thawk * *** empty log message *** * * Revision 1.1.1.1 2004/10/12 16:30:24 thawk * * * Revision 1.126 2004/10/04 01:10:53 steve * Clean up spurious trailing white space. * * Revision 1.125 2004/09/25 01:58:12 steve * Some commentary on ivl_logic_pin. * * Revision 1.124 2003/12/03 02:46:24 steve * Add support for wait on list of named events. * * Revision 1.123 2003/11/08 20:06:21 steve * Spelling fixes in comments. * * Revision 1.122 2003/08/22 23:14:26 steve * Preserve variable ranges all the way to the vpi. * * Revision 1.121 2003/08/15 02:23:52 steve * Add synthesis support for synchronous reset. * * Revision 1.120 2003/07/30 01:13:28 steve * Add support for triand and trior. * * Revision 1.119 2003/06/23 01:25:44 steve * Module attributes make it al the way to ivl_target. * * Revision 1.118 2003/05/14 05:26:41 steve * Support real expressions in case statements. * * Revision 1.117 2003/04/22 04:48:29 steve * Support event names as expressions elements. * * Revision 1.116 2003/04/11 05:18:08 steve * Handle signed magnitude compare all the * way through to the vvp code generator. * * Revision 1.115 2003/03/10 23:40:53 steve * Keep parameter constants for the ivl_target API. * * Revision 1.114 2003/03/06 01:24:37 steve * Obsolete the ivl_event_name function. * * Revision 1.113 2003/03/06 00:28:41 steve * All NetObj objects have lex_string base names. * * Revision 1.112 2003/02/26 01:29:24 steve * LPM objects store only their base names. * * Revision 1.111 2003/01/30 16:23:07 steve * Spelling fixes. * * Revision 1.110 2003/01/26 21:15:58 steve * Rework expression parsing and elaboration to * accommodate real/realtime values and expressions. * * Revision 1.109 2002/12/21 00:55:58 steve * The $time system task returns the integer time * scaled to the local units. Change the internal * implementation of vpiSystemTime the $time functions * to properly account for this. Also add $simtime * to get the simulation time. */ #endif confluence-0.10.6/src/misc/0040755002340600244710000000000010312276327015051 5ustar hawkit1cadgrpconfluence-0.10.6/src/misc/intbig.mli0100644002340600244710000000503110266541665017034 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (* Intbig: arbitrary-precision integers. *) type intbig;; (* Constants. *) val zero : intbig;; val one : intbig;; val two : intbig;; val ones : intbig;; (* All ones. Same as -1. *) (* Arithmetics. *) val abs : intbig -> intbig;; val neg : intbig -> intbig;; val add : intbig -> intbig -> intbig;; val sub : intbig -> intbig -> intbig;; val mul : intbig -> intbig -> intbig;; val div : intbig -> intbig -> intbig;; val modu : intbig -> intbig -> intbig;; val pow : intbig -> intbig -> intbig;; (* Comparisons. *) val sign : intbig -> int;; val compare : intbig -> intbig -> int;; val eq : intbig -> intbig -> bool;; val ne : intbig -> intbig -> bool;; val le : intbig -> intbig -> bool;; val ge : intbig -> intbig -> bool;; val lt : intbig -> intbig -> bool;; val gt : intbig -> intbig -> bool;; (* Shifting. *) val shift_left : intbig -> intbig -> intbig;; val shift_right : intbig -> intbig -> intbig;; (* Bitwise logics. *) val bw_not : intbig -> intbig;; val bw_and : intbig -> intbig -> intbig;; val bw_or : intbig -> intbig -> intbig;; val bw_xor : intbig -> intbig -> intbig;; (* String conversion. *) val string_of_intbig : intbig -> string;; val intbig_of_string : string -> intbig;; val binary_string_of_intbig : intbig -> intbig -> string;; (* Value -> Width -> BinaryString *) val intbig_of_binary_string : string -> intbig;; (* Numeric type conversion. *) val int_of_intbig : intbig -> int;; val intbig_of_int : int -> intbig;; val char_of_intbig : intbig -> char;; val intbig_of_char : char -> intbig;; val float_of_intbig : intbig -> float;; val intbig_of_float : float -> intbig;; (* Unit tests. *) val test : string -> unit;; confluence-0.10.6/src/misc/intbig.ml0100644002340600244710000002167210266541665016674 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Intbig: arbitrary-precision integers. *) open Big_int;; type intbig = big_int;; (** Constants. *) let zero = zero_big_int;; let one = unit_big_int;; let two = add_big_int one one;; let ones = minus_big_int one;; let v16 = big_int_of_string "16";; (** Arithmetics. *) let abs = abs_big_int;; let neg = minus_big_int;; let add = add_big_int;; let sub = sub_big_int;; let mul = mult_big_int;; let div = div_big_int;; let modu = mod_big_int;; let pow a b = if lt_big_int b zero then raise (Invalid_argument "Intbig.pow: Right operand less than 0."); power_big_int_positive_big_int a b;; (** Comparisons. *) let sign = sign_big_int;; let compare = compare_big_int;; let eq = eq_big_int;; let ne a b = not (eq a b);; let le = le_big_int;; let ge = ge_big_int;; let lt = lt_big_int;; let gt = gt_big_int;; (** Shifting. *) let shift_left value shift = if lt shift zero then raise (Invalid_argument "Intbig.shift_left: Right operand less than 0."); mul value (pow two shift);; let shift_right value shift = if lt shift zero then raise (Invalid_argument "Intbig.shift_right: Right operand less than 0."); div value (pow two shift);; (** Bitwise logics. *) let bw_not a = sub (neg a) one;; let rec bw_and a b = if eq a zero && eq b zero then zero else if eq a zero && eq b ones then zero else if eq a ones && eq b zero then zero else if eq a ones && eq b ones then ones else let (aq, ar) = quomod_big_int a two in let (bq, br) = quomod_big_int b two in add (mul (bw_and aq bq) two) (div (add ar br) two);; let bw_or a b = bw_not (bw_and (bw_not a) (bw_not b));; let bw_xor a b = bw_or (bw_and a (bw_not b)) (bw_and (bw_not a) b);; (** String conversion. *) let rec binary_string_of_intbig1 value width sofar = if (le width zero) then sofar else binary_string_of_intbig1 (div value two) (sub width one) ((if (eq (modu value two) one) then "1" else "0") ^ sofar);; let binary_string_of_intbig value width = binary_string_of_intbig1 value width "";; let rec intbig_of_binary_string1 str factor sofar = if str = "" then sofar else intbig_of_binary_string1 (String2.left_string str) (mul factor two) (if String2.right_char str = '0' then sofar else (add sofar factor));; let rec intbig_of_binary_string str = intbig_of_binary_string1 str one zero;; let hexCharToInt hexChar = match hexChar with '0' -> 0 | '1' -> 1 | '2' -> 2 | '3' -> 3 | '4' -> 4 | '5' -> 5 | '6' -> 6 | '7' -> 7 | '8' -> 8 | '9' -> 9 | 'A' | 'a' -> 10 | 'B' | 'b' -> 11 | 'C' | 'c' -> 12 | 'D' | 'd' -> 13 | 'E' | 'e' -> 14 | 'F' | 'f' -> 15 | _ -> raise (Invalid_argument "Intbig.intbig_of_string: Invalid hex character.");; let rec hexToIntbig hexStr base value = if hexStr = "" then value else hexToIntbig (String2.left_string hexStr) (mul base v16) (add (mul (big_int_of_int (hexCharToInt (String2.right_char hexStr))) base) value);; let string_of_intbig = string_of_big_int;; let intbig_of_string str = if String.length str >= 2 then match String2.take_left str 2 with "0x" -> hexToIntbig (String2.drop_left str 2) one zero | "1x" -> let s = String2.drop_left str 2 in let l = String.length s in let v = hexToIntbig s one zero in let m = hexToIntbig (String.make l 'F') one zero in bw_or (bw_not m) v | "0b" -> intbig_of_binary_string (String2.drop_left str 2) | "1b" -> let s = String2.drop_left str 2 in let l = String.length s in let v = intbig_of_binary_string s in let m = intbig_of_binary_string (String.make l '1') in bw_or (bw_not m) v | _ -> big_int_of_string str else big_int_of_string str;; (** Numeric type conversion. *) let int_of_intbig = int_of_big_int;; let intbig_of_int = big_int_of_int;; let char_of_intbig i = try char_of_int (int_of_intbig i) with Invalid_argument _ | Failure _ -> raise (Invalid_argument "Intbig.char_of_intbig: Invalid ascii character.");; let intbig_of_char c = intbig_of_int (int_of_char c);; let float_of_intbig = float_of_big_int;; let intbig_of_float a = intbig_of_int (int_of_float a);; (* XXX Not precise. *) (** Unit tests. *) let test n = Ut.assert_bool n "zero" (eq zero (intbig_of_string "0")); Ut.assert_bool n "one" (eq one (intbig_of_string "1")); Ut.assert_bool n "ones" (eq ones (intbig_of_string "-1")); Ut.assert_bool n "v16 " (eq v16 (intbig_of_string "16")); Ut.assert_bool n "abs1" (eq zero (abs zero)); Ut.assert_bool n "abs2" (eq one (abs ones)); Ut.assert_bool n "neg1" (eq one (neg ones)); Ut.assert_bool n "neg2" (eq ones (neg one)); Ut.assert_bool n "pow1" (eq (mul two two) (pow (neg two) two)); Ut.assert_bool n "ne1" (ne one two); Ut.assert_bool n "le1" (le one one); Ut.assert_bool n "le2" (le one two); Ut.assert_bool n "le3" (not (le two one)); Ut.assert_bool n "ge1" (ge one one); Ut.assert_bool n "ge2" (ge two one); Ut.assert_bool n "ge3" (not (ge one two)); Ut.assert_bool n "shift_left1" (eq (shift_left one zero) one); Ut.assert_bool n "shift_left2" (eq (shift_left one two) (intbig_of_string "4")); Ut.assert_bool n "shift_left3" (eq (shift_left ones two) (intbig_of_string "-4")); Ut.assert_bool n "shift_right1" (eq (shift_right one zero) one); Ut.assert_bool n "shift_right2" (eq (shift_right one one) (intbig_of_string "0")); Ut.assert_bool n "shift_right3" (eq (shift_right (intbig_of_string "-4") one) (neg two)); Ut.assert_bool n "shift_right4" (eq (shift_right (intbig_of_string "-4") two) ones); Ut.assert_bool n "not1" (eq (bw_not one) (intbig_of_string "-2")); Ut.assert_bool n "not2" (eq (bw_not zero) ones); Ut.assert_bool n "not3" (eq (bw_not (intbig_of_string "0xF0")) (intbig_of_string "1x0F")); Ut.assert_bool n "of_string1" (eq (intbig_of_string "0xF0") (intbig_of_string "240")); Ut.assert_bool n "of_string2" (eq (intbig_of_string "0x00") (intbig_of_string "0")); Ut.assert_bool n "of_string3" (eq (intbig_of_string "1xF") (intbig_of_string "-1")); Ut.assert_bool n "of_string4" (eq (intbig_of_string "1xE") (intbig_of_string "-2")); Ut.assert_bool n "of_string5" (eq (intbig_of_string "1x0F") (intbig_of_string "-241")); Ut.assert_bool n "of_string6" (eq (intbig_of_string "0b10") two); Ut.assert_bool n "of_string7" (eq (intbig_of_string "0b00") zero); Ut.assert_bool n "of_string8" (eq (intbig_of_string "1b0") (intbig_of_string "-2")); Ut.assert_bool n "of_string9" (eq (intbig_of_string "1b1") (intbig_of_string "-1")); Ut.assert_bool n "binary_string_of1" (binary_string_of_intbig (intbig_of_string "0") (intbig_of_string "0") = ""); Ut.assert_bool n "binary_string_of2" (binary_string_of_intbig (intbig_of_string "0") (intbig_of_string "1") = "0"); Ut.assert_bool n "binary_string_of3" (binary_string_of_intbig (intbig_of_string "0") (intbig_of_string "8") = "00000000"); Ut.assert_bool n "binary_string_of4" (binary_string_of_intbig (intbig_of_string "-1") (intbig_of_string "0") = ""); Ut.assert_bool n "binary_string_of5" (binary_string_of_intbig (intbig_of_string "-1") (intbig_of_string "1") = "1"); Ut.assert_bool n "binary_string_of6" (binary_string_of_intbig (intbig_of_string "-1") (intbig_of_string "8") = "11111111"); Ut.assert_bool n "binary_string_of7" (binary_string_of_intbig (intbig_of_string "0x35") (intbig_of_string "8") = "00110101"); Ut.assert_bool n "of_binary_string1" (eq (intbig_of_binary_string ("0")) (intbig_of_string "0")); Ut.assert_bool n "of_binary_string2" (eq (intbig_of_binary_string ("1")) (intbig_of_string "1")); Ut.assert_bool n "of_binary_string3" (eq (intbig_of_binary_string ("0000")) (intbig_of_string "0")); Ut.assert_bool n "of_binary_string4" (eq (intbig_of_binary_string ("0101")) (intbig_of_string "5")); Ut.assert_bool n "of_binary_string5" (eq (intbig_of_binary_string ("1111")) (intbig_of_string "15")); Ut.assert_bool n "and1" (eq (bw_and (intbig_of_string "12") (intbig_of_string "10")) (intbig_of_string "8")); Ut.assert_bool n "or1" (eq (bw_or (intbig_of_string "12") (intbig_of_string "10")) (intbig_of_string "14")); Ut.assert_bool n "xor1" (eq (bw_xor (intbig_of_string "12") (intbig_of_string "10")) (intbig_of_string "6")); ;; confluence-0.10.6/src/misc/list2.mli0100644002340600244710000000245110266541665016620 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (* Common list functions. *) val mapi : (int -> 'a -> 'b) -> 'a list -> 'b list;; val iteri : (int -> 'a -> unit) -> 'a list -> unit;; val index : 'a -> 'a list -> int -> int;; val indexq : 'a -> 'a list -> int -> int;; val indexf : ('a -> bool) -> 'a list -> int -> int;; val range : int -> int -> int list;; val take : 'a list -> int -> 'a list;; val drop : 'a list -> int -> 'a list;; val make : int -> 'a -> 'a list;; confluence-0.10.6/src/misc/list2.ml0100644002340600244710000000424410266541665016451 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (* Common list functions. *) let mapi func elements = let rec f i sofar elements = match elements with [] -> sofar | element :: elements -> f (i + 1) (func i element :: sofar) elements in List.rev (f 0 [] elements) ;; let iteri func elements = let rec f i elements = match elements with [] -> () | element :: elements -> func i element; f (i + 1) elements in f 0 elements ;; let rec index element elements num = match elements with [] -> raise Not_found | e :: elements -> if e = element then num else index element elements (num + 1);; let rec indexq element elements num = match elements with [] -> raise Not_found | e :: elements -> if e == element then num else indexq element elements (num + 1);; let rec indexf pred elements num = match elements with | [] -> raise Not_found | e :: elements -> if pred e then num else indexf pred elements (num + 1);; let rec range first last = if first = last then [last] else if first < last then first :: range (first + 1) last else first :: range (first - 1) last;; let rec take l n = if n <= 0 then [] else List.hd l :: take (List.tl l) (n - 1);; let rec drop l n = if n <= 0 then l else drop (List.tl l) (n - 1);; let rec make l element = if l <= 0 then [] else element :: make (l - 1) element;; confluence-0.10.6/src/misc/report.ml0100644002340600244710000000274710266541665016735 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) let error_limit = ref (-1);; let set_error_limit limit = error_limit := limit ;; let errors_encountered = ref 0;; let errorReported () = !errors_encountered > 0 ;; let fatal msg = prerr_string ("\n" ^ msg ^ "\n"); prerr_newline (); exit(1) ;; let error msg = incr errors_encountered; if !error_limit < 0 || !errors_encountered <= !error_limit then begin prerr_string ("\n" ^ msg ^ "\n"); prerr_newline () end ;; let warning msg = print_string ("\n" ^ msg ^ "\n"); print_newline () ;; let debug msg = print_string ("** Debug: " ^ msg); print_newline () ;; let hashSize h = string_of_int (Hashtbl.fold (fun a b c -> c + 1) h 0);; confluence-0.10.6/src/misc/loc.ml0100644002340600244710000000324710266541665016173 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) type loc = Unify of string * int * int (* file, line, col *) | Argument of string * int * int * int (* file, line, col, argument *) | Unknown of string;; let create file line col = Unify (file, line, col);; let unknown msg = Unknown msg;; let argument loc arg = match loc with Unify (file, line, col) -> Argument (file, line, col, arg) | Argument (file, line, col, _) -> Argument (file, line, col, arg) | Unknown msg -> Unknown msg;; let toString loc = match loc with Unify (file, line, col) -> file ^ " " ^ string_of_int line ^ "," ^ string_of_int col | Argument (file, line, col, arg) -> file ^ " " ^ string_of_int line ^ "," ^ string_of_int col ^ " arg " ^ string_of_int arg | Unknown msg -> "Location Unknown: " ^ msg;; let isKnown loc = match loc with Unknown _ -> false | _ -> true;; confluence-0.10.6/src/misc/loc.mli0100644002340600244710000000226710266541665016345 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) type loc = Unify of string * int * int (* file, line, col *) | Argument of string * int * int * int (* file, line, col, argument *) | Unknown of string;; val create : string -> int -> int -> loc;; val unknown : string -> loc;; val argument : loc -> int -> loc;; val toString : loc -> string;; val isKnown : loc -> bool;; confluence-0.10.6/src/misc/report.mli0100644002340600244710000000207710266541665017102 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) val set_error_limit : int -> unit;; val errorReported : unit -> bool;; val fatal : string -> unit;; val error : string -> unit;; val warning : string -> unit;; val debug : string -> unit;; val hashSize : ('a, 'b) Hashtbl.t -> string;; confluence-0.10.6/src/misc/string2.ml0100644002340600244710000001731110266541666017004 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Common string functions. *) let replace str cOld cNew = let s = String.copy str in let n = String.length s in let rec f i = if i != n then if s.[i] = cOld then begin s.[i] <- cNew; f (i + 1); end; in f 0; s;; let take_left str count = String.sub str 0 count;; let take_right str count = let l = String.length str in String.sub str (l - count) count;; let drop_left str count = let l = String.length str in String.sub str count (l - count);; let drop_right str count = let l = String.length str in String.sub str 0 (l - count);; let right_char str = str.[String.length str - 1];; let left_char str = str.[0];; let right_string str = drop_left str 1;; let left_string str = drop_right str 1;; let cons_left char string = String.make 1 char ^ string ;; let cons_right string char = string ^ String.make 1 char ;; let replace_meta_chars s = let rec f i s1 = if i == (String.length s) then s1 else match s.[i] with '\\' -> f (i + 1) (s1 ^ "\\\\") | '"' -> f (i + 1) (s1 ^ "\\\"") | '\n' -> f (i + 1) (s1 ^ "\\n") | '\r' -> f (i + 1) (s1 ^ "\\r") | '\t' -> f (i + 1) (s1 ^ "\\t") | c -> f (i + 1) (s1 ^ String.make 1 c) in f 0 "";; let replace_xml_chars s = let rec f i s1 = if i == (String.length s) then s1 else match s.[i] with '<' -> f (i + 1) (s1 ^ "<") | '>' -> f (i + 1) (s1 ^ ">") | '&' -> f (i + 1) (s1 ^ "&") | '"' -> f (i + 1) (s1 ^ """) | '\'' -> f (i + 1) (s1 ^ "'") | c -> f (i + 1) (s1 ^ String.make 1 c) in f 0 "";; let replace_printf_chars s = let rec f i s1 = if i == (String.length s) then s1 else match s.[i] with '\\' -> f (i + 1) (s1 ^ "\\\\") | '"' -> f (i + 1) (s1 ^ "\\\"") | '\n' -> f (i + 1) (s1 ^ "\\n") | '\r' -> f (i + 1) (s1 ^ "\\r") | '\t' -> f (i + 1) (s1 ^ "\\t") | '%' -> f (i + 1) (s1 ^ "%%") | c -> f (i + 1) (s1 ^ String.make 1 c) in f 0 "";; let insert_meta_chars s char_map = let l = String.length s - 1 in let rec f i s1 = if i == l then (* Ignores \ if last character. *) s1 else if s.[i] = '\\' then try f (i + 2) (s1 ^ List.assoc s.[i + 1] char_map) with Not_found -> f (i + 1) (s1 ^ "\\") (* If not found, just use \. *) else f (i + 1) (s1 ^ String.make 1 s.[i]) in f 0 "" ;; let rec map func str = if str = "" then "" else String.make 1 (func (left_char str)) ^ map func (right_string str);; let rec map2 func str1 str2 = if str1 = "" then "" else String.make 1 (func (left_char str1) (left_char str2)) ^ map2 func (right_string str1) (right_string str2);; (* let rec fold_left f i str = if str = "" then i else fold_left f (f i (left_char str)) (right_string str) ;; let rec fold_right f str i = if str = "" then i else fold_right f (f (right_char str) i) (left_string str) ;; *) let rec chars_of_string str = if str = "" then [] else left_char str :: chars_of_string (right_string str) ;; let rec string_of_chars chars = match chars with | [] -> "" | c :: chars -> String.make 1 c ^ string_of_chars chars ;; (** [string_of_char char] creates a string from a single [char]. *) let string_of_char char = String.make 1 char ;; (** [join strings delimiter] joins a list of [strings] together with a [delimiter]. *) let join strings delimiter = let rec join strings = match strings with | [] -> "" | [string] -> string | string :: strings -> string ^ delimiter ^ join strings in join strings ;; (** [split string delimitiers] splits a [string] delimtied by any character specified in the [delimitiers] string. *) let split string delimiters = let rec on_delimit sofar i = if i < 0 then sofar else if String.contains delimiters string.[i] then on_delimit sofar (i - 1) else off_delimit sofar (string_of_char string.[i]) (i - 1) and off_delimit sofar word i = if i < 0 then word :: sofar else if String.contains delimiters string.[i] then on_delimit (word :: sofar) (i - 1) else off_delimit sofar (string_of_char string.[i] ^ word) (i - 1) in on_delimit [] (String.length string - 1) ;; (** [replace_chars_in_string string_of_char string] replaces the characters in a [string] defined by a function, [string_of_char]. *) let replace_chars_in_string string_of_char string = let l = String.length string in let rec f i sofar = if i >= l then sofar else f (i + 1) (sofar ^ string_of_char string.[i]) in f 0 "" ;; (* Unit tests. *) let test n = Ut.assert_bool n "replace1" (replace "abcd" 'a' 'A' = "Abcd"); Ut.assert_bool n "take_left1" (take_left "abcd" 0 = ""); Ut.assert_bool n "take_left2" (take_left "abcd" 1 = "a"); Ut.assert_bool n "take_left3" (take_left "abcd" 2 = "ab"); Ut.assert_bool n "take_right1" (take_right "abcd" 0 = ""); Ut.assert_bool n "take_right2" (take_right "abcd" 1 = "d"); Ut.assert_bool n "take_right3" (take_right "abcd" 2 = "cd"); Ut.assert_bool n "drop_left1" (drop_left "abcd" 0 = "abcd"); Ut.assert_bool n "drop_left2" (drop_left "abcd" 1 = "bcd"); Ut.assert_bool n "drop_left3" (drop_left "abcd" 2 = "cd"); Ut.assert_bool n "drop_right1" (drop_right "abcd" 0 = "abcd"); Ut.assert_bool n "drop_right2" (drop_right "abcd" 1 = "abc"); Ut.assert_bool n "drop_right3" (drop_right "abcd" 2 = "ab"); Ut.assert_bool n "left_char 1" (left_char "abcd" = 'a'); Ut.assert_bool n "left_char 2" (left_char "a" = 'a'); Ut.assert_bool n "right_char 1" (right_char "abcd" = 'd'); Ut.assert_bool n "right_char 2" (right_char "a" = 'a'); Ut.assert_bool n "left_string 1" (left_string "abcd" = "abc"); Ut.assert_bool n "left_string 2" (left_string "a" = ""); Ut.assert_bool n "right_string 1" (right_string "abcd" = "bcd"); Ut.assert_bool n "right_string 2" (right_string "a" = ""); Ut.assert_bool n "replace_meta_chars1" (replace_meta_chars "abc" = "abc"); Ut.assert_bool n "replace_meta_chars2" (replace_meta_chars "a\nbc" = "a\\nbc"); Ut.assert_bool n "replace_meta_chars3" (replace_meta_chars "a\nb\\\"c" = "a\\nb\\\\\\\"c"); Ut.assert_bool n "map 1" (map (fun a -> a) "abc" = "abc"); Ut.assert_bool n "map 2" (map (fun a -> a) "" = ""); Ut.assert_bool n "map2 1" (map2 (fun a b -> b) "" "" = ""); Ut.assert_bool n "map2 2" (map2 (fun a b -> b) "abc" "def" = "def"); Ut.assert_bool n "chars_of_string 1" (chars_of_string "abcd" = ['a'; 'b'; 'c'; 'd']); Ut.assert_bool n "chars_of_string 2" (chars_of_string "" = []); Ut.assert_bool n "string_of_chars 1" (string_of_chars ['a'; 'b'; 'c'; 'd'] = "abcd"); Ut.assert_bool n "string_of_chars 2" (string_of_chars [] = ""); Ut.assert_bool n "join 1" (join ["a"; "b"; "c"] ", " = "a, b, c"); ;; confluence-0.10.6/src/misc/string2.mli0100644002340600244710000000423210266541666017153 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (* Common string functions. *) val replace : string -> char -> char -> string;; val take_left : string -> int -> string;; val take_right : string -> int -> string;; val drop_left : string -> int -> string;; val drop_right : string -> int -> string;; val right_char : string -> char;; val left_char : string -> char;; val right_string : string -> string;; val left_string : string -> string;; val cons_left : char -> string -> string;; val cons_right : string -> char -> string;; val replace_meta_chars : string -> string;; val replace_xml_chars : string -> string;; val replace_printf_chars : string -> string;; val insert_meta_chars : string -> (char * string) list -> string;; val map : (char -> char) -> string -> string;; val map2 : (char -> char -> char) -> string -> string -> string;; (* val fold_left : ('a -> char -> 'a) -> 'a -> string -> 'a;; val fold_right : (char -> 'a -> 'a) -> string -> 'a -> 'a;; *) val chars_of_string : string -> char list;; val string_of_chars : char list -> string;; val join : string list -> string -> string;; val split : string -> string -> string list;; val string_of_char : char -> string;; val replace_chars_in_string : (char -> string) -> string -> string;; (* Unit tests. *) val test : string -> unit;; confluence-0.10.6/src/misc/test_suite.ml0100644002340600244710000000175610266541666017612 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) open Ut;; let test_suite n = run_test n "Intbig" Intbig.test; run_test n "String2" String2.test; ;; let run () = run_test "" "Top" test_suite; report () ;; confluence-0.10.6/src/misc/test_suite.mli0100644002340600244710000000161210266541666017752 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) val test_suite : string -> unit;; val run : unit -> unit;; confluence-0.10.6/src/misc/ut.ml0100644002340600244710000000505510266541666016046 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Unit testing and assertions. *) let pass = ref 0;; let fail = ref 0;; (** Asserts that a boolean expression is true. *) let assert_bool test_name assert_name test = if not test then begin incr fail; print_string ("** Assertion Failure: " ^ test_name ^ "/" ^ assert_name); print_newline () end else incr pass ;; (** Runs a test given the parent test name, the sub test name, and the test function. *) let run_test parent_name test_name test = test (parent_name ^ "/" ^ test_name) ;; (** Reports the test results and resets the test counters. *) let report () = print_string ("Total Assertions: " ^ string_of_int (!pass + !fail) ^ " Passed: " ^ string_of_int !pass ^ " Failed: " ^ string_of_int !fail); print_newline (); pass := 0; fail := 0 ;; let print_msg msg = print_string msg; print_newline () ;; confluence-0.10.6/src/misc/ut.mli0100644002340600244710000000204710266541666016215 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2004 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (* Unit testing and assertions. *) val assert_bool : string -> string -> bool -> unit;; val run_test : string -> string -> (string -> unit) -> unit;; val report : unit -> unit;; val print_msg : string -> unit;; confluence-0.10.6/src/misc/version.ml0100644002340600244710000000162110312275627017067 0ustar hawkit1cadgrp(* Confluence System Design Language Compiler Copyright (C) 2003-2005 Tom Hawkins (tomahawkins@yahoo.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) (** Current version of Confluence and FNF. *) let version = "0.10.6";;