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

打印 上一主题 下一主题

主题 539|帖子 539|积分 1617

简介


  • 开发板:EGO1
  • 开发环境:Windows10 + Xilinx Vivado 2020
  • 数字逻辑大作业题目 7: 乒乓球比赛模拟机的设计
  • 乒乓球比赛模拟机用发光二极管(LED)模拟乒乓球运动轨迹,是由甲乙双方参赛,加上裁判的三人游戏(也可以不用裁判)。
管脚约束代码:
点击查看代码
  1. set_property IOSTANDARD LVCMOS33 [get_ports CLK]
  2. set_property IOSTANDARD LVCMOS33 [get_ports hitA]
  3. set_property IOSTANDARD LVCMOS33 [get_ports hitB]
  4. set_property PACKAGE_PIN P17 [get_ports CLK]
  5. set_property PACKAGE_PIN P5 [get_ports hitA]
  6. set_property PACKAGE_PIN R1 [get_ports hitB]
  7. set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[5]}]
  8. set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[4]}]
  9. set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[0]}]
  10. set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[3]}]
  11. set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[2]}]
  12. set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[1]}]
  13. set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[7]}]
  14. set_property IOSTANDARD LVCMOS33 [get_ports {ballLocation[6]}]
  15. set_property PACKAGE_PIN F6 [get_ports {ballLocation[7]}]
  16. set_property PACKAGE_PIN G4 [get_ports {ballLocation[6]}]
  17. set_property PACKAGE_PIN G3 [get_ports {ballLocation[5]}]
  18. set_property PACKAGE_PIN J4 [get_ports {ballLocation[4]}]
  19. set_property PACKAGE_PIN H4 [get_ports {ballLocation[3]}]
  20. set_property PACKAGE_PIN J3 [get_ports {ballLocation[2]}]
  21. set_property PACKAGE_PIN J2 [get_ports {ballLocation[1]}]
  22. set_property PACKAGE_PIN K2 [get_ports {ballLocation[0]}]
  23. set_property IOSTANDARD LVCMOS33 [get_ports speedA]
  24. set_property PACKAGE_PIN P4 [get_ports speedA]
  25. set_property IOSTANDARD LVCMOS33 [get_ports speedB]
  26. set_property PACKAGE_PIN N4 [get_ports speedB]
  27. set_property IOSTANDARD LVCMOS33 [get_ports {statusOut[3]}]
  28. set_property IOSTANDARD LVCMOS33 [get_ports {statusOut[2]}]
  29. set_property IOSTANDARD LVCMOS33 [get_ports {statusOut[1]}]
  30. set_property PACKAGE_PIN K1 [get_ports {statusOut[3]}]
  31. set_property PACKAGE_PIN H6 [get_ports {statusOut[2]}]
  32. set_property PACKAGE_PIN M1 [get_ports {statusOut[1]}]
  33. set_property PACKAGE_PIN K3 [get_ports {statusOut[0]}]
  34. set_property IOSTANDARD LVCMOS33 [get_ports {statusOut[0]}]
  35. set_property IOSTANDARD LVCMOS33 [get_ports {LED1[5]}]
  36. set_property IOSTANDARD LVCMOS33 [get_ports {LED0[0]}]
  37. set_property IOSTANDARD LVCMOS33 [get_ports {LED0[3]}]
  38. set_property IOSTANDARD LVCMOS33 [get_ports {LED1[2]}]
  39. set_property IOSTANDARD LVCMOS33 [get_ports {LED0[6]}]
  40. set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[1]}]
  41. set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[4]}]
  42. set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[7]}]
  43. set_property IOSTANDARD LVCMOS33 [get_ports {LED1[6]}]
  44. set_property IOSTANDARD LVCMOS33 [get_ports {LED0[1]}]
  45. set_property IOSTANDARD LVCMOS33 [get_ports {LED1[3]}]
  46. set_property IOSTANDARD LVCMOS33 [get_ports {LED0[4]}]
  47. set_property IOSTANDARD LVCMOS33 [get_ports {LED0[7]}]
  48. set_property IOSTANDARD LVCMOS33 [get_ports {LED1[0]}]
  49. set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[2]}]
  50. set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[0]}]
  51. set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[5]}]
  52. set_property IOSTANDARD LVCMOS33 [get_ports {LED1[4]}]
  53. set_property IOSTANDARD LVCMOS33 [get_ports {LED0[2]}]
  54. set_property IOSTANDARD LVCMOS33 [get_ports {LED0[5]}]
  55. set_property IOSTANDARD LVCMOS33 [get_ports {LED1[1]}]
  56. set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[3]}]
  57. set_property IOSTANDARD LVCMOS33 [get_ports {LEDBit[6]}]
  58. set_property IOSTANDARD LVCMOS33 [get_ports {LED1[7]}]
  59. set_property PACKAGE_PIN B4 [get_ports {LED0[0]}]
  60. set_property PACKAGE_PIN A4 [get_ports {LED0[1]}]
  61. set_property PACKAGE_PIN A3 [get_ports {LED0[2]}]
  62. set_property PACKAGE_PIN B1 [get_ports {LED0[3]}]
  63. set_property PACKAGE_PIN A1 [get_ports {LED0[4]}]
  64. set_property PACKAGE_PIN B3 [get_ports {LED0[5]}]
  65. set_property PACKAGE_PIN B2 [get_ports {LED0[6]}]
  66. set_property PACKAGE_PIN D5 [get_ports {LED0[7]}]
  67. set_property PACKAGE_PIN D4 [get_ports {LED1[0]}]
  68. set_property PACKAGE_PIN E3 [get_ports {LED1[1]}]
  69. set_property PACKAGE_PIN D3 [get_ports {LED1[2]}]
  70. set_property PACKAGE_PIN F4 [get_ports {LED1[3]}]
  71. set_property PACKAGE_PIN F3 [get_ports {LED1[4]}]
  72. set_property PACKAGE_PIN E2 [get_ports {LED1[5]}]
  73. set_property PACKAGE_PIN D2 [get_ports {LED1[6]}]
  74. set_property PACKAGE_PIN H2 [get_ports {LED1[7]}]
  75. set_property PACKAGE_PIN G2 [get_ports {LEDBit[0]}]
  76. set_property PACKAGE_PIN C2 [get_ports {LEDBit[1]}]
  77. set_property PACKAGE_PIN C1 [get_ports {LEDBit[2]}]
  78. set_property PACKAGE_PIN H1 [get_ports {LEDBit[3]}]
  79. set_property PACKAGE_PIN G1 [get_ports {LEDBit[4]}]
  80. set_property PACKAGE_PIN F1 [get_ports {LEDBit[5]}]
  81. set_property PACKAGE_PIN E1 [get_ports {LEDBit[6]}]
  82. set_property PACKAGE_PIN G6 [get_ports {LEDBit[7]}]
  83. set_property IOSTANDARD LVCMOS33 [get_ports reset]
  84. set_property PACKAGE_PIN P2 [get_ports reset]
复制代码
设计要求


  • 主要功能

    • 模拟乒乓球比赛,用发光二极管(LED)模拟乒乓球运动轨迹,由甲乙双方参赛;
    • 用8个LED灯表示球桌,其中点亮的LED来回移动表示乒乓球的运动,球速可以调节;
    • 当球移动到最左侧或最右侧时,表示一方的击球位置。如果提前击球,或未及时击球,则对方得一分;
    • 甲乙得分使用数码管计分,一局11球;
    • 用发光二极管表示甲乙的发球权,每5分交换发球权。

  • 附加功能

    • 用发光二极管提示甲乙的接球和发球;
    • 比赛结束后,用数码管动态显示胜利的一方。

工作原理

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

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

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

游戏控制器模块


  • 模块功能:控制整个模拟器各组件状态;
  • 设计思路:该模块主要是用于控制比赛的进行。在设计中,使用status表示当前的比赛状态。010表示A发球,001表示B发球,110表示玩家A接球,101表示玩家B接球。这样的规定能够有效区分乒乓球不同的运动状态,并判定发/击球的有效性,同时显示在LED灯上来提示选手。另外再用accurateBallLocation [32:0]来表示球的精确位置,范围为$1000_{10} - 9000_{10} $,这样使球在LED显示的误差范围内,可以被击中。
  • 代码:
点击查看代码
  1. `timescale 1ns / 1ps
  2. module GameController(  //全局状态控制器
  3.     input CLK,
  4.     input reg hitA, //玩家A输入
  5.     input [1: 0] speedA, //玩家A速度
  6.     input reg hitB,  //玩家B输入
  7.     input [1: 0] speedB,  //玩家B速度
  8.     input reg serviceSide, //发球方
  9.     input reg reset,    //重置
  10.     output reg [2: 0] status, //全局状态
  11.     output reg [7: 0] ballLocation, //球位置
  12.     output reg getScoreA,   //A得分
  13.     output reg getScoreB    //B得分
  14.     );
  15.     reg hitATrigger;
  16.     reg hitBTrigger;
  17.     reg [2: 0] speed;
  18.     reg [15: 0] accurateBallLocation;
  19.     reg resetTrigger;
  20.     // reg serviceSide;
  21.     initial begin   //初始化变量
  22.         hitATrigger = 'b0;
  23.         hitBTrigger = 'b0;
  24.         status = 'b010;
  25.         accurateBallLocation = 'd2000;
  26.         speed = 'd2;
  27.         // serviceSide = 'b0;
  28.         getScoreA = 'b0;
  29.         getScoreB = 'b0;
  30.         resetTrigger = 'b0;
  31.     end
  32.     always @(posedge CLK) begin     //根据报告所述转换状态
  33.         if(resetTrigger == 'b0 && reset == 'b1) begin
  34.             hitATrigger = 'b0;
  35.             hitBTrigger = 'b0;
  36.             status = 'b010;
  37.             accurateBallLocation = 'd2000;
  38.             speed = 'd2;
  39.             // serviceSide = 'b0;
  40.             getScoreA = 'b0;
  41.             getScoreB = 'b0;
  42.         end
  43.         else begin
  44.             if(status == 'b010 || status == 'b001) begin//换发球
  45.                 status = serviceSide == 'b0 ? 'b010 : 'b001;
  46.                 getScoreA = 'b0;
  47.                 getScoreB = 'b0;
  48.             end
  49.             if(status == 'b010) begin //A发球
  50.                 accurateBallLocation = 'd2000;
  51.                 if(hitATrigger == 'b0 && hitA == 'b1) begin
  52.                     status = 'b101;
  53.                     if(speedA == 'd00) speed = 'd2;
  54.                     else speed = 'd4;
  55.                 end
  56.                 hitATrigger = hitA;
  57.             end
  58.             else if(status == 'b001) begin //B发球
  59.                 accurateBallLocation = 'd10000;
  60.                 if(hitBTrigger == 'b0 && hitB == 'b1) begin
  61.                     status = 'b110;
  62.                     if(speedB == 'd00) speed = 'd2;
  63.                     else speed = 'd4;
  64.                 end
  65.                 hitBTrigger = hitB;
  66.             end
  67.             else if(status == 'b110) begin //A接球
  68.                 if(hitATrigger == 'b0 && hitA == 'b1) begin
  69.                     if(accurateBallLocation >= 'd1000 && accurateBallLocation <= 'd3000) begin
  70.                         status = 'b101;
  71.                         if(speedA == 'd00) speed = 'd2;
  72.                         else speed = 'd4;
  73.                     end
  74.                 end
  75.                 hitATrigger = hitA;
  76.                 if(accurateBallLocation < 'd500) begin
  77.                     getScoreB = 'b1;
  78.                     status = serviceSide == 'b0 ? 'b010 : 'b001;
  79.                 end
  80.                 accurateBallLocation -= speed * 'd3;
  81.             end
  82.             else if(status == 'b101) begin //B接球
  83.                 if(hitBTrigger == 'b0 && hitB == 'b1) begin
  84.                     if(accurateBallLocation >= 'd9000 && accurateBallLocation <= 'd11000) begin
  85.                         status = 'b110;
  86.                         if(speedB == 'd00) speed = 'd2;
  87.                         else speed = 'd4;
  88.                     end
  89.                 end
  90.                 hitBTrigger = hitB;
  91.                 if(accurateBallLocation >'d11500) begin
  92.                     getScoreA = 'b1;
  93.                     status = serviceSide == 'b0 ? 'b010 : 'b001;
  94.                 end
  95.                 accurateBallLocation += speed * 'd3;
  96.             end
  97.         end
  98.         
  99.         resetTrigger = reset;
  100.         if(accurateBallLocation >= 'd2000 && accurateBallLocation < 'd3000) ballLocation = 'b10000000;//球的位置显示
  101.         if(accurateBallLocation >= 'd3000 && accurateBallLocation < 'd4000) ballLocation = 'b01000000;
  102.         if(accurateBallLocation >= 'd4000 && accurateBallLocation < 'd5000) ballLocation = 'b00100000;
  103.         if(accurateBallLocation >= 'd5000 && accurateBallLocation < 'd6000) ballLocation = 'b00010000;
  104.         if(accurateBallLocation >= 'd6000 && accurateBallLocation < 'd7000) ballLocation = 'b00001000;
  105.         if(accurateBallLocation >= 'd7000 && accurateBallLocation < 'd8000) ballLocation = 'b00000100;
  106.         if(accurateBallLocation >= 'd8000 && accurateBallLocation < 'd9000) ballLocation = 'b00000010;
  107.         if(accurateBallLocation >= 'd9000 && accurateBallLocation <= 'd10000) ballLocation = 'b00000001;
  108.     end
  109. endmodule
复制代码
时钟分频模块


  • 模块功能:对时钟分频;
  • 设计思路:将EG01100MHZ的时钟分频为1000HZ
  • 代码:
点击查看代码
  1. `timescale 1ns / 1ps
  2. module Player(CLK, EN, hit, speed, hitOut, speedOut);
  3.     input CLK, EN, hit, speed;
  4.     output reg hitOut;
  5.     output reg [1: 0] speedOut;
  6.     reg [31: 0] activeInterval = 'd1000;    //一个下降沿到下一个上升沿直接最小时间间隔
  7.     reg [31: 0] interval;
  8.     reg hitTrigger;
  9.     initial begin
  10.         interval = 'd0;
  11.         hitTrigger = 'b0;
  12.         hitOut = 'b0;
  13.         speedOut = 'b1;
  14.     end
  15.     always @(posedge CLK) begin
  16.         if(EN == 'b1) begin
  17.             if(hitTrigger =='b0 && hit == 'b1) begin
  18.                 if(interval >= activeInterval) begin
  19.                     hitOut = hit;
  20.                 end
  21.             end
  22.             else if(hitTrigger == 'b1 && hit == 'b0) begin
  23.                 interval = 'd0;
  24.                 hitOut = hit;
  25.             end
  26.             hitTrigger = hit;
  27.             interval += 1;
  28.             if(speed == 'b0) begin
  29.                 speedOut = 'd00;
  30.             end
  31.             else begin
  32.                 speedOut = 'd01;
  33.             end
  34.         end
  35.     end
  36. endmodule
复制代码
乒乓球控制模块


  • 模块功能:接受信号控制乒乓球从左向右移动,或者从右向左移动,并且可以根据玩家选择的击球速度去调整;
  • 设计思路:用8LED模拟,点亮的灯表示球的位置,然后像流水灯一样来回滚动,在发球时暂停。
  • 代码:这里实际上包括在了游戏控制,下面代码是调用其他的Main。
点击查看代码
  1. `timescale 1ns / 1ps
  2. module ClockDivider(originCLK, dividedCLK);
  3.     input originCLK;
  4.     output dividedCLK;
  5.     reg tempDivCLK;
  6.     reg [31: 0] count;
  7.     // reg [31: 0] ratio = 'd2;
  8.     reg [31: 0] ratio = 'd100_000;  //时钟分频器,将P17的100MHz分为1000Hz
  9.     initial begin
  10.         tempDivCLK = 'b0;
  11.         count = 'd0;
  12.     end
  13.     always @(posedge originCLK) begin
  14.         count = count + 1;
  15.         if(count == ratio)
  16.             count = 'd0;
  17.         
  18.         if(count == 'd0)
  19.             tempDivCLK = 'b0;
  20.         if(count == ratio / 2)
  21.             tempDivCLK = 'b1;
  22.     end
  23.     assign dividedCLK = tempDivCLK;
  24. endmodule
复制代码
分数处理模块


  • 模块功能:计数。每进行一轮控制分数加1,判断是否已打够11球,是则判别出获胜方。
  • 设计思路:在A,B两人分数上升沿时,对总分加1,然后判断是否已满11球。若满11球,比较判断出胜利的一方,随后将其状态传给显示模块用于显示结果。
  • 代码:
点击查看代码
  1. `timescale 1ns / 1ps
  2. module Main(
  3.     input CLK,
  4.     input hitA,
  5.     input speedA,
  6.     input hitB,
  7.     input speedB,
  8.     input reset,
  9.     output reg [3: 0] statusOut,
  10.     output wire [7: 0] ballLocation,
  11.     output wire [7:0] LED0,
  12.     output wire [7:0] LED1,
  13.     output wire [7:0] LEDBit
  14.     );
  15.     wire [2: 0] status;
  16.     wire dividedCLK;
  17.     wire [1: 0] speedOutA;
  18.     wire [1: 0] speedOutB;
  19.     wire getScoreA, getScoreB;
  20.     ClockDivider clockDivider(CLK, dividedCLK);
  21.     wire serviceSide;
  22.     reg EnA;
  23.     reg EnB;
  24.     initial begin
  25.         EnA = 'b1;
  26.         EnB = 'b1;
  27.     end
  28.     Player player1(dividedCLK, EnA, hitA, speedA, hitOutA, speedOutA);
  29.     Player player2(dividedCLK, EnB, hitB, speedB, hitOutB, speedOutB);
  30.     GameController gameController(  //调用全局状态控制器
  31.         dividedCLK,
  32.         hitOutA,
  33.         speedOutA,
  34.         hitOutB,
  35.         speedOutB,
  36.         serviceSide,
  37.         reset,
  38.         status,
  39.         ballLocation,
  40.         getScoreA,
  41.         getScoreB
  42.         
  43.     );
  44.     always @(posedge dividedCLK) begin
  45.         if(status == 'b010) begin
  46.             statusOut = 'b1000;
  47.         end
  48.         else if(status == 'b001) begin
  49.             statusOut = 'b0001;
  50.         end
  51.         else if(status == 'b110) begin
  52.             statusOut = 'b0100;
  53.         end
  54.         else if(status == 'b101) begin
  55.             statusOut = 'b0010;
  56.         end
  57.     end
  58.     reg [7:0][7:0] dataIn;
  59.     reg [31:0] count;
  60.     initial begin
  61.         count = 'd0;
  62.         while(count < 8) begin
  63.             dataIn[count] = 'd100;
  64.             count ++;
  65.         end
  66.         count = 'd0;
  67.     end
  68.     DigitalTubeDriver digitalTubeDriver(    //调用数码管驱动
  69.         dividedCLK,
  70.         dataIn,
  71.         LED0,
  72.         LED1,
  73.         LEDBit
  74.     );
  75.    
  76.     wire endGame;
  77.     wire [1:0] winner;
  78.     wire [15: 0] scoreA;
  79.     wire [15: 0] scoreB;
  80.     ScoreBoard scoreBoard(
  81.         dividedCLK,
  82.         getScoreA,
  83.         getScoreB,
  84.         reset,
  85.         serviceSide,
  86.         endGame,
  87.         winner,
  88.         scoreA,
  89.         scoreB
  90.     );
  91.     reg [7:0] i;
  92.     reg [7:0] j;
  93.     reg [31:0] countTemp;
  94.     reg [31:0] countTemp2;
  95.     reg resetTrigger;
  96.     reg [31: 0] flowLightCount;
  97.     reg endGameTrigger;
  98.     initial begin
  99.         resetTrigger = 'b0;
  100.         flowLightCount = 'd0;
  101.         endGameTrigger = 'd0;
  102.     end
  103.     always @(posedge dividedCLK) begin
  104.         
  105.         if(resetTrigger == 'b0 && reset == 'b1) begin
  106.             EnA = 'b1;
  107.             EnB = 'b1;
  108.             dataIn[2] = 'd100;//不显示
  109.             dataIn[3] = 'd100;
  110.             dataIn[4] = 'd100;
  111.             dataIn[5] = 'd100;
  112.             endGameTrigger = 'd0;
  113.         end
  114.         resetTrigger = reset;
  115.    
  116.         i = 'd0;
  117.         countTemp = scoreB;
  118.         while(i < 'd2) begin
  119.             dataIn[i] = countTemp % 'd10;
  120.             countTemp /= 'd10;
  121.             i++;
  122.         end
  123.         
  124.         j = 'd6;
  125.         countTemp2 = scoreA;
  126.         while(j < 'd8) begin
  127.             dataIn[j] = countTemp2 % 'd10;
  128.             countTemp2 /= 'd10;
  129.             j++;
  130.         end
  131.         
  132.         if(endGame == 'b1) begin    //游戏结束时显示箭头指向赢的玩家
  133.             if(endGameTrigger == 'b0) begin
  134.                 EnA = 'b0;
  135.                 EnB = 'b0;
  136.             end
  137.             if(winner == 'b10) begin
  138.                 case(flowLightCount)
  139.                     'd100: dataIn[2] = 'd22;//箭头
  140.                     'd200: dataIn[3] = 'd22;
  141.                     'd300: dataIn[4] = 'd22;
  142.                     'd400: dataIn[5] = 'd22;
  143.                 endcase
  144.                 flowLightCount++;
  145.                 if(flowLightCount == 'd500) begin
  146.                     flowLightCount = 'd0;
  147.                     dataIn[2] = 'd100;
  148.                     dataIn[3] = 'd100;
  149.                     dataIn[4] = 'd100;
  150.                     dataIn[5] = 'd100;
  151.                 end
  152.             end
  153.             else begin
  154.                 case(flowLightCount)
  155.                     'd100: dataIn[5] = 'd21;//箭头
  156.                     'd200: dataIn[4] = 'd21;
  157.                     'd300: dataIn[3] = 'd21;
  158.                     'd400: dataIn[2] = 'd21;
  159.                 endcase
  160.                 flowLightCount++;
  161.                 if(flowLightCount == 'd500) begin
  162.                     flowLightCount = 'd0;
  163.                     dataIn[2] = 'd100;
  164.                     dataIn[3] = 'd100;
  165.                     dataIn[4] = 'd100;
  166.                     dataIn[5] = 'd100;
  167.                 end
  168.             end
  169.         end
  170.         endGameTrigger = endGame;
  171.     end
  172. endmodule
复制代码
数码管显示模块


  • 模块功能:利用数码管显示比赛数据;
  • 设计思路:使用$ 8 * 8 $的矩阵显示每个数码管的显示情况,另外设有对每个数码管表示显示的标志,从而动态地去更新。在有一方获胜后,会将不显示分数的数码管动态地闪烁箭头,以此来表示获胜的一方。
  • 代码:
点击查看代码
  1. `timescale 1ns / 1ps
  2. module ScoreBoard(
  3.     input CLK,
  4.     input getScoreA,
  5.     input getScoreB,
  6.     input reset,
  7.     output reg serviceSide,
  8.     output reg endGame,
  9.     output reg [1:0] winner,
  10.     output reg [15: 0] scoreA,
  11.     output reg [15: 0] scoreB
  12.     );
  13.     reg getScoreATrigger;
  14.     reg getScoreBTrigger;
  15.     reg resetTrigger;
  16.     initial begin
  17.         serviceSide = 'b0;
  18.         endGame = 'b0;
  19.         getScoreATrigger = 'b0;
  20.         getScoreBTrigger = 'b0;
  21.         scoreA = 'b0;
  22.         scoreB = 'b0;
  23.         resetTrigger = 'b0;
  24.     end
  25.     always @(posedge CLK) begin
  26.         if(resetTrigger == 'b0 && reset == 'b1) begin
  27.             serviceSide = 'b0;
  28.             endGame = 'b0;
  29.             getScoreATrigger = 'b0;
  30.             getScoreBTrigger = 'b0;
  31.             scoreA = 'b0;
  32.             scoreB = 'b0;
  33.         end
  34.         else begin  //getScoreA或getScoreB出现上升沿,对应玩家得分
  35.             if(getScoreATrigger == 'b0 && getScoreA == 'b1)
  36.                 scoreA ++;
  37.             if(getScoreBTrigger == 'b0 && getScoreB == 'b1)
  38.                 scoreB ++;
  39.             getScoreATrigger = getScoreA;
  40.             getScoreBTrigger = getScoreB;
  41.             
  42.             if((scoreA + scoreB) / 5 % 2 == 'd0)    //每5个球换发
  43.                 serviceSide = 'b0;
  44.             else
  45.                 serviceSide = 'b1;
  46.             if(scoreA + scoreB == 'd11) //到达11个球时游戏结束
  47.                 endGame = 'b1;
  48.             if(endGame == 1) begin  //游戏结束时判断赢的那方
  49.                 if(scoreA > scoreB)
  50.                 winner = 'b10;
  51.                 else if(scoreA < scoreB)
  52.                 winner = 'b01;
  53.                 else
  54.                 winner = 'b11;
  55.             end
  56.             else begin
  57.                 winner = 'b00;
  58.             end
  59.         end
  60.         
  61.         resetTrigger = reset;
  62.     end
  63. 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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王柳

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表