【FPGA & Verilog】4bitBCD码加法器+7段数码管

发布时间:2024年01月16日

顶层文件:

module add_bcd(
input [9:0]I_1,
input [9:0]I_0,
input clk,
input rst_n,
output [7:0]seg,
output [7:0]value,
output select,
output ?[3:0]encode_1,
output ?[3:0]encode_0,
output ?[3:0]high_bit,
output ?[3:0]low_bit
);

assign value ={high_bit,low_bit};

encoder encoder_inst2(
.in(I_1),
.out(encode_1)
);

encoder encoder_inst1(
.in(I_0),
.out(encode_0)
);

bcd_adder bcd_adder_0(
.A(encode_1),
.B(encode_0),
.Sum(low_bit),
.Cout(high_bit)
);

divider_N divider_N1(
.clk_50m(clk),// 基准时钟
.rst_n(rst_n),
.clk_1hz(select)// N 分频后得到的时钟
);

display_driver display_driver1(
.value(value),
.seg(seg),
.select(select)
);


endmodule

测试文件:

`timescale 1ns/1ns
module add_bcd_tb();
reg [9:0]I_1;
reg [9:0]I_0;
reg clk;
reg rst_n;
wire [7:0]seg;
wire [7:0]value;
wire select;
wire [3:0]encode_1;
wire ?[3:0]encode_0;
wire ?[3:0]high_bit;
wire ?[3:0]low_bit;
add_bcd u1(
.I_1(I_1),
.I_0(I_0),
.clk(clk),
.rst_n(rst_n),
.seg(seg),
.value(value),
.select(select),
.encode_1(encode_1),
.encode_0(encode_0),
.high_bit(high_bit),
.low_bit(low_bit)
);
initial begin
?? ?clk=0 ;
?? ?rst_n=0 ;
?? ?#20 rst_n=1;
?? ?#300 I_0=10'b1111111110;I_1=10'b1111111101;
?? ?#300 I_0=10'b1111111101;I_1=10'b1111111011;
?? ?#300 I_0=10'b1111111011;I_1=10'b1111110111;
?? ?#300 I_0=10'b1111110111;I_1=10'b1111101111;
? ?#300 I_0=10'b1111101111;I_1=10'b1111011111;
?? ?#300 I_0=10'b1111011111;I_1=10'b1110111111;
? ?#300 I_0=10'b1110111111;I_1=10'b1101111111;
?? ?#300 I_0=10'b0111111111;I_1=10'b0111111111;
?? ?#300 I_0=10'b1111111110;I_1=10'b1111111101;
?? ?#300 I_0=10'b1111111101;I_1=10'b1111111011;
?? ?#300 I_0=10'b1111111011;I_1=10'b1111110111;
?? ?#300 I_0=10'b1111110111;I_1=10'b1111101111;
? ?? ?#300 I_0=10'b1111111110;I_1=10'b1111111101;

end
always #10 clk=~clk;
endmodule


module bcd_adder(A,B,Sum,Cout);
?? ?input [3:0]A,B;
?? ?output [3:0]Sum;
?? ?output [3:0]Cout;
?? ?wire [4:0]Temp;
?? ?
?? ?assign Temp = A + B ;
?? ?assign {Cout,Sum} = (Temp > 4'd9)? Temp+4'd6 : Temp;
?? ?
endmodule

module display_driver(
? ? input wire [7:0] value,
? ? output reg [7:0] seg,
?? ? input select
);
wire [3:0]number;
assign number = select ? value[7:4] : value [3:0];?
always @(*) begin
? ? case ({number})
? ? ? ? 4'b0000: begin seg <= 8'b11000000; end// 0
? ? ? ? 4'b0001: begin seg <= 8'b11111001; end// 1
? ? ? ? 4'b0010: begin seg <= 8'b10100100; end// 2
? ? ? ? 4'b0011: begin seg <= 8'b10110000; end// 3
? ? ? ? 4'b0100: begin seg <= 8'b10011001; end// 4
? ? ? ? 4'b0101: begin seg <= 8'b10010010; end// 5
? ? ? ? 4'b0110: begin seg <= 8'b10000010; end// 6
? ? ? ? 4'b0111: begin seg <= 8'b11111000; end// 7
? ? ? ? 4'b1000: begin seg <= 8'b10000000; ?end// 8
? ? ? ? 4'b1001: begin seg <= 8'b10010000; end// 9
? ? ? ? default: begin seg <= 8'b00000000; end// Error
? ? endcase
?? ?end

endmodule


//
//module seg(clk,rst_n,data,dig,led);
//input clk;
//input rst_n;
//input [23:0] data;
//output reg [5:0] dig; //六位控制六个数码管
//output reg [7:0] led;
//
//reg [3:0] d;
//always@ (posedge clk or negedge rst_n ) begin
//?? ?if(~rst_n)
//?? ?led<= 8'b0;
//?? ?else begin
//?? ?case (d)
//?? ?4'h0:led<= 8'b00111111 ;//0
//?? ?4'h1:led<= 8'b00000110;//1
//?? ?4'h2:led<= 8'b01011011 ;//2
//?? ?4'h3:led<= 8'b01001111 ;//3
//?? ?4'h4:led<= 8'b01100110;//4
//?? ?4'h5:led<= 8'b01101101 ;//5
//?? ?4'h6:led<= 8'b01111101 ;//6
//?? ?4'h7:led<= 8'b00000111;//7
//?? ?4'h8:led<= 8'b01111111 ;//8?
//?? ?4'h9:led<= 8'b01101111 ;//9?
//?? ?4'ha:led<= 8'b01110111 ;//a
//?? ?4'hb:led<= 8'b01111100;//b
//?? ?4'hc:led<= 8'b00111001 ;//c
//?? ?4'hd:led<= 8'b01011110;//d
//?? ?4'he:led<= 8'b01111001 ;//e
//?? ?4'hf:led<= 8'b01110001 ;//f
//?? ?default: led<=8'b0 ;
//?? ?endcase
//?? ?end
//end
//
//wire [2:0]cnt2;
//
//flag flag_m0 (
//.clk(clk),// INPUT
//.rst_n(rst_n),// INPUT
//.cnt(cnt2)
//);
//
//always@ (posedge clk or negedge rst_n ) begin
//?? ? if(~rst_n)
//?? ? ?dig<= 6'b0;
//?? ? else begin?
//?? ? case (cnt2)
//?? ??? ?3'd0 :begin dig<= 6'b000001; d<=data[3:0];end
//?? ??? ?3'd1 :begin dig<= 6'b000010; d<=data[7:4];end
//?? ??? ?3'd2 :begin dig<= 6'b000100; d<=data[11:8];end
//?? ??? ?3'd3 :begin dig<= 6'b001000; d<=data[15:12];end
//?? ??? ?3'd4 :begin dig<= 6'b010000; d<=data[19:16];end
//?? ??? ?3'd5 :begin dig<= 6'b100000; d<=data[23:20];end
//?? ??? ?default:begin dig <= 6'b0 ;end
//?? ? ?endcase
//?? ?end
//end
//
//endmodule

module encoder(
? ? input [9:0]in,
? ? output reg [3:0]out
? ? );?
always @(*) begin
? ? if (in[9]==0) begin
? ? ? ? out = 4'b1001;
? ? end
? ? else if(in[8]==0) begin
? ? ? ? out = 4'b1000;
? ? end
? ? else if(in[7]==0) begin
? ? ? ? out = 4'b0111;
? ? end
? ? else if(in[6]==0) begin
? ? ? ? out = 4'b0110;
? ? end
? ? else if(in[5]==0) begin
? ? ? ? out = 4'b0101;
? ? end
? ? else if(in[4]==0) begin
? ? ? ? out = 4'b0100;
? ? end
? ? else if(in[3]==0) begin
? ? ? ? out = 4'b0011;
? ? end
? ? else if(in[2]==0) begin
? ? ? ? out = 4'b0010;
? ? end
?? ? else if(in[1]==0) begin
? ? ? ? out = 4'b0001;
? ? end
?? ? else if(in[0]==0) begin
? ? ? ? out = 4'b0000;
? ? end
?? ? else
?? ? ? ? out = 4'b0000;
end
endmodule

module divider_N(
clk_50m,// 基准时钟
rst_n,
clk_1hz// N 分频后得到的时钟
);
input clk_50m;
input rst_n;
output reg clk_1hz;
reg [24:0] cnt;
//parameter c_25m = 25'd24_999_999; //可改变这个值,改变输出频率。
parameter c_25m = 10'd5; //100khz
always@(posedge clk_50m or negedge rst_n)
if (!rst_n)
cnt <= 25'b0;
else if (cnt >= c_25m )
cnt <= 25'b0;
else
cnt <= cnt + 1'b1;

always@(posedge clk_50m or negedge rst_n)
if (!rst_n)
clk_1hz <= 1'b0;
else if (cnt == c_25m )
clk_1hz <= !clk_1hz;

endmodule

可私信获取项目文件

文章来源:https://blog.csdn.net/m0_51956878/article/details/135606769
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。