Archive for the ‘Code’ Category

sync

星期四, 08月 10th, 2006

module sync(
    input   rst_n,
    input   clk_i,
    input   clk_o,
    input   i_h,
    output  o_h
);

reg hand;
reg ack;
reg ack_p1;
reg ack_p2;

always @(posedge clk_i or negedge rst_n) begin
    if( ~rst_n )        hand <= 1′b0;
    else if( i_h )      hand <= 1′b1;
    else if( ack_p2 )   hand <= 1′b0;
end

always @(posedge clk_o or negedge rst_n) begin
    if( ~rst_n )        ack <= 1′b0;
    else                ack <= hand;
end

always @(posedge clk_o or negedge rst_n) begin
    if( !rst_n ) begin
        ack_p1 <= 1′b0;
        ack_p2 <= 1′b0;
    end
    else begin
        ack_p1 <= ack;
        ack_p2 <= ack_p1;
    end
end

always @(posedge clk_o or negedge rst_n) begin
    if( ~rst_n )                o_h <= 1′b0;
    else if(!ack_p2 & ack_p1)   o_h <= 1′b1;
    else                        o_h <= 1′b0;
end

endmodule

class D primer

星期三, 06月 21st, 2006

module class_d(
    input               clk,
    input               rst_n,
    input               i2s_sck,
    input               i2s_ws,
    input               i2s_sd,
    output              o_pwm
);

wire    [15:0]  l_data;
i2s_rx I2S_RX(
    .clk        ( clk_d02          ),
    .rst_n      ( rst_n            ),
    .i2s_sck    ( i2s_sck          ),
    .i2s_ws     ( i2s_ws           ),
    .i2s_sd     ( i2s_sd           ),
    .o_l_data   ( l_data           ),
    .o_l_data_en( l_data_en        )
);

//interpolating INT_FILTER(
//
//);
reg    [19:0]r_left_data;

always @(posedge clk or negedge rst_n ) begin
    if( ~rst_n )        r_left_data <= 0;
    else if( l_data_en )r_left_data <= {l_data, 4′b0};
end

wire    [3:0] sdm_data;

// forced data
parameter PCM_DEPTH = 256*1024;
reg     [7:0]pcm_data[0:PCM_DEPTH-1];
initial $readmemh("01K_768kSample_16bit.pcm.txt", pcm_data);

reg [17:0] pcm_index;
wire[18:0] pcm_index_l, pcm_index_r;

initial #1 pcm_index = 0;
assign  pcm_index_l = pcm_index*4;
assign  pcm_index_r = pcm_index_l + 2;

wire[15:0] data_l;
wire[15:0] data_r;
assign data_l = { pcm_data[pcm_index_l+1], pcm_data[pcm_index_l] };
assign data_r = { pcm_data[pcm_index_r+1], pcm_data[pcm_index_r] };

wire clk_d32;
always @(posedge clk_d32 or negedge rst_n) begin
    if( !rst_n ) begin
        pcm_index <= 0;
    end
    else begin
        pcm_index <= pcm_index + 1;
    end
end
wire [15:0] forced_data;
assign forced_data = { data_l[15:0] };

sdm SDM(
    .clk     ( clk          ),
    .rst_n   ( rst_n        ),
    .i_data  ( forced_data  ),
    .i_ddc   ( o_pwm        ),
    .o_sdm   ( sdm_data     )
);

wire    [31:0] luted_data;
pwm_lut LUT(
    .clk        ( clk_d32       ),
    .rst_n      ( rst_n         ),
    .i_sdm_data ( sdm_data      ),
    .o_pwm_data ( luted_data    )
);

shift_reg LINE_OUT(
    .clk        ( clk           ),
    .rst_n      ( rst_n         ),
    .i_pwm_data ( luted_data    ),
    .o_pwm      ( o_pwm         )
);

clk_d02 CLK_D02(
    .i_clk      ( clk           ),
    .rst_n      ( rst_n         ),
    .o_clk      ( clk_d02       )
);

clk_d16 CLK_D32(
    .i_clk      ( clk           ),
    .rst_n      ( rst_n         ),
    .o_clk      ( clk_d32       )
);

endmodule

module i2s_rx(
    input               clk,
    input               rst_n,
    input               i2s_sck,
    input               i2s_ws,
    input               i2s_sd,
    output reg[15:0]    o_l_data,
    output reg          o_l_data_en
);

reg sck_p1, sck_p2;
always @(posedge clk or negedge rst_n) begin: sck_sample
    if( ~rst_n ) begin
        sck_p1 <= 0;
        sck_p2 <= 0;
    end
    else begin
        sck_p2 <= sck_p1;
        sck_p1 <= i2s_sck;
    end
end

reg ws_p1, ws_p2;
always @(posedge clk or negedge rst_n) begin: ws_sample
    if( ~rst_n ) begin
        ws_p1 <= 0;
        ws_p2 <= 0;
    end
    else begin
        ws_p2 <= ws_p1;
        ws_p1 <= i2s_ws;
    end
end

assign sck_hp = ~sck_p2 & sck_p1;

reg [4:0] r_cnt;
always @( posedge clk or negedge rst_n ) begin: counter
    if( ~rst_n ) begin
        r_cnt <= 0;
    end
    else begin
        if( r_cnt > 17 ) ;
        else if( ws_p1 != ws_p2 )    r_cnt <= 0;
        else if( sck_hp )            r_cnt <= r_cnt + 1;
    end
end

always @(posedge clk or negedge rst_n ) begin: b_l_data
    if( ~rst_n ) begin
        o_l_data <= 0;
    end
    else if( sck_hp & ws_p2 == 1′b1) begin
        case ( r_cnt )
            5′h00: ;
            5′h01: begin o_l_data[15] <= i2s_sd; o_l_data_en <= 1′b0;   end
            5′h02: begin o_l_data[14] <= i2s_sd;                        end
            5′h03: begin o_l_data[13] <= i2s_sd;                        end
            5′h04: begin o_l_data[12] <= i2s_sd;                        end
            5′h05: begin o_l_data[11] <= i2s_sd;                        end
            5′h06: begin o_l_data[10] <= i2s_sd;                        end
            5′h07: begin o_l_data[09] <= i2s_sd;                        end
            5′h08: begin o_l_data[08] <= i2s_sd;                        end
            5′h09: begin o_l_data[07] <= i2s_sd;                        end
            5′h0a: begin o_l_data[06] <= i2s_sd;                        end
            5′h0b: begin o_l_data[05] <= i2s_sd;                        end
            5′h0c: begin o_l_data[04] <= i2s_sd;                        end
            5′h0d: begin o_l_data[03] <= i2s_sd;                        end
            5′h0e: begin o_l_data[02] <= i2s_sd;                        end
            5′h0f: begin o_l_data[01] <= i2s_sd;                        end
            5′h10: begin o_l_data[00] <= i2s_sd; o_l_data_en <= 1′b1;   end
        endcase
    end
end

endmodule

module sdm(
    input               clk,
    input               rst_n,
    input       [15: 0] i_data,     // signed data
    input               i_ddc,
    output      [ 3: 0] o_sdm
);

parameter
    w_fb = 16,
    w_s1 = w_fb + 4;

// 1st order

wire[15:0]  feedback_1st;
assign feedback_1st[15:0]
    = i_ddc == 1 ? 16′h7fff
    : 16′h8001;

reg [23:0]  r_accm_1st;
wire[16:0]  diff_1st_sum;       // 1st differential
assign diff_1st_sum[16:0] = { i_data[15], i_data[15:0] } - { feedback_1st[15], feedback_1st[15:0] };

wire [24:0] accm_1st_sum;       // 1st accumulator
wire [23:0] accm_1st;

assign accm_1st_sum[24:0] = { {8{diff_1st_sum[16]}} ,diff_1st_sum[16:0] } + { r_accm_1st[23], r_accm_1st[23:0] };
assign accm_1st[23:0]
    = accm_1st_sum[24:23] == 2′b01 ? 24′h7f_ffff
    : accm_1st_sum[24:23] == 2′b10 ? 24′h80_0001
    : accm_1st_sum[23: 0];

always @(negedge clk or negedge rst_n) begin: reg_accm_1st
    if( ~rst_n ) begin
        r_accm_1st[23:0] <= #1 24′h0;
    end
    else begin
        r_accm_1st <= #1 accm_1st;
    end
end

// 2nd order
wire[23:0]  feedback_2nd;
assign feedback_2nd[23:0]
    = i_ddc == 1 ? 24′h7f_ffff
    : 24′h80_0001;

reg [31:0]  r_accm_2nd;
wire[24:0]  diff_2nd_sum;       // 2nd differential
assign diff_2nd_sum[24:0] = { accm_1st[23], accm_1st[23:0] } - { feedback_2nd[23], feedback_2nd[23:0] };

wire [32:0] accm_2nd_sum;       // 2nd accumulator
wire [31:0] accm_2nd;

assign accm_2nd_sum[32:0] = { {8{diff_2nd_sum[24]}} ,diff_2nd_sum[24:0] } + { r_accm_2nd[31], r_accm_2nd[31:0] };
assign accm_2nd[31:0]
    = accm_2nd_sum[32:31] == 2′b01 ? 32′h7fff_ffff
    : accm_2nd_sum[32:31] == 2′b10 ? 32′h8000_0001
    : accm_2nd_sum[31: 0];

always @(negedge clk or negedge rst_n) begin: reg_accm_2nd
    if( ~rst_n ) begin
        r_accm_2nd[31:0] <= #1 32′h0;
    end
    else begin
        r_accm_2nd <= #1 accm_2nd;
    end
end

//  // decimation filter
//  reg [3:0]   r_step;
//  always @(posedge clk or negedge rst_n ) begin: step
//      if( ~rst_n ) begin
//          r_step <= 1′b0;
//      end
//      else begin
//          r_step <= r_step + 1;
//      end
//  end
//
//  wire [8:0] sdm_sum_o;
//  wire [7:0] sdm_sum;
//  reg [7:0] r_integrator_sdm;
//
//  assign sdm_sum_o[8:0] = { r_integrator_sdm[7], r_integrator_sdm[7:0] } + { {5{r_accm_2nd[31]}}, r_accm_2nd[31:28] };
//  assign sdm_sum[7:0]
//      = sdm_sum_o[8:7] == 2′b01 ? 8′h7f
//      : sdm_sum_o[8:7] == 2′b10 ? 8′h80
//      : sdm_sum_o[7:0];
//
//  always @(posedge clk or negedge rst_n ) begin: integrator_sdm
//      if( ~rst_n )                r_integrator_sdm <= 1′b0;
//      else if( r_step == 4′h0 )   r_integrator_sdm <= 0;
//      else                        r_integrator_sdm <= sdm_sum[7:0];
//  end
//
//  always @(posedge clk or negedge rst_n ) begin: out_sdm
//      if( ~rst_n )                o_sdm <= 1′b0;
//      else if( r_step == 4′h0 )   o_sdm <= r_integrator_sdm[7:4];
//  end

assign o_sdm = accm_2nd[31:28];
endmodule

module pwm_lut(
    input               clk,
    input               rst_n,
    input       [ 3: 0] i_sdm_data,
    output      [31: 0] o_pwm_data
);

reg [31:0] r_pwm_data;

always @(posedge clk or negedge rst_n) begin: pwm
    if( ~rst_n ) begin
        r_pwm_data <= 0;
    end
    else begin
        case ( i_sdm_data )
            4′h7:   r_pwm_data <= { {01{1′b0}}, {31{1′b1}} };
            4′h6:   r_pwm_data <= { {03{1′b0}}, {29{1′b1}} };
            4′h5:   r_pwm_data <= { {05{1′b0}}, {27{1′b1}} };
            4′h4:   r_pwm_data <= { {07{1′b0}}, {25{1′b1}} };
            4′h3:   r_pwm_data <= { {09{1′b0}}, {23{1′b1}} };
            4′h2:   r_pwm_data <= { {11{1′b0}}, {21{1′b1}} };
            4′h1:   r_pwm_data <= { {13{1′b0}}, {19{1′b1}} };
            4′h0:   r_pwm_data <= { {15{1′b0}}, {17{1′b1}} };
            4′hf:   r_pwm_data <= { {17{1′b0}}, {15{1′b1}} };
            4′he:   r_pwm_data <= { {19{1′b0}}, {13{1′b1}} };
            4′hd:   r_pwm_data <= { {21{1′b0}}, {11{1′b1}} };
            4′hc:   r_pwm_data <= { {23{1′b0}}, {09{1′b1}} };
            4′hb:   r_pwm_data <= { {25{1′b0}}, {07{1′b1}} };
            4′ha:   r_pwm_data <= { {27{1′b0}}, {05{1′b1}} };
            4′h9:   r_pwm_data <= { {29{1′b0}}, {03{1′b1}} };
            4′h8:   r_pwm_data <= { {31{1′b0}}, {01{1′b1}} };
        endcase
    end
end

assign o_pwm_data = r_pwm_data[31:0];

endmodule

module shift_reg(
    input               clk,
    input               rst_n,
    input       [31: 0] i_pwm_data,
    output              o_pwm
);

reg [4:0]   r_step;
always @(posedge clk or negedge rst_n ) begin: step
    if( ~rst_n ) begin
        r_step <= 1′b0;
    end
    else begin
        r_step <= r_step + 1;
    end
end

reg         r_reverse;
always @(posedge clk or negedge rst_n ) begin: reverse
    if( ~rst_n ) begin
        r_reverse <= 1′b0;
    end
    else begin
        if( r_step == 0)  r_reverse <= ~r_reverse;
    end
end

reg [31:0]  r_shift;
always @(posedge clk or negedge rst_n ) begin: shift
    if( ~rst_n ) begin
        r_shift <= 0;
    end
    else begin
        if( r_step == 0 )       r_shift <= i_pwm_data;
        else if( r_reverse )    r_shift <= { 1′b0, r_shift[31:1] };
        else                    r_shift <= { r_shift[30:0], 1′b0 };
    end
end

reg         r_pwm;
always @(posedge clk or negedge rst_n) begin: pwm
    if( ~rst_n ) begin
        r_pwm <= 1′b0;
    end
    else begin
        if( r_reverse )         r_pwm <= r_shift[0];
        else                    r_pwm <= r_shift[31];
    end
end

assign o_pwm = r_pwm;

// ***********dump pwm

integer    fp_pwm;
initial fp_pwm= $fopen("pwm.txt");
always@(negedge clk) $fwrite(fp_pwm,"%h\n",o_pwm);

endmodule

clock domain synchronizer

星期五, 02月 24th, 2006

module sync(
    rst_n,
    clka,
    clkb,

    clka_sig  ,          
    o_clkb_sig
);
input   rst_n;
input   clka;
input   clkb;
input   clka_sig  ;
output  o_clkb_sig  ;

reg hand_a2b;    // hand, from clka to clkb
reg hand_b2a;    // hand ack,
reg hand_b2a_p1;
reg hand_b2a_p2;

always @(posedge clkb or negedge rst_n) begin
    if( !rst_n ) begin
        hand_b2a_p1 <= 1′b0;
        hand_b2a_p2 <= 1′b0;
    end
    else begin
        hand_b2a_p1 <= hand_b2a;
        hand_b2a_p2 <= hand_b2a_p1;
    end
end

always @(posedge clka or negedge rst_n) begin
    if( ~rst_n )            hand_a2b <= 1′b0;
    else if( clka_sig   )   hand_a2b <= 1′b1;
    else if( hand_b2a_p2 )  hand_a2b <= 1′b0;
end

always @(posedge clkb or negedge rst_n) begin
    if( ~rst_n )       hand_b2a <= 1′b0;
    else               hand_b2a <= hand_a2b;
end

assign o_clkb_sig   = hand_b2a_p2;

endmodule


登录 | 访问数21663 | 水木BLOG | 水木社区 | 关于我们 | Blog论坛 | 法律声明 | 隐私权保护 | 京ICP证050249号
水木社区Blog系统是基于KBS系统WordPress MU架构的