module ProLogicDecoder( ss, L, R, Left, Right, Center, Surround );

// input specifications
input ss;
input [5:0] L, R;

// output specifications
output [6:0] Left, Right, Center, Surround;

// declarations
wire [6:0] Left, Right, Center, Surround;
wire [6:0] LpR, LmR, mC, mS;


// assignments for Left and Right
//
// Left and Right are padded with a zero
// to make them the same size as Center
// and Surround
assign Left = {1'b0, L};
assign Right = {1'b0, R};

// calculate sum and difference between
// Left and Right.
//
// the subtraction must be handled specially
// to avoid clipping in the audio output,
// or other types of discontinuities
mapLpR adder( .L(Left), .R(Right), .out(LpR) );
mapLmR subtracter( .L(Left), .R(Right), .out(LmR) );

// calculate the Center and Surround outputs
// from the prior sum and difference.
//
// the root2encoder calculates the binary value
// that most closely represents dividing the
// input by the square root of 2
root2encoder Croot2Encoder( .in(LpR), .out(mC) );
root2encoder Sroot2Encoder( .in(LmR), .out(mS) );

// mux output depending on ss input flag
//
// Center and Surround should be 0 if ss is 0
mux2to1x7 Cmux( .in1(mC), .in0(7'b000_0000), .s(ss), .out(Center) );
mux2to1x7 Smux( .in1(mS), .in0(7'b000_0000), .s(ss), .out(Surround) );

endmodule



// multiplexer
module mux2to1x7( in1, in0, s, out );

input [6:0] in1, in0;
input s;
output [6:0] out;

wire [6:0] out;

assign out = s? in1 : in0;

endmodule




// special adder
module mapLpR( L, R, out );

input [6:0] L, R;
output [6:0] out;

wire [6:0] out;

assign out = L + R;

endmodule




// special subtractor
module mapLmR( L, R, out );

input [6:0] L, R;
output [6:0] out;

wire [6:0] sum, out;

assign sum = L + 63;         // add 63 to avoid subtraction clipping
assign out = sum - R;

endmodule




// divide by square root of 2
module root2encoder( in, out );

input [6:0] in;
output [6:0] out;

reg [6:0] out;

always @ ( in )
   case( in )
      0 : out <=  0;
      1 : out <=  1;
      2 : out <=  1;
      3 : out <=  2;
      4 : out <=  3;
      5 : out <=  4;
      6 : out <=  4;
      7 : out <=  5;
      8 : out <=  6;
      9 : out <=  6;
      10 : out <=  7;
      11 : out <=  8;
      12 : out <=  8;
      13 : out <=  9;
      14 : out <=  10;
      15 : out <=  11;
      16 : out <=  11;
      17 : out <=  12;
      18 : out <=  13;
      19 : out <=  13;
      20 : out <=  14;
      21 : out <=  15;
      22 : out <=  16;
      23 : out <=  16;
      24 : out <=  17;
      25 : out <=  18;
      26 : out <=  18;
      27 : out <=  19;
      28 : out <=  20;
      29 : out <=  21;
      30 : out <=  21;
      31 : out <=  22;
      32 : out <=  23;
      33 : out <=  23;
      34 : out <=  24;
      35 : out <=  25;
      36 : out <=  25;
      37 : out <=  26;
      38 : out <=  27;
      39 : out <=  28;
      40 : out <=  28;
      41 : out <=  29;
      42 : out <=  30;
      43 : out <=  30;
      44 : out <=  31;
      45 : out <=  32;
      46 : out <=  33;
      47 : out <=  33;
      48 : out <=  34;
      49 : out <=  35;
      50 : out <=  35;
      51 : out <=  36;
      52 : out <=  37;
      53 : out <=  37;
      54 : out <=  38;
      55 : out <=  39;
      56 : out <=  40;
      57 : out <=  40;
      58 : out <=  41;
      59 : out <=  42;
      60 : out <=  42;
      61 : out <=  43;
      62 : out <=  44;
      63 : out <=  45;
      64 : out <=  45;
      65 : out <=  46;
      66 : out <=  47;
      67 : out <=  47;
      68 : out <=  48;
      69 : out <=  49;
      70 : out <=  49;
      71 : out <=  50;
      72 : out <=  51;
      73 : out <=  52;
      74 : out <=  52;
      75 : out <=  53;
      76 : out <=  54;
      77 : out <=  54;
      78 : out <=  55;
      79 : out <=  56;
      80 : out <=  57;
      81 : out <=  57;
      82 : out <=  58;
      83 : out <=  59;
      84 : out <=  59;
      85 : out <=  60;
      86 : out <=  61;
      87 : out <=  62;
      88 : out <=  62;
      89 : out <=  63;
      90 : out <=  64;
      91 : out <=  64;
      92 : out <=  65;
      93 : out <=  66;
      94 : out <=  66;
      95 : out <=  67;
      96 : out <=  68;
      97 : out <=  69;
      98 : out <=  69;
      99 : out <=  70;
      100 : out <=  71;
      101 : out <=  71;
      102 : out <=  72;
      103 : out <=  73;
      104 : out <=  74;
      105 : out <=  74;
      106 : out <=  75;
      107 : out <=  76;
      108 : out <=  76;
      109 : out <=  77;
      110 : out <=  78;
      111 : out <=  78;
      112 : out <=  79;
      113 : out <=  80;
      114 : out <=  81;
      115 : out <=  81;
      116 : out <=  82;
      117 : out <=  83;
      118 : out <=  83;
      119 : out <=  84;
      120 : out <=  85;
      121 : out <=  86;
      122 : out <=  86;
      123 : out <=  87;
      124 : out <=  88;
      125 : out <=  88;
      126 : out <=  89;
      127 : out <=  90;
   endcase

endmodule