没有复位Verilog HDL逻辑程序的编写

       今天收到一个朋友的请求,帮忙看他们学校自制的一个Cyclone I 的古老的板子,仔细一看板子的电路原理图,没有按键、没有拨码开关、没有复位,整个板子的芯片外围电路只有四个共阴极的七段数码管和16个LED灯,需要编写一个代码测试一下。

        功能要求如下:

         (1)板子的输入端口之后一个时钟信号 clk ,输出信号为四位的位选信号 sel,八位的段选信号 seg;

         (2)板子上电之后的最初状态是4个数码管显示 0000,随后,最左边两个数码管显示 59,表征 59 分钟,最右边两个数码管显示 59,表示 59 秒,每隔 1 秒,数码管秒计数减 1 ,直到最后显示为 0000 。其实质就是倒计时 1 小时,周而复始。

        总结:

        这个逻辑挺简单的,本质上就是计数器的应用,困难的地方在于没有复位,无论是同步复位还是异步复位都没有,所以就需要用到寄存器赋初值的知识点,这里用到了initial 语句来赋初值。如  initial   count = 4'd0;

        实验结果证明,即便是没有复位也是可以实现逻辑控制的,initial 在一些场合也是可以被综合的。

Verilog HDL 程序如下:

  1 // *********************************************************************************
  2 // Project Name : 
  3 // Email        : 
  4 // Create Time  : 2020// :
  5 // Module Name  : 
  6 // editor       : Qing
  7 // Version      : Rev1.0.0
  8 // *********************************************************************************
  9 
 10 
 11 module count_disp(
 12     input                           clk         ,
 13 
 14     output          reg[3:0]        sel         ,
 15     output          reg[7:0]        seg
 16     );
 17 
 18 //========================================================================
 19 // =========== Define Parameter and Internal signals =========== 
 20 //========================================================================/
 21 
 22 
 23 reg                 [27:0]          cnt         ;
 24 reg                 [7:0]           cnt_miao    ;
 25 reg                 [7:0]           cnt_fen     ;
 26 reg                 [15:0]          cnt_move    ;
 27 reg                 [2:0]           cnt_sel     ;
 28 reg                 [3:0]           disp_data   ;
 29 
 30 wire                [3:0]           l_miao      ;
 31 wire                [3:0]           h_miao      ;
 32 wire                [3:0]           l_fen       ;
 33 wire                [3:0]           h_fen       ;
 34 
 35 
 36 //=============================================================================
 37 //****************************     Main Code    *******************************
 38 //=============================================================================
 39 
 40 initial cnt_move = 16'd0;
 41 always @(posedge clk) begin
 42     if(cnt_move == 49999) // 49999
 43         cnt_move <= 16'd0;
 44     else
 45         cnt_move <= cnt_move + 1'b1;
 46 end
 47 
 48 initial cnt_sel = 3'd0;
 49 always @(posedge clk) begin
 50     if(cnt_move == 49999) begin
 51         if(cnt_sel == 3'd3)
 52             cnt_sel <= 3'd0;
 53         else
 54             cnt_sel <= cnt_sel + 1'b1;
 55     end
 56     else
 57         cnt_sel <= cnt_sel;
 58 end
 59 
 60 initial cnt = 28'd0;
 61 always @(posedge clk ) begin
 62     if(cnt == 49999999)  // 49999999
 63         cnt <= 28'd0;
 64     else 
 65         cnt <= cnt + 1'b1;
 66 end
 67 
 68 
 69 initial cnt_miao = 8'd59;
 70 always @(posedge clk) begin
 71     if(cnt == 49999999) begin  //////////////
 72         if(cnt_miao == 0)
 73             cnt_miao <= 59;
 74         else
 75             cnt_miao <= cnt_miao - 1'b1;
 76     end
 77     else
 78         cnt_miao <= cnt_miao;
 79 end
 80 
 81 initial cnt_fen = 8'd59;
 82 always @(posedge clk ) begin
 83     if((cnt_miao == 0) && (cnt == 49999999)) begin //////////
 84         if(cnt_fen == 0)
 85             cnt_fen <= 8'd59;
 86         else
 87             cnt_fen <= cnt_fen - 1'b1;
 88     end
 89     else
 90         cnt_fen <= cnt_fen;
 91 end
 92 
 93 assign l_miao  = cnt_miao % 10;
 94 assign h_miao  = cnt_miao / 10 % 10;
 95 
 96 assign l_fen   = cnt_fen % 10;
 97 assign h_fen   = cnt_fen / 10 % 10;
 98 
 99 
100 initial sel = 4'b1111;
101 initial disp_data = 4'd0;
102 always @(posedge clk) begin
103     if(cnt_move == 49999) begin
104         case(cnt_sel)
105             0: begin sel <= 4'b0001; disp_data <= l_miao; end  // 共阴极
106             1: begin sel <= 4'b0010; disp_data <= h_miao; end
107             2: begin sel <= 4'b0100; disp_data <= l_fen ; end
108             3: begin sel <= 4'b1000; disp_data <= h_fen ; end
109             default: begin sel <= 4'b1111; disp_data <= 4'd0; end
110         endcase
111     end
112 end
113 
114 always @(posedge clk) begin
115     case(disp_data)
116         0: seg <= 8'h3f;
117         1: seg <= 8'h06;
118         2: seg <= 8'h5B;
119         3: seg <= 8'h4F;
120         4: seg <= 8'h66;
121         5: seg <= 8'h6D;
122         6: seg <= 8'h7D;
123         7: seg <= 8'h07;
124         8: seg <= 8'h7F;
125         9: seg <= 8'h6F;
126         default: seg <= 8'h3f;
127     endcase
128 end
129 
130 
131 endmodule
View Code

testbench如下:

 1 `timescale 1ns/1ps
 2 
 3 module count_disp_tb;
 4     reg                            clk                ;  //  时钟信号
 5 
 6     wire            [3:0]        sel                ;  //  段选信号
 7     wire            [7:0]        seg                ;  //  位选信号
 8 
 9 count_disp count_disp_inst(
10    .clk  ( clk     ),
11    .sel  ( sel     ),
12    .seg  ( seg     )
13    );
14 
15 initial
16     clk = 1'b0;
17     always #10 clk = ~clk;
18 
19 endmodule
View Code
原文地址:https://www.cnblogs.com/571328401-/p/14772801.html