Digital IC design study notes _verilog to achieve BCD counter

Digital IC design study notes

4. Verilog implements BCD counter

1 原理图
2 Verilog 代码
3 Modelsim仿真
  • BCD code: Binary-Coded Decimal, a binary coded decimal number, is a decimal number code that uses a 4-digit binary number to represent one of the 0-9 digits in the decimal number. BCD coding can be divided into two types: authorized code and unauthorized code. The authorized codes are such as 8421 code, 5421 code and 2421 code, and the unauthorized codes are such as remaining 3 codes, Gray codes, and remaining 3 cyclic codes.
  • The most commonly used BCD code is the 8421 code, and the weights of each bit are 8d, 4d, 2d, and 1d. Similarly, the weights of each bit of the 5421 code are 5d, 4d, 2d, and 1d. The characteristic of the 5421 code is that the highest bit has 5 consecutive 0s and then 5 consecutive ones. Therefore, when the counter adopts this code, the highest bit can produce a symmetrical square wave output; the remaining 3 codes are obtained by adding 0011b to the 8421 code; The characteristic of Gray code is that any two adjacent codes have only one binary number different, and the encoding format is not unique; the remaining 3 cyclic codes have the characteristics of Gray codes and the beginning and the end of the code can be connected to loop, so that the feedback shift register can be used to Realization, simple hardware implementation.
    Insert picture description here
  • One of the main applications of the BCD code is the nixie tube. Assuming that the decimal number 158 is to be displayed, the general solution is to split the number, tens, hundreds, and thousands of the decimal number that needs to be displayed, that is, split 158 ​​out 1, 5, 8, and then find out the corresponding digital tube display segment code and send it to the IO port connected to the digital tube. In this process, the following operations can be performed: first divide by 158/100 = 1 to get the hundred's place, then take the remainder 158% 100 = 58 and then continue with the division operation 58/10 = 5 to get the ten's place, and then take the remainder again 158%10 = 8, get the ones place. It can be seen from the above process that division is needed, but because the division operation consumes more calculation time, the overall instruction cycle required is too long. But if it is converted to BCD code first, the calculation time can be greatly reduced.

1. Schematic
Insert picture description here

2 Verilog code

//----TOP module--------------------------
module BCD_counter_top(
	input clk,
	input rst_n,
	input cin,
	
	output cout,
	output [11:0] q
);
	wire cout3_0;
	wire cout7_4;
	BCD_counter uut3_0(
		.clk(clk),
		.cin(cin),
		.rst_n(rst_n),
		.cout(cout3_0),
		.q(q[3:0])
	);
	BCD_counter uut7_4(
		.clk(clk),
		.cin(cout3_0),
		.rst_n(rst_n),
		.cout(cout7_4),
		.q(q[7:4])
	);
	BCD_counter uut11_8(
		.clk(clk),
		.cin(cout7_4),
		.rst_n(rst_n),
		.cout(cout),
		.q(q[11:8])
	);
endmodule
//----BCD_counter------------------
module BCD_counter(
	input clk, 
	input rst_n,
	input cin,
	output   cout,
	output [3:0] q
);
	reg [3:0] cnt;
//----cnt-------------------------------	
	always@(posedge clk or negedge rst_n)
		if(!rst_n)
			cnt <= 4'd0;
		else if(cin == 1)begin
			if(cnt == 4'd9)
				cnt <= 4'd0;
			else
				cnt <= cnt + 4'd1;
		end else
			cnt <= cnt;
//----cout-------------------------------
//	always@(posedge clk or negedge rst_n)
//		if(!rst_n)
//			cout <= 0;
//		else if(cin ==1 )begin
//			if(cnt == 4'd9)
//			cout <= 1;
//		else
//			cout <= cout;
//		end else
//			cout <= 0;
	assign cout = (cin ==1 && cnt == 4'd9)? 1'b1:1'b0;	
	assign q = cnt;

endmodule

3 Modelsim simulation
Insert picture description here
Insert picture description here
part of the content transferred from Xiaomei Ge FPGA self-study notes^^

[Note]: Personal study notes, if there are any mistakes, please feel free to enlighten me. This is polite~~~

Guess you like

Origin blog.csdn.net/weixin_50722839/article/details/109572565