IT评测·应用市场-qidao123.com技术社区

标题: 蓝桥杯FPGA赛道模拟题1之步伐设计题代码 [打印本页]

作者: 来自云龙湖轮廓分明的月亮    时间: 2025-4-14 09:00
标题: 蓝桥杯FPGA赛道模拟题1之步伐设计题代码
1.顶层文件

  1. module test(
  2. input  wire sys_clk,
  3. input  wire sys_rst,
  4. input  wire [3:0]key_in,
  5. output wire [7:0]sel,
  6. output wire [7:0]seg,
  7. output reg  [7:0]led
  8. );
  9. //定义状态
  10. localparam STOP=3'd0;
  11. localparam START=3'd1;
  12. localparam PAUSE=3'd2;
  13. //signals define
  14. wire [4:0]  d_count;
  15. wire [3:0]   key_data;
  16. reg  [31:0] data;
  17. reg    en_count;
  18. reg    rst_count;
  19. reg  [2:0] st_count;
  20. reg  [7:0] u_count1;
  21. reg   [7:0] u_count2;
  22. reg   [23:0]led_count;
  23. cdown cdown_inst(
  24. .sys_clk  (sys_clk  ),
  25. .sys_rst  (sys_rst  ),
  26. .count_en  (en_count),
  27. .count_rst  (rst_count),
  28. .count     (d_count)
  29. );
  30. seg seg_inst(
  31.         .clk      (sys_clk),
  32.         .rst      (sys_rst),
  33.         .seg      (seg),
  34.         .sel      (sel),
  35.         .dsp_data (data)
  36.         );
  37. key key_inst(
  38.         .sys_clk (sys_clk),
  39.         .sys_rst (sys_rst),
  40.         .key_in  (key_in),
  41.         .key_data (key_data)
  42. );
  43. //LED
  44. always @(posedge sys_clk or negedge sys_rst)begin
  45.         if(sys_rst==1'b0)begin
  46.                 led<=8'b1111_1111;
  47.                 led_count<=0;
  48.         end else begin
  49.                 if(st_count==STOP)//停止状态
  50.                   led<=8'b1111_1111;
  51.                 else if(st_count==START)//开始状态灯亮
  52.                   led<=8'b1111_1110;  
  53.                 else begin
  54.                    if(led_count==24'd5_000_000)begin
  55.                         led_count<=0;
  56.                         led<=led ^ 8'b0000_0001;//led灯每隔0.01秒闪烁
  57.             end else
  58.                         led_count<=led_count+1;
  59.                 end
  60.         end
  61. end
  62. //seg
  63. always @(posedge sys_clk or negedge sys_rst)begin
  64.         if(sys_rst==1'b0)
  65.         data <={4'd2,4'd0,4'd10,4'd0,4'd0,4'd11,4'd0,4'd0};
  66.         else begin
  67.                 data[31:28]<=d_count/10;
  68.                 data[27:24]<=d_count%10;
  69.                 data[19:16]<=u_count1/10;
  70.                 data[15:12]<=u_count1%10;
  71.                 data[7:4]<=u_count2/10;
  72.                 data[3:0]<=u_count2%10;
  73.         end
  74. end
  75. //KEY
  76. always @(posedge sys_clk or negedge sys_rst)begin
  77.      if(sys_rst==1'b0)begin
  78.           u_count1<=8'b0;
  79.           u_count2<=8'b0;
  80.           en_count<=1'b0;
  81.           st_count<=STOP;
  82.         end else begin
  83.                 case(key_data)//状态更新
  84.                 4'b0001:     begin
  85.                                                                 if(st_count==START)//如果当前按键状态处于开始,则按下按键1计数器1加1
  86.                                                                         u_count1<=u_count1+8'd1;
  87.                                                  end
  88.                 4'b0010:     begin
  89.                                                                 if(st_count==START)//如果当前状态处于处于开始,按下按键三计数器加1
  90.                                                                         u_count2<=u_count2+8'd1;
  91.                                                  end
  92.                 4'b0100:     begin
  93.                                                                 if(st_count==STOP)begin//如果处于停止状态,则下一个状态切换到开始状态
  94.                                                                 en_count<=1'b1;
  95.                                                                 st_count<=START;
  96.                                                                 rst_count<=1'b1;
  97.                                                                 end else if((st_count==START)&&(d_count!=4'd0))begin//如果当前状态处于开始状态,并且倒计时计数器不为0则切换到停止状态,并且倒计时计数器停止计数
  98.                                                         st_count<=PAUSE;
  99.                                                         en_count<=1'b0;
  100.                                                         end else if(st_count==PAUSE)begin//否则如果当前状态处于停止状态,则下一个状态切换到开始状态,继续使能倒计时计数器
  101.                                                         st_count<=START;
  102.                                                         en_count<=1'b1;
  103.                                                 end
  104.                                         end
  105.                 endcase
  106.         if((st_count==START)&&(d_count==4'd0))begin//没有任何按键按下时,如果处于开始状态,并且倒计时计数器自动计数记到0,自动切换到停止状态
  107.                         st_count<=STOP;
  108.                         en_count<=1'b0;
  109.                         rst_count<=1'b0;
  110.                 end  
  111.         end  
  112. end                                                          
  113. endmodule
复制代码
 2、计数模块

  1. module cdown(
  2. input wire sys_clk,
  3. input wire sys_rst,
  4. input wire count_en,
  5. input wire count_rst,
  6. output reg [4:0] count
  7. );
  8. localparam COUNT_MAX_1S=28'd50_000_000;
  9. localparam COUNT_MAX_10=5'd20;
  10. reg [27:0] count_reg;
  11. //1s计数器
  12. always @(posedge sys_clk or negedge sys_rst)begin
  13.         if(sys_rst==1'b0)
  14.                 count_reg<=0;
  15.         else begin
  16.                 if(count_en==1'b1)begin
  17.                         if(count_reg==COUNT_MAX_1S-1)
  18.                                 count_reg<=0;
  19.                         else
  20.                                 count_reg<=count_reg+1;
  21.                 end
  22.         end
  23. end
  24. //倒计时器
  25. always @(posedge sys_clk or negedge sys_rst)begin
  26.         if(sys_rst==1'b0)begin
  27.                 count<=5'd20;
  28.         end else begin
  29.                 if(count_en==1'b1)begin
  30.                  if((count_reg==COUNT_MAX_1S-1)&&(count!=0))begin
  31.                                 count<=count-1;
  32.                  end
  33.          end else if(count_rst==1'b0)
  34.                         count<=5'd20;
  35.         end
  36. end
  37. endmodule
复制代码
3.按键模块

  1. module key(
  2.     input   wire                sys_clk,
  3.     input   wire                sys_rst,
  4.     input   wire    [3:0]       key_in,
  5.          output reg      [3:0]                  key_data
  6. );
  7. //按键键值定义
  8. localparam  KEY_VAL_S1 =4'b0001;
  9. localparam  KEY_VAL_S2 =4'b0010;
  10. localparam  KEY_VAL_S3 =4'b0100;
  11. localparam  KEY_VAL_S4=4'b1000;
  12. localparam  KEY_VAL_NL=4'b1111;
  13. localparam  KEY_COUNT_MAX =20'd500000;
  14. //按键状态定义
  15. localparam  IDLE      =3'd0;
  16. localparam  PRESS     =3'd1;
  17. localparam  RELEASE   =3'd2;
  18. //按键扫描计数器,每隔0.01秒扫描一次按键
  19. reg [19:0]   key_count;
  20. //寄存器的定义用来存储不同的状态
  21. reg [3:0]    key_status;
  22. //按键计数更新
  23. always@(posedge sys_clk or negedge sys_rst) begin
  24.     if(sys_rst==1'b0)
  25.         key_count <=0;
  26.         else begin
  27.              if(key_count == KEY_COUNT_MAX-1)begin
  28.                 key_count <= 0;
  29.             end else
  30.                 key_count = key_count + 1;   
  31.         end
  32.     end
  33. //按键状态更新
  34. always@(posedge sys_clk or negedge sys_rst)begin
  35.     if(sys_rst==1'b0)begin//复位
  36.         key_data <= KEY_VAL_NL;
  37.                   key_status<=IDLE;
  38.          end else begin
  39.     if(key_data == KEY_VAL_NL) begin
  40.                         if(key_count==KEY_COUNT_MAX-1)begin
  41.                                 if(key_status==IDLE)begin//当前没有按键时,并且按键扫描时间到,进行判断
  42.                                 if(key_in!=4'b1111)//当按键键不等于1111
  43.                                                 key_status<=PRESS;//按键处于按下状态
  44.                                    end  else if(key_status==PRESS)begin//在有按键按下,赋予键值
  45.                                                         case(key_in)
  46.                                                                 4'b1110: begin key_data <=KEY_VAL_S1; key_status <=RELEASE; end
  47.                                                                 4'b1101: begin key_data <=KEY_VAL_S2; key_status <=RELEASE; end
  48.                                                                 4'b1011: begin key_data <=KEY_VAL_S3; key_status <=RELEASE; end
  49.                                                                 4'b0111: begin key_data <=KEY_VAL_S4; key_status <=RELEASE; end
  50.                                                                 default: begin key_data <=KEY_VAL_NL; key_status <=IDLE;    end
  51.                                                         endcase
  52.                                         end else begin
  53.                                                         if(key_in == 4'b1111)
  54.                                                                         key_status <=IDLE;
  55.                                                         end
  56.                                                 end
  57.                                         end else
  58.                                              key_data <=KEY_VAL_NL;
  59.                                 end
  60.                         end
  61. endmodule
复制代码
4.数码管

  1. module seg
  2. (
  3.         input           wire                       clk                                                ,
  4.         input         wire                            rst                                                ,
  5.         input         wire        [31:0]         dsp_data                                ,
  6.         output         reg         [7:0]         seg                                        ,//段选端
  7.         output         reg         [7:0]         sel                                        //位选段
  8. );
  9.        
  10. /*
  11. localparam         SEG_0 = 8'b1100_0000, SEG_1 = 8'b1111_1001,
  12.                                 SEG_2 = 8'b1010_0100, SEG_3 = 8'b1011_0000,
  13.                                 SEG_4 = 8'b1001_1001, SEG_5 = 8'b1001_0010,
  14.                                 SEG_6 = 8'b1000_0010, SEG_7 = 8'b1111_1000,
  15.                                 SEG_8 = 8'b1000_0000, SEG_9 = 8'b1001_0000,
  16.                                 SEG_A = 8'b1000_1000, SEG_B = 8'b1000_0011,
  17.                                 SEG_C = 8'b1100_0110, SEG_D = 8'b1010_0001,
  18.                                 SEG_E = 8'b1000_0110, SEG_F = 8'b1000_1110,
  19.                                 SEG_X = 8'b1011_1111;        //-
  20. */
  21. localparam [7:0] DIGIT0 =8'b1100_0000 ;
  22. localparam [7:0] DIGIT1 =8'b1111_1001 ;
  23. localparam [7:0] DIGIT2 =8'b1010_0100;
  24. localparam [7:0] DIGIT3 =8'b1011_0000;
  25. localparam [7:0] DIGIT4 =8'b1001_1001;
  26. localparam [7:0] DIGIT5 =8'b1001_0010;
  27. localparam [7:0] DIGIT6 =8'b1000_0010;
  28. localparam [7:0] DIGIT7 =8'b1111_1000;
  29. localparam [7:0] DIGIT8 =8'b1000_0000;
  30. localparam [7:0] DIGIT9 =8'b1001_0000 ;
  31. localparam [7:0] DIGITX =8'b1011_1111 ;
  32. localparam [7:0] DIGOFF =8'b1111_1111 ;
  33. localparam                 DSP_COUNT = 20'd50000; //
  34. //reg define
  35. /*
  36. localparam         SEG_C7 = 8'b0000_0001,
  37.                                 SEG_C6 = 8'b0000_0010,
  38.                                 SEG_C5 = 8'b0000_0100,
  39.                                 SEG_C4 = 8'b0000_1000,
  40.                                 SEG_C3 = 8'b0001_0000,
  41.                                 SEG_C2 = 8'b0010_0000,
  42.                                 SEG_C1 = 8'b0100_0000,
  43.                                 SEG_C0 = 8'b1000_0000;
  44. */
  45. /* */
  46. reg         [19:0]         dsp_count                                ;
  47. reg         [3:0]           bits                                        ;
  48. reg         [3:0]                bcd                                ;
  49. reg         [31:0]        dsp_reg                                                ;
  50. reg         [7:0]         dsp_code                                ;
  51. //1ms的计数器               
  52. always @(posedge clk or negedge rst)begin        
  53.         if(!rst)
  54.                 dsp_count <= 20'd0;
  55.         else begin
  56.                 if (dsp_count == DSP_COUNT-1) begin
  57.                         dsp_count <= 20'd0;
  58.                 end else
  59.                         dsp_count <= dsp_count + 20'd1;
  60.                 end       
  61. end                
  62. //               
  63. always @(posedge clk or negedge rst) begin
  64.          if(!rst)begin
  65.            sel <= 8'b1111_1111;
  66.                 bits <=4'd0;
  67.          end else begin
  68.             if(dsp_count==DSP_COUNT-1)begin//每一毫秒更新一次
  69.                     bits<=bits+4'd1;
  70.                  if(bits==4'd8)
  71.                     bits <=4'd0;
  72.                  case(bits)
  73.                                  4'd0: begin sel<=8'b1111_1110;bcd<=dsp_data[31:28] ;end
  74.                                  4'd1: begin sel<=8'b1111_1101;bcd<=dsp_data[27:24] ;end
  75.                                  4'd2: begin sel<=8'b1111_1011;bcd<=dsp_data[23:20] ;end
  76.                                  4'd3: begin sel<=8'b1111_0111;bcd<=dsp_data[19:16] ;end
  77.                                  4'd4: begin sel<=8'b1110_1111;bcd<=dsp_data[15:12] ;end
  78.                                  4'd5: begin sel<=8'b1101_1111;bcd<=dsp_data[11:8] ;end
  79.                                  4'd6: begin sel<=8'b1011_1111;bcd<=dsp_data[7:4] ;end
  80.                                  4'd7: begin sel<=8'b0111_1111;bcd<=dsp_data[3:0] ;end
  81.                  default:sel<=8'b1111_1111;
  82.             endcase
  83.          end
  84.   end
  85. end
  86. always @(posedge clk or negedge rst)begin
  87.         if(!rst)
  88.                 seg<=DIGOFF;
  89.   else begin
  90.                 case(bcd)
  91.                         4'd0: seg<=DIGIT0;
  92.                         4'd1: seg<=DIGIT1;
  93.                         4'd2: seg<=DIGIT2;
  94.                         4'd3: seg<=DIGIT3;
  95.                         4'd4: seg<=DIGIT4;
  96.                         4'd5: seg<=DIGIT5;
  97.                         4'd6: seg<=DIGIT6;
  98.                         4'd7: seg<=DIGIT7;
  99.                         4'd8: seg<=DIGIT8;
  100.                         4'd9: seg<=DIGIT9;
  101.                         4'ha: seg<=DIGOFF;
  102.                         4'hb: seg<=DIGITX;
  103.                 default: seg<=DIGOFF;
  104.         endcase
  105.   end
  106. end
  107. endmodule               
复制代码
5.引脚束缚


 声明:本代码有参考网上的资料,如有侵权请联系作者删除,此外作者水平有限,如果错误请联系作责纠正

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4