`timescale 1ps/1ps module mult_cic#(parameter DW = 38)( input mclk,//45.1584MHZ input reset_n, input signed[DW-1:0] pcm_in,//352.8khz output signed[31:0] pcm_out //88.2khz ); wire signed [DW-1:0]integrator_temp; wire signed [DW-1:0] decimate_temp; wire signed [DW-1:0] comb_temp; integrator#(.DW(38)) U_integrator( .mclk(mclk), .reset_n(reset_n), .din(pcm_in), .dout(integrator_temp) ); decimate#(.DW(38)) U_decimate( .mclk(mclk), .reset_n(reset_n), .din(integrator_temp), .dout(decimate_temp) ); comb#(.DW(38)) U_comb( .mclk(mclk), .reset_n(reset_n), .din(decimate_temp), .dout(comb_temp) ); //divide assign pcm_out = comb_temp[37:6]; endmodule module integrator#(parameter DW = 38)( input mclk, input reset_n, input signed [DW-1:0] din, output signed [DW-1:0] dout ); localparam LAST_CYCLE = 128; reg [6:0] i; reg signed [DW-1:0] temp_xin1,temp_xin2,temp_xin3; wire signed [DW-1:0] i1_temp,i2_temp,i3_temp; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) i <= 0; else i<= i+1; end always @(posedge mclk or negedge reset_n) begin //The first level integrator if(reset_n == 1'b0) temp_xin1 <= 0; else if(i == (LAST_CYCLE-1)) temp_xin1 <= i1_temp; end assign i1_temp = (reset_n == 1'b0)?38'b0:( din + temp_xin1); always @(posedge mclk or negedge reset_n) begin //The second level integrator if(reset_n == 1'b0) temp_xin2 <= 0; else if(i == (LAST_CYCLE-1)) temp_xin2 <= i2_temp; end assign i2_temp = (reset_n == 1'b0)?38'b0:( i1_temp + temp_xin2); always @(posedge mclk or negedge reset_n) begin //The third level integrator if(reset_n == 1'b0) temp_xin3 <= 0; else if(i == (LAST_CYCLE-1)) temp_xin3 <= i3_temp; end assign i3_temp = (reset_n == 1'b0)?38'b0:( i2_temp + temp_xin3); assign dout = i3_temp; endmodule module decimate#(parameter DW = 38)( input mclk, input reset_n, input signed [DW-1:0] din, output signed [DW-1:0] dout ); localparam LAST_CYCLE = 512; reg [8:0] i;//88.2 reg signed [DW-1:0] dout_pcm; assign dout = dout_pcm; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) begin i <= 0; dout_pcm<=0; end else begin i<= i+1; if(i == (LAST_CYCLE-1)) begin dout_pcm<=din; //downsmple(x,n)--n--4 end end end endmodule module comb#(parameter DW = 38)( input mclk, input reset_n, input signed [DW-1:0] din, output signed [DW-1:0] dout ); localparam LAST_CYCLE = 512; reg [8:0] i;//88.2 reg signed [DW-1:0] d1,d2,d3,d4; wire signed [DW-1:0] c1,c2; always @(posedge mclk or negedge reset_n) begin if(reset_n == 1'b0) begin i <= 0; d1 <=0; d2 <=0; d3 <=0; d4 <=0; end else begin i<= i+1; if(i == (LAST_CYCLE-1)) begin d1<=din; d2<=d1; d3<=c1; d4<=c2; end end end assign c1 = (reset_n ==1'b0)?38'b0:(d1-d2);//comb1 assign c2 = (reset_n ==1'b0)?38'b0:(c1-d3);//comb2 assign dout =(reset_n ==1'b0)?38'b0:(c2-d4);//comb3 endmodule