1. The IIR digital filter design.
 

// IIR.v

// 2nd order iir module
module iir2(out,data_in,clk1,clk2,reset,a0,na1,na2,b0,b1,b2,ka,kb);

output [31:0]out;
input [31:0]data_in;
input clk1,clk2,reset;
input [31:0] a0,na1,na2,b0,b1,b2,ka,kb;

integer maska,maskb;
integer temp1,temp2,temp3,temp4;

reg [31:0]r1;
reg [31:0]r2;
reg [31:0]r3;
reg [31:0]r4;
reg [31:0]r5;
reg [31:0]r6;
reg [31:0]r7;
reg [31:0]r8;
reg [31:0]r9;
reg [31:0]r10;
reg [31:0]r11;
reg [31:0]r12;
reg [31:0]r13;
reg [31:0]out;
 
 

always @ (ka or kb)
begin
        maska=(1<<(32-ka))-1;
        maska=~maska;
        maskb=(1<<(32-kb))-1;
        maskb=~maskb;

end

always @ (posedge clk1)
begin
     if (reset==0)
        begin
        r2<=r1;
        r4<=r3;
        r6<=r5;
        r8<=r7;
        r10<=r9;
        r12<=r11;
        r13<=data_in;
        end
     else
        begin
                r1<=0;
                r2<=0;
                r3<=0;
                r4<=0;
                r5<=0;
                r6<=0;
                r7<=0;
                r8<=0;
                r9<=0;
                r10<=0;
                r11<=0;
                r12<=0;
                r13<=0;
        end

end
 
 

always @ (posedge clk2)
begin
        temp1=r13*a0+r8;
        if  (~temp1[31])
                temp2=temp1>>ka;
        else
             begin
                  temp2=(temp1>>ka)|maska;
                  if (temp1 & ((1<<ka)-1))
                        temp2=temp2+1;
             end

        temp3=temp2*b0+r12;
        if (~temp3[31])
                temp4=temp3>>kb;
        else
             begin
                temp4=(temp3>>kb)|maskb;
                if (temp3 & ((1<<kb)-1))
                        temp4=temp4+1;
             end

        r1<=temp2;
        r3<=r2;
        r5<=r4*na2;
        r7<=r2*na1+r6;
        r9<=r4*b2;
        r11<=r2*b1+r10;
        out<=temp4;

end

endmodule

// 2nd order module
module iir_2(out,data_in,clk1,clk2,reset);
output [31:0]out;
input [31:0]data_in;
input clk1,clk2;
input reset;

iir2 sect2(out,data_in,clk1,clk2,reset,'d16384,'d16955,-'d7033,'d6101,'d12202,'d6101,'d14,'d16);

endmodule
 

// 4th order module
module iir_4(out,data_in,clk1,clk2,reset);
output [31:0]out;
input [31:0]data_in;
input clk1,clk2;
input reset;

wire [31:0] d1;

iir2 sect1(d1,data_in,clk1,clk2,reset,'d8192,'d12011,-'d4759,'d1878,'d3757,'d1878,'d13,'d16);
iir2 sect2(out,d1,clk1,clk2,reset,'d16384,'d23722,-'d13339,'d5666,'d11330,'d5665,'d14,'d16);

endmodule

// 8th order iir module
module iir_8(out,data_in,clk1,clk2,reset);
output [31:0]out;
input [31:0]data_in;
input clk1,clk2;
input reset;

wire [31:0] d1,d2,d3;
 

iir2 sect1(d1,data_in,clk1,clk2,reset,'d2048,'d3523,-'d1542,'d529,'d1058,'d529,'d11,'d16);
iir2 sect2(d2,d1,clk1,clk2,reset,'d4096,'d6803,-'d3242,'d2096,'d4257,'d2162,'d12,'d16);
iir2 sect3(d3,d2,clk1,clk2,reset,'d4096,'d6515,-'d3526,'d4332,'d8662,'d4332,'d12,'d16);
iir2 sect4(out,d3,clk1,clk2,reset,'d4096,'d6446,-'d3892,'d6078,'d11968,'d5893,'d12,'d16);
 

endmodule

//============================================================================

// TEST_IIR.v

`include "iir.v"
module TEST_IIR;

wire [31:0] out;
reg [31:0] data_in;
reg clk1;
reg clk2;
reg reset;

reg [31:0]dat[0:192];
integer i,fp;

initial begin
$shm_open("wavespre.shm");
$shm_probe("AS");
//fp=$fopen("OUT2.dat");   // output for 2nd order iir module
//fp=$fopen("OUT4.dat");   // output for 4th order iir module
fp=$fopen("OUT8.dat");     // output for 8th order iir module

                clk1= 0;
                clk2= 0;

                #5 reset=1;
                #40 reset=0;

                $readmemh("sdh.dat",dat,0,192);
                data_in = dat[0];
                for (i=1;i<193;i=i+1)
                   begin
                        #20 data_in = dat[i];
                        #20 data_in = 0;
                   end
                $shm_close();
                $fclose(fp);
                $finish;
end

always @ (posedge clk1)
        begin
        $fwrite(fp,"%d %d\n",$stime,out);
        $display("%d %d\n",$stime,out);
        end

//iir_2 filter2 (out,data_in,clk1,clk2,reset); //test 2nd order
//iir_4 filter4 (out,data_in,clk1,clk2,reset); //test 4th order
iir_8 filter8 (out,data_in,clk1,clk2,reset);  //test 8th order

always

begin

#5 clk1 = ~clk1;
#5 clk2 = clk1;
 

end

endmodule
 

//===============================================================

//sdh.dat

0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
fffffffe
0
fffffffe
0
fffffffe
ffffffff
ffffffff
ffffffff
0
fffffffe
0
fffffffe
0
fffffffe
ffffffff
ffffffff
ffffffff
fffffffd
4
fffffff2
18
ffffffd4
45
ffffff93
9e
ffffff19
143
fffffe38
282
fffffc58
5b5
fffff53d
27ff
5ac3
4a49
53a8
4d7c
51c8
4ebb
50e6
4f61
506b
4fbb
5029
4fe9
500b
4ffb
5001
5000
5000
5001
4ffb
500b
4fe9
5029
4fbb
506b
4f61
50e6
4ebb
51c8
4d7c
53a8
4a49
5ac3
27ff
fffff53d
5b5
fffffc58
282
fffffe38
143
ffffff19
9e
ffffff93
45
ffffffd4
18
fffffff2
4
ffffffff
ffffffff
1
ffffffff
0
1
ffffffff
2
fffffffe
2
fffffffe
1
ffffffff
0
1
ffffffff
1
1
fffffffc
e
ffffffe8
2c
ffffffbb
6d
ffffff62
e7
fffffebd
1c8
fffffd7e
3a8
fffffa4b
ac3
ffffd801
ffffa53d
ffffb5b7
ffffac58
ffffb284
ffffae38
ffffb145
ffffaf1a
ffffb09f
ffffaf95
ffffb045
ffffafd7
ffffb017
ffffaff5
ffffb005
ffffafff
ffffb000
ffffb000
ffffafff
ffffb005
ffffaff5
ffffb017
ffffafd7
ffffb045
ffffaf95
ffffb09f
ffffaf1a
ffffb145
ffffae38
ffffb284
ffffac58
ffffb5b7
ffffa53d
ffffd801
ac3
fffffa4b
3a8
fffffd7e
1c8
fffffebd
e7
ffffff62
6d
ffffffbb
2c
ffffffe8
e
fffffffc
3
1
1
1
2
0
2
0
2
0
1
1
1
2
0
2
0
2

//=============================================================

//OUT8.dat

         5          x
        25          0
        45          0
        65          0
        85          0
       105          0
       125          0
       145          0
       165          0
       185          0
       205          0
       225          0
       245          0
       265          0
       285          0
       305          0
       325          0
       345          0
       365          0
       385          0
       405          0
       425          0
       445          0
       465          0
       485          0
       505          0
       525          0
       545          0
       565          0
       585          0
       605          0
       625          0
       645          0
       665          0
       685          0
       705          0
       725          0
       745          0
       765          0
       785          0
       805          0
       825          0
       845          0
       865          0
       885          0
       905          0
       925          0
       945          0
       965          0
       985          0
      1005          0
      1025          0
      1045          0
      1065          0
      1085          0
      1105          0
      1125          0
      1145          0
      1165          0
      1185          0
      1205          0
      1225          0
      1245          0
      1265          0
      1285          0
      1305          0
      1325          0
      1345          0
      1365          0
      1385          0
      1405          0
      1425          0
      1445          0
      1465          0
      1485          0
      1505          0
      1525          0
      1545          0
      1565          0
      1585          0
      1605          0
      1625          0
      1645          0
      1665          0
      1685          0
      1705          0
      1725          0
      1745          0
      1765          0
      1785          0
      1805          0
      1825          0
      1845          0
      1865          0
      1885          0
      1905          0
      1925          0
      1945          0
      1965          0
      1985          0
      2005          0
      2025          0
      2045          0
      2065          1
      2085          0
      2105          8
      2125          0
      2145         37
      2165          0
      2185        129
      2205          0
      2225        365
      2245          0
      2265        870
      2285          0
      2305       1807
      2325          0
      2345       3339
      2365          0
      2385       5575
      2405          0
      2425       8509
      2445          0
      2465      11973
      2485          0
      2505      15638
      2525          0
      2545      19058
      2565          0
      2585      21773
      2605          0
      2625      23420
      2645          0
      2665      23843
      2685          0
      2705      23146
      2725          0
      2745      21672
      2765          0
      2785      19921
      2805          0
      2825      18409
      2845          0
      2865      17530
      2885          0
      2905      17452
      2925          0
      2945      18090
      2965          0
      2985      19147
      3005          0
      3025      20231
      3045          0
      3065      20981
      3085          0
      3105      21184
      3125          0
      3145      20828
      3165          0
      3185      20089
      3205          0
      3225      19254
      3245          0
      3265      18615
      3285          0
      3305      18364
      3325          0
      3345      18539
      3365          0
      3385      19019
      3405          0
      3425      19581
      3445          0
      3465      19976
      3485          0
      3505      19998
      3525          0
      3545      19532
      3565          0
      3585      18540
      3605          0
      3625      17040
      3645          0
      3665      15063
      3685          0
      3705      12639
      3725          0
      3745       9817
      3765          0
      3785       6693
      3805          0
      3825       3457
      3845          0
      3865        393
      3885          0
      3905 4294965140
      3925          0
      3945 4294963431
      3965          0
      3985 4294962768
      4005          0
      4025 4294963159
      4045          0
      4065 4294964383
      4085          0
      4105 4294966033
      4125          0
      4145        321
      4165          0
      4185       1404
      4205          0
      4225       1724
      4245          0
      4265       1269
      4285          0
      4305        264
      4325          0
      4345 4294966388
      4365          0
      4385 4294965450
      4405          0
      4425 4294965042
      4445          0
      4465 4294965259
      4485          0
      4505 4294965977
      4525          0
      4545 4294966914
      4565          0
      4585        438
      4605          0
      4625        876
      4645          0
      4665        821
      4685          0
      4705        348
      4725          0
      4745 4294966974
      4765          0
      4785 4294966382
      4805          0
      4825 4294966096
      4845          0
      4865 4294966222
      4885          0
      4905 4294966705
      4925          0
      4945         67
      4965          0
      4985        667
      5005          0
      5025       1006
      5045          0
      5065        986
      5085          0
      5105        643
      5125          0
      5145        123
      5165          0
      5185 4294966922
      5205          0
      5225 4294966619
      5245          0
      5265 4294966599
      5285          0
      5305 4294966837
      5325          0
      5345 4294967199
      5365          0
      5385        189
      5405          0
      5425        180
      5445          0
      5465 4294966972
      5485          0
      5505 4294965830
      5525          0
      5545 4294963981
      5565          0
      5585 4294961448
      5605          0
      5625 4294958350
      5645          0
      5665 4294954910
      5685          0
      5705 4294951434
      5725          0
      5745 4294948284
      5765          0
      5785 4294945810
      5805          0
      5825 4294944281
      5845          0
      5865 4294943813
      5885          0
      5905 4294944327
      5925          0
      5945 4294945557
      5965          0
      5985 4294947100
      6005          0
      6025 4294948518
      6045         0
      6065 4294949449
      6085          0
      6105 4294949698
      6125          0
      6145 4294949279
      6165          0
      6185 4294948402
      6205          0
      6225 4294947393
      6245          0
      6265 4294946588
      6285          0
      6305 4294946227
      6325          0
      6345 4294946387
      6365          0
      6385 4294946967
      6405          0
      6425 4294947740
      6445          0
      6465 4294948435
      6485          0
      6505 4294948832
      6525          0
      6545 4294948835
      6565          0
      6585 4294948496
      6605          0
      6625 4294947987
      6645          0
      6665 4294947541
      6685          0
      6705 4294947385
      6725          0
      6745 4294947691
      6765          0
      6785 4294948556
      6805          0
      6825 4294950010
      6845          0
      6865 4294952035
      6885          0
      6905 4294954578
      6925          0
      6945 4294957545
      6965          0
      6985 4294960781
      7005          0
      7025 4294964058
      7045          0
      7065 4294967080
      7085          0
      7105       2225
      7125          0
      7145       3806
      7165          0
      7185       4370
      7205          0
      7225       3944
      7245          0
      7265       2759
      7285          0
      7305       1204
      7325          0
      7345 4294967028
      7365          0
      7385 4294966032
      7405          0
      7425 4294965742
      7445          0
      7465 4294966162
      7485          0
      7505 4294967084
      7525          0
      7545        861
      7565          0
      7585       1723
      7605          0
      7625       2106
      7645          0
      7665       1921
      7685          0
      7705       1277
         5          x
        25          0
        45          0
        65          0
        85          0
       105          0
       125          0
       145          0
       165          0
       185          0
       205          0
       225          0
       245          0
       265          0
       285          0
       305          0
       325          0
       345          0
       365          0
       385          0
       405          0
       425          0
       445          0
       465          0
       485          0
       505          0
       525          0
       545          0
       565          0
       585          0
       605          0
       625          0
       645          0
       665          0
       685          0
       705          0
       725          0
       745          0
       765          0
       785          0
       805          0
       825          0
       845          0
       865          0
       885          0
       905          0
       925          0
       945          0
       965          0
       985          0
      1005          0
      1025          0
      1045          0
      1065          0
      1085          0
      1105          0
      1125          0
      1145          0
      1165          0
      1185          0
      1205          0
      1225          0
      1245          0
      1265          0
      1285          0
      1305          0
      1325          0
      1345          0
      1365          0
      1385          0
      1405          0
      1425          0
      1445          0
      1465          0
      1485          0
      1505          0
      1525          0
      1545          0
      1565          0
      1585          0
      1605          0
      1625          0
      1645          0
      1665          0
      1685          0
      1705          0
      1725          0
      1745          0
      1765          0
      1785          0
      1805          0
      1825          0
      1845          0
      1865          0
      1885          0
      1905          0
      1925          0
      1945          0
      1965          0
      1985          0
      2005          0
      2025          0
      2045          0
      2065          1
      2085          0
      2105          8
      2125          0
      2145         37
      2165          0
      2185        129
      2205          0
      2225        365
      2245          0
      2265        870
      2285          0
      2305       1807
      2325          0
      2345       3339
      2365          0
      2385       5575
      2405          0
      2425       8509
      2445          0
      2465      11973
      2485          0
      2505      15638
      2525          0
      2545      19058
      2565          0
      2585      21773
      2605          0
      2625      23420
      2645          0
      2665      23843
      2685          0
      2705      23146
      2725          0
      2745      21672
      2765          0
      2785      19921
      2805          0
      2825      18409
      2845          0
      2865      17530
      2885          0
      2905      17452
      2925          0
      2945      18090
      2965          0
      2985      19147
      3005          0
      3025      20231
      3045          0
      3065      20981
      3085          0
      3105      21184
      3125          0
      3145      20828
      3165          0
      3185      20089
      3205          0
      3225      19254
      3245          0
      3265      18615
      3285          0
      3305      18364
      3325          0
      3345      18539
      3365          0
      3385      19019
      3405          0
      3425      19581
      3445          0
      3465      19976
      3485          0
      3505      19998
      3525          0
      3545      19532
      3565          0
      3585      18540
      3605          0
      3625      17040
      3645          0
      3665      15063
      3685          0
      3705      12639
      3725          0
      3745       9817
      3765          0
      3785       6693
      3805          0
      3825       3457
      3845          0
      3865        393
      3885          0
      3905 4294965140
      3925          0
      3945 4294963431
      3965          0
      3985 4294962768
      4005          0
      4025 4294963159
      4045          0
      4065 4294964383
      4085          0
      4105 4294966033
      4125          0
      4145        321
      4165          0
      4185       1404
      4205          0
      4225       1724
      4245          0
      4265       1269
      4285          0
      4305        264
      4325          0
      4345 4294966388
      4365          0
      4385 4294965450
      4405          0
      4425 4294965042
      4445          0
      4465 4294965259
      4485          0
      4505 4294965977
      4525          0
      4545 4294966914
      4565          0
      4585        438
      4605          0
      4625        876
      4645          0
      4665        821
      4685          0
      4705        348
      4725          0
      4745 4294966974
      4765          0
      4785 4294966382
      4805          0
      4825 4294966096
      4845          0
      4865 4294966222
      4885          0
      4905 4294966705
      4925          0
      4945         67
      4965          0
      4985        667
      5005          0
      5025       1006
      5045          0
      5065        986
      5085          0
      5105        643
      5125          0
      5145        123
      5165          0
      5185 4294966922
      5205          0
      5225 4294966619
      5245          0
      5265 4294966599
      5285          0
      5305 4294966837
      5325          0
      5345 4294967199
      5365          0
      5385        189
      5405          0
      5425        180
      5445          0
      5465 4294966972
      5485          0
      5505 4294965830
      5525          0
      5545 4294963981
      5565          0
      5585 4294961448
      5605          0
      5625 4294958350
      5645          0
      5665 4294954910
      5685          0
      5705 4294951434
      5725          0
      5745 4294948284
      5765          0
      5785 4294945810
      5805          0
      5825 4294944281
      5845          0
      5865 4294943813
      5885          0
      5905 4294944327
      5925          0
      5945 4294945557
      5965          0
      5985 4294947100
      6005          0
      6025 4294948518
      6045          0
      6065 4294949449
      6085          0
      6105 4294949698
      6125          0
      6145 4294949279
      6165          0
      6185 4294948402
      6205          0
      6225 4294947393
      6245          0
      6265 4294946588
      6285          0
      6305 4294946227
      6325          0
      6345 4294946387
      6365          0
      6385 4294946967
      6405          0
      6425 4294947740
      6445          0
      6465 4294948435
      6485          0
      6505 4294948832
      6525          0
      6545 4294948835
      6565          0
      6585 4294948496
      6605          0
      6625 4294947987
      6645          0
      6665 4294947541
      6685          0
      6705 4294947385
      6725          0
      6745 4294947691
      6765          0
      6785 4294948556
      6805          0
      6825 4294950010
      6845          0
      6865 4294952035
      6885          0
      6905 4294954578
      6925          0
      6945 4294957545
      6965          0
      6985 4294960781
      7005          0
      7025 4294964058
      7045          0
      7065 4294967080
      7085          0
      7105       2225
      7125          0
      7145       3806
      7165          0
      7185       4370
      7205          0
      7225       3944
      7245          0
      7265       2759
      7285          0
      7305       1204
      7325          0
      7345 4294967028
      7365          0
      7385 4294966032
      7405          0
      7425 4294965742
      7445          0
      7465 4294966162
      7485          0
      7505 4294967084
      7525          0
      7545        861
      7565          0
      7585       1723
      7605          0
      7625       2106
      7645          0
      7665       1921
      7685          0
      7705       1277
 

2. The wavelet denoising system design

module DOWN2 ( clock, reset, in, out)

input clock, reset;
input [15:0] in;
output [15:0] out;

reg [15:0] out;
reg dw_2;
 

always@( posedge clock or negedge reset)
 begin
   if(!reset)
     out<=16'h0000;
   else
     out<= dw_2 ? in : out;
  end

always@( posedge clock or negedge reset)
 dw_2 <= (!reset) ? 0 : (dw_2 ^ 1);

endmodule

module RTL(clock, reset, in, out);

input clock, reset;
input [15:0] indat;
output [15:0] out1;

reg [15:0] reg1;
reg [15:0] reg2;
reg [31:0] reg3;
reg [31:0] reg4;
reg [31:0] reg5;
reg [31:0] reg6;
reg [31:0] reg7;
reg [31:0] reg8;
reg [31:0] reg9;
reg [15:0] out;

parameter b0 = 16'hc000;
parameter b1 = 16'h4000;
parameter b2 = 16'h0;
parameter kb = 'd15;

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

task mult16;

output [31:0] c;
input [15:0] a;
input [15:0] b;
input phi;
reg [15:0] reg1;
reg [15:0] reg2;
reg [31:0] c, reg3;

begin

    if (a[15] == 1)
               reg1 = ~a + 16'h0001;
           else if (a[15] == 0)
               reg1 = a;
           if (b[15] == 1)
               reg2 = ~b + 16'h0001;
           else if (b[15] == 0)
               reg2 = b;
           reg3 = reg1*reg2;
           if (a[15]^b[15] == 1)
               c = ~reg3 + 32'h00000001;
           else if (a[15]^b[15] == 0)
               c = reg3;

end

endtask

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

task add32;

input clock;
input [31:0] in1;
input [31:0] in2;
output [31:0] out;
reg [31:0] out;
reg [31:0] temp;

begin

  temp <= in1 + in2;

  if ((in1[31] == in2[31]) && (!temp[31]) && (in1[31]))

  out <={1'b1,{31{1'b0}}}; // handle negative overflow

  else if ((in1[31] == in2[31]) && (temp[31]) && (!in1[31]))

  out <={1'b0,{31{1'b1}}}; // handle positive overflow

  else

  out <= temp;

end

endtask

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

task shift_kb;

input clock;
input [31:0] in;
input [5:0] kb;
output [31:0] out;

begin

  if (!in[31])//positive

  out <= in >> kb;

  else //negative

  //out <= {{kb{1'b1}}, {in[31:kb]}};
  out <= {(32'hffffffff<<(32-kb))^(in>>kb)};
end

endtask

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

always @ (posedge clock or negedge reset)

begin

  if (!reset)

     begin

 reg1 <= 16'h0000;
 reg2 <= 16'h0000;
 reg3 <= 32'h00000000;
 reg4 <= 32'h00000000;
 reg5 <= 32'h00000000;
 reg6 <= 32'h00000000;
 reg7 <= 32'h00000000;
 reg8 <= 32'h00000000;
 reg9 <= 32'h00000000;
 out <= 16'h0000;

     end

  else

     begin

 reg1 <= in;
 reg2 <= reg1;
 reg6 <= reg5;
 reg8 <= reg7;
        add32 (clock, reg8, reg3, reg9);
 add32 (clock, reg6, reg4, reg7);
 mult16(reg3, in, b0, clock);
 mult16(reg4, reg1, b1, clock);
 mult16(reg5, reg2, b2, clock);
 shift_kb (clock, reg9, kb, out);

     end

end

endmodule
 

`include "RTL.v"
`include "down2.v"

module RTLx6_hi_d (clock, reset, in, out);

input clock, reset;
input [15:0] in;
output [15:0] out;

wire [15:0] temp1;
wire [15:0] temp2;
wire [15:0] temp3;
wire [15:0] temp4;
wire [15:0] temp5;
wire [15:0] temp6;

RTL u1(.clock(clock), .reset(reset), .in(in), .out(temp1));
defparam u1.kb = 'd15;
defparam u1.b0 = 16'hc000;
defparam u1.b1 = 16'h4000;
defparam u1.b2 = 16'h0;

RTL u2(.clock(clock), .reset(reset), .in(temp1), .out(temp2));
defparam u2.kb = 'd15;
defparam u2.b0 = 16'h5f0e;
defparam u2.b1 = 16'hc309;
defparam u2.b2 = 16'hdeb1;

RTL u3(.clock(clock), .reset(reset), .in(temp2), .out(temp3));
defparam u3.kb = 'd15;
defparam u3.b0 = 16'h2137;
defparam u3.b1 = 16'hbd3e;
defparam u3.b2 = 16'h218b;

RTL u4(.clock(clock), .reset(reset), .in(temp3), .out(temp4));
defparam u4.kb = 'd15;
defparam u4.b0 = 16'h200f;
defparam u4.b1 = 16'hc000;
defparam u4.b2 = 16'h1ff1;

RTL u5(.clock(clock), .reset(reset), .in(temp4), .out(temp5));
defparam u5.kb = 'd14;
defparam u5.b0 = 16'h6107;
defparam u5.b1 = 16'h3446;
defparam u5.b2 = 16'h133f;

RTL u6(.clock(clock), .reset(reset), .in(temp5), .out(temp6));
defparam u6.kb = 'd13;
defparam u6.b0 = 16'h618f;
defparam u6.b1 = 16'h41c7;
defparam u6.b2 = 16'hd79;

DOWN2 u7(.clock(clock), .reset(reset), .in(temp6), .out(out));

endmodule
 

`include "RTL.v"
`include "down2.v"

module RTLx6_hi_i (clock, reset, in, out);

input clock, reset;
input [15:0] in;
output [15:0] out;

wire [15:0] temp1;
wire [15:0] temp2;
wire [15:0] temp3;
wire [15:0] temp4;
wire [15:0] temp5;
wire [15:0] temp6;

RTL u1(.clock(clock), .reset(reset), .in(in), .out(temp1));
defparam u1.kb = 'd15;
defparam u1.b0 = 16'hc032;
defparam u1.b1 = 16'h4032;
defparam u1.b2 = 16'h0;

RTL u2(.clock(clock), .reset(reset), .in(temp1), .out(temp2));
defparam u2.kb = 'd15;
defparam u2.b0 = 16'h216a;
defparam u2.b1 = 16'h3d5f;
defparam u2.b2 = 16'ha13f;

RTL u3(.clock(clock), .reset(reset), .in(temp2), .out(temp3));
defparam u3.kb = 'd15;
defparam u3.b0 = 16'h2151;
defparam u3.b1 = 16'hbd3e;
defparam u3.b2 = 16'h2171;

RTL u4(.clock(clock), .reset(reset), .in(temp3), .out(temp4));
defparam u4.kb = 'd14;
defparam u4.b0 = 16'h133f;
defparam u4.b1 = 16'h3446;
defparam u4.b2 = 16'h6107;

RTL u5(.clock(clock), .reset(reset), .in(temp4), .out(temp5));
defparam u5.kb = 'd14;
defparam u5.b0 = 16'hd23;
defparam u5.b1 = 16'h4022;
defparam u5.b2 = 16'h5f1e;

RTL u6(.clock(clock), .reset(reset), .in(temp5), .out(temp6));
defparam u6.kb = 'd14;
defparam u6.b0 = 16'h20fb;
defparam u6.b1 = 16'hbe5c;
defparam u6.b2 = 16'h20a9;

DOWN2 u7(.clock(clock), .reset(reset), .in(temp6), .out(out));

endmodule
 

`include "RTL.v"
`include "down2.v"

module RTLx6_lo_d (clock, reset, in, out);

input clock, reset;
input [15:0] in;
output [15:0] out;

wire [15:0] temp1;
wire [15:0] temp2;
wire [15:0] temp3;
wire [15:0] temp4;
wire [15:0] temp5;
wire [15:0] temp6;

RTL u1(.clock(clock), .reset(reset), .in(in), .out(temp1));
defparam u1.kb = 'd15;
defparam u1.b0 = 16'hdea3;
defparam u1.b1 = 16'h5ea3;
defparam u1.b2 = 16'h0;

RTL u2(.clock(clock), .reset(reset), .in(temp1), .out(temp2));
defparam u2.kb = 'd14;
defparam u2.b0 = 16'h1ff3;
defparam u2.b1 = 16'h4016;
defparam u2.b2 = 16'h2023;

RTL u3(.clock(clock), .reset(reset), .in(temp2), .out(temp3));
defparam u3.kb = 'd14;
defparam u3.b0 = 16'ha48;
defparam u3.b1 = 16'hcdcd;
defparam u3.b2 = 16'h4a74;

RTL u4(.clock(clock), .reset(reset), .in(temp3), .out(temp4));
defparam u4.kb = 'd15;
defparam u4.b0 = 16'h17a3;
defparam u4.b1 = 16'hdea3;
defparam u4.b2 = 16'h7728;

RTL u5(.clock(clock), .reset(reset), .in(temp4), .out(temp5));
defparam u5.kb = 'd14;
defparam u5.b0 = 16'h22a8;
defparam u5.b1 = 16'h4572;
defparam u5.b2 = 16'h22ca;

RTL u6(.clock(clock), .reset(reset), .in(temp5), .out(temp6));
defparam u6.kb = 'd14;
defparam u6.b0 = 16'h20fb;
defparam u6.b1 = 16'h41a4;
defparam u6.b2 = 16'h20a9;

DOWN2 u7(.clock(clock), .reset(reset), .in(temp6), .out(out));

endmodule
 

`include "RTL.v"
`include "down2.v"

module RTLx6_lo_r (clock, reset, in, out);

input clock, reset;
input [15:0] in;
output [15:0] out;

wire [15:0] temp1;
wire [15:0] temp2;
wire [15:0] temp3;
wire [15:0] temp4;
wire [15:0] temp5;
wire [15:0] temp6;

RTL u1(.clock(clock), .reset(reset), .in(in), .out(temp1));
defparam u1.kb = 'd15;
defparam u1.b0 = 16'h5ea3;
defparam u1.b1 = 16'hdea3;
defparam u1.b2 = 16'h0;

RTL u2(.clock(clock), .reset(reset), .in(temp1), .out(temp2));
defparam u2.kb = 'd14;
defparam u2.b0 = 16'h2024;
defparam u2.b1 = 16'h4016;
defparam u2.b2 = 16'h1ff2;

RTL u3(.clock(clock), .reset(reset), .in(temp2), .out(temp3));
defparam u3.kb = 'd14;
defparam u3.b0 = 16'h5469;
defparam u3.b1 = 16'hd286;
defparam u3.b2 = 16'h10bf;

RTL u4(.clock(clock), .reset(reset), .in(temp3), .out(temp4));
defparam u4.kb = 'd15;
defparam u4.b0 = 16'h2671;
defparam u4.b1 = 16'h4cbc;
defparam u4.b2 = 16'h264c;

RTL u5(.clock(clock), .reset(reset), .in(temp4), .out(temp5));
defparam u5.kb = 'd15;
defparam u5.b0 = 16'h1fd8;
defparam u5.b1 = 16'h4000;
defparam u5.b2 = 16'h2028;

RTL u6(.clock(clock), .reset(reset), .in(temp5), .out(temp6));
defparam u6.kb = 'd13;
defparam u6.b0 = 16'h618f;
defparam u6.b1 = 16'hbe39;
defparam u6.b2 = 16'hd79;

DOWN2 u7(.clock(clock), .reset(reset), .in(temp6), .out(out));

endmodule
 

`include "RTXx6_lo_d.v"
`include "RTXx6_hi_d.v"
`include "RTXx6_lo_r.v"
`include "RTXx6_lo_r.v"
`include "down2.v"

module d (clock, reset, in, out);

input clock, reset;
input [15:0] in;

output [15:0]out;

wire [15:0] t11;
wire [15:0] t12;
wire [15:0] t21;
wire [15:0] t22;
wire [15:0] t23;
wire [15:0] t24;
wire [15:0] t31;
wire [15:0] t32;
wire [15:0] t33;
wire [15:0] t34;
wire [15:0] t35;
wire [15:0] t36;
wire [15:0] t41;
wire [15:0] t42;
wire [15:0] t43;
wire [15:0] t44;
wire [15:0] t45;
wire [15:0] t46;
wire [15:0] t47;
wire [15:0] t48;
wire [15:0] t49;
wire [15:0] t4a;
wire [15:0] t4b;
 

`include "DW02_mult.v"  // include two's complement multiplier
`include "DW01_add.v"  // and carry save adder from Design Ware
/***********************************************************************************

 The modules  in this file model an 8 tap,Interleaved (by 2) FIR filter incorperationg
 the two phase clocking scheme, bit it can be easily extended to model an N tap filter.
 The module "pfcell" model the following hardware structure which was derived using the
 "cutset retiming" technique. It was derived from the TRANSPOSED DIRECT implementation
 of the FIR. The cells (unmodified) were chosen with the delay to  the left and the
 combinational logic to the right. Again, this choice of cell adds and extra delay to the
 output of the TOTAL FIR structure. This time when cutset retiming is done, not delays
 pipeline delays are added, but in order to get rid of broadcasting and global logic problems
 H(z) has to be changed to H(z^2). This calls for interleaving the system input by 2. Now there
 is a TOTAL system delay for 2 (1 per interleaved signal) at the output. This purely interleaved
 FIR is chosen as opposed to the pipelined interleaved version, because it has a lower
 system delay.

************************************************************************************/

module pf2cell(rin,sin,rout,sout,bin,ph1,ph2,rst);

 parameter cobw=31; // cell output bit width
 parameter ibw=16; // cell input bit width
 parameter shf=4; // amount that the be coeffs. are right shifted
 parameter scfbw=16-shf; // coeffs. bit width (scale factor is 2^(scfbw-1))
 

 input [ibw-1:0] rin; // cell data input
 input [scfbw-1:0] bin; // cell coeff. input
 input [cobw-1:0] sin; // cell input from previos cell
 output [ibw-1:0] rout; // cell data output
 output [cobw-1:0] sout; // cell output to next cell
 input ph1,ph2,rst; // clocks and reset
 

 reg [ibw-1:0]a,rout;  // delayed input
 wire [(ibw+scfbw)-1:0] b; // result of multiplication
 reg [(ibw+scfbw)-1:0] c,d; // delayed result of multiplication
 reg [cobw-1:0] e,di,f,sout; // bus at the bottom of cell
 wire [cobw-1:0] ei;  // check this variable for adder
     // overflow
 wire co;   // carry out from adder
 
 

 always @(posedge ph1)  // on the first phase of clock
 begin
  if(rst==0)
  begin
   a<=rin;
   d<=c;
   f<=sin;
  end
  else
  begin
   a<=0;
   d<=0;
   f<=0;

  end
 end

 always @(posedge ph2) // on the second phase of the clock
 begin
  if(rst==0)
  begin

   rout<=a;
   c<=b;
   sout<=e;
  end
  else
  begin
   rout<=0;
   c<=0;
   sout<=0;

  end
 end

 always @(ei) // When results of adder are ready
 begin
  if((f[cobw-1]==di[cobw-1])&(f[cobw-1]!=ei[cobw-1])&(f[cobw-1]==1'b1))
   e<={1'b1,{(cobw-1){1'b0}}}; // handle negative overflow

  else if((f[cobw-1]==di[cobw-1])&(f[cobw-1]!=ei[cobw-1])&(f[cobw-1]==1'b0))
   e<={1'b0,{(cobw-1){1'b1}}}; // handle positve overflow
  else
   e<=ei;  // when no overflow is detected

 end

 always @(d) // before inputing to the adder
 begin
   // sign extend d to the cell output bit width
  di<={{(cobw-(ibw+scfbw)){d[ibw+scfbw-1]}},d};
 end

 DW02_mult #(ibw,scfbw) U1(a,bin,1'b1,b);  // instantiate two's
        // compliment multiplier
 DW01_add #(cobw) U2(ei,co,f,di,1'b0); // intantiate carry save adder
 

endmodule

module qmfilters2(din,ldout,hdout,bin,ph1,ph2,rst);

 parameter cobw=31; // cell output bit width
 parameter ibw=16; // cell input bit width
 parameter shf=4; // amount that the be coeffs. are right shifted
 parameter scfbw=16-shf; // coeffs. bit width (scale factor is 2^(scfbw-1))
 

 input [ibw-1:0] din;  // filter data input
 input [scfbw-1:0] bin;  // input to serailly load coefficients
 output [cobw-scfbw:0] ldout,hdout;  // filter output, after down scaling
 input ph1,ph2,rst;  // clocks and reset

 reg [scfbw-1:0] b [0:7]; // shift registers to hold coeffs.

 wire [ibw-1:0] lr0,lr1,lr2,lr3,lr4,lr5,lr6,lr7; //cell data inputs & outputs
 wire [cobw-1:0] ls0,ls1,ls2,ls3,ls4,ls5,ls6,ls7,ls8;

 wire [ibw-1:0] hr0,hr1,hr2,hr3,hr4,hr5,hr6,hr7; //cell data inputs & outputs
 wire [cobw-1:0] hs0,hs1,hs2,hs3,hs4,hs5,hs6,hs7,hs8;

 always @(posedge ph1) // coeffs. are loaded serially on reset

 begin
  if(rst==1)
  begin
   b[0]<=bin;
   b[1]<=b[0];
   b[2]<=b[1];
   b[3]<=b[2];
   b[4]<=b[3];
   b[5]<=b[4];
   b[6]<=b[5];
   b[7]<=b[6];

  end
 

 end

 assign ls8=0; // ground last "sin" input
 assign hs8=0;

 pf2cell #(cobw,ibw,shf,scfbw) cell1(din,ls1,lr0,ls0,b[0],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell2(lr0,ls2,lr1,ls1,b[1],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell3(lr1,ls3,lr2,ls2,b[2],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell4(lr2,ls4,lr3,ls3,b[3],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell5(lr3,ls5,lr4,ls4,b[4],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell6(lr4,ls6,lr5,ls5,b[5],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell7(lr5,ls7,lr6,ls6,b[6],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell8(lr6,ls8,lr7,ls7,b[7],ph1,ph2,rst);
 
 

 pf2cell #(cobw,ibw,shf,scfbw) cell9(din,hs1,hr0,hs0,-b[7],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell10(hr0,hs2,hr1,hs1,b[6],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell11(hr1,hs3,hr2,hs2,-b[5],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell12(hr2,hs4,hr3,hs3,b[4],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell13(hr3,hs5,hr4,hs4,-b[3],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell14(hr4,hs6,hr5,hs5,b[2],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell15(hr5,hs7,hr6,hs6,-b[1],ph1,ph2,rst);
 pf2cell #(cobw,ibw,shf,scfbw) cell16(hr6,hs8,hr7,hs7,b[0],ph1,ph2,rst);
 
 

 assign ldout=ls0[cobw-1:scfbw-1]; // scale the system output down
 assign hdout=hs0[cobw-1:scfbw-1];
 
 
 

endmodule
 

module threshold(clock, in, out);

input clock;
input [15:0] in;
output [15:0] out;
reg [15:0] reg1;
reg [15:0] out;

parameter T= 16;

always@(posedge clock)
begin
reg1=0;
  if(in[15]==1)
    begin
       reg1<=~in;
         if(reg1<16)
        out<=~(16'h0);
      else
        out<=~(reg1-T);
    end
   else if((in[15]==0) && (in<T))
           out<=0;
   else
    out<= (in-T);
end

//assign out=(reg1<T) ? 1 : (reg1-T);
endmodule
 

`include "DWT_lo.v"
`include "DWT_hi.v"
`include "DWT_lo_r.v"
`include "DWT_hi_r.v"
`include "down2.v"
`include "threshold.v"

module filter (clock, reset, in, out);

input clock, reset;
input [15:0] in;

output [15:0]out;

wire [15:0] t11;
wire [15:0] t12;
wire [15:0] t21;
wire [15:0] t22;
wire [15:0] t23;
wire [15:0] t24;
wire [15:0] t31;
wire [15:0] t32;
wire [15:0] t33;
wire [15:0] t34;
wire [15:0] t35;
wire [15:0] t36;
wire [15:0] t41;
wire [15:0] t42;
wire [15:0] t43;
wire [15:0] t44;
wire [15:0] t45;
wire [15:0] t46;
wire [15:0] t47;
wire [15:0] t48;
wire [15:0] t49;
wire [15:0] t4a;
wire [15:0] t4b;
wire [15:0] t4c;
wire [15:0] t4d;
wire [15:0] t4e;
wire [15:0] t4f;
wire [15:0] t4g;
wire [15:0] th1;
wire [15:0] th2;
wire [15:0] th3;
wire [15:0] th4;
wire [15:0] th5;
wire [15:0] th6;
wire [15:0] th7;
wire [15:0] t51;
wire [15:0] t52;
wire [15:0] t53;
wire [15:0] t54;
wire [15:0] t55;
wire [15:0] t56;
wire [15:0] t57;
wire [15:0] t58;
wire [15:0] t61;
wire [15:0] t62;
wire [15:0] t63;
wire [15:0] t64;
wire [15:0] t71;
wire [15:0] t72;

DWT_HI u1(.clock(clock), .reset(reset), .in(in), .out(t11));
DWT_HI u2(.clock(clock), .reset(reset), .in(th1), .out(t21));
DWT_HI u3(.clock(clock), .reset(reset), .in(t12), .out(t23));
DWT_HI u4(.clock(clock), .reset(reset), .in(th2), .out(t31));
DWT_HI u5(.clock(clock), .reset(reset), .in(t22), .out(t33));
DWT_HI u6(.clock(clock), .reset(reset), .in(t23), .out(t35));
DWT_HI u7(.clock(clock), .reset(reset), .in(t24), .out(t37));
DWT_HI u8(.clock(clock), .reset(reset), .in(th3), .out(t41));
DWT_HI u9(.clock(clock), .reset(reset), .in(t32), .out(t43));
DWT_HI u10(.clock(clock), .reset(reset), .in(t33), .out(t45));
DWT_HI u11(.clock(clock), .reset(reset), .in(t34), .out(t47));
DWT_HI u12(.clock(clock), .reset(reset), .in(t35), .out(t49));
DWT_HI u13(.clock(clock), .reset(reset), .in(t36), .out(t4b));
DWT_HI u14(.clock(clock), .reset(reset), .in(t37), .out(t4d));
DWT_HI u15(.clock(clock), .reset(reset), .in(t38), .out(t4f));

DWT_LO u16(.clock(clock), .reset(reset), .in(in), .out(t12));
DWT_LO u17(.clock(clock), .reset(reset), .in(th1), .out(t22));
DWT_LO u18(.clock(clock), .reset(reset), .in(t12), .out(t24));
DWT_LO u19(.clock(clock), .reset(reset), .in(th2), .out(t32));
DWT_LO u20(.clock(clock), .reset(reset), .in(t22), .out(t34));
DWT_LO u21(.clock(clock), .reset(reset), .in(t23), .out(t36));
DWT_LO u22(.clock(clock), .reset(reset), .in(t24), .out(t38));
DWT_LO u23(.clock(clock), .reset(reset), .in(th3), .out(t42));
DWT_LO u24(.clock(clock), .reset(reset), .in(t32), .out(t44));
DWT_LO u25(.clock(clock), .reset(reset), .in(t33), .out(t46));
DWT_LO u26(.clock(clock), .reset(reset), .in(t34), .out(t48));
DWT_LO u27(.clock(clock), .reset(reset), .in(t35), .out(t4a));
DWT_LO u28(.clock(clock), .reset(reset), .in(t36), .out(t4c));
DWT_LO u29(.clock(clock), .reset(reset), .in(t37), .out(t4e));
DWT_LO u30(.clock(clock), .reset(reset), .in(t38), .out(t4g));

DWT_HI_r u31(.clock(clock), .reset(reset), .in(th4), .out(t51));
DWT_HI_r u32(.clock(clock), .reset(reset), .in(th6), .out(t52));
DWT_HI_r u33(.clock(clock), .reset(reset), .in(t45), .out(t53));
DWT_HI_r u34(.clock(clock), .reset(reset), .in(t47), .out(t54));
DWT_HI_r u35(.clock(clock), .reset(reset), .in(t49), .out(t55));
DWT_HI_r u36(.clock(clock), .reset(reset), .in(t4b), .out(t56));
DWT_HI_r u37(.clock(clock), .reset(reset), .in(t4d), .out(t57));
DWT_HI_r u38(.clock(clock), .reset(reset), .in(t4f), .out(t58));
DWT_HI_r u39(.clock(clock), .reset(reset), .in(t51), .out(t61));
DWT_HI_r u40(.clock(clock), .reset(reset), .in(t53), .out(t62));
DWT_HI_r u41(.clock(clock), .reset(reset), .in(t55), .out(t63));
DWT_HI_r u42(.clock(clock), .reset(reset), .in(t57), .out(t64));
DWT_HI_r u43(.clock(clock), .reset(reset), .in(t61), .out(t71));
DWT_HI_r u44(.clock(clock), .reset(reset), .in(t63), .out(t72));
DWT_HI_r u45(.clock(clock), .reset(reset), .in(t71), .out(out));

DWT_LO_r u46(.clock(clock), .reset(reset), .in(th5), .out(t51));
DWT_LO_r u47(.clock(clock), .reset(reset), .in(th7), .out(t52));
DWT_LO_r u48(.clock(clock), .reset(reset), .in(t46), .out(t53));
DWT_LO_r u49(.clock(clock), .reset(reset), .in(t48), .out(t54));
DWT_LO_r u50(.clock(clock), .reset(reset), .in(t4a), .out(t55));
DWT_LO_r u51(.clock(clock), .reset(reset), .in(t4c), .out(t56));
DWT_LO_r u52(.clock(clock), .reset(reset), .in(t4e), .out(t57));
DWT_LO_r u53(.clock(clock), .reset(reset), .in(t4f), .out(t58));
DWT_LO_r u54(.clock(clock), .reset(reset), .in(t52), .out(t61));
DWT_LO_r u55(.clock(clock), .reset(reset), .in(t54), .out(t62));
DWT_LO_r u56(.clock(clock), .reset(reset), .in(t56), .out(t63));
DWT_LO_r u57(.clock(clock), .reset(reset), .in(t58), .out(t64));
DWT_LO_r u58(.clock(clock), .reset(reset), .in(t62), .out(t71));
DWT_LO_r u59(.clock(clock), .reset(reset), .in(t64), .out(t72));
DWT_LO_r u60(.clock(clock), .reset(reset), .in(t72), .out(out));

threshold u61(.clock(clock), .in(t11), .out(th1));
threshold u61(.clock(clock), .in(t21), .out(th2));
threshold u61(.clock(clock), .in(t31), .out(th3));
threshold u61(.clock(clock), .in(t41), .out(th4));
threshold u61(.clock(clock), .in(t42), .out(th5));
threshold u61(.clock(clock), .in(t43), .out(th6));
threshold u61(.clock(clock), .in(t44), .out(th7));
 

endmouule
 

`include "FINAL.v"
module filter_test_fixture;

reg clock, reset;
reg [15:0] in;
reg [15:0]dat[1:1024];
wire [15:0] out;
integer j;
initial
begin
      $shm_open("filter.shm");
      $shm_probe("AS");
      $monitor("time = %d; clock = %b; in=%h; out=%h",$stime, clock, in, out);
      in = 16'h0000;
      clock = 0;
      reset = 1;
      #1 reset = 0;
      #3 reset = 1;

      $readmemh("sx.dat",dat,1,1024);
  for (j=1;j<1025;j=j+1)
     #2 in = dat[j];
                $shm_close();
                $finish;

      #20 $shm_close();
      $finish;
 end
 always #1 clock=~clock; /* 2ns clock cycle */

 filter f1(clock, reset, in, out);

endmodule
 

`include "RTLx6_hi_r.v"

module RTL_test_fixture;
reg clock, reset;
reg [15:0] in;
reg [15:0]dat[1:1024];
wire [15:0] out;
integer j;
initial
begin
      $shm_open("RTL.shm");
      $shm_probe("AS");
      $monitor("time = %d; clock = %b; in=%h; out=%h",$stime, clock, in, out);
      in = 16'h0000;
      clock = 0;
      reset = 1;
      #1 reset = 0;
      #3 reset = 1;

      $readmemh("sx.dat",dat,1,1024);
  for (j=1;j<1025;j=j+1)
     #2 in = dat[j];
                $shm_close();
                $finish;

      #20 $shm_close();
      $finish;
 end
 always #1 clock=~clock; /* 2ns clock cycle */

 RTLx6_lo_d u1(clock, reset, in, out);

endmodule
 

//matlab codes ==================================================
 

function [scfb, sb]= fircoef(bits,N,wn);
%input the number of bits you want the coeffs. scaled to, the order of the fir,
% and the cut-off freqency

scaleto=2^(bits-1) -1; % magnitude of the most extreme scaled value desired

bs=fir1(N,wn);  % Obtain unscaled coefficients

extrb=max(abs(bs)); % most extreme of the "b" coeffs.

scfb=floor(log2(scaleto/extrb)); % what power of 2 is the "b" scale factor

sb=round((2^scfb)*bs);  % obtain scaled "b" coeffs.

% intfir.m

function out = intfir(in,b,kb)

ex_in=[in zeros(1,7)];
n=length(ex_in);

[m1,m2]=size(b);

for i=1:m1
s1m1(i)=0;
s2m1(i)=0;
end;

for i=1:n
    input=ex_in(i);
    for j=1:m1
        g=input*b(j,1)+s1m1(j);
        s1m1(j)=b(j,2)*input+s2m1(j);
        s2m1(j)=input*b(j,3);
        ex_out(i)=fix(g/(2^kb(j)));
        input=ex_out(i);
    end;
end;

out=ex_out(8:n);
 

%  This file generates the test data for the class project for
%     Spring 1999.  The project involves denoising data using
%     wavelets.
fun = 4;            %   Generate a doppler signal
nsize = 10;         %   1024 points in original signal
snrat = 3;          %   Signal to noise ratio equal to 5
init = 4205;        %   Seed for the random noise generator
name = 'db6';       %   Use the Daubechies family (number 6)
                    %       wavelet
tptr = 'rigrsure';   %   Use Stein's unbiased estimate to select
                    %       threshold
sorh = 's';         %   Use soft thresholding
scal = 'sln';       %   Use rescaling using a single estimate
nlev = 4;           %   Level to use thresholding

%   Generate original and noisy signals

%   use ">help wnoise" to see how to do this

[x, xnoise] = wnoise(fun, nsize, snrat, init);

%   Generate the denoised signal by using thresholding at level 4.
%   This can be done in one step using the Matlab function "wden"
%   Use ">help wden" to see how to use this function

[xd, cxd, lxd] = wden(xnoise, tptr, sorh, scal, nlev, name);

%   Now plot the result

clf

figure(1)

plot(xnoise, 'b+');     %   plot the noisey signal using blue
hold on             %   hold plot to plot original on the same plot
plot(xd, 'r-');     %   plot the denoised signal using red
title('Noisy Signal and Denoised Signal')
xlabel('Sample Number');
ylabel('Magnitude')
print -deps plot1.eps
hold off

figure(2)

plot(x)             %   plot the original signal for comparison
hold on
plot(xd, 'r-');     %   plot the denoised signal using red
title('Original Signal and Denoised Signal')
xlabel('Sample Number');
ylabel('Magnitude')
print -deps plot2.eps
hold off
 

%  proj_1.m

clear

% load noisy data
load xnoise.dat -ascii;
xn=xnoise;

% scale the input data
bits=16;
smax=2^(bits-1)-1;

max_xn=max(abs(xn));
xn_temp=smax/max_xn;
xscfac=fix(log2(xn_temp));
xscaf=2^xscfac;
sx=round(xn.*xscaf);

% save the scaled data file as sx.dat
%fid=fopen('sx.dat','write');
%fprintf(fid,'%x\n',sx);
%fclose(fid);

% filter parameter

[lo_d,hi_d,lo_r,hi_r]=wfilters('db6');

% lo_d
z=roots(lo_d);
sos=zp2sos(z,0,lo_d(1));
[m1,m2]=size(sos);
for i=1:m1
    for j=1:3
        lo_db(i,j)=sos(i,j);
     end;
end;

for i=1:m1
temp=max(abs(lo_db(i,:)));
temp=smax/temp;
lo_d_kb(i)=fix(log2(temp));
lo_d_bscaf(i)=2^lo_d_kb(i);
sc_lo_db(i,:)=round(lo_db(i,:).*lo_d_bscaf(i));
end;

% hi_d
z=roots(hi_d);
sos=zp2sos(z,0,hi_d(1));
[m1,m2]=size(sos);
for i=1:m1
    for j=1:3
        hi_db(i,j)=sos(i,j);
     end;
end;

for i=1:m1
temp=max(abs(hi_db(i,:)));
temp=smax/temp;
hi_d_kb(i)=fix(log2(temp));
hi_d_bscaf(i)=2^hi_d_kb(i);
sc_hi_db(i,:)=round(hi_db(i,:).*hi_d_bscaf(i));
end;

% lo_r
z=roots(lo_r);
sos=zp2sos(z,0,lo_r(1));
[m1,m2]=size(sos);
for i=1:m1
    for j=1:3
        lo_rb(i,j)=sos(i,j);
     end;
end;

for i=1:m1
temp=max(abs(lo_rb(i,:)));
temp=smax/temp;
lo_r_kb(i)=fix(log2(temp));
lo_r_bscaf(i)=2^lo_r_kb(i);
sc_lo_rb(i,:)=round(lo_rb(i,:).*lo_r_bscaf(i));
end;

% hi_r
z=roots(hi_r);
sos=zp2sos(z,0,hi_r(1));
[m1,m2]=size(sos);
for i=1:m1
    for j=1:3
        hi_rb(i,j)=sos(i,j);
     end;
end;

for i=1:m1
temp=max(abs(hi_rb(i,:)));
temp=smax/temp;
hi_r_kb(i)=fix(log2(temp));
hi_r_bscaf(i)=2^hi_r_kb(i);
sc_hi_rb(i,:)=round(hi_rb(i,:).*hi_r_bscaf(i));
end;
 

%%%%%%%% denoise the signal

% level 1
input=decomp(sx);
out1_1=intfir(input,sc_lo_db,lo_d_kb);
out1_2=intfir(input,sc_hi_db,hi_d_kb);

%level 2
input=decomp(out1_1);
out2(1,:)=intfir(input,sc_lo_db,lo_d_kb);
out2(2,:)=intfir(input,sc_hi_db,hi_d_kb);

input=decomp(out1_2);
out2(3,:)=intfir(input,sc_lo_db,lo_d_kb);
out2(4,:)=intfir(input,sc_hi_db,hi_d_kb);

%level 3
for i=1:4
    input=decomp(out2(i,:));
    out3(2*i-1,:)=intfir(input,sc_lo_db,lo_d_kb);
    out3(2*i  ,:)=intfir(input,sc_hi_db,hi_d_kb);
end;
 

% level 4
for i=1:8
    input=decomp(out3(i,:));
    out4(2*i-1,:)=intfir(input,sc_lo_db,lo_d_kb);
    out4(2*i  ,:)=intfir(input,sc_hi_db,hi_d_kb);
end;
 
 

%%%%%%%% thresholding signal

thr=thselect(xn,'rigrsure');
scthr=fix(thr*xscaf);

for i=1:16
th_out(i,:)=threshold(out4(i,:),scthr);
end;
 

%%%%%%%%% reconstruct the signal

% level 4
input=[];
for i=1:8
    input=recon(th_out(2*i-1,:));
    rout4(2*i-1,:)=intfir(input,sc_lo_rb,lo_r_kb);
    input=recon(th_out(2*i  ,:));
    rout4(2*i  ,:)=intfir(input,sc_hi_rb,hi_r_kb);
    r_out4(i,:)=(rout4(2*i-1,:)+rout4(2*i,:))/2;
end;

%level 3
input=[];
for i=1:4
    input=recon(r_out4(2*i-1,:));
    rout3(2*i-1,:)=intfir(input,sc_lo_rb,lo_r_kb);
    input=recon(r_out4(2*i  ,:));
    rout3(2*i  ,:)=intfir(input,sc_hi_rb,hi_r_kb);
    r_out3(i,:)=(rout3(2*i-1,:)+rout3(2*i,:))/2;
end;

%level 2
input=[];
for i=1:2
    input=recon(r_out3(2*i-1,:));
    rout2(2*i-1,:)=intfir(input,sc_lo_rb,lo_r_kb);
    input=recon(r_out3(2*i  ,:));
    rout2(2*i  ,:)=intfir(input,sc_hi_rb,hi_r_kb);
    r_out2(i,:)=(rout2(2*i-1,:)+rout2(2*i,:))/2;
end;

%level 1
    input=recon(r_out2(1,:));
    rout1(1,:)=intfir(input,sc_lo_rb,lo_r_kb);
    input=recon(r_out2(2,:));
    rout1(2,:)=intfir(input,sc_hi_rb,hi_r_kb);
    r_out1=(rout1(1,:)+rout1(2,:))/2;
 
 

%%%%%%%  rescale the signal and make the comparison

load x.dat -ascii;
load xdnoise.dat -ascii;

sout=r_out1./xscaf;
noise_x=sout-x;
SNR_x=20*log10(sum(x.^2)/sum(noise_x.^2))

noise_xd=sout-xdnoise;
SNR_xd=20*log10(sum(xdnoise.^2)/sum(noise_xd.^2))

%%%%%%%   print the signals
 

subplot(411),plot(x);ylabel('x');
subplot(412),plot(xdnoise);ylabel('xdn');
subplot(413),plot(sout);ylabel('sout');
subplot(414),plot(xn);ylabel('xn');
 

% recon.m

function out=recon(in)

n=length(in);
for i=1:n
    out(2*i-1)=in(i);
    out(2*i)=in(i);
end;
 

function ratio=snr();

input=shold;  % remember "shold.m" returns the input signal
out=myplot; % and "myplot.m" returns the verilog output signal

[b a]=cheby1(8,1.0,0.1);

signal=filter(b,a,input); %ideal output

noise=signal-out';  % noise caused by hardware implementation

ratio=20*log10(sum(signal.^2)/sum(noise.^2));
 

clear
load xnoise.dat -ascii;
x=xnoise;

% scale the input data
bits=16;
smax=2^(bits-1)-1;

max_x=max(abs(x));
x_temp=smax/max_x;
xscfac=fix(log2(x_temp))
xscaf=2^xscfac;
sx=round(x.*xscaf);

% 2nd order fir
[kb,b]=fircoef(16,2,0.2);
out=decomp(sx,b,kb);
%out=recon(sx,b,kb);
outs=out/xscaf;
b=fir1(2,0.2);
outf=filter(b,1,x);
error1=outs-outf

% test lo_d fir (11th order)
%[lo_d,hi_d,lo_r,hi_r]=wfilters('db6');

lo_d=fir1(4,0.2);
z=roots(lo_d);
sos=zp2sos(z,0,lo_d(1));
[m1,m2]=size(sos);
for i=1:m1
    for j=1:3
        lo_db(i,j)=sos(i,j);
     end;
end;

for i=1:m1
temp=max(abs(lo_db(i,:)));
temp=smax/temp;
lo_d_kb(i)=fix(log2(temp));
lo_d_bscaf(i)=2^lo_d_kb(i);
sc_lo_db(i,:)=round(lo_db(i,:).*lo_d_bscaf(i));
end;

out=decomp(sx,sc_lo_db,lo_d_kb);
outs=out/xscaf;

outf=filter(lo_d,1,x);

error=outs-outf;

subplot(211),plot(outs);
subplot(212),plot(outf);
 

clear
load xnoise.dat -ascii;
x=xnoise;

% scale the input data
bits=16;
smax=2^(bits-1)-1;

max_x=max(abs(x));
x_temp=smax/max_x;
xscfac=fix(log2(x_temp))
xscaf=2^xscfac;
sx=round(x.*xscaf);

% 2nd order fir
%[kb,b]=fircoef(16,2,0.2);
%out=decomp(sx,b,kb);
%out=recon(sx,b,kb);
%outs=out/xscaf;
%b=fir1(2,0.2);
%outf=filter(b,1,x);
%error1=outs-outf

% test lo_d fir (11th order)
[lo_d,hi_d,lo_r,hi_r]=wfilters('db6');
lo_d=lo_d;
%lo_d=fir1(6,0.2);
z=roots(lo_d);
sos=zp2sos(z,0,lo_d(1));
[m1,m2]=size(sos);
for i=1:m1
    for j=1:3
        lo_db(i,j)=sos(i,j);
     end;
end;

for i=1:m1
temp=max(abs(lo_db(i,:)));
temp=smax/temp;
lo_d_kb(i)=fix(log2(temp));
lo_d_bscaf(i)=2^lo_d_kb(i);
sc_lo_db(i,:)=round(lo_db(i,:).*lo_d_bscaf(i));
end;

out=intfir(sx,sc_lo_db,lo_d_kb);
outs=out/xscaf;

outf(1,:)=filter(lo_db(1,:),1,x);
for i=2:m1
outf(i,:)=filter(lo_db(i,:),1,outf(i-1,:));
end;

error=outs-outf(m1,:);

n=length(outs);
i=1:n;
subplot(211),plot(i,outs,i,outf(m1,:),'r');
subplot(212),plot(error);
 

% threshold.m

function [out]=threshold(in,thr)

len=length(in);

for i=1:len
    t=abs(in(i));
    if (t>thr)
       out(i)=sign(in(i))*(t-thr);
    elseif (t<=thr)
       out(i)=0;
    end;
end;