在数字中的设计中BCD计数是核心部分,不仅要按照秒、分、时、天、月方式计数,还要考虑到计数的矫正(包括初始化矫正等)。因此本部分程序要与预定义按键的功能相结合。设计的思路如下:
- 采用自顶向下的设计方法
- 采用模块例化的方法,使代码可以重用。
- 子模块按功能方式例化传递不同的参数。
顶层代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
module count ( input rst, input clk, input s_p, input sw_in_l, input sw_in_r, input sw_in_p, input sw_in_m, output [ 3: 0 ] s_out_l, output [ 3: 0 ] s_out_h, output [ 3: 0 ] m_out_l, output [ 3: 0 ] m_out_h, output [ 3: 0 ] h_out_l, output [ 3: 0 ] h_out_h, output [ 3: 0 ] d_out_l, output [ 3: 0 ] d_out_h, output [ 3: 0 ] mh_out_l, output [ 3: 0 ] mh_out_h, output reg [ 9: 0 ] dp_out_pos ); wire m_p; wire h_p; wire d_p; wire mh_p; always@( posedge clk or posedge rst ) if ( rst ) begin dp_out_pos <= 10'b1; end else begin if ( dp_out_pos == 0 ) dp_out_pos <= 10'b1; if ( sw_in_l ) if ( !dp_out_pos[ 9 ] ) begin dp_out_pos <= { dp_out_pos[ 8: 0 ], dp_out_pos[ 9] }; end if ( sw_in_r ) if ( !dp_out_pos[ 0 ] ) begin dp_out_pos <= { dp_out_pos[ 0 ], dp_out_pos[ 9: 1 ] }; end end counter #( .RADIX1( 9 ), .RADIX2( 5 ), .RADIX3( 0 ) ) counter_second ( .rst ( rst ), .clk ( clk ), .dp_in_pos( dp_out_pos[ 1: 0 ] ), .sw_in_p ( sw_in_p ), .sw_in_m ( sw_in_m ), .x_in_p ( s_p ), .x_out_l ( s_out_l ), .x_out_h ( s_out_h ), .x_out_p ( m_p ) ); counter #( .RADIX1( 9 ), .RADIX2( 5 ), .RADIX3( 0 ) ) counter_minute ( .rst ( rst ), .clk ( clk ), .dp_in_pos( dp_out_pos[ 3: 2 ] ), .sw_in_p ( sw_in_p ), .sw_in_m ( sw_in_m ), .x_in_p ( m_p ), .x_out_l ( m_out_l ), .x_out_h ( m_out_h ), .x_out_p ( h_p ) ); counter #( .RADIX1( 3 ), .RADIX2( 2 ), .RADIX3( 3 ) ) counter_hour ( .rst ( rst ), .clk ( clk ), .dp_in_pos ( dp_out_pos[ 5: 4 ] ), .sw_in_p ( sw_in_p ), .sw_in_m ( sw_in_m ), .x_in_p ( h_p ), .x_out_l ( h_out_l ), .x_out_h ( h_out_h ), .x_out_p ( d_p ) ); counter #( .RADIX1( 1 ), .RADIX2( 3 ), .RADIX3( 2 ) ) counter_day ( .rst ( rst ), .clk ( clk ), .dp_in_pos ( dp_out_pos[ 7: 6 ] ), .sw_in_p ( sw_in_p ), .sw_in_m ( sw_in_m ), .x_in_p ( d_p ), .x_out_l ( d_out_l ), .x_out_h ( d_out_h ), .x_out_p ( mh_p ) ); counter #( .RADIX1( 2 ), .RADIX2( 1 ), .RADIX3( 1 ) ) counter_month ( .rst ( rst ), .clk ( clk ), .dp_in_pos( dp_out_pos[ 9: 8 ] ), .sw_in_p ( sw_in_p ), .sw_in_m ( sw_in_m ), .x_in_p ( mh_p ), .x_out_l ( mh_out_l ), .x_out_h ( mh_out_h ), .x_out_p () ); endmodule |
两位BCD码计数器:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
module counter #( parameter RADIX1 = 9, parameter RADIX2 = 5, parameter RADIX3 = 0 // 0 => second or minute; 1 => month; 2 => day ; 3 => hour. ) ( input rst, input clk, input [ 1: 0 ] dp_in_pos, // position input sw_in_p, // button ++ input sw_in_m, // button -- input x_in_p, // x input pulse enable carry_in output reg[ 3: 0 ] x_out_l, output reg[ 3: 0 ] x_out_h, output reg[ 3: 0 ] month, output reg x_out_p // carry out ); always@( posedge clk or posedge rst ) if ( rst ) begin x_out_l <= (RADIX3 == 2 || RADIX3 == 1 ) ? 1 : 0; x_out_h <= 0; x_out_p <= 1'b0; month <= 1; end else begin x_out_p <= 1'b0; if ( sw_in_p ) // button ++ begin if ( dp_in_pos[ 0 ] ) begin // if ( x_out_l == RADIX1 ) x_out_l <= 0; if ( x_out_l == 9 ) x_out_l <= 0; else x_out_l <= x_out_l + 1; end else if ( dp_in_pos[ 1 ] ) begin // if ( x_out_h == RADIX2 ) x_out_h <= 0; if ( x_out_h == 9 ) x_out_h <= 0; else x_out_h <= x_out_h + 1; end end if ( sw_in_m ) // button -- begin if ( dp_in_pos[ 0 ] ) begin // if ( x_out_l == 0 ) x_out_l <= RADIX1; if ( x_out_l == 0 ) x_out_l <= 9; else x_out_l <= x_out_l - 1; end else if ( dp_in_pos[ 1 ] ) begin // if ( x_out_h == 0 ) x_out_h <= RADIX2; if ( x_out_h == 0 ) x_out_h <= 9; else x_out_h <= x_out_h - 1; end end if ( x_in_p ) begin if ( RADIX3 == 0 ) begin if ( x_out_l == RADIX1 ) begin x_out_l <= 0; if ( x_out_h == RADIX2 ) begin x_out_h <= 0; x_out_p <= 1'b1; end else x_out_h <= x_out_h + 1; end else x_out_l <= x_out_l + 1; end else if (( RADIX3 == 1 )||( RADIX3 == 3 )) begin if ( ( x_out_l == RADIX1 ) && ( x_out_h == RADIX2 ) ) begin x_out_l <= (RADIX3 == 1) ? 1'b1 : 1'b0; x_out_h <= 0; x_out_p <= 1'b1; end else if ( x_out_l == 9 ) begin x_out_l <= 0; x_out_h <= x_out_h + 1; end else x_out_l <= x_out_l + 1; end else if ( RADIX3 == 2 ) begin case ( month ) 1, 3, 5, 7, 8, 10, 12: begin if ( ( x_out_l == 1 ) && ( x_out_h == 3 ) ) begin x_out_l <= 1; x_out_h <= 0; x_out_p <= 1'b1; month <= month + 1; end else begin if ( x_out_l == 9 ) begin x_out_l <= 0; x_out_h <= x_out_h + 1; end else x_out_l <= x_out_l + 1; end end 2:// possibly developed for leap year adjustment begin if ( ( x_out_l == 8 ) && ( x_out_h == 2 ) ) begin x_out_l <= 1; x_out_h <= 0; x_out_p <= 1'b1; month <= month + 1; end else begin if ( x_out_l == 9 ) begin x_out_l <= 0; x_out_h <= x_out_h + 1; end else x_out_l <= x_out_l + 1; end end 4, 6, 9, 11: begin if ( ( x_out_l == 0 ) && ( x_out_h == 3 ) ) begin x_out_l <= 1; x_out_h <= 0; x_out_p <= 1'b1; month <= month + 1; end else begin if ( x_out_l == 9 ) begin x_out_l <= 0; x_out_h <= x_out_h + 1; end else x_out_l <= x_out_l + 1; end end default: month <= 1; endcase end end end endmodule |
在本系统程序设计时采用信号或输入、输出端口的命名方法如下:
(1)对变量的定义一般采用多个能体现变量含义的单词或缩写,中间采用下划线”_”级联,如:sw_in_l(按键-输入-左),sw_in_r(按键-输入-右)。
(2)对接口设计的输入端一般都采用“in”指示信号的方向为输入。如:sw_in_r。
(3)对接口的输出端一般都采用“out”指示信号的方向为输出。 如:sw_out_r。
(4)对于模块之间的级联的变量,设为中性,即不带“in”或“out”标志。如:h_p。