在数字中的设计中BCD计数是核心部分,不仅要按照秒、分、时、天、月方式计数,还要考虑到计数的矫正(包括初始化矫正等)。因此本部分程序要与预定义按键的功能相结合。设计的思路如下:
- 采用自顶向下的设计方法
- 采用模块例化的方法,使代码可以重用。
- 子模块按功能方式例化传递不同的参数。
顶层代码如下:
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码计数器:
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。