(* Example of a MPEG-2 video encoder as found in :
   Carloni and Sangiovanni-Vincentelli, Coping with LID in SOC Design, 
   IEEE Mico 2002

   Relay stations are the same as in :
   Casu and Macchiarulo, A New Approach to Latency Insensitive Design, DAC04
*)

let node ip_2_1 ((x::'a), (y::'a)) = x
let node ip_2_2 ((x::'a), (y::'a)) = (x ,x)
let node relay x = x

let node preprocessing x = x
let node frame_mem x = (x, x)
let node motion_est (x, y) = ip_2_2 (x, y)
let node motion_comp (x, y) = ip_2_2 (x, y)
let node dct x = x
let node quantizer (x, y) = ip_2_2 (x, y)
let node inverse_quantizer x = x
let node idct x = x
let node variable_length_code_enc (x, y) = ip_2_1 (x, y)
let node buff x = (x, x)
let node regulator x = x


let node mpeg input = output where
  rec out_v1 = preprocessing (buffer in_v1)
  and (out_v2_1, out_v2_2) = frame_mem (buffer in_v2)
  and out_v3 = (buffer in_v3_1) - (buffer in_v3_2)
  and out_v4 = dct (buffer in_v4)
  and (out_v5_1, out_v5_2) = quantizer (buffer in_v5_1, 
                                        buffer in_v5_2)
  and out_v6 = inverse_quantizer (buffer in_v6)
  and out_v7 = idct (buffer in_v7)
  and out_v8 = (buffer in_v8_1) + (buffer in_v8_2)
  and (out_v9_1, out_v9_2) = frame_mem (buffer in_v9)
  and (out_v10_1, out_v10_2) = motion_comp (buffer in_v10_1, 
                                            buffer in_v10_2)
  and (out_v11_1, out_v11_2) = motion_est (buffer in_v11_1, 
                                           buffer in_v11_2)
  and out_v12 = variable_length_code_enc (buffer in_v12_1, 
                                          buffer in_v12_2)
  and (out_v14_1, out_v14_2) = buff (buffer in_v14)
  and out_v15 = regulator (buffer in_v15)
  and output = out_v14_2

  and in_v1 = input
  and in_v2 = delay (relay (merge 1(0) 4012 (delay out_v1)))
  and in_v3_1 = merge 1(0) 4012 (delay out_v2_1)
  and in_v3_2 = merge 1(0) 4012 (delay out_v10_1)
  and in_v4 = merge 1(0) 4012 (delay out_v3)
  and in_v5_1 = merge 1(0) 4012 (delay out_v4)
  and in_v5_2 = merge 1(0) 4012 (delay out_v15)
  and in_v6 = merge 1(0) 4012 (delay out_v5_1)
  and in_v7 = merge 1(0) 4012 (delay out_v6)
  and in_v8_1 = delay (relay (merge 1(0) 4012 (delay out_v7)))
  and in_v8_2 = merge 1(0) 4012 (delay out_v10_2)
  and in_v9 = merge 1(0) 4012 (delay out_v8)
  and in_v10_1 = merge 1(0) 4012 (delay out_v9_1)
  and in_v10_2 = delay (relay (merge 1(0) 4012 (delay out_v11_1)))
  and in_v11_1 = delay (relay (delay (relay (merge 1(0) 4012 (delay out_v2_2)))))
  and in_v11_2 = delay (relay (merge 1(0) 4012 (delay out_v9_2)))
  and in_v12_1 = delay (relay (merge 1(0) 4012 (delay out_v11_2)))
  and in_v12_2 = merge 1(0) 4012 (delay out_v5_2)
  and in_v14 = merge 1(0) 4012 (delay out_v12)
  and in_v15 = merge 1(0) 4012 (delay out_v14_1)