### verilog output ### sub ALF_WriteVerilog { local($object) = @_; if (&StringMatch($ALF_Type{$object},'CELL')) { &ALF_WriteVerilogModule($object,$ALF_Parent{$object}); } else { print("# ALF Data Warning:\tobject cannot be translated to Verilog\t",&ALF_ObjectInfoText($object),"\n"); } } sub ALF_WriteVerilogModule { local($cell,$library) = @_; local @pins = &ALF_FindMatchingObjects($cell,'PIN'); local (@internal,@external,%index,%type); foreach $pin (@pins) { local $net = &ALF_VerilogName($ALF_Name{$pin}); local $index = $ALF_1stIndex{$pin}; $index{$net} = $index if defined($index); local $direction = $ALF_Value{&ALF_FindMatchingObject($pin,'DIRECTION')}; if (&StringMatch($direction,'input','output','both')) { $external[$#external+1] = $net; $type{$net} = &ALF_VerilogDirection($direction); } elsif (&StringMatch($direction,'none')) { $internal[$#internal+1] = $net; $type{$net} = &ALF_VerilogDirection($direction); } else { print("ALF Data Error:\tpin with undefined direction\t",&ALF_ObjectInfoText($pin),"\n"); } } local $module = &ALF_VerilogName($ALF_Name{$cell}); print(FILEOUT "module $module (\n\t"); print(FILEOUT join(" ,\n\t",@external)); print(FILEOUT "\n) ;\n"); foreach $net (@external,@internal) { print(FILEOUT join("\t",$type{$net},$index{$net},$net)," ;\n"); } local $structure = &ALF_FindMatchingObject(&ALF_FindMatchingObject($cell,'FUNCTION'),'STRUCTURE'); foreach $component (&Array($ALF_Children{$structure})) { &ALF_WriteVerilogComponent($component,$library); } print(FILEOUT "endmodule\n\n"); } sub ALF_WriteVerilogComponent { local($component,$library) = @_; local $ref = &ALF_VerilogName($ALF_Type{$component}); local $inst = &ALF_VerilogName($ALF_Name{$component}); # $inst = "\\$inst" unless (&ALF_LexicalMatch('non_escaped_identifier',$inst) || &ALF_LexicalMatch('escaped_identifier',$inst)); print(FILEOUT "$ref $inst ("); local $cell = $ALF_Link{$component}; local (%pin_connect,%pin_msb,%pin_lsb); foreach $pin (&ALF_FindMatchingObjects($cell,'PIN')) { local $none = &ALF_FindMatchingObject($pin,'DIRECTION',undef,'none'); unless ($none) { local($key,$msb,$lsb) = &ALF_BusBits(join('',&ALF_VerilogName($ALF_Name{$pin}),$ALF_1stIndex{$pin})); $pin_msb{$key} = $msb; $pin_lsb{$key} = $lsb; $pin_connect{$key} = &CreateArray(); } } foreach $connect (&Array($ALF_Children{$component})) { local ($terminal,$index) = &ALF_BusBits(&ALF_VerilogName($ALF_Type{$connect})); local $node = &ALF_VerilogName($ALF_Value{$connect}); local $pin = $ALF_Link{$terminal}; local $msb = $pin_msb{$terminal}; local $lsb = $pin_lsb{$terminal}; local $position = defined($index)? $msb-$index : 0; if ($index > $msb || $index < $lsb) { print("# ALF Data Error:\tcomponent with bus connection out of range\t",&ALF_ObjectInfoText($component),"\n"); print("# ALF Data Error:\tsubscript $index out of range [$msb:$lsb]\t",&ALF_ObjectInfoText($connect),"\n"); } else { &ReplaceArrayValue($pin_connect{$terminal},$position,$node); } } local $space = "\n\t"; foreach $key (keys %pin_connect) { local $pin_connect = join(' , ',&Array($pin_connect{$key})); if (&ArraySize($pin_connect{$key}) > 1) { print(FILEOUT $space,"\.$key ( { $pin_connect } )"); } else { print(FILEOUT $space,"\.$key ( $pin_connect )"); } $space = " ,\n\t"; } print(FILEOUT "\n) ;\n"); } ### little helpers ### sub ALF_VerilogDirection { local($direction) = @_; &StringMatch($direction,'both')? 'inout' : &StringMatch($direction,'input')? 'input' : &StringMatch($direction,'output')? 'output' : &StringMatch($direction,'none')? 'wire' : undef; } sub ALF_VerilogName { local($name) = @_; &ALF_LexicalMatch('non_escaped_identifier',$name) ? $name : &ALF_LexicalMatch('escaped_identifier',$name) ? $name : &ALF_LexicalMatch('indexed_identifier',$name) ? $name : &ALF_LexicalMatch('bit_literal',$name) ? "1\47b$name" : "\\$name"; } 1;