有必要仔细阐述这一节,目前就是用在数码管显示,在单片机使用时,我们通常是将十进制数字进行/和%运算,得到每个位置的十进制数字,在这里可能是为了节省使用存储器的量,运用的是加三移位法具体其实就是将每个数字不顾位置,各自转换为二进制形式
例如:
255 变成 0010 _0101_0101 的过程

移位的次数一定是该数字的二进制位数,加三不确定(加三也是要判断每4位的二进制大于4才加三,所以是每次移位以后都要判断)
module bcd_8421(input wire sys_clk,input wire sys_rst,input wire [19:0] data,output reg [3:0] ge,output reg [3:0] shi,output reg [3:0] bai,output reg [3:0] qian,output reg [3:0] wan,output reg [3:0] shi_wan);reg [4:0] cnt_shift; //移位判断计数器
reg [43:0] data_shift; //移位判断数据寄存器
reg shift_flag; //移位判断标志信号always @(posedge sys_clk or negedge sys_rst) //0到21的循环计数(移位加三的方式实现的话,首位各加一个,999_999十进制换算到二进制有20位)if(!sys_rst )cnt_shift <= 5'd0;else if ((cnt_shift==5'd21) && (shift_flag == 1'b1))cnt_shift <= 5'd0;else if (shift_flag == 1'b1)cnt_shift <= cnt_shift + 1'b1;else cnt_shift <= cnt_shift;always @(posedge sys_clk or negedge sys_rst) //移位判断标志信号,控制移位判断的先后顺序if(!sys_rst )shift_flag <= 1'b0;else shift_flag <= ~shift_flag;always @(posedge sys_clk or negedge sys_rst) //data_shift有44位,其中高24位是999_999形成的BCD码需要24位,低20位是999_999的二进制形式是20位if(!sys_rst )data_shift <=44'b0;else if (cnt_shift == 5'd0)data_shift <= {24'b0, data }; else if ((cnt_shift <= 5'd20)&&(shift_flag==1'b0)) //cnt_shift=0时,还是上次的,因为六位数最大变成二进制有20位,所以考虑有20次判断和移位操作,21次稳定,将它输出,begindata_shift[23:20] <= (data_shift[23:20]>4) ? (data_shift[23:20]+2'd3) : (data_shift[23:20]);data_shift[27:24] <= (data_shift[27:24]>4) ? (data_shift[27:24]+2'd3) : (data_shift[27:24]);data_shift[31:28] <= (data_shift[31:28]>4) ? (data_shift[31:28]+2'd3) : (data_shift[31:28]);data_shift[35:32] <= (data_shift[35:32]>4) ? (data_shift[35:32]+2'd3) : (data_shift[35:32]);data_shift[39:36] <= (data_shift[39:36]>4) ? (data_shift[39:36]+2'd3) : (data_shift[39:36]);data_shift[43:40] <= (data_shift[43:40]>4) ? (data_shift[43:40]+2'd3) : (data_shift[43:40]);end else if ((cnt_shift <= 5'd20)&&(shift_flag==1'b1))data_shift <= data_shift << 1;else data_shift <= data_shift;
always @(posedge sys_clk or negedge sys_rst) //当计数器等于20时,对各位置的赋值(BCD)if(!sys_rst )begin ge <= 4'b0;shi <= 4'b0;bai <= 4'b0;qian <= 4'b0;wan <= 4'b0;shi_wan <= 4'b0;endelse if (cnt_shift == 5'd21)beginge <= data_shift[23:20];shi <= data_shift[27:24];bai <= data_shift[31:28];qian <= data_shift[35:32];wan <= data_shift[39:36];shi_wan <= data_shift[43:40];end elsebeginge <= ge ;shi <= shi ;bai <= bai ;qian <= qian ;wan <= wan ;shi_wan <= shi_wan ;end endmodule
module vtf;// Inputsreg sys_clk;reg sys_rst;reg [19:0] data;// Outputswire [3:0] ge;wire [3:0] shi;wire [3:0] bai;wire [3:0] qian;wire [3:0] wan;wire [3:0] shi_wan;// Instantiate the Unit Under Test (UUT)bcd_8421 uut (.sys_clk(sys_clk), .sys_rst(sys_rst), .data(data), .ge(ge), .shi(shi), .bai(bai), .qian(qian), .wan(wan), .shi_wan(shi_wan));initial begin// Initialize Inputssys_clk = 0;sys_rst = 0;data = 0;// Wait 100 ns for global reset to finish#100;sys_rst <= 1'b1;data <= 20'd0;#100000;data <= 20'd123_456;#100000;data <= 20'd999_999;#100000;data <= 20'd123_895;#100000;data <= 20'd456_789;#100000;data <= 20'd999_999;#100000;data <= 20'd456_789;// Add stimulus hereendalways # 10 sys_clk = ~sys_clk;endmodule









![[学习笔记]黑马程序员python教程](https://img-blog.csdnimg.cn/75601c7cf6ef4da0b107543c33e788cd.png)










