哈工大数字逻辑大作业-乒乓球比赛模拟机的设计(不完整)

  由于本人偷懒一直没有按时去做这个大作业,导致在验收前一天才开始去动手去做,感到十分痛苦。 建议每个人都自己提前去尝试完成,如果实在是像我一样没时间了,可以参考一下这个做法。

 1.我使用的是vivado2021.2版本,第一步create project,这一步一定要按照学校发的实验指导书把开发板的型号输入,咱们学校应该用的都是xc7a35tcsg324-3,如果开发板不一样后续管教约束的时候会出现错误。2.create design sources这里我们把文件命名为pingpong1.v,然后把代码替换进去,再create constraints,文件名为pingpong.xdc,再把管脚约束代码替换进去,保存,这样代码部分就全部完成了,不需要仿真代码,直接烧板子就可以了。

module pingpong1(
    input clk,    //时钟
    input rst,    //复位键
    input [0:4] key,    //按键输入
    output [0:7] seg_cs,   //数码管位选
    output [0:7] seg_data0,    //前四个数码管
    output ring,
    output [0:15] led,   //LED灯
    output [0:7] seg_data1    //后四个数码管
    );

    reg beep = 1'b0;   //蜂鸣器
    reg [0:7] smg;    //数码管段码
    reg [0:7] wz;    //数码管位选
    reg [0:1] cnt_wz; //数码管状态
    reg [0:17] cnt_500Hz;   //500Hz扫描
    reg [0:20] cnt_xd = 0;    //消抖计时
    reg [0:26] speed;   //球的运动计时
    reg [0:25] sound;   //蜂鸣器计时
    reg [0:26] sd = 27'd25000000;   //球的运动速度,如果觉得游戏速度过慢,可以修改程序里其的数值
    reg [0:6] player1 = 0;   //玩家1的得分
    reg [0:6] player2 = 0;   //玩家2的得分
    reg [0:3] num; //中间变量 
    reg [0:1] key_out = 0;    //按键
    reg [0:15] light = 16'h8000;  //LED的过渡寄存器
    reg state = 1'b0;   //游戏运行状态,0是发球状态,1是击球状态
    reg pos = 1'b0;   //球的运动方向,0是向右,1是向左
    reg DIR = 1'b0;   //500Hz分频
    reg DIR1 = 1'b0;   //0.5s分频 
    reg DIR2 = 1'b0;   //1s分频

    parameter xd = 21'd1000000;    //计时_10ms

    always@(posedge clk) begin    //消抖计时
    if(key == 5'b00000)    //抖动即重新开始
        cnt_xd <= 0;
    else if(cnt_xd == xd)
        cnt_xd <= xd;
    else
        cnt_xd <= cnt_xd + 1;
    end

    always@(posedge clk) begin
    if(cnt_xd == 0)
        key_out <= 0;
    else if(cnt_xd == (xd - 21'b1))    //产生1个时间单位的按键信号
        case(key)     //根据键入得到对应的值
        5'b10000: key_out <= 1;
        5'b00010: key_out <= 2;
        endcase
    else
        key_out <= 0;   //0表示无按键按下
    end
    
    always @(posedge clk) begin   //球的运动计时模块
    if(state == 1)
    begin
        if(speed >= sd)
        begin
            speed <= 0; 
            DIR1 <= 1'b1;
        end
        else
        begin
            speed <= speed + 1;
            DIR1 <= 1'b0;
        end
    end
    else
    begin
        if(speed >= 27'd100000000)   //1s
        begin
            speed <= 0; 
            DIR2 <= 1'b1;
        end
        else
        begin
            speed <= speed + 1;
            DIR2 <= 1'b0;
        end
    end
    end

    always @(posedge clk) begin   //游戏的核心逻辑模块
    if(!rst)
    begin
        player1 <= 0;
        player2 <= 0;
    end
    else if(key_out == 1)
    begin
        if(state == 1'b0 & light == 16'h0001)
        begin
            state <= 1'b1;
            pos <= 1'b1;
            sd <= 27'd25000000;
        end
        else if(light == 16'h0002)
        begin
            pos <= 1'b1;
            if(speed >= sd / 2)     
                sd <= 27'd25000000;
            else if(speed >= sd / 4)
                sd <= 27'd20000000;
            else if(speed >= sd / 8)
                sd <= 27'd15000000;
            else
                sd <= 27'd10000000;
        end
        else
        begin
            pos <= pos;
            state <= state;
        end 
    end
    else if(key_out == 2)
    begin
        if(state == 1'b0 & light == 16'h8000)
        begin
            state <= 1'b1;
            pos <= 1'b0;
            sd <= 27'd25000000;
        end
        else if(light == 16'h4000)
        begin
            pos <= 1'b0;
            if(speed >= sd / 2)
                sd <= 27'd25000000;
            else if(speed >= sd / 4)
                sd <= 27'd20000000;
            else if(speed >= sd / 8)
                sd <= 27'd15000000;
            else
                sd <= 27'd10000000;
        end
        else
        begin
            pos <= pos;
            state <= state;
        end
    end
    else if(light <= 16'h0000)
    begin
        state <= 0;
        if(DIR2 == 1'b1)
        case (pos)
            1'b0 : player1 <= player1 + 1;
            1'b1 : player2 <= player2 + 1;
        endcase
    end
    else
    begin
        state <= state;
        pos <= pos;
        player1 <= player1;
        player2 <= player2;
    end
    end

    always @(posedge clk) begin   //蜂鸣器输出模块
    if(key_out == 2 & light == 16'h4000)
        beep <= 1'b1;
    else if(key_out == 1 & light == 16'h0002)
        beep <= 1'b1;
    else if(beep == 1)
    begin
        if(sound >= 26'd50000000)   //0.5s
        begin
            sound <= 0;
            beep <= 0; 
        end
        else
            sound <= sound + 1;
    end
    else
        beep <= beep;
    end

    always @(posedge clk) begin   //LED灯状态输出模块
    if(DIR1 == 1'b1)
        case (pos)
            1'b0 : light <= light >> 1;
            1'b1 : light <= light << 1; 
            default: light <=  0;
        endcase
    else if(light <= 16'h0000 & DIR2 == 1'b1)
        case (pos)
            1'b0 : light <= 16'h0001;
            1'b1 : light <= 16'h8000;
            default: light <= 0;
        endcase
    else
        light <= light;
    end

    always@(posedge clk) begin   //数码管扫描计时
    if(cnt_500Hz >= 18'd200000)  //500Hz
    begin
        cnt_500Hz <= 0;
        DIR <= 1'b1;   //产生一个上升沿
    end
    else
    begin
        cnt_500Hz <= cnt_500Hz +1;
        DIR <= 1'b0;
    end   
    end

    always@(posedge DIR) begin
    if(cnt_wz == 3)
        cnt_wz <= 0;
    else
        cnt_wz <= cnt_wz + 1;  //cnt_wz表示不同数码管的状态
    end

    always @(posedge clk) begin
    case(cnt_wz)
    2'd0 : wz <= 8'b10000000;
    2'd1 : wz <= 8'b01000000;
    2'd2 : wz <= 8'b00000010;
    2'd3 : wz <= 8'b00000001;
    default : wz <= 8'b00000000;
    endcase
    end

    always @(posedge clk) begin
    case (cnt_wz)
        2'd0 : num <= player1 / 10;
        2'd1 : num <= player1 % 10;
        2'd2 : num <= player2 / 10;
        2'd3 : num <= player2 % 10;
        default: num <= 0;
    endcase 
    end

    always @(posedge clk) begin
    case (num)
        4'd0: smg <= 8'b11111100;
        4'd1: smg <= 8'b01100000;
        4'd2: smg <= 8'b11011010;
        4'd3: smg <= 8'b11110010;
        4'd4: smg <= 8'b01100110;
        4'd5: smg <= 8'b10110110;
        4'd6: smg <= 8'b10111110;
        4'd7: smg <= 8'b11100000;
        4'd8: smg <= 8'b11111110;
        4'd9: smg <= 8'b11110110;
        default: smg <= 8'b00000000;
    endcase
    end

    assign ring = beep;
    assign seg_data0 = smg;    //段码输送
    assign seg_data1 = smg;
    assign seg_cs = wz;     //位选输送
    assign led = light;    //LED输送
endmodule
set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports clk]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports rst]
set_property -dict {PACKAGE_PIN M6 IOSTANDARD LVCMOS33} [get_ports {ring} ]
#数码管位选
set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33} [get_ports {seg_cs[0]}]
set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33} [get_ports {seg_cs[1]}]
set_property -dict {PACKAGE_PIN C1 IOSTANDARD LVCMOS33} [get_ports {seg_cs[2]}]
set_property -dict {PACKAGE_PIN H1 IOSTANDARD LVCMOS33} [get_ports {seg_cs[3]}]
set_property -dict {PACKAGE_PIN G1 IOSTANDARD LVCMOS33} [get_ports {seg_cs[4]}]
set_property -dict {PACKAGE_PIN F1 IOSTANDARD LVCMOS33} [get_ports {seg_cs[5]}]
set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports {seg_cs[6]}]
set_property -dict {PACKAGE_PIN G6 IOSTANDARD LVCMOS33} [get_ports {seg_cs[7]}]
#数码管段选
set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {seg_data0[0]}]
set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {seg_data0[1]}]
set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {seg_data0[2]}]
set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports {seg_data0[3]}]
set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports {seg_data0[4]}]
set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {seg_data0[5]}]
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {seg_data0[6]}]
set_property -dict {PACKAGE_PIN D5 IOSTANDARD LVCMOS33} [get_ports {seg_data0[7]}]
#另一组数码管段选
set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33} [get_ports {seg_data1[0]}]
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports {seg_data1[1]}]
set_property -dict {PACKAGE_PIN D3 IOSTANDARD LVCMOS33} [get_ports {seg_data1[2]}]
set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33} [get_ports {seg_data1[3]}]
set_property -dict {PACKAGE_PIN F3 IOSTANDARD LVCMOS33} [get_ports {seg_data1[4]}]
set_property -dict {PACKAGE_PIN E2 IOSTANDARD LVCMOS33} [get_ports {seg_data1[5]}]
set_property -dict {PACKAGE_PIN D2 IOSTANDARD LVCMOS33} [get_ports {seg_data1[6]}]
set_property -dict {PACKAGE_PIN H2 IOSTANDARD LVCMOS33} [get_ports {seg_data1[7]}]
#八个LED
set_property -dict {PACKAGE_PIN F6 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {led[4]}]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {led[5]}]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {led[6]}]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {led[7]}]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {led[8]}]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {led[9]}]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {led[10]}]
set_property -dict {PACKAGE_PIN J5 IOSTANDARD LVCMOS33} [get_ports {led[11]}]
set_property -dict {PACKAGE_PIN K6 IOSTANDARD LVCMOS33} [get_ports {led[12]}]
set_property -dict {PACKAGE_PIN L1 IOSTANDARD LVCMOS33} [get_ports {led[13]}]
set_property -dict {PACKAGE_PIN M1 IOSTANDARD LVCMOS33} [get_ports {led[14]}]
set_property -dict {PACKAGE_PIN K3 IOSTANDARD LVCMOS33} [get_ports {led[15]}]
#五个按键
set_property -dict {PACKAGE_PIN R11 IOSTANDARD LVCMOS33} [get_ports {key[0]}]
set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports {key[1]}]
set_property -dict {PACKAGE_PIN R15 IOSTANDARD LVCMOS33} [get_ports {key[2]}]
set_property -dict {PACKAGE_PIN V1  IOSTANDARD LVCMOS33} [get_ports {key[3]}]
set_property -dict {PACKAGE_PIN U4  IOSTANDARD LVCMOS33} [get_ports {key[4]}]

3.连接开发板,这里我们按照实验指导书的教学一步步跟着走即可,我们先把开发板和电脑用线连接上  然后在vivado进行如下操作1.选择Run Synthesis 2.在弹出窗口选择 Run Implementation 点击OK  3. 等待一会完成之后,在弹出窗口再选择 Open Implemented Design 4.选择 Generate Bitstream,下载比特流文件 5.下载完成后选择 Open Hardware Manager 6.auto connect 7.在页面上面的program divice 里点击program 

这样就连接上开发板,可以进行实操检验了。  上面的两个数字是双方得分,下面是乒乓球运动区域,具体讲解可以参考b站,这里右很多FPGA实例,这个代码也是从这个视频中学到的。主要是有开发板操作的讲解,代码讲解较为粗糙,需要自己理解并写实验报告。FPGA | 密码锁、饮料机、数字时钟和呼吸灯等设计分享与讲解(附程序代码)_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值