BASYS2开发板初学记录(3)——FPGA仿真

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/WilliamYuYuYu/article/details/78931520

BASYS2开发板初学记录(3)——FPGA仿真

2017-12-27

注:win10系统+软件Xilinx_ISE14.7+开发板BASYS2

关键词:

FPGA

BASYS2

Xilinx_ISE

Verilog

紧接着上篇,填第二个坑:FPGA程序仿真。

仿真的实现步骤上上篇已经记录过,此处记录仿真程序的语法。


完整仿真程序如下:

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: HUST
// Engineer:William Yu
//
// Create Date:   23:02:11 12/23/2017
// Design Name:   tele_pwm
// Module Name:   C:/Users/WilliamYu/Desktop/tele_pwm/tele_pwm/test.v
// Project Name:  tele_pwm
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: tele_pwm
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module test;

    //[1]输入
    // Inputs
    reg clk;
    reg reset;
    reg ch1;
    reg ch2;
    reg ch3;
    reg ch4;
    reg ch5;
    reg ch6;
    //[2]输出 
    // Outputs
    wire [3:0] ledout;
    wire pwmout1;
    wire pwmout2;
    wire pwmout3;
    wire pwmout4;
    wire pwmout5;


    //[3]经由tele_pwm.v处理的所有参变量
    // Instantiate the Unit Under Test (UUT)
    tele_pwm uut (
        .clk(clk), 
        .reset(reset), 
        .ch1(ch1), 
        .ch2(ch2), 
        .ch3(ch3), 
        .ch4(ch4), 
        .ch5(ch5), 
        .ch6(ch6), 
        .ledout(ledout), 
        .pwmout1(pwmout1), 
        .pwmout2(pwmout2), 
        .pwmout3(pwmout3), 
        .pwmout4(pwmout4),
        .pwmout5(pwmout5)
    );


    //[4]设置初始数值
    // Initialize Inputs
    initial begin
        clk = 0;
        reset = 1;
        ch1 = 0;
        ch2 = 0;
        ch3 = 0;
        ch4 = 0;
        ch5 = 0;
        ch6 = 0;

        // Wait 100 ns for global reset to finish
        #100 reset=0;

    end


        //[5]一直执行程序
    parameter PERIOD = 20;  //周期20ns
    always begin      //每隔 PERIOD/2ns clk翻转一次,时基
         #(PERIOD/2) clk=1'b1;
         #(PERIOD/2) clk=1'b0;
    end

    //模拟遥控器通道1信号 1.5ms为高,总周期20ms
    always begin 
        //计算示例
         #(18500000) ch1=1'b1;    //1.5ms *10^6 =1500000  翻转为高
         #(1500000) ch1=1'b0;   //(20-1.5)ms *10^6 =18500000  翻转为低
        end

    //模拟遥控器通道2信号 1.5ms为高,总周期20ms
    always begin
         #(18500000) ch2=1'b1;   //1.5ms *10^6 =1500000  翻转为高
         #(1500000) ch2=1'b0;  //(20-1.5)ms *10^6 =18500000  翻转为低
        end

    //模拟遥控器通道3信号 1ms为高,总周期20ms  
    always begin
        #(19000000) ch3=1'b1;   
         #(1000000) ch3=1'b0; 
        end

    //模拟遥控器通道4信号 2ms为高,总周期20ms
    always begin        
        #(18000000) ch4=1'b1;   
        #(2000000) ch4=1'b0;  
        end 

    //模拟遥控器通道5信号 2ms为高,总周期20ms  
    always begin
        #(18000000) ch5=1'b1;   
         #(2000000) ch5=1'b0;  
        end

    //模拟遥控器通道6信号,总周期20ms  
    //通道6有两种状态:【A】或者【B】
  //[A]打开状态2ms为高,跳舞
    always begin 
        #(18000000) ch6=1'b1;   
         #(2000000) ch6=1'b0;  
        end

  //[B]关闭状态1ms为高,遥控
//  always begin 
//      #(19000000) ch6=1'b1;   
//       #(1000000) ch6=1'b0;  
//      end


endmodule

输入变量是6个通道,我们需要模拟这6个信号。

【第一点】:仿真遥控器1-5通道的PWM波形,调整相应的数字

//模拟遥控器通道1信号 1.5ms为高,总周期20ms
always begin 
    //计算示例
     #(18500000) ch1=1'b1;    //1.5ms *10^6 =1500000  翻转为高
     #(1500000) ch1=1'b0;   //(20-1.5)ms *10^6 =18500000  翻转为低
    end

//模拟遥控器通道2信号 1.5ms为高,总周期20ms
always begin
     #(18500000) ch2=1'b1;   //1.5ms *10^6 =1500000  翻转为高
     #(1500000) ch2=1'b0;  //(20-1.5)ms *10^6 =18500000  翻转为低
    end

//模拟遥控器通道3信号 1ms为高,总周期20ms  
always begin
    #(19000000) ch3=1'b1;   
     #(1000000) ch3=1'b0; 
    end

//模拟遥控器通道4信号 2ms为高,总周期20ms
always begin        
    #(18000000) ch4=1'b1;   
    #(2000000) ch4=1'b0;  
    end 

//模拟遥控器通道5信号 2ms为高,总周期20ms  
always begin
    #(18000000) ch5=1'b1;   
     #(2000000) ch5=1'b0;  
    end

【第二点】:仿真遥控器6通道的PWM波形,状态[A]和状态[B]都需仿真检查。


    //模拟遥控器通道6信号,总周期20ms  
    //通道6有两种状态:【A】或者【B】
  //[A]打开状态2ms为高,跳舞
    always begin 
        #(18000000) ch6=1'b1;   
         #(2000000) ch6=1'b0;  
        end

  //[B]关闭状态1ms为高,遥控
//  always begin 
//      #(19000000) ch6=1'b1;   
//       #(1000000) ch6=1'b0;  
//      end

【第三点】:在模拟跳舞按摩动作组时,由于8s的仿真耗时比较长,所以设置counter8s的初值,直接跳跃检查某一秒的状态,取消相应语句前的注释,并注释掉其他语句即可。这几句语句块,在上篇的verilog程序里面,不在仿真程序里。

reg [31:0] counter8s=0;   //8s= 20ns* 400 000 000  //400 000 000 < 2^32  //仿真检查刚开始的状态 
//reg [31:0] counter8s=100000001;//仿真检查2s之后的状态
//reg [31:0] counter8s=200000001;//仿真检查4s之后的状态
//reg [31:0] counter8s=300000001;//仿真检查4s之后的状态

几个仿真截图

【1】ch6置低,5个PWM信号输出,应该时刻和5个PWM信号输入相同,遥控指令。
这里写图片描述

【2】ch6置高,5个PWM信号执行动作组,0-4s一个一个依次置高,4-8s一个一个依次置低。此处仿真0s的状态,应该看到dance_en为高,pwmout1为高PWM。
这里写图片描述
【3】仿真,非常好玩,非常必要,通过仿真应该能看到原程序里的漏洞,dance_en、counter_ch6_flag这几个变量就是在补漏洞啊。
这里写图片描述

还记得原程序里面check ch6 这一段吗?就是为了补这个洞。


// ----------- check ch6 --------------
reg [16:0] ch6_counter = 0;  //ch6_counter在1ms到2ms之间, 2ms=20ns* 100 000  //10^5 < 2^17
reg [19:0] counter20ms=0;  //20ms=20ns* 1000 000  //10^6 < 2^20

always @(posedge clk)
begin
        if(counter20ms>1000000)begin  //一个clk是20ns,10^6是20ms
            counter20ms<=0;
            ch6_counter<=0;end
        else 
        counter20ms <= counter20ms +1;  

        if (ch6) begin  
            ch6_counter<=ch6_counter+1;
            if (ch6_counter > 75000)   //1.5ms=75000 * 20ns
            ch6_flag <= 1;
            else ch6_flag <=0;
        end![遥控](C:\Users\WilliamYu\Desktop\BASYS2\遥控.JPG)![遥控](C:\Users\WilliamYu\Desktop\BASYS2\遥控.JPG)

end

reg [19:0] counter_ch6_flag=0;

always @(posedge clk)
begin
    if(ch6_flag)
            dance_en<=1;    
    else begin  //记录ch6低电平持续时间是否持续超过2ms,超过则认为已经拉低
        counter_ch6_flag<=counter_ch6_flag+1;   
        if(counter_ch6_flag>1000000)  
        begin
            dance_en<=0;
            counter_ch6_flag<=0;
        end
    end
end

(2017-12-27–William Yu)

阅读更多

没有更多推荐了,返回首页