// Cliff's notes concerning 1619
//
// (1) The top example shows my concern over added default ports used with .*
// (2) The second example shows a proposed modification (albeit rather ugly)
// (3) The third example shows how to handle this with the current syntax and no
// default ports
// (4) The forth example shows how to `include a core model in an existing model
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// IP Provider - New Model for accum module
//---------------------------------------------------------------------------
// IP Provider believes the better version of the model inverts the dataout
// MSB when not reset and has added an invert-MSB (inv_msb) control input 
// and set it to 1 so that future use of the model will invert the dataout
// MSB by default
//---------------------------------------------------------------------------
module accum (
  output logic [7:0] dataout,
  input        [7:0] datain,
  input              clk, rst_n='1, inv_msb='1);

  always @(posedge clk, negedge rst_n)
    if (!rst_n) dataout <= '0;
    else        dataout <= {inv_msb,7'b0}^datain; // New functionality
endmodule


// All other models as defined in Mantis 1619
...

module alu_accum4 (
   output [15:0] dataout,
   input   [7:0] ain, bin,
   input   [2:0] opcode,
   input         clk);
   wire    [7:0] alu_out;

   alu   alu   (.*, .zero());
   // accum rst input is tied high AND inv_msb is now tied high 
   // (inv_msb port did not exist before - added by IP provider)
   accum accum (.*, .dataout(dataout[7:0]), .datain(alu_out));
   xtend xtend (.*, .dout(dataout[15:8]),   .din(alu_out[7]));
endmodule

//---------------------------------------------------------------------------

// Alternative (Ugly) syntax - not much better or safer but does require
// "responsible" action by the IP provider
module accum (
  output logic [7:0] dataout,
  input        [7:0] datain,
  input              clk,
  // Shows that this port can be omitted in .* connection
  input ()           rst_n='1, 
  // missing () shows that this port must be listed by .*
  input              inv_msb='1);

  always @(posedge clk, negedge rst_n)
    if (!rst_n) dataout <= '0;
    else        dataout <= {inv_msb,7'b0}^datain; // New functionality
endmodule

//---------------------------------------------------------------------------

// Alternative instantiation without default ports

module alu_accum4 (
   output [15:0] dataout,
   input   [7:0] ain, bin,
   input   [2:0] opcode,
   input         clk);
   wire    [7:0] alu_out;

   alu   alu   (.*, .zero());
   accum accum (.*, .dataout(dataout[7:0]), .datain(alu_out), .rst_n('1), 
   `ifdef INV_MSB
   .inv_msb('1));
   `else
   .inv_msb('0));
   `endif

   xtend xtend (.*, .dout(dataout[15:8]),   .din(alu_out[7]), .rst('0));
endmodule

//---------------------------------------------------------------------------

// Alternative (currently legal) syntax for accum module
// use config instance statement to select the correct accum 
// in the alu_accum4 

module accum (
  output logic [7:0] dataout,
  input        [7:0] datain,
  input              clk,

  assign rst_n='1; 
  assign inv_msb='1;

  // module in module
  `include "accum_core.v"
endmodule

// Separate file accum_core.v
module accum_core (
  output logic [7:0] dataout,
  input        [7:0] datain,
  input              clk,
  input              rst_n, 
  input              inv_msb);

  always @(posedge clk, negedge rst_n)
    if (!rst_n) dataout <= '0;
    else        dataout <= {inv_msb,7'b0}^datain; // New functionality
endmodule

//---------------------------------------------------------------------------

