Verilog應用——24秒籃球計數器

設計思路

    需要一個模3計數器和模10計數器,這裏需要設計一個可變模數的計數器,並對兩個計數器進行級聯。顯示模塊則採用最常用的七段顯示器,這裏需要注意的是,當十位數爲0時,應該令顯示器熄滅,合理控制計數器控制端即可。

變模計數器

思路

採用行爲級建模。

代碼實現

設計模塊

//filename:_24count.v
module varmodcnt(CP,CLR,EN,Q,carry_out);
parameter n=4,MOD=10;
input CP,CLR,EN;
output reg[n-1:0] Q;
output carry_out;
/*參數說明:
輸入:CP爲時鐘信號,CLR爲清零信號,EN爲使能信號
輸出:Q爲輸出,carry_out爲進位信號
*/
//敏感信號:CP上升沿,CLR下降沿
always@(posedge CP,negedge CLR)
begin
	if(!CLR)    Q<='d0;//置零
	else if(!EN)    Q<=Q; //保持
	else begin
	    if(Q==MOD-1)    Q<='d0;  //達到MOD-1,歸零
	    else	    Q<=Q+1;//未達到MOD-1時,加一
	end
end
assign carry_out=(Q==MOD-1);  //Q=MOD-1時,進位信號有效
endmodule

module _24count(
input CP,
input CR,
output [3:0]Q0,Q1);
/*端口說明:
輸入:
CP爲時鐘信號,CR爲輸入清零信號
輸出:
Q1爲十位上數字對應的四位二進制,Q0爲十位上數字對應的四位二進制數
*/
//中間變量:TC進位信號,CLR爲爲24模的清零信號
wire TC0,TC1;
wire CLR;

varmodcnt #(4,10) U0(CP,CLR,EN,Q0,TC0);   //個位信號
varmodcnt #(4,3) U1(CP,CLR,TC0,Q1,TC1);   //十位信號
assign CLR=CR&(~({Q1,Q0}==8'b0010_0101));   //當外部清零信號有效或者輸出爲24時,進行清零
endmodule

測試模塊

//filename:tb_24count
`timescale 100ms/10ms
module tb_24count();
reg CP;
reg CR;
wire [3:0] Q0,Q1;
/*端口說明:
輸入:
CP爲時鐘信號,CR爲輸入清零信號
輸出:
Q1爲十位上數字對應的四位二進制,Q0爲十位上數字對應的四位二進制數
*/
//中間
_24count U(CP,CR,Q0,Q1);

initial 
	$monitor($time,"\tQ0=%b,Q1=%b\n",Q0,Q1);
//時鐘信號
initial
	CP=0;
always
	#5 CP=~CP;	
//元件例化
initial
begin
	//清零
	CR=0;
	#5;
	//計數25s
	CR=1;
	#300;
	$stop;
end
endmodule

仿真結果

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

顯示

思路

七段顯示器74HC4511之前已經進行了仿真,這裏只需注意十位顯示器的控制輸入應該在十位爲0的時候無效。注意這一點即可。

代碼顯示

設計模塊


//filename:_24show.v
module _24show(
input CP,CR,BL,LT,
output [6:0] L1,L0);
/*端口描述:
CP爲時鐘信號,CR爲清零信號,BL,LT實現滅燈和燈測試
*/
wire [3:0]Q0,Q1;
wire BL1;
_24count U(CP,CR,Q0,Q1);
assign BL1=BL&(Q1!=4'b0000);//十位顯示器的控制輸入應該在十位爲0的時候無效
_74HC4511 U1(1'b0,BL,LT,Q1,L1); 
_74HC4511 U0(1'b0,BL,LT,Q0,L0);
endmodule
 

module _74HC4511(
input LE,BL,LT,
input [3:0] D,
output reg [6:0] L);   //輸入輸出

wire [2:0] E;   
assign E={LE,BL,LT}; //中間變量用於後續的控制端優先級判斷
always@(*)
begin
    if(LE==0&&BL==1&&LT==1)
	begin
	  case(D)
		4'b0000:L=7'b111_1110;
		4'b0001:L=7'b011_0000;
		4'b0010:L=7'b110_1101;
		4'b0011:L=7'b111_1001;
		4'b0100:L=7'b011_0011;
		4'b0101:L=7'b101_1011;
		4'b0110:L=7'b001_1111;
		4'b0111:L=7'b111_0000;
		4'b1000:L=7'b111_1111;
		4'b1001:L=7'b111_1011;  
  		4'b1010:L=7'b000_0000;//以下爲無效狀態
  		4'b1011:L=7'b000_0000; 
  		4'b1100:L=7'b000_0000;
  		4'b1101:L=7'b000_0000;
  		4'b1110:L=7'b000_0000;
  		4'b1111:L=7'b000_0000; 		
	   endcase
	end
    else 
	begin
	    casex(E)
		3'bxx0:L=7'b111_1111;  //燈測試
		3'bx01:L=7'b000_0000;  //滅燈
		3'b111:L<=L;			//鎖存
		  endcase
	end
end
endmodule

//filename:_24count.v
module _24count(
input CP,
input CR,
output [3:0]Q0,Q1);
/*端口說明:
輸入:
CP爲時鐘信號,CR爲輸入清零信號
輸出:
Q1爲十位上數字對應的四位二進制,Q0爲十位上數字對應的四位二進制數
*/
//中間變量:TC進位信號,CLR爲爲24模的清零信號
wire TC0,TC1;
wire CLR;

varmodcnt #(4,10) U0(CP,CLR,EN,Q0,TC0);   //個位信號
varmodcnt #(4,3) U1(CP,CLR,TC0,Q1,TC1);   //十位信號
assign CLR=CR&(~({Q1,Q0}==8'b0010_0101));   //當外部清零信號有效或者輸出爲24時,進行清零
endmodule

測試模塊


//filename:tb_show.v
`timescale 100ms/10ms
module tb_show();
reg CP,CR;
reg BL,LT;
wire [6:0] L1,L0;

_24show U3(CP,CR,BL,LT,L1,L0);  //實例化元器件


initial 
	$monitor($time,"\tL1=%b,L0=%b\n,",L1,L0);
//時鐘信號
initial
	CP=0;
always
	#5 CP=~CP;
initial
begin
   //清零
	CR=0;BL=1'b1;LT=1'b1;
	#5;
	//24s計時器開始計數
	CR=1;BL=1'b1;LT=1'b1;
	#300;
	$stop;
end
endmodule

仿真

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章