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

本文详细介绍了使用BASYS2开发板进行FPGA程序仿真的过程,包括Verilog语言编写仿真脚本的方法,以及如何模拟遥控信号输入并观察PWM输出的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)

FPGA 开发版资料 1数字逻辑电路基础实验 01_led1 #################################### led灯驱动实验 点亮全部8个led 02_led_twinkle #################################### led灯闪烁实验,8个LED灯会以一定频率闪烁 03_led_water #################################### led流水灯实验 04_key_led #################################### 读取按键信号实验 如果按下的是key1,那么点亮LED1 如果按下的是key2,那么点亮LED1-LED2 以此类推,如果下按key8,那么全部点亮8个led 05_ckey_led #################################### 拨码开关驱动控制LED 如果拨码开关推上去1,那么点亮LED1 如果拨码开关推上去2,那么点亮LED2 06_sled #################################### 静态数码管显示实验 8个数码管显示,依次显示显示"0到f" 07_dled #################################### 动态数码管显示实验 08_beep #################################### 蜂鸣器输出报警声实验 滴。。滴。。滴。。 09_uart #################################### PC机上开串口调试助手,发送一个字符到开发板(中间通过串口线相连) FPGA收到字符后,回发给PC机上,在串口助手上显示 10_ps2_keyboard_test #################################### FPGA通过ps2接收键盘数据,然后把接收到的字母A到Z键值转换相应的ASII码,通过串口发送到PC机上。 实验时,需要接键盘,还要用调试助手,下载程序后,在键盘上按下一个键,比如A,则在PC调试助手上可看到A 11_lcd1602 #################################### 本实验是用LCD1602显示英文 显示“HELLO WORLD!” 12_lcd12864 #################################### 本实验是用LCD12864显示英文 显示 Our FPGA EDA NIOS II SOPC FPGA 13_vga256 #################################### 连接开发板的VGA接口和电脑液晶屏, 即可显示640*480分辨率下的256种色彩 14_tlc549adc #################################### 利用状态机实现对TLC549的采样控制,实验时可调节电位器RW1(在开发板底板左下角),改变ADC 的模拟量输入值,数据采集读取后在数码管上显示。可以自己用万用表测一下输入电压, 然后与读取到的数据比较一下。注意:数码管显示的数据不是最终结果,还需要转换。 转换方法: 比如,采样电压值为V ,ADC转换后读取的8位二进制数为D,Vref为参考电压值,这里是2.5V 那么以下等式成立: V=(D/256)*Vref 15_tlc5620dac #################################### 利用状态机实现对tlc5620dac控制,实验时按key1,可选择DAC的通道,数码管1显示,按key2,key3可 输入8位数/模转换值,由数码管3,4显示,按key4,选择输出电压模式,由数码管8显示,0表示1倍,1表示2倍,按key5,将当前数据发送到DAC模块启动一次DA转换,这时可以万用表测量输出,也可以与理论值做下比较。 注意: TLC5620的输出电压为: V(A,B,C,D)=Vref*(Code/256)(1+RNG) Vref为参考电压值,这里是2.5V A B C D表示4个不同的通道,Code为8位二进制数,RNG为电压模式值,为0或1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值