DDS_封装

module    key_board(
        clk,rst_n,col,row,
        fword,pword,da_data,clk_ad,da_data_rom,
        boxi,ast_source_valid
);
input                       clk;
input                       rst_n;
input                  [3:0]   row;
output                        clk_ad;
output    reg            [3:0]   col;
output    reg            [31:0]    fword;
output    reg            [11:0]    pword;
output    reg            [1:0]    boxi;
output    wire                ast_source_valid;
output                [11:0]    da_data;    
input                [11:0]    da_data_rom;
//div clk
reg                      clk_1k;
reg            [20:0]    cnt;

always @(posedge clk or negedge rst_n)
    if(!rst_n)begin
        clk_1k <= 1;
        cnt    <= 0;
    end
    else if(cnt < 24999)
        cnt <= cnt + 1'b1;
    else begin
        cnt <= 0;
        clk_1k <= ~clk_1k;
    end

    
//fsm
reg            [4:0]    cnt_time;
reg            [7:0]    row_col;
reg            [2:0]    state;
reg                    flag;//输出值有效标志
always @(posedge clk_1k or negedge rst_n)
    if(!rst_n)begin
        flag <= 0;
        state <= 0;
        cnt_time <= 0;
        row_col <= 0;
        col <= 0;
    end 
    else begin
        case(state)
        3'd0: begin
            if(row != 4'b1111)begin
                if(cnt_time < 19) //延时20ms
                    cnt_time <= cnt_time + 1;
                else begin
                    cnt_time <= 0;
                    state <= state + 1'b1;
                    col <= 4'b1110;   //扫描第一列
                end
            end
            else     cnt_time <= 0;
        end
        3'd1: begin
                if(row != 4'b1111)begin
                    row_col <= {row,col};//储存键值
                    flag <= 1;
                    state <= state + 1;
                    col <= 4'b0000;
                end
                else    col <= {col[2:0],col[3]};
        end
        3'd2: begin
                if(row == 4'b1111)begin
                    if(cnt_time < 19)begin
                        cnt_time <= cnt_time + 1;
                        flag <= 0;
                    end
                    else begin
                        cnt_time <= 0;
                        state <= 0;
                        col <= 4'b0000;
                    end
                end
                else begin
                    cnt_time <= 0;
                    flag <= 0;
                end
        end
        default : state <= 0;        
        endcase
    end
reg                    next_flag;
always @(posedge clk or negedge rst_n)
    if(!rst_n)
        next_flag <= 'd0;
    else 
        next_flag <= flag;
    
reg        [2:0]        cnt_f;
reg        [2:0]        cnt_p;
reg        [2:0]        cnt_h;
always @(posedge clk or negedge rst_n)
    if(!rst_n)begin
        cnt_f <='d0;
        cnt_p <='d0;
        boxi <= 'd0;
        cnt_h <= 'd0;
    end
    else if(next_flag == 1 && flag == 0)begin
        case(row_col)
            8'b1110_1110 : begin        
                if(boxi > 1)
                    boxi <= 0;
                else
                    boxi <= boxi + 1'b1;                    
            end
            8'b1110_1101 : begin
                if(cnt_f > 3)
                    cnt_f <= 0;
                else
                    cnt_f <= cnt_f + 1'd1;
            end
            8'b1110_1011 : begin
                if(cnt_p > 2)
                    cnt_p <= 0;
                else    
                    cnt_p <= cnt_p + 1'd1;
            end
            8'b1110_0111 : begin
                if(cnt_h > 3)
                    cnt_h <= 0;
                else
                    cnt_h <= cnt_h + 1'd1;
            end
            8'b1101_1110 : begin
                if(cnt_f < 1)
                    cnt_f <= 4;
                else
                    cnt_f <= cnt_f - 1'd1;
            end
            8'b1101_1101 : begin
                if(cnt_p < 1)
                    cnt_p <= 4;
                else
                    cnt_p <= cnt_p - 1'd1;
            end
            8'b1101_1011 : begin
                if(cnt_h < 1)
                    cnt_h <= 0;
                else
                    cnt_h <= cnt_h - 1'd1;
            end
            8'b1101_0111 : begin        end
            8'b1011_1110 : begin        end
            8'b1011_1101 : begin        end
            8'b1011_1011 : begin        end
            8'b1011_0111 : begin        end
            8'b0111_1110 : begin        end
            8'b0111_1101 : begin        end
            8'b0111_1011 : begin        end
            8'b0111_0111 : begin        end        
            default      : begin        end
        endcase
    end
//频率
always @(posedge clk or negedge rst_n)
    if(!rst_n)
        fword <= 429496729; // 5M
    else 
        case(cnt_f)
            3'd0 : fword <= 428496729; //5M
            3'd1 : fword <= 42849672;  //500K
            3'd2 : fword <= 4284967;   //50K
            3'd3 : fword <= 428496;    //5K
            3'd4 : fword <= 42849;     //500
            default:fword <= fword;
        endcase
//相位    
parameter        PHASE_90 = 11'd1028;
always @(posedge clk or negedge rst_n)
    if(!rst_n)
        pword <= PHASE_90;
    else 
        case(cnt_p)
            3'd0 : pword <= PHASE_90;
            3'd1 : pword <= PHASE_90 + PHASE_90;
            3'd2 : pword <= PHASE_90 + PHASE_90 + PHASE_90;
            3'd3 : pword <= PHASE_90 + PHASE_90 + PHASE_90 + PHASE_90;
            default : pword <= pword;
        endcase
        
//da输出
reg        [11:0]        da_data_r;
always @(posedge clk or negedge rst_n)
    if(!rst_n)
        da_data_r <= da_data_rom;
    else
        case(cnt_h)
            3'd0 : da_data_r <= da_data_rom;
            3'd1 : da_data_r <= {1'd0 + da_data_rom[11:1]};
            3'd2 : da_data_r <= {2'd0 + da_data_rom[11:2]};
            3'd3 : da_data_r <= {3'd0 + da_data_rom[11:3]};
            3'd4 : da_data_r <= {4'd0 + da_data_rom[11:4]};
            default : da_data_r <= da_data_rom;
        endcase

assign    da_data = da_data_r;        
//fir
        
/*    fir_dds_0002 fir_dds_inst (
        .clk              (clk),              //                     clk.clk
        .reset_n          (rst_n),          //                     rst.reset_n
        .ast_sink_data    (da_data_r),    //   avalon_streaming_sink.data
        .ast_sink_valid   (1'b1),   //                        .valid
        .ast_sink_error   (1'b0),   //                        .error
        .ast_source_data  (da_data),  // avalon_streaming_source.data
        .ast_source_valid (ast_source_valid), //                        .valid
        .ast_source_error ()  //                        .error
    );        */
assign        clk_ad =~ clk;        
endmodule
module    dds_crtl(
        clk,rst_n,
        fword,pword,
        da_data_rom,
        boxi
);
input            clk;
input            rst_n;
input    [31:0]    fword;
input    [11:0]    pword;
input    [1:0]    boxi;
output    reg        [11:0]    da_data_rom;


reg        [31:0]    fcnt;
//频率控制字
always @(posedge clk or negedge rst_n)
    if(!rst_n)
        fcnt <= 'd0;
    else
        fcnt <= fcnt + fword;
        
//相位控制字     
reg    [11:0]        rom_addr_sin;
reg    [11:0]        rom_addr_ceil;
reg    [11:0]        rom_addr_sanjiao;

always @(posedge clk or negedge rst_n)
    if(!rst_n)begin
        rom_addr_sin <= 'd0;
        rom_addr_ceil <= 'd0;
        rom_addr_sanjiao <= 'd0;
        da_data_rom <= 'd0;
    end
        else
            case(boxi)
                2'd0 : begin 
                    rom_addr_sin  <= fcnt[31:20] + pword;
                    da_data_rom <= da_data_rom_sin;            
                end
                2'd1 : begin
                    rom_addr_ceil <= fcnt[31:20] + pword;
                    da_data_rom <= da_data_rom_ceil;
                end
                2'd2 : begin
                    rom_addr_sanjiao <= fcnt[31:20] + pword;
                    da_data_rom <= da_data_rom_sanjiao;
                end
                default : begin
                    rom_addr_sin <= fcnt[31:20] + pword;
                    da_data_rom <= da_data_rom_sin;
                end
            endcase

                            
//正弦波
wire    [11:0]    da_data_rom_ceil;
wire    [11:0]    da_data_rom_sanjiao;
wire    [11:0]    da_data_rom_sin;
rom_dds    rom_dds_inst (
    .address ( rom_addr_sin ),
    .clock ( clk ),
    .q ( da_data_rom_sin )
    );        
//方波
rom_ceil    rom_ceil_inst (
    .address ( rom_addr_ceil),
    .clock ( clk ),
    .q ( da_data_rom_ceil )
    );
//三角
rom_sanjioao    rom_sanjioao_inst (
    .address ( rom_addr_sanjiao ),
    .clock ( clk ),
    .q ( da_data_rom_sanjiao )
    );
        
            
        
endmodule
原文地址:https://www.cnblogs.com/bixiaopengblog/p/6636849.html