// *************************************************************************** //
// file     : HBF2L.v
// desp     : 2 Level Half band filter
// author   : duweitao@cuc.edu.cn
// date     : July.20th.2007
// version  : 0.1
// modified : 
// *************************************************************************** // 
`ifdef INCTSC
`include "timescale.v"
`endif
module HBF2L(
  RST   ,   // high level reset asyn
  CLK   ,   // clock , posedge 
  DINEN ,   // data input enable
  DINI  ,   // data input I
  DINQ  ,   // data input Q
  DOUTEN,   // data output enable
  DOUTI ,   // data output I
  DOUTQ ,   // data output Q
  OUTIDX,   // data output index
  CLKOUT);  // clock output only for simulation

// global param
parameter INPUTWL   = 16;
parameter OUTPUTWL  = 16;
parameter COEFWL    = 16;
// local param
parameter K1        = 16;
parameter K1LOG2    = 4;
parameter K2        = 8;
parameter K2LOG2    = 3;
parameter C2Q       = 2; // time of DFF clock to Q in ns 


// module param
// pecnt
parameter PCYWL     = 6;
parameter PCYMAX    = 31;
parameter PCYIDL    = ((1<<PCYWL)-1);
// crdctl
parameter CADDRWL   = 5;    // crom address word length
// dchannel
parameter DADDRWL   = 5;    // 2 bank data address word length
// outctl
parameter OCYWL     = 6;

input RST, CLK,  DINEN;
input [INPUTWL-1:0] DINI, DINQ;
output DOUTEN;
output [OUTPUTWL-1:0] DOUTI, DOUTQ;
output [1:0] OUTIDX;
output CLKOUT;

wire[PCYWL-1:0]     pecyW;
wire[CADDRWL-1:0]   craW; 
wire[COEFWL-1:0]    coefW, crdW;
///////////////////////////////////////////////////////////////////////////////////////
pecnt U_pecnt(
  .CLK   (CLK  ),   // clock , posedge 
  .RST   (RST  ),   // high level reset asyn
  .DINEN (DINEN),   // data input enable
  .PECY  (pecyW));  // pe cycle counter

defparam U_pecnt.C2Q       = C2Q   ;    // time of DFF clock to Q in ns 
defparam U_pecnt.PCYMAX    = PCYMAX;    // max value of pe counter
defparam U_pecnt.PCYWL     = PCYWL ;    // word length pe cycle counter 
defparam U_pecnt.PCYIDL    = PCYIDL;    // pe cycle idle value
///////////////////////////////////////////////////////////////////////////////////////
crdctl U_crdctl(
  .CLK   (CLK   ),   // clock , posedge 
  .RST   (RST   ),   // high level reset asyn
  .DINEN (DINEN ),   // data input enable
  .PECY  (pecyW ),   // PE cycle counter 
  .CRD   (crdW  ),   // crom read data
  .RE    (      ),   // crom read enable, when use Altera FPGA, left it blank
  .CRA   (craW  ),   // read address
  .COEF  (coefW ));  // clock output only for simulation

defparam U_crdctl.COEFWL    =  COEFWL;
defparam U_crdctl.K1        = K1     ;
defparam U_crdctl.K2        = K2     ;
defparam U_crdctl.C2Q       = C2Q    ;    // time of DFF clock to Q in ns 
defparam U_crdctl.PCYMAX    = PCYMAX ;    // max value of pe counter
defparam U_crdctl.PCYWL     = PCYWL  ;    // word length pe cycle counter 
defparam U_crdctl.PCYIDL    = PCYIDL ;    // pe cycle idle value
defparam U_crdctl.CADDRWL   = CADDRWL;    // crom addr word length
///////////////////////////////////////////////////////////////////////////////////////
crom U_crom(
  .CLK   (CLK   ),         // clock
  .CRA   (craW  ),         // coeff read address
  .CRD   (crdW  ));        // coeff read data
///////////////////////////////////////////////////////////////////////////////////////
dchnnel U_dch_I(
  .CLK   (CLK   ),   // clock , posedge 
  .RST   (RST   ),   // high level reset asyn
  .DIN   (DINI  ),   // data input  
  .DINEN (DINEN ),   // data input enable
  .PECY  (pecyW ),   // pe cycle counter
  .COEF  (coefW ),   // data input enable
  .DOUT  (DOUTI ),   // data output I
  .DOUTEN(DOUTEN),   // data output enable
  .OUTIDX(OUTIDX),   // data output index
  .CLKOUT(CLKOUT));  // output clock


defparam U_dch_I.INPUTWL   = INPUTWL ;    //  input word length
defparam U_dch_I.OUTPUTWL  = OUTPUTWL;    // output word length
defparam U_dch_I.COEFWL    = COEFWL  ;    // coefficent word length
defparam U_dch_I.K1        = K1      ;    
defparam U_dch_I.K1LOG2    = K1LOG2  ;    
defparam U_dch_I.K2        = K2      ;    
defparam U_dch_I.K2LOG2    = K2LOG2  ;
defparam U_dch_I.C2Q       = C2Q     ;    // clock to Q time in ns
defparam U_dch_I.PCYWL     = PCYWL   ;    // pe cycle word length
defparam U_dch_I.PCYMAX    = PCYMAX  ;    // pe cycle max value
defparam U_dch_I.PCYIDL    = PCYIDL  ;    // pe counter IDLE value
defparam U_dch_I.OCYWL     = OCYWL   ;    // pe cycle word length
defparam U_dch_I.ADDRWL    = DADDRWL ;    // 2 bank data ram address word length
///////////////////////////////////////////////////////////////////////////////////////
dchnnel U_dch_Q(
  .CLK   (CLK   ),   // clock , posedge 
  .RST   (RST   ),   // high level reset asyn
  .DIN   (DINQ  ),   // data input  
  .DINEN (DINEN ),   // data input enable
  .PECY  (pecyW ),   // pe cycle counter
  .COEF  (coefW ),   // data input enable
  .DOUT  (DOUTQ ),   // data output I
  .DOUTEN(      ),   // data output enable
  .OUTIDX(      ),   // data output index
  .CLKOUT(      ));  // output clock

defparam U_dch_Q.INPUTWL   = INPUTWL ;    //  input word length
defparam U_dch_Q.OUTPUTWL  = OUTPUTWL;    // output word length
defparam U_dch_Q.COEFWL    = COEFWL  ;    // coefficent word length
defparam U_dch_Q.K1        = K1      ;    
defparam U_dch_Q.K1LOG2    = K1LOG2  ;    
defparam U_dch_Q.K2        = K2      ;
defparam U_dch_Q.K2LOG2    = K2LOG2  ;
defparam U_dch_Q.C2Q       = C2Q     ;    // clock to Q time in ns
defparam U_dch_Q.PCYWL     = PCYWL   ;    // pe cycle word length
defparam U_dch_Q.PCYMAX    = PCYMAX  ;    // pe cycle max value
defparam U_dch_Q.PCYIDL    = PCYIDL  ;    // pe counter IDLE value
defparam U_dch_Q.OCYWL     = OCYWL   ;    // pe cycle word length
defparam U_dch_Q.ADDRWL    = DADDRWL ;    // 2 bank data ram address word length
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////

endmodule   // HBF2L()
