草庐IT

FPGA:乒乓球比赛模拟机的设计

Az1r 2023-03-28 原文

简介

  • 开发板:EGO1

  • 开发环境:Windows10 + Xilinx Vivado 2020

  • 数字逻辑大作业题目 7: 乒乓球比赛模拟机的设计

  • 乒乓球比赛模拟机用发光二极管(LED)模拟乒乓球运动轨迹,是由甲乙双方参赛,加上裁判的三人游戏(也可以不用裁判)。

管脚约束代码:

点击查看代码
set_property IOSTANDARD LVCMOS33 [get_ports CLK]
set_property IOSTANDARD LVCMOS33 [get_ports hitA]
set_property IOSTANDARD LVCMOS33 [get_ports hitB]
set_property PACKAGE_PIN P17 [get_ports CLK]
set_property PACKAGE_PIN P5 [get_ports hitA]
set_property PACKAGE_PIN R1 [get_ports hitB]

set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[6]}]
set_property PACKAGE_PIN F6 [get_ports {ballLocation[7]}]
set_property PACKAGE_PIN G4 [get_ports {ballLocation[6]}]
set_property PACKAGE_PIN G3 [get_ports {ballLocation[5]}]
set_property PACKAGE_PIN J4 [get_ports {ballLocation[4]}]
set_property PACKAGE_PIN H4 [get_ports {ballLocation[3]}]
set_property PACKAGE_PIN J3 [get_ports {ballLocation[2]}]
set_property PACKAGE_PIN J2 [get_ports {ballLocation[1]}]
set_property PACKAGE_PIN K2 [get_ports {ballLocation[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports speedA]
set_property PACKAGE_PIN P4 [get_ports speedA]
set_property IOSTANDARD LVCMOS33 [get_ports speedB]
set_property PACKAGE_PIN N4 [get_ports speedB]

set_property IOSTANDARD LVCMOS33 [get_ports {statusOut[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {statusOut[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {statusOut[1]}]
set_property PACKAGE_PIN K1 [get_ports {statusOut[3]}]
set_property PACKAGE_PIN H6 [get_ports {statusOut[2]}]
set_property PACKAGE_PIN M1 [get_ports {statusOut[1]}]
set_property PACKAGE_PIN K3 [get_ports {statusOut[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {statusOut[0]}]

set_property IOSTANDARD LVCMOS33 [get_ports {LED1[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED0[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED1[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED0[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED1[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED1[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED0[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED0[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED1[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED1[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED0[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED0[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED1[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LED1[7]}]
set_property PACKAGE_PIN B4 [get_ports {LED0[0]}]
set_property PACKAGE_PIN A4 [get_ports {LED0[1]}]
set_property PACKAGE_PIN A3 [get_ports {LED0[2]}]
set_property PACKAGE_PIN B1 [get_ports {LED0[3]}]
set_property PACKAGE_PIN A1 [get_ports {LED0[4]}]
set_property PACKAGE_PIN B3 [get_ports {LED0[5]}]
set_property PACKAGE_PIN B2 [get_ports {LED0[6]}]
set_property PACKAGE_PIN D5 [get_ports {LED0[7]}]
set_property PACKAGE_PIN D4 [get_ports {LED1[0]}]
set_property PACKAGE_PIN E3 [get_ports {LED1[1]}]
set_property PACKAGE_PIN D3 [get_ports {LED1[2]}]
set_property PACKAGE_PIN F4 [get_ports {LED1[3]}]
set_property PACKAGE_PIN F3 [get_ports {LED1[4]}]
set_property PACKAGE_PIN E2 [get_ports {LED1[5]}]
set_property PACKAGE_PIN D2 [get_ports {LED1[6]}]
set_property PACKAGE_PIN H2 [get_ports {LED1[7]}]
set_property PACKAGE_PIN G2 [get_ports {LEDBit[0]}]
set_property PACKAGE_PIN C2 [get_ports {LEDBit[1]}]
set_property PACKAGE_PIN C1 [get_ports {LEDBit[2]}]
set_property PACKAGE_PIN H1 [get_ports {LEDBit[3]}]
set_property PACKAGE_PIN G1 [get_ports {LEDBit[4]}]
set_property PACKAGE_PIN F1 [get_ports {LEDBit[5]}]
set_property PACKAGE_PIN E1 [get_ports {LEDBit[6]}]
set_property PACKAGE_PIN G6 [get_ports {LEDBit[7]}]

set_property IOSTANDARD LVCMOS33 [get_ports reset]
set_property PACKAGE_PIN P2 [get_ports reset]

设计要求

  1. 主要功能
    1. 模拟乒乓球比赛,用发光二极管(LED)模拟乒乓球运动轨迹,由甲乙双方参赛;
    2. 用8个LED灯表示球桌,其中点亮的LED来回移动表示乒乓球的运动,球速可以调节;
    3. 当球移动到最左侧或最右侧时,表示一方的击球位置。如果提前击球,或未及时击球,则对方得一分;
    4. 甲乙得分使用数码管计分,一局11球;
    5. 用发光二极管表示甲乙的发球权,每5分交换发球权。
  2. 附加功能
    1. 用发光二极管提示甲乙的接球和发球;
    2. 比赛结束后,用数码管动态显示胜利的一方。

工作原理

本电路由时钟分频模块,玩家控制器模块,分数处理模块,游戏控制模块,乒乓球运动控制模块和数码管显示模块组成。

  1. 比赛开始前,可以通过reset开关重置比赛;
  2. 比赛进行时,甲乙两位选手通过扳动开关来实现挥动球拍和控制球速的效果。当乒乓球到击球位置时,若选手未及时击球,或提前击球,则输掉一球,对方加一分。每打5球,就交换一次球权,共打11球,数码管上会显示当前得分,分高者获胜;
  3. 比赛结束后,数码管会显示箭头来表示一方的获胜;
  4. 另外还有4个LED来表示双方的发球和接球。
  5. 系统方框图:


各部分模块具体功能及设计思路

游戏控制器模块

  1. 模块功能:控制整个模拟器各组件状态;
  2. 设计思路:该模块主要是用于控制比赛的进行。在设计中,使用status表示当前的比赛状态。010表示A发球,001表示B发球,110表示玩家A接球,101表示玩家B接球。这样的规定能够有效区分乒乓球不同的运动状态,并判定发/击球的有效性,同时显示在LED灯上来提示选手。另外再用accurateBallLocation [32:0]来表示球的精确位置,范围为$1000_{10} - 9000_{10} $,这样使球在LED显示的误差范围内,可以被击中。
  3. 代码:
点击查看代码
`timescale 1ns / 1ps



module GameController(  //全局状态控制器
    input CLK, 
    input reg hitA, //玩家A输入
    input [1: 0] speedA, //玩家A速度
    input reg hitB,  //玩家B输入
    input [1: 0] speedB,  //玩家B速度
    input reg serviceSide, //发球方
    input reg reset,    //重置
    output reg [2: 0] status, //全局状态
    output reg [7: 0] ballLocation, //球位置
    output reg getScoreA,   //A得分
    output reg getScoreB    //B得分
    );

    reg hitATrigger;
    reg hitBTrigger;
    reg [2: 0] speed;
    reg [15: 0] accurateBallLocation;
    reg resetTrigger;
    // reg serviceSide;


    initial begin   //初始化变量
        hitATrigger = 'b0;
        hitBTrigger = 'b0;
        status = 'b010;
        accurateBallLocation = 'd2000;
        speed = 'd2;
        // serviceSide = 'b0;

        getScoreA = 'b0;
        getScoreB = 'b0;
        resetTrigger = 'b0;
    end



    always @(posedge CLK) begin     //根据报告所述转换状态
        if(resetTrigger == 'b0 && reset == 'b1) begin
            hitATrigger = 'b0;
            hitBTrigger = 'b0;
            status = 'b010;
            accurateBallLocation = 'd2000;
            speed = 'd2;
            // serviceSide = 'b0;

            getScoreA = 'b0;
            getScoreB = 'b0;
        end
        else begin
            if(status == 'b010 || status == 'b001) begin//换发球
                status = serviceSide == 'b0 ? 'b010 : 'b001;
                getScoreA = 'b0;
                getScoreB = 'b0;
            end

            if(status == 'b010) begin //A发球

                accurateBallLocation = 'd2000;

                if(hitATrigger == 'b0 && hitA == 'b1) begin
                    status = 'b101;
                    if(speedA == 'd00) speed = 'd2;
                    else speed = 'd4;
                end 
                hitATrigger = hitA;



            end
            else if(status == 'b001) begin //B发球

                accurateBallLocation = 'd10000;

                if(hitBTrigger == 'b0 && hitB == 'b1) begin
                    status = 'b110;
                    if(speedB == 'd00) speed = 'd2;
                    else speed = 'd4;
                end 
                hitBTrigger = hitB;


            end
            else if(status == 'b110) begin //A接球
                if(hitATrigger == 'b0 && hitA == 'b1) begin
                    if(accurateBallLocation >= 'd1000 && accurateBallLocation <= 'd3000) begin
                        status = 'b101;
                        if(speedA == 'd00) speed = 'd2;
                        else speed = 'd4;
                    end 
                end 
                hitATrigger = hitA;

                if(accurateBallLocation < 'd500) begin
                    getScoreB = 'b1;
                    status = serviceSide == 'b0 ? 'b010 : 'b001;
                end 

                accurateBallLocation -= speed * 'd3;

            end
            else if(status == 'b101) begin //B接球
                if(hitBTrigger == 'b0 && hitB == 'b1) begin
                    if(accurateBallLocation >= 'd9000 && accurateBallLocation <= 'd11000) begin
                        status = 'b110;
                        if(speedB == 'd00) speed = 'd2;
                        else speed = 'd4;
                    end 
                end 
                hitBTrigger = hitB;

                if(accurateBallLocation >'d11500) begin 
                    getScoreA = 'b1;
                    status = serviceSide == 'b0 ? 'b010 : 'b001;
                end 

                accurateBallLocation += speed * 'd3;

            end
        end
        

        resetTrigger = reset;

        if(accurateBallLocation >= 'd2000 && accurateBallLocation < 'd3000) ballLocation = 'b10000000;//球的位置显示
        if(accurateBallLocation >= 'd3000 && accurateBallLocation < 'd4000) ballLocation = 'b01000000;
        if(accurateBallLocation >= 'd4000 && accurateBallLocation < 'd5000) ballLocation = 'b00100000;
        if(accurateBallLocation >= 'd5000 && accurateBallLocation < 'd6000) ballLocation = 'b00010000;
        if(accurateBallLocation >= 'd6000 && accurateBallLocation < 'd7000) ballLocation = 'b00001000;
        if(accurateBallLocation >= 'd7000 && accurateBallLocation < 'd8000) ballLocation = 'b00000100;
        if(accurateBallLocation >= 'd8000 && accurateBallLocation < 'd9000) ballLocation = 'b00000010;
        if(accurateBallLocation >= 'd9000 && accurateBallLocation <= 'd10000) ballLocation = 'b00000001;

    end


endmodule

玩家控制模块

  1. 模块功能:控制玩家输入与接发球操作;

  2. 设计思路:在设计电路中规定了使能端EN,玩家只有在轮到自己发/击球时才有效;并规定了击球的间隔,模拟了击空的情况除此之外还设计实现了玩家击球速度的选择

  3. 代码:

点击查看代码
`timescale 1ns / 1ps


module Player(CLK, EN, hit, speed, hitOut, speedOut);
    input CLK, EN, hit, speed;
    output reg hitOut;
    output reg [1: 0] speedOut;
 
    reg [31: 0] activeInterval = 'd1000;    //一个下降沿到下一个上升沿直接最小时间间隔

    reg [31: 0] interval;
    reg hitTrigger;
 
    initial begin
        interval = 'd0;
        hitTrigger = 'b0;
        hitOut = 'b0;
        speedOut = 'b1;
    end


    always @(posedge CLK) begin
        if(EN == 'b1) begin
            if(hitTrigger =='b0 && hit == 'b1) begin
                if(interval >= activeInterval) begin
                    hitOut = hit;
                end
            end
            else if(hitTrigger == 'b1 && hit == 'b0) begin
                interval = 'd0;
                hitOut = hit;
            end
            hitTrigger = hit;
            interval += 1;

            if(speed == 'b0) begin
                speedOut = 'd00;
            end
            else begin
                speedOut = 'd01;
            end
        end

    end


endmodule

时钟分频模块

  1. 模块功能:对时钟分频;

  2. 设计思路:将EG01100MHZ的时钟分频为1000HZ

  3. 代码:

点击查看代码
`timescale 1ns / 1ps



module ClockDivider(originCLK, dividedCLK);
    input originCLK;
    output dividedCLK;
    reg tempDivCLK;
    reg [31: 0] count;
    // reg [31: 0] ratio = 'd2;
    reg [31: 0] ratio = 'd100_000;  //时钟分频器,将P17的100MHz分为1000Hz
    initial begin
        tempDivCLK = 'b0;
        count = 'd0;
    end
    always @(posedge originCLK) begin
        count = count + 1;
        if(count == ratio)
            count = 'd0;
        
        if(count == 'd0) 
            tempDivCLK = 'b0;
        if(count == ratio / 2) 
            tempDivCLK = 'b1;

    end
    assign dividedCLK = tempDivCLK;
endmodule

乒乓球控制模块

  1. 模块功能:接受信号控制乒乓球从左向右移动,或者从右向左移动,并且可以根据玩家选择的击球速度去调整;

  2. 设计思路:用8LED模拟,点亮的灯表示球的位置,然后像流水灯一样来回滚动,在发球时暂停。

  3. 代码:这里实际上包括在了游戏控制,下面代码是调用其他的Main。

点击查看代码
`timescale 1ns / 1ps


module Main(
    input CLK, 
    input hitA, 
    input speedA, 
    input hitB, 
    input speedB, 
    input reset,
    output reg [3: 0] statusOut, 
    output wire [7: 0] ballLocation,
    output wire [7:0] LED0, 
    output wire [7:0] LED1, 
    output wire [7:0] LEDBit
    );


    wire [2: 0] status;
    wire dividedCLK;
    wire [1: 0] speedOutA;
    wire [1: 0] speedOutB;
    wire getScoreA, getScoreB;
    ClockDivider clockDivider(CLK, dividedCLK);
    wire serviceSide;

    reg EnA;
    reg EnB;
    initial begin
        EnA = 'b1;
        EnB = 'b1;
    end

    Player player1(dividedCLK, EnA, hitA, speedA, hitOutA, speedOutA);
    Player player2(dividedCLK, EnB, hitB, speedB, hitOutB, speedOutB);

    GameController gameController(  //调用全局状态控制器
        dividedCLK, 
        hitOutA, 
        speedOutA, 
        hitOutB, 
        speedOutB, 
        serviceSide,
        reset,
        status, 
        ballLocation, 
        getScoreA, 
        getScoreB
        
    );

    always @(posedge dividedCLK) begin
        if(status == 'b010) begin
            statusOut = 'b1000;
        end
        else if(status == 'b001) begin
            statusOut = 'b0001;
        end
        else if(status == 'b110) begin
            statusOut = 'b0100;
        end
        else if(status == 'b101) begin
            statusOut = 'b0010;
        end
    end

    reg [7:0][7:0] dataIn;

    reg [31:0] count;
    initial begin 
        count = 'd0;
        while(count < 8) begin
            dataIn[count] = 'd100;
            count ++;
        end
        count = 'd0;
    end

    DigitalTubeDriver digitalTubeDriver(    //调用数码管驱动
        dividedCLK, 
        dataIn, 
        LED0, 
        LED1, 
        LEDBit
    );

    
    wire endGame;
    wire [1:0] winner;
    wire [15: 0] scoreA;
    wire [15: 0] scoreB;

    ScoreBoard scoreBoard(
        dividedCLK, 
        getScoreA, 
        getScoreB, 
        reset,
        serviceSide, 
        endGame, 
        winner, 
        scoreA, 
        scoreB
    );


    reg [7:0] i;
    reg [7:0] j;
    reg [31:0] countTemp;
    reg [31:0] countTemp2;
    reg resetTrigger;
    reg [31: 0] flowLightCount;
    reg endGameTrigger;
    initial begin
        resetTrigger = 'b0;
        flowLightCount = 'd0;
        endGameTrigger = 'd0;
    end

    always @(posedge dividedCLK) begin
        
        if(resetTrigger == 'b0 && reset == 'b1) begin
            EnA = 'b1;
            EnB = 'b1;
            dataIn[2] = 'd100;//不显示
            dataIn[3] = 'd100;
            dataIn[4] = 'd100;
            dataIn[5] = 'd100;
            endGameTrigger = 'd0;
        end
        resetTrigger = reset;

    
        i = 'd0;
        countTemp = scoreB;
        while(i < 'd2) begin
            dataIn[i] = countTemp % 'd10;
            countTemp /= 'd10;
            i++;
        end
        

        j = 'd6;
        countTemp2 = scoreA;
        while(j < 'd8) begin
            dataIn[j] = countTemp2 % 'd10;
            countTemp2 /= 'd10;
            j++;
        end
        
        if(endGame == 'b1) begin    //游戏结束时显示箭头指向赢的玩家
            if(endGameTrigger == 'b0) begin
                EnA = 'b0;
                EnB = 'b0;
            end

            if(winner == 'b10) begin
                case(flowLightCount)
                    'd100: dataIn[2] = 'd22;//箭头
                    'd200: dataIn[3] = 'd22;
                    'd300: dataIn[4] = 'd22;
                    'd400: dataIn[5] = 'd22;
                endcase
                flowLightCount++;
                if(flowLightCount == 'd500) begin
                    flowLightCount = 'd0;
                    dataIn[2] = 'd100;
                    dataIn[3] = 'd100;
                    dataIn[4] = 'd100;
                    dataIn[5] = 'd100;
                end 
            end
            else begin
                case(flowLightCount)
                    'd100: dataIn[5] = 'd21;//箭头
                    'd200: dataIn[4] = 'd21;
                    'd300: dataIn[3] = 'd21;
                    'd400: dataIn[2] = 'd21;
                endcase
                flowLightCount++;
                if(flowLightCount == 'd500) begin
                    flowLightCount = 'd0;
                    dataIn[2] = 'd100;
                    dataIn[3] = 'd100;
                    dataIn[4] = 'd100;
                    dataIn[5] = 'd100;
                end 
            end
        end

        endGameTrigger = endGame;

    end


endmodule

分数处理模块

  1. 模块功能:计数。每进行一轮控制分数加1,判断是否已打够11球,是则判别出获胜方。

  2. 设计思路:在A,B两人分数上升沿时,对总分加1,然后判断是否已满11球。若满11球,比较判断出胜利的一方,随后将其状态传给显示模块用于显示结果。

  3. 代码:

点击查看代码
`timescale 1ns / 1ps


module ScoreBoard(
    input CLK, 
    input getScoreA, 
    input getScoreB, 
    input reset,
    output reg serviceSide, 
    output reg endGame, 
    output reg [1:0] winner, 
    output reg [15: 0] scoreA, 
    output reg [15: 0] scoreB
    );
    reg getScoreATrigger;
    reg getScoreBTrigger;
    reg resetTrigger;
    initial begin
        serviceSide = 'b0;
        endGame = 'b0;
        getScoreATrigger = 'b0;
        getScoreBTrigger = 'b0;
        scoreA = 'b0;
        scoreB = 'b0;
        resetTrigger = 'b0;
    end
    always @(posedge CLK) begin
        if(resetTrigger == 'b0 && reset == 'b1) begin
            serviceSide = 'b0;
            endGame = 'b0;
            getScoreATrigger = 'b0;
            getScoreBTrigger = 'b0;
            scoreA = 'b0;
            scoreB = 'b0;
        end
        else begin  //getScoreA或getScoreB出现上升沿,对应玩家得分
            if(getScoreATrigger == 'b0 && getScoreA == 'b1)
                scoreA ++;
            if(getScoreBTrigger == 'b0 && getScoreB == 'b1)
                scoreB ++;

            getScoreATrigger = getScoreA;
            getScoreBTrigger = getScoreB;
            
            if((scoreA + scoreB) / 5 % 2 == 'd0)    //每5个球换发
                serviceSide = 'b0;
            else
                serviceSide = 'b1;
            if(scoreA + scoreB == 'd11) //到达11个球时游戏结束
                endGame = 'b1;

            if(endGame == 1) begin  //游戏结束时判断赢的那方
                if(scoreA > scoreB)
                winner = 'b10;
                else if(scoreA < scoreB)
                winner = 'b01;
                else
                winner = 'b11;
            end
            else begin
                winner = 'b00;
            end
        end
        
        resetTrigger = reset;

    end

endmodule

数码管显示模块

  1. 模块功能:利用数码管显示比赛数据;

  2. 设计思路:使用$ 8 * 8 $的矩阵显示每个数码管的显示情况,另外设有对每个数码管表示显示的标志,从而动态地去更新。在有一方获胜后,会将不显示分数的数码管动态地闪烁箭头,以此来表示获胜的一方。

  3. 代码:

点击查看代码
`timescale 1ns / 1ps
//参考EGO1的数码管显示模块

module DigitalTubeDriver(   //数码管驱动
    input CLK, 
    input reg [7:0][7:0] dataIn,    //输入数据
    output reg [7:0] LED0,  //输出的LED0,管理前4位显示
    output reg [7:0] LED1,  //输出的LED1,管理后4位显示
    output reg [7:0] LEDBit //LEDBIT,管理每个亮或不亮
    );

    reg [3:0] count;


    wire [7:0] data0;

    initial begin
        LEDBit = 'b00000001;
        count = 'd0;
    end

    // assign LED1 = LED0;

    always @(posedge CLK) begin

        case(dataIn[count]) //检查每种数字或符号对应亮哪些边
            'd0: LED0 = 'b00111111;
            'd1: LED0 = 'b00000110;
            'd2: LED0 = 'b01011011;
            'd3: LED0 = 'b01001111;
            'd4: LED0 = 'b01100110;
            'd5: LED0 = 'b01101101;
            'd6: LED0 = 'b01111101;
            'd7: LED0 = 'b00000111;
            'd8: LED0 = 'b01111111;
            'd9: LED0 = 'b01101111;
            'd21: LED0 = 'b01110000;
            'd22: LED0 = 'b01000110;
            default: LED0 = 'b00000000;
        endcase

        if(count == 'd7) begin
            count = 'd0;
            LEDBit = 'b00000001;
        end
        else if(count == 'd0) begin
            LEDBit = 'b10000000;
            count = 'd1;
        end
        else begin
            count++;
            LEDBit = LEDBit >> 1;
        end
        LED1 = LED0;

    end

endmodule

参考文献

[1] Vivado环境下多个并行的仿真测试文件如何支持单独仿真。

https://blog.csdn.net/CDCL19_220327/article/details/125802252?spm=1001.2014.3001.5502

[2] Vivado里程序固化详细教程。

https://blog.csdn.net/sinat_15674025/article/details/84535754?spm=1001.2014.3001.5502

[3] xilinx vivado 自带仿真工具xsim信号为蓝色Z态的解决办法。

https://blog.csdn.net/Shawge/article/details/107592471?spm=1001.2014.3001.5502

[4] Vivado环境下多个并行的仿真测试文件如何支持单独仿真?

https://blog.csdn.net/CDCL19_220327/article/details/125802252?spm=1001.2014.3001.5502

有关FPGA:乒乓球比赛模拟机的设计的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  3. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  4. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  5. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  6. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  7. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  8. ruby-on-rails - 设计注册确认 - 2

    我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:

  9. ruby-on-rails - 在这种情况下我如何模拟一个对象?没有明显的方法可以用模拟替换对象 - 2

    假设我在Store的模型中有这个非常简单的方法:defgeocode_addressloc=Store.geocode(address)self.lat=loc.latself.lng=loc.lngend如果我想编写一些不受地理编码服务影响的测试脚本,这些脚本可能已关闭、有限制或取决于我的互联网连接,我该如何模拟地理编码服务?如果我可以将地理编码对象传递到该方法中,那将很容易,但我不知道在这种情况下该怎么做。谢谢!特里斯坦 最佳答案 使用内置模拟和stub的rspecs,你可以做这样的事情:setupdo@subject=MyCl

  10. ruby - "public/protected/private"方法是如何实现的,我该如何模拟它? - 2

    在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定

随机推荐