FPGA project :dds

 

 

module top (
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire    [3:0]   key         ,

    output      wire    [7:0]   dac_data    

);    // output      wire            dac_cl    ,
      // assign dac_clk = ~sys_clk ;

    // 例化间连线
    wire      [3:0]       wave_ctrl_w ;

key_ctrl key_ctrl_insert(
    .sys_clk                    ( sys_clk     ) ,
    .sys_rst_n                  ( sys_rst_n   ) ,
    .key_in                     ( key         ) ,

    .wave_ctrl                  ( wave_ctrl_w )
);

dds_ctrl dds_ctrl_insert(
    .sys_clk                    ( sys_clk    ) ,
    .sys_rst_n                  ( sys_rst_n  ) ,
    .wave_ctrl                  ( wave_ctrl_w) ,

    .dac_data                   ( dac_data   )    
);
endmodule
module dds_ctrl(
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire    [3:0]   wave_ctrl   ,

    output      wire    [7:0]   dac_data    
);

    parameter   F_WARD = 20'd42949 ; 
    parameter   P_WARD = 12'd1024  ; 
    // reg signal
    reg     [31:0]      fre_add      ; // 频率字累加
    reg     [11:0]      rom_addr_reg ; // 相位字累加
    reg     [13:0]      rom_addr     ; // 读 rom地址
    wire    [13:0]      rom_addr_w   ; 
    reg     [03:00]     wave_ctrl_reg;
    assign              rom_addr_w = rom_addr ;
    // [03:00]     wave_ctrl_reg    ;
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            wave_ctrl_reg <= 4'd0 ;
        end else begin
            wave_ctrl_reg <= wave_ctrl ;
        end
    end
    // reg     [31:0]      fre_add      ; // 频率字累加
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            fre_add <= 32'd0 ;
        end else begin
            if(fre_add == 32'hFFFF_FFFF - 1'b1 || (wave_ctrl_reg != wave_ctrl)) begin
                fre_add <= 32'd0 ;
            end else begin
                if(|wave_ctrl_reg == 1'b1) begin
                    fre_add <= F_WARD + fre_add ; 
                end else begin
                    fre_add <= 32'd0 ;
                end
            end
        end
    end
    // reg     [11:0]      rom_addr_reg ; // 相位字累加
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            rom_addr_reg <= 12'd0 ;
        end else begin
            if( rom_addr_reg == 12'hFFF) begin
                rom_addr_reg <= 12'd0 ;
            end else begin
                rom_addr_reg <= P_WARD + fre_add[31:20] ; // 取fre_add 的高12位宽。
            end
        end
    end
    // reg     [13:0]      rom_addr     ; // 读 rom地址
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            rom_addr <= 14'd0 ;
        end else begin
            case (wave_ctrl)
            4'b1000: rom_addr <= rom_addr_reg ;
            4'b0100: rom_addr <= rom_addr_reg + 12'hFFF  + 1'b1;
            4'b0010: rom_addr <= rom_addr_reg + 13'h1FFE + 1'b1;
            4'b0001: rom_addr <= rom_addr_reg + 14'h2FFD + 1'b1;
            default: rom_addr <= 14'd0 ;
            endcase
        end
    end

rom_16384x8	rom_16384x8_inst (
	.address        ( rom_addr_w   ),
	.clock          ( sys_clk      ),
	.q              ( dac_data     )
	);

endmodule
module key_ctrl(
    input       wire                sys_clk     ,
    input       wire                sys_rst_n   ,
    input       wire    [3:0]       key_in      ,

    output      reg     [3:0]       wave_ctrl
);
    wire    [3:0]       key_out ;
    // 例化
key_filter    
#(
    .MAX_CNT_20MS ( 20'd999_999 )
)
key_filter_insert
(
    .sys_clk                    ( sys_clk   ) ,
    .sys_rst_n                  ( sys_rst_n ) ,
    .key_in                     ( key_in    ) ,

    .key_out                    ( key_out   )  
);

    // output signal
    // wave_ctrl
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            wave_ctrl <= 4'd0 ;
        end else begin
            case (key_out)
            4'b1000 : wave_ctrl <= 4'b1000 ;
            4'b0100 : wave_ctrl <= 4'b0100 ;
            4'b0010 : wave_ctrl <= 4'b0010 ;
            4'b0001 : wave_ctrl <= 4'b0001 ;
            default : wave_ctrl <= wave_ctrl ;
            endcase
        end
    end
endmodule
module key_filter
#(
    parameter MAX_CNT_20MS = 20'd999_999 
)(
    input           wire            sys_clk     ,
    input           wire            sys_rst_n   ,
    input           wire    [3:0]   key_in      ,

    output          reg     [3:0]   key_out  
);
    // reg signal define
    reg     [3:0]       key_r0  ;
    reg     [3:0]       key_r1  ;
    reg     [3:0]       key_r2  ;
    reg                 nege    ;
    reg                 pose    ;

    reg     [19:00]     cnt_20ms     ;
    reg                 add_cnt_flag ;
    reg                 flag_20ms    ;

    // key_r0 key_r1 key_r2
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            key_r0 <= 4'b1111 ;
            key_r1 <= 4'b1111 ;
            key_r2 <= 4'b1111 ;
        end else begin
            key_r0 <= key_in ;
            key_r1 <= key_r0 ;
            key_r2 <= key_r1 ;
        end
    end

    // nege
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            nege <= 1'b0 ;
        end else begin
            if(| (~key_r1 &  key_r2)) begin
                nege <= 1'b1 ;
            end else begin
                nege <= 1'b0 ;
            end
        end
    end
    // pose
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            pose <= 1'b0 ;
        end else begin
            if(| ( key_r1 & ~key_r2)) begin
                pose <= 1'b1 ;
            end else begin
                pose <= 1'b0 ;
            end
        end
    end

    // add_cnt_flag
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            add_cnt_flag <= 1'b0 ;
        end else begin
            if(nege) begin
                add_cnt_flag <= 1'b1 ;
            end else begin
                if(pose || cnt_20ms == MAX_CNT_20MS) begin
                    add_cnt_flag <= 1'b0 ;
                end else begin
                    add_cnt_flag <= add_cnt_flag ;
                end
            end
        end
    end

    // cnt_20ms 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cnt_20ms <= 20'd0 ;
        end else begin
            if(add_cnt_flag) begin
                if(cnt_20ms == MAX_CNT_20MS) begin
                    cnt_20ms <= 20'd0 ;
                end else begin
                    cnt_20ms <= cnt_20ms + 20'd1 ;
                end
            end else begin
                cnt_20ms <= 20'd0 ;
            end
        end
    end
    // falg_20ms
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            flag_20ms <= 1'b0 ;
        end else begin
            if(cnt_20ms == MAX_CNT_20MS - 1'b1) begin
                flag_20ms <= 1'b1 ;
            end else begin
                flag_20ms <= 1'b0 ;
            end
        end
    end

    // [3:0]key_out
    always @(posedge sys_clk or negedge sys_rst_n) begin
    // always @(*) begin // 这样的话 会综合成 数据选择器
        if(~sys_rst_n) begin
            key_out <= 4'b0000 ;
        end else begin
            if(flag_20ms) begin
                key_out <= ~key_r2 ;
            end else begin
                key_out <= 4'b0000 ;
            end
        end
    end
endmodule
`timescale 1ns/1ns
module test_dds_ctrl();
    reg             sys_clk     ;
    reg             sys_rst_n   ;
    reg     [3:0]   wave_ctrl   ;

    wire    [7:0]   adc_data    ;

// Instantiation
dds_ctrl dds_insert_test(
    .sys_clk        ( sys_clk   ) ,
    .sys_rst_n      ( sys_rst_n ) ,
    .wave_ctrl      ( wave_ctrl ) ,

    .adc_data       ( adc_data  )    
);

    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b0 ;
        wave_ctrl <= 4'b0000 ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( 210 )          ;
        sys_rst_n <= 1'b0 ;
        #( 10 )           ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( CYCLE * 50 )   ;
        #( CYCLE * 100 )  ;
        #( CYCLE * 20000 )

        wave_ctrl <= 4'b1000 ;
        #( CYCLE * 12'hFFF  * 100 ) ;

        wave_ctrl <= 4'b0100 ;
        #( CYCLE * 12'hFFF  * 100 ) ;

        wave_ctrl <= 4'b0010 ;
        #( CYCLE * 12'hFFF  * 100 ) ;
        
        wave_ctrl <= 4'b0001 ;
        #( CYCLE * 12'hFFF  * 100 ) ;

        #( CYCLE * 50 )   ;
        #( CYCLE * 100 )  ;

        $stop             ;
    end

    always #( CYCLE / 2 ) sys_clk = ~sys_clk ;

endmodule
`timescale 1ns/1ns
module test_key_ctrl();
    reg                 sys_clk     ;
    reg                 sys_rst_n   ;
    reg     [3:0]       key_in      ;

    wire    [3:0]       wave_ctrl   ;

    defparam    key_ctrl_insert.key_filter_insert.MAX_CNT_20MS = 200 ;
// Instantiation
key_ctrl key_ctrl_insert(
    .sys_clk            ( sys_clk   ) ,
    .sys_rst_n          ( sys_rst_n ) ,
    .key_in             ( key_in    ) ,

    .wave_ctrl          ( wave_ctrl )
);
    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b0 ;
        key_in    <= 4'b1111 ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( 210 )          ;
        sys_rst_n <= 1'b0 ;
        #( 10 )           ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( CYCLE * 50 )   ;

        key_in    <= 4'b0111 ;
        #( CYCLE * 700)       ;
        key_in    <= 4'b1111 ;
        #( CYCLE * 700 )      ;
        #( CYCLE * 100 )     ;
        
        key_in    <= 4'b1011 ;
        #( CYCLE * 700 )      ;
        key_in    <= 4'b1111 ;
        #( CYCLE * 700 )      ;
        #( CYCLE * 100 )     ;

        key_in    <= 4'b0111 ;
        #( CYCLE * 700 )      ;
        key_in    <= 4'b1111 ;
        #( CYCLE * 50 )      ;
        #( CYCLE * 100 )     ;
        
        key_in    <= 4'b1101 ;
        #( CYCLE * 700 )      ;
        key_in    <= 4'b1111 ;
        #( CYCLE * 700 )      ;
        #( CYCLE * 100 )     ;

        key_in    <= 4'b1110 ;
        #( CYCLE * 700 )      ;
        key_in    <= 4'b1111 ;
        #( CYCLE * 700 )      ;
        #( CYCLE * 100 )     ;
        $stop             ;
    end

    always #( CYCLE / 2 ) sys_clk = ~sys_clk ;

endmodule
`timescale 1ns/1ns
module test_top();
    reg              sys_clk     ;
    reg              sys_rst_n   ;
    reg      [3:0]   key         ;

    wire     [7:0]   dac_data    ;

// Instantiation
top top_insert_test(
    .sys_clk            ( sys_clk    ) ,
    .sys_rst_n          ( sys_rst_n  ) ,
    .key                ( key        ) ,

    .dac_data           ( dac_data )    
);
    defparam top_insert_test.key_ctrl_insert.key_filter_insert.MAX_CNT_20MS = 100 ;

    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 1'b0 ;
        key       <= 4'b1111 ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( 210 )          ;
        sys_rst_n <= 1'b0 ;
        #( 10 )           ;
        #( CYCLE * 10 )   ;
        sys_rst_n <= 1'b1 ;
        #( CYCLE * 50 )   ;
        #( CYCLE * 100 )  ;

        key <= 4'b0111    ;
        #( CYCLE * 10000) ;
        key <= 4'b1111    ;
        #( CYCLE * 10000) ;
        #( CYCLE * 12'hFFF  * 100 ) ;

        key <= 4'b1011    ;
        #( CYCLE * 10000) ;
        key <= 4'b1111    ;
        #( CYCLE * 10000) ;
        #( CYCLE * 12'hFFF  * 100 ) ;

        key <= 4'b1101    ;
        #( CYCLE * 10000) ;
        key <= 4'b1111    ;
        #( CYCLE * 10000) ;
        #( CYCLE * 12'hFFF  * 100 ) ;
        
        key <= 4'b1110    ;
        #( CYCLE * 10000) ;
        key <= 4'b1111    ;
        #( CYCLE * 10000) ;
        #( CYCLE * 12'hFFF  * 100 ) ;

        key <= 4'b1110    ;
        #( CYCLE * 10000) ;
        key <= 4'b1111    ;
        #( CYCLE * 10000) ;
        #( CYCLE * 12'hFFF  * 100 ) ;

        #( CYCLE * 50 )   ;
        #( CYCLE * 100 )  ;

        $stop             ;
    end

    always #( CYCLE / 2 ) sys_clk = ~sys_clk ;

endmodule

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值