数据生成模块
module data_gen
#(
parameter CNT_MAX = 23'd4999_999 ,
parameter DATA_MAX = 20'd999_999
)
(
input wire sys_clk ,
input wire sys_rst_n ,
output reg [19:0] data ,
output wire [5:0] point ,
output wire sign ,
output reg seg_en
);
reg [22:0] cnt_100ms;
reg cnt_flag ;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_100ms <= 23'd0;
else if(cnt_100ms == CNT_MAX)
cnt_100ms <= 23'd0;
else
cnt_100ms <= 1'b1 + cnt_100ms;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_flag <= 1'b0;
else if (cnt_100ms == CNT_MAX - 1)
cnt_flag <= 1'b1;
else
cnt_flag <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
data <= 20'd0;
else if((data == DATA_MAX)&&(cnt_flag == 1'b1))
data <= 20'd0;
else if(cnt_flag == 1'b1)
data <= data + 1'b1;
else
data <= data;
assign point = 6'b000_000;
assign sign = 1'b0;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
seg_en <= 1'b0;
else
seg_en <= 1'b1;
endmodule
`timescale 1ns/1ns
module tb_data_gen();
reg sys_clk ;
reg sys_rst_n ;
wire [19:0] data ;
wire [5:0] point ;
wire sign ;
wire seg_en ;
initial
begin
sys_clk =1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
data_gen
#(
.CNT_MAX (9) ,
.DATA_MAX(9)
)
data_gen_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n) ,
.data (data ),
.point (point ),
.sign (sign ),
.seg_en(seg_en)
);
endmodule
计数器 cnt_flag
data
加入BCD码模块
module bcd_8421
(
input sys_clk ,
input sys_rst_n ,
input wire [19:0] data ,
output reg [3:0] unit ,
output reg [3:0] ten ,
output reg [3:0] hun ,
output reg [3:0] tho ,
output reg [3:0] t_tho ,
output reg [3:0] h_hun
);
reg [4:0] cnt_shift;
reg [43:0] data_shift;
reg shift_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
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_n)
if(sys_rst_n == 1'b0)
data_shift <= 44'b0;
else if(cnt_shift == 5'd0)
data_shift <= {24'b0,data};
else if((cnt_shift <= 20)&&(shift_flag ==1'b0))
begin
data_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 <= 20)&&(shift_flag ==1'b1))
data_shift <= data_shift << 1;
else
data_shift <= data_shift ;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
shift_flag <= 1'b0;
else
shift_flag <= ~shift_flag;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
begin
unit <= 4'b0;
ten <= 4'b0;
hun <= 4'b0;
tho <= 4'b0;
t_tho <= 4'b0;
h_hun <= 4'b0;
end
else if(cnt_shift == 5'd21)
begin
unit <= data_shift[23:20];
ten <= data_shift[27:24];
hun <= data_shift[31:28];
tho <= data_shift[35:32];
t_tho <= data_shift[39:36];
h_hun <= data_shift[43:40];
end
endmodule
`timescale 1ns/1ns
module tb_bcd_8421();
reg sys_clk;
reg sys_rst_n;
reg [19:0] data;
wire [3:0] unit ;
wire [3:0] ten ;
wire [3:0] hun ;
wire [3:0] tho ;
wire [3:0] t_tho ;
wire [3:0] h_hun ;
initial
begin
sys_clk =1'b1;
sys_rst_n <= 1'b0;
data <= 20'd0;
#30
sys_rst_n <= 1'b1;
data <= 20'd123_456;
#3000
data <= 20'd654_321;
#3000
data <= 20'd987_654;
#3000
data <= 20'd999_999;
end
always #10 sys_clk = ~sys_clk;
bcd_8421 bcd_8421_inst
(
. sys_clk ( sys_clk ) ,
. sys_rst_n ( sys_rst_n ) ,
. data (data ) ,
. unit (unit ) ,
. ten (ten ) ,
. hun (hun ) ,
. tho (tho ) ,
. t_tho (t_tho ) ,
. h_hun (h_hun )
);
endmodule
cnt_shift
动态显示模块
module seg_dynamic
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [19:0] data ,
input wire [5:0] point ,
input wire sign ,
input wire seg_en ,
output reg [5:0] sel ,
output reg [7:0] seg
);
parameter CNT_MAX = 16'd49_999;
wire [3:0] unit;
wire [3:0] ten ;
wire [3:0] hun ;
wire [3:0] tho ;
wire [3:0] t_tho;
wire [3:0] h_hun;
reg [23:0] data_reg;
reg [15:0] cnt_1ms;
reg flag_1ms;
reg [2:0] cnt_sel;
reg [5:0] sel_reg;
reg [3:0] data_disp;
reg dot_disp;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
data_reg <= 24'b0;
else if((h_hun)||(point[5]))
data_reg <= {h_hun,t_tho,tho,hun,ten,unit};
else if(((t_tho)||(point[4]))&&(sign == 1'b1))
data_reg <= {4'd10,t_tho,tho,hun,ten,unit};
else if(((t_tho)||(point[4]))&&(sign == 1'b0))
data_reg <= {4'd11,t_tho,tho,hun,ten,unit};
else if(((tho)||(point[3]))&&(sign == 1'b1))
data_reg <= {4'd11,4'd10,tho,hun,ten,unit};
else if(((tho)||(point[3]))&&(sign == 1'b0))
data_reg <= {4'd11,4'd11,tho,hun,ten,unit};
else if(((hun)||(point[2]))&&(sign == 1'b1))
data_reg <= {4'd11,4'd11,4'd10,hun,ten,unit};
else if(((hun)||(point[2]))&&(sign == 1'b0))
data_reg <= {4'd11,4'd11,4'd11,hun,ten,unit};
else if(((ten)||(point[1]))&&(sign == 1'b1))
data_reg <= {4'd11,4'd11,4'd11,4'd10,ten,unit};
else if(((ten)||(point[1]))&&(sign == 1'b0))
data_reg <= {4'd11,4'd11,4'd11,4'd11,ten,unit};
else if(((unit)||(point[0]))&&(sign == 1'b1))
data_reg <= {4'd11,4'd11,4'd11,4'd11,4'd10,unit};
else
data_reg <= {4'd11,4'd11,4'd11,4'd11,4'd11,unit};
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_1ms <= 16'd0;
else if (cnt_1ms == CNT_MAX)
cnt_1ms <= 16'd0;
else
cnt_1ms <= cnt_1ms + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
flag_1ms <= 1'b0;
else if (cnt_1ms == CNT_MAX - 1'b1)
flag_1ms <= 1'b1;
else
flag_1ms <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_sel <= 3'd0;
else if ((cnt_sel == 3'd5)&&(flag_1ms == 1'b1))
cnt_sel <= 3'd0;
else if (flag_1ms == 1'b1)
cnt_sel <= cnt_sel + 1'b1;
else
cnt_sel <= cnt_sel;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
sel_reg <= 6'b000_000;
else if((cnt_sel == 3'd0)&&(flag_1ms == 1'b1))
sel_reg <= 6'b000_001;
else if (flag_1ms == 1'b1)
sel_reg <= sel_reg <<1;
else
sel_reg <= sel_reg;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
data_disp <= 4'd0;
else if((seg_en == 1'b1)&&(flag_1ms == 1'b1))
case(cnt_sel)
3'd0 : data_disp <= data_reg[3:0];
3'd1 : data_disp <= data_reg[7:4];
3'd2 : data_disp <= data_reg[11:8];
3'd3 : data_disp <= data_reg[15:12];
3'd4 : data_disp <= data_reg[19:16];
3'd5 : data_disp <= data_reg[23:20];
default:data_disp <= 4'd0;
endcase
else
data_disp <= data_disp;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
dot_disp <= 1'b1;
else if(flag_1ms == 1'b1)
dot_disp <= ~point[cnt_sel];
else
dot_disp <= dot_disp;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
seg <= 8'b111_111;
else
case(data_disp)
4'd0 : seg <= {dot_disp,7'b100_0000} ;
4'd1 : seg <= {dot_disp,7'b111_1001} ;
4'd2 : seg <= {dot_disp,7'b010_0100} ;
4'd3 : seg <= {dot_disp,7'b011_0000} ;
4'd4 : seg <= {dot_disp,7'b001_1001} ;
4'd5 : seg <= {dot_disp,7'b001_0010} ;
4'd6 : seg <= {dot_disp,7'b000_0010} ;
4'd7 : seg <= {dot_disp,7'b111_1000} ;
4'd8 : seg <= {dot_disp,7'b000_0000} ;
4'd9 : seg <= {dot_disp,7'b001_0000} ;
4'd10: seg <= 8'b1011_1111;
4'd11: seg <= 8'b111_111;
default: seg <= 8'b1100_0000;
endcase
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
sel <= 6'b000_000;
else
sel <= sel_reg;
bcd_8421 bcd_8421_inst
(
. sys_clk ( sys_clk ) ,
. sys_rst_n ( sys_rst_n ) ,
. data (data ) ,
. unit (unit ) ,
. ten (ten ) ,
. hun (hun ) ,
. tho (tho ) ,
. t_tho (t_tho ) ,
. h_hun (h_hun )
);
endmodule
`timescale 1ns/1ns
module tb_seg_dynamic();
reg sys_clk ;
reg sys_rst_n ;
reg [19:0] data ;
reg [5:0] point ;
reg sign ;
reg seg_en ;
wire [5:0] sel ;
wire [7:0] seg ;
initial
begin
sys_clk =1'b1;
sys_rst_n <= 1'b0;
data <= 20'd0;
point <= 6'b0;
sign <= 1'b0;
seg_en <= 1'b0;
#30
sys_rst_n <= 1'b1;
data <= 20'd9876;
point <= 6'b0;
sign <= 1'b1;
seg_en <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
defparam seg_dynamic_inst.CNT_MAX = 20'd5;
seg_dynamic seg_dynamic_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n ) ,
. data ( data ) ,
. point ( point ) ,
. sign ( sign ) ,
. seg_en ( seg_en ) ,
. sel ( sel ) ,
. seg ( seg )
);
endmodule
b没有使用最高位 a符号位
数据显示
module hc595_ctrl
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [5:0] sel ,
input wire [7:0] seg ,
output reg ds ,
output reg shcp ,
output reg stcp ,
output wire oe
);
wire [13:0] data ;
reg [1:0] cnt ;
reg [3:0] cnt_bit ;
assign data = {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel};
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt <= 2'd0;
else if (cnt == 2'd3)
cnt <= 2'd0;
else
cnt <= cnt + 1'b1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_bit <= 4'd0;
else if ((cnt_bit == 4'd13)&&(cnt == 2'd3))
cnt_bit <= 4'd0;
else if (cnt == 2'd3)
cnt_bit <= cnt_bit + 1'b1;
else
cnt_bit <= cnt_bit;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
ds <= 1'b0;
else if(cnt == 2'd0)
ds <= data[cnt_bit];
else
ds <= ds;
//移位时钟
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
shcp <= 1'b0;
else if (cnt == 2'd2)
shcp <= 1'b1;
else if (cnt == 2'd0)
shcp <= 1'b0;
else
shcp <= shcp;
//存储寄存器时钟
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
stcp <= 1'b0;
else if ((cnt_bit == 4'd0)&&(cnt == 2'd0))
stcp <= 1'b1;
else if ((cnt_bit == 4'd0)&&(cnt == 2'd2))
stcp <= 1'b0;
else
stcp <= stcp;
assign oe = 1'b0;
endmodule
module seg_595_dynamic
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [19:0] data ,
input wire [5:0] point ,
input wire sign ,
input wire seg_en ,
output wire ds ,
output wire oe ,
output wire shcp ,
output wire stcp
);
wire [5:0] sel;
wire [7:0] seg;
seg_dynamic seg_dynamic_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n ) ,
. data ( data ) ,
. point ( point ) ,
. sign ( sign ) ,
. seg_en ( seg_en ) ,
. sel ( sel ) ,
. seg ( seg )
);
hc595_ctrl hc595_ctrl_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n(sys_rst_n) ,
. sel ( sel ) ,
. seg ( seg ) ,
.ds (ds ) ,
.shcp (shcp ) ,
.stcp (stcp ) ,
. oe ( oe )
);
endmodule
module top_seg_595
(
input wire sys_clk ,
input wire sys_rst_n ,
output wire ds ,
output wire shcp ,
output wire stcp ,
output wire oe
);
wire [19:0] data;
wire [5:0] point;
wire sign;
wire seg_en;
data_gen
#(
.CNT_MAX(23'd9),
.DATA_MAX(20'd999_999)
)
data_gen_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n ) ,
. data ( data ) ,
. point ( point ) ,
. sign ( sign ) ,
. seg_en ( seg_en ) ,
);
seg_595_dynamic seg_595_dynamic_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n ) ,
. data ( data ) ,
. point ( point ) ,
. sign ( sign ) ,
. seg_en ( seg_en ) ,
.ds (ds ),
.shcp (shcp),
.stcp (stcp),
. oe ( oe )
);
endmodule
`timescale 1ns/1ns
module tb_top_seg_595();
reg sys_clk ;
reg sys_rst_n ;
wire ds ;
wire shcp ;
wire stcp ;
wire oe ;
initial
begin
sys_clk =1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
defparam top_seg_595_inst.data_gen_inst.CNT_MAX = 23'd49;
defparam top_seg_595_inst.seg_595_dynamic_inst.seg_dynamic_inst.CNT_MAX =16'd19;
top_seg_595 top_seg_595_inst
(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n ),
.ds (ds ),
.shcp (shcp ),
.stcp (stcp ),
. oe ( oe )
);
endmodule