Line 41... |
Line 41... |
|
|
|
|
|
|
|
|
typedef enum bit[3:0] { VK_EMPTY=4'h0,
|
typedef enum bit[3:0] { VK_EMPTY=4'h0,
|
VK_EOF,
|
|
VK_DUMMY1,
|
VK_DUMMY1,
|
VK_DUMMY2,
|
VK_DUMMY2,
|
VK_DUMMY3,
|
VK_DUMMY3,
|
|
|
VK_DUMMY4,
|
VK_DUMMY4,
|
VK_DUMMY5,
|
VK_TRANSIT,
|
VK_APPLY,
|
VK_APPLY,
|
VK_K,
|
VK_EOF,
|
VK_DUMMY6,
|
|
VK_DUMMY7,
|
VK_K[2]= 4'h8,
|
VK_DUMMY8,
|
|
VK_DUMMY9
|
VK_S[3]= 4'd12,
|
|
VK_DUMMY5
|
} VKind;
|
} VKind;
|
|
|
|
function logic [1:0] CH_NUM( logic [3:0] k );
|
|
CH_NUM = k[1:0];
|
|
endfunction
|
|
|
typedef enum bit[3:0] { VMS_EMPTY=4'h0,
|
typedef enum bit[3:0] { VMS_EMPTY=4'h0,
|
VMS_EOF,
|
|
VMS_READY,
|
VMS_READY,
|
VMS_WRITE,
|
VMS_PROCESS,
|
|
VMS_BOMB,
|
|
|
VMS_READ,
|
VMS_READ,
|
|
VMS_APPLY,
|
VMS_STOP // end of tree
|
VMS_STOP // end of tree
|
} VMeta;
|
} VMeta;
|
|
|
typedef enum bit[1:0]{ TO_PARENT=2'h0,
|
typedef enum bit[1:0]{ TO_PARENT=2'h0,
|
TO_CHILDREN,
|
TO_CHILDREN,
|
Line 111... |
Line 118... |
0: // working mode
|
0: // working mode
|
begin
|
begin
|
case( state )
|
case( state )
|
VMS_EMPTY: // sleeping
|
VMS_EMPTY: // sleeping
|
begin
|
begin
|
value <= fromParent==VK_APPLY || fromParent==VK_K ? fromParent : VK_DUMMY9; // write self
|
if ( !value )
|
case( fromParent )
|
begin // writing left
|
VK_EMPTY:; // still sleeping
|
value <= fromParent;//==VK_APPLY || fromParent==VK_EMPTY || fromParent==VK_K0 ? fromParent : VK_DUMMY5; // write self
|
VK_APPLY: // write subtrees
|
if ( fromParent && CH_NUM( fromParent )==0 )
|
state <= VMS_WRITE;
|
|
default: // i'm a leaf
|
|
begin
|
begin
|
message.msg <= VMS_READY;
|
message.msg <= VMS_READY;
|
message.tgt <= TO_PARENT;
|
message.tgt <= TO_PARENT;
|
state <= VMS_READY;
|
state <= VMS_READY;
|
end
|
end
|
endcase
|
|
end
|
end
|
|
else if ( CH_NUM( value )!=0 && ~fromLeft[0] )
|
VMS_WRITE:
|
|
begin
|
|
case( step )
|
|
0: // writing left
|
|
if ( fromLeft == VMS_EMPTY )
|
|
begin // write left
|
begin // write left
|
message.msg <= fromParent;
|
message.msg <= fromParent;
|
message.tgt <= TO_LEFT;
|
message.tgt <= TO_LEFT;
|
end
|
end
|
else
|
else if ( CH_NUM( value )==2 && ~fromRight[0] )
|
begin // begin writing right
|
begin // begin writing right
|
message.msg <= fromParent;
|
message.msg <= fromParent;
|
message.tgt <= TO_RIGHT;
|
message.tgt <= TO_RIGHT;
|
step <= step+4'h1;
|
|
end
|
|
1: // writing right
|
|
if ( fromRight == VMS_EMPTY )
|
|
begin // write right
|
|
message.msg <= fromParent;
|
|
message.tgt <= TO_RIGHT;
|
|
end
|
end
|
else
|
else
|
begin // job well done, notify parent
|
begin
|
message.msg <= VMS_READY;
|
message.msg <= VMS_READY;
|
message.tgt <= TO_PARENT;
|
message.tgt <= TO_PARENT;
|
state <= VMS_READY;
|
state <= VMS_READY;
|
step <= 0;
|
|
end
|
end
|
endcase
|
|
end
|
end
|
|
|
VMS_READ:
|
VMS_READ:
|
begin
|
begin
|
case( step )
|
if ( message.msg == VK_EOF )
|
0:
|
|
if ( value != VK_APPLY )
|
|
begin
|
begin
|
message.msg <= VK_EOF; // leaf's report
|
message.msg <= VMS_READY; // end read 2
|
message.tgt <= TO_PARENT;
|
|
state <= VMS_READY;
|
state <= VMS_READY;
|
end
|
end
|
else if ( fromLeft==VMS_READY )
|
// else if ( message.msg == VMS_READY && value != VK_TRANSIT )
|
|
// begin
|
|
// message.msg <= value; // read self
|
|
// message.tgt <= TO_PARENT;
|
|
// end
|
|
else if ( CH_NUM( value )==0 )
|
begin
|
begin
|
message.msg <= VMS_READ; // begin read left
|
message.msg <= VK_EOF; // end read 1.1
|
message.tgt <= TO_LEFT;
|
|
step <= 4'h1;
|
|
end
|
end
|
else
|
else if ( ~step[0] && fromLeft == VMS_READY )
|
message.msg <= VK_EMPTY; // wait for left
|
|
1:
|
|
case( fromLeft )
|
|
VK_EMPTY:;
|
|
VK_EOF:
|
|
begin
|
begin
|
step <= 4'h2;
|
message.msg <= VMS_READ; // command left
|
message.msg <= VK_EMPTY;
|
message.tgt <= TO_LEFT;
|
end
|
end
|
default: // transfer left
|
else if ( ~step[0] && fromLeft != VK_EOF )
|
begin
|
begin
|
message.msg <= fromLeft;
|
message.msg <= fromLeft; // transfer left
|
message.tgt <= TO_PARENT;
|
message.tgt <= TO_PARENT;
|
end
|
end
|
endcase
|
else if ( CH_NUM( value )==1 )
|
2: // begin read right
|
|
if ( fromRight==VMS_READY )
|
|
begin
|
begin
|
message.msg <= VMS_READ;
|
message.msg <= VK_EOF; // end read 1.2
|
message.tgt <= TO_RIGHT;
|
|
step <= 4'h3;
|
|
end
|
end
|
else
|
else if ( fromRight == VMS_READY )
|
message.msg <= VK_EMPTY; // wait for right
|
|
3:
|
|
case( fromRight )
|
|
VK_EMPTY:;
|
|
VK_EOF:
|
|
begin
|
begin
|
message.msg <= fromRight;
|
message.msg <= VMS_READ; // command right
|
state <= VMS_READY;
|
message.tgt <= TO_RIGHT;
|
step <= 0;
|
step[0] <= 1;
|
end
|
end
|
default: // transfer right
|
else if ( fromRight != VK_EOF )
|
begin
|
begin
|
message.msg <= fromRight;
|
message.msg <= fromRight; // transfer right
|
message.tgt <= TO_PARENT;
|
message.tgt <= TO_PARENT;
|
end
|
end
|
endcase
|
else
|
endcase
|
begin
|
|
message.msg <= VK_EOF; // end read 1.3
|
|
step[0] <= 0;
|
|
end
|
|
|
|
|
end
|
end
|
|
|
VMS_READY:
|
VMS_READY:
|
begin
|
begin
|
case( fromParent )
|
case( fromParent )
|
|
VMS_BOMB: // clear
|
|
begin
|
|
message.msg <= VMS_BOMB;
|
|
message.tgt <= TO_CHILDREN;
|
|
state <= VMS_EMPTY;
|
|
value <= VK_EMPTY;
|
|
end
|
VMS_READ: // read self
|
VMS_READ: // read self
|
begin
|
begin
|
|
if ( value != VK_TRANSIT )
|
|
begin
|
message.msg <= value;
|
message.msg <= value;
|
message.tgt <= TO_PARENT;
|
message.tgt <= TO_PARENT;
|
|
end
|
state <= VMS_READ;
|
state <= VMS_READ;
|
end
|
end
|
|
VMS_APPLY: // apply string from parent to itself
|
|
begin
|
|
if ( CH_NUM( value )!=0 )
|
|
begin
|
|
message.msg <= VMS_APPLY;
|
|
message.tgt <= TO_CHILDREN;
|
|
end
|
|
begin
|
|
case( value )
|
|
VK_K0,
|
|
VK_S0,
|
|
VK_S1:
|
|
begin // add argument
|
|
value[1:0] <= value[1:0] +1; // K0 -> K1, S0 -> S1, S1 -> S2
|
|
state <= VMS_EMPTY; // WRITE
|
|
end
|
|
VK_K1: // K main
|
|
begin
|
|
value <= VK_TRANSIT;
|
|
state <= VMS_READY;
|
|
message.msg <= VMS_BOMB;
|
|
message.tgt <= TO_RIGHT;
|
|
end
|
|
VK_S2: // S main
|
|
begin
|
|
state <= VMS_APPLY;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
default:
|
default:
|
begin
|
begin
|
message.msg <= VMS_READY;
|
message.msg <= VMS_READY;
|
message.tgt <= TO_PARENT;
|
message.tgt <= TO_PARENT;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
|
VMS_APPLY:
|
|
if ( fromParent != VK_EOF )
|
|
begin
|
|
message.msg <= fromParent; // Sxyz -> `(_`_xz) (_`_yz)
|
|
message.tgt <= TO_CHILDREN;
|
|
end
|
|
else
|
|
begin
|
|
message.msg <= VK_EMPTY;
|
|
state <= VMS_READY;
|
|
value <= VK_APPLY; // Sxyz -> _`_ (`xz) (`yz)
|
|
end
|
endcase
|
endcase
|
end
|
end
|
default: // reset mode
|
default: // reset mode
|
begin
|
begin
|
state <= VMS_EMPTY;
|
state <= VMS_EMPTY;
|
|
value <= VK_EMPTY;
|
message.msg <= VMS_EMPTY;
|
message.msg <= VMS_EMPTY;
|
step <= 0;
|
step <= 0;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|