FPGA 学习 03

    科技2022-07-10  88

    music_test.v 文件

    module music_test( Clk, //时钟信号 Rst_n, //复位信号 CNT_ENABLE, //Cnt_Enable=1 时,开启定时 //Cnt_Enable=0 时低电平时,不使能定时 beep ); input Clk ; input Rst_n ; input CNT_ENABLE ; output beep ; wire [31:0]CNT_NOW ; wire Full_Flag1; wire [31:0]CNT_ARR; wire [31:0]Compare_cnt; //这里的频率是: 50_000_000/50_000 = 1000Hz 的频率 timer beep0( .Clk(Clk) , //时钟 .Rst_n(Rst_n) , //复位信号 .CNT_ARR(CNT_ARR) , //定时器重装载值 24999(类似与32的重装载值),相当于定时 .MODE(1'b1) , // Mode : 1 循环定时 Mode : 0 单次定时 .CNT_ENABLE(~CNT_ENABLE) , //CNT_ENABLE : 1 定时器计数器使能,开始计数 //CNT_ENABLE : 0 定时器计数不使能,停止计数 // ~CNT_ENABLE 这里给定的是取反的信号,主要是太吵,不需要可以更改 .CNT_NOW(CNT_NOW) , //实时定时器计数器 .Full_Flag() //计数完成标志位,这里没有用到,且Full_Flag是输出信号,所以不用的时候可以不连接信号 ); sound_lut sound_lut0( .Clk(Full_Flag1), .Rst_n(Rst_n), .ARR(CNT_ARR), // CNT_ARR 传递给 beep0 的 CNT_ARR 使用 .Compare_cnt(Compare_cnt) ); //250ms固定定时,用于切换音调,Full_Flag1信号用于传递给 sound_lut0 模块使用 timer timer_250ms( .Clk(Clk), .Rst_n(Rst_n), .CNT_ARR(6250000), .MODE(1'b1), .CNT_ENABLE(1'b1), .CNT_NOW(), .Full_Flag(Full_Flag1) ); assign beep =(CNT_NOW >=Compare_cnt)? 1'b1:1'b0 ; //只有一个时钟周期是高电平,CNT_NOW是在 0-24999+1之间徘徊 endmodule

    sound_lut.v 文件

    module sound_lut( Clk, Rst_n, ARR , Compare_cnt ); input Clk; input Rst_n; output reg[31:0]ARR; output reg[31:0]Compare_cnt; reg [4:0]index; always@(posedge Clk or negedge Rst_n) if(!Rst_n) index <= 0; else if(index >= 5'd20) index <= 0; else index <= index + 1'b1; always@(*)begin case(index) 0 : ARR = 191130; 1 : ARR = 170241; 2 : ARR = 151689; 3 : ARR = 143183; 4 : ARR = 127550; 5 : ARR = 113635; 6 : ARR = 101234; 7 : ARR = 95546 ; 8 : ARR = 85134 ; 9 : ARR = 75837 ; 10: ARR = 71581 ; 11: ARR = 63775 ; 12: ARR = 56817 ; 13: ARR = 50617 ; 14: ARR = 47823 ; 15: ARR = 42563 ; 16: ARR = 37921 ; 17: ARR = 35793 ; 18: ARR = 31887 ; 19: ARR = 28408 ; 20: ARR = 25309 ; default: ARR = 191130; endcase end always@(*)begin case(index) 0 : Compare_cnt= 95565 ; 1 : Compare_cnt= 85120 ; 2 : Compare_cnt= 75844 ; 3 : Compare_cnt= 71591 ; 4 : Compare_cnt= 63775 ; 5 : Compare_cnt= 56817 ; 6 : Compare_cnt= 50617 ; 7 : Compare_cnt= 47773 ; 8 : Compare_cnt= 42567 ; 9 : Compare_cnt= 37939 ; 10: Compare_cnt= 35792 ; 11: Compare_cnt= 31887 ; 12: Compare_cnt= 28408 ; 13: Compare_cnt= 25308 ; 14: Compare_cnt= 23912 ; 15: Compare_cnt= 21282 ; 16: Compare_cnt= 18960 ; 17: Compare_cnt= 17896 ; 18: Compare_cnt= 15943 ; 19: Compare_cnt= 14204 ; 20: Compare_cnt= 12655 ; default: Compare_cnt = 24999; endcase end endmodule

    timer.v 文件

    //通用定时器模块 //描述: //通过定义 timer 里面的 input 的数值 // 得到 output 里面的数值,这样就可以得到我们想要的输出(2个 分别是 CNT_NOW 和 Full_Flag 两个输出信号) // 时钟和复位信号是输入信号,一般由系统给定 // CNT_ARR、MODE、CNT_ENABLE 可以自己给定固定值或者通过外部的输入给定一个值(信号) module timer( Clk , //时钟 Rst_n , //复位信号 CNT_ARR , //定时器重装载值(类似与32的重装载值) MODE , // Mode : 1 循环定时 Mode : 0 单次定时 CNT_ENABLE , //CNT_ENABLE : 1 定时器计数器使能,开始计数 //CNT_ENABLE : 0 定时器计数不使能,停止计数 CNT_NOW , //实时定时器计数器 Full_Flag //计数完成标志位 ); // 定义: input Clk ; input Rst_n; input [31:0]CNT_ARR ; //通用32位定时计数器 input MODE ; input CNT_ENABLE; output [31:0]CNT_NOW ; //当前32位定时计数器的值 output reg Full_Flag ; //计数完成标志位 //自己模块定义的信号 reg [31:0]cnt; //定义一个32位的计数器 reg oneshot ; //定义一个 单次计数值计满 触发信号 wire Full_Flag_r; //Full_Flag_r 用于延时Full_Flag 的一个周期 assign CNT_NOW = cnt; //定时器的值 assign Full_Flag_r = (CNT_NOW == CNT_ARR - 1)?1'b1:1'b0; //第1个 always 块 always@(posedge Clk) Full_Flag <= Full_Flag_r; //第2个 always 块 always@(posedge Clk or negedge Rst_n) if(!Rst_n) //复位信号到来,数据清零(qingling) cnt <=0; else if(MODE == 1'b1)begin //判断是否是循环模式 if((CNT_ENABLE == 1'b1) && (cnt < CNT_ARR)) //判断CNT_ENABLE 是否启动,且计数值是否小于重装载值 cnt <= cnt + 1'b1; //cnt++ else //否则数据清零 cnt <= 0; end else if(!MODE)begin //判断是否是单次计数模式 if(oneshot) //oneshot信号为1,表示满足一次计数条件 cnt <= cnt + 1'b1; else cnt <= 0; end //第3个 always 块 always@(posedge Clk or negedge Rst_n) if(!Rst_n) //复位信号清零 oneshot <= 1'b0; else if(!MODE) begin //判断是在一次计数模式下 if(CNT_ENABLE == 1'b1) //判断CNT_ENABLE 是否启动 oneshot <= 1'b1; else if(CNT_NOW == CNT_ARR - 1) //判断计数值是否等于重转载值 oneshot <= 1'b0; else //保持不变 oneshot <= oneshot; end else//在循环模式下,oneshot =0 ; oneshot <= 1'b0; endmodule

    timer_tb.v 文件

    `timescale 1ns/1ns `define clk_period 20 // 定时器定时模块测试源文件 module timer_tb; // 定义的测试模块的名称,一般命名 是后面加 _tb,表示这是测试模块 // 测试模块的输入输出 定义: input 类型 --> reg 类型替换 // output 类型 --> wire 类型替换 reg Clk ; reg Rst_n; reg [31:0]CNT_ARR ; //通用32位定时计数器 reg MODE ; reg CNT_ENABLE; wire [31:0]CNT_NOW ; //当前32位定时计数器的值 wire Full_Flag ; //计数完成标志位 timer timer0( .Clk(Clk) , //时钟 .Rst_n(Rst_n) , //复位信号 .CNT_ARR(CNT_ARR) , //定时器重装载值(类似与32的重装载值) .MODE(MODE) , // Mode : 1 循环定时 Mode : 0 单次定时 .CNT_ENABLE(CNT_ENABLE) , //CNT_ENABLE : 1 定时器计数器使能,开始计数 //CNT_ENABLE : 0 定时器计数不使能,停止计数 .CNT_NOW(CNT_NOW) , //实时定时器计数器 .Full_Flag(Full_Flag) //计数完成标志位 ); /*********** 定义初始化测试信号 ************/ initial Clk = 1; //定义时钟信号 always #(`clk_period/2) Clk = ~Clk; initial begin //执行一次,叫 initial 加入 begin //初始化所有输入信号 Rst_n = 0; CNT_ARR = 0; MODE = 0; CNT_ENABLE = 0; #(`clk_period*20 + 1); //复位信号 Rst_n = 1; 模块正式开始工作 Rst_n = 1; #(`clk_period*20); //设置预设值为1000,模式为循环定时模式 CNT_ARR = 1000; MODE = 1; #(`clk_period*20); //设置为循环模式,延时20个时钟周期 CNT_ENABLE = 1; //开始启动计数定时器 #(`clk_period*12000); CNT_ENABLE = 0; //关闭计数定时器 #(`clk_period*20); //设置预设值为600,模式为循环定时模式 CNT_ARR = 600; MODE = 1; #(`clk_period*20); CNT_ENABLE = 1; #(`clk_period*8000); CNT_ENABLE = 0; #(`clk_period*20); //设置预设值为1000,模式为单次定时模式 CNT_ARR = 1000; MODE = 0; #(`clk_period*20); // CNT_ENABLE = 1; #(`clk_period) CNT_ENABLE = 0; 表示给定的是一个脉冲信号,进入的是单次计数模式 CNT_ENABLE = 1; #(`clk_period); CNT_ENABLE = 0; #(`clk_period*1200); //设置预设值为600,模式为单次定时模式 CNT_ARR = 600; MODE = 0; #(`clk_period*20); // CNT_ENABLE = 1; #(`clk_period) CNT_ENABLE = 0; 表示给定的是一个脉冲信号,进入的是单次计数模式 CNT_ENABLE = 1; #(`clk_period); CNT_ENABLE = 0; #(`clk_period*1200); $stop; end endmodule

    assigment .tcl 文件

    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to Clk set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to Rst_n set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to CNT_ENABLE set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to beep set_location_assignment PIN_E1 -to Clk set_location_assignment PIN_E16 -to Rst_n set_location_assignment PIN_M16 -to CNT_ENABLE set_location_assignment PIN_L16 -to beep
    Processed: 0.011, SQL: 8