FPGA project : example_rom
2023-12-15 18:24:09
?控制模块波形:(其他模块只复用)
module top (
input wire sys_clk ,
input wire sys_rst_n ,
input wire key_1 ,
input wire key_2 ,
output wire ds ,
output wire oe ,
output wire shcp ,
output wire stcp
);
wire [7:0] addr_w ;
wire key_1_out ;
wire key_2_out ;
wire [07:00] data_w_1;
wire [19:00] data_w_2;
assign data_w_2 = {12'd0,data_w_1} ;
wire [5:0] point ;
wire sign ;
wire seg_en ;
assign point = 6'b000000 ;
assign sign = 1'b0 ;
assign seg_en = 1'b1 ;
key_filter key_filter_insert1
(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( key_1 ) ,
.key_out ( key_1_out )
);
key_filter key_filter_insert2
(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( key_2 ) ,
.key_out ( key_2_out )
);
rom_ctrl rom_ctrl_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_1 ( key_1_out ) ,
.key_2 ( key_2_out ) ,
.addr ( addr_w )
);
rom_8x256 rom_8x256_inst (
.address ( addr_w ),
.clock ( sys_clk ),
.q ( data_w_1 )
);
seg_595_dynamic seg_595_dynamic_insert (
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.data ( data_w_2 ) ,
.point ( point ) ,
.sign ( sign ) ,
.seg_en ( seg_en ) ,
.ds ( ds ) ,
.oe ( oe ) ,
.shcp ( shcp ) ,
.stcp ( stcp )
);
endmodule
/*
对data_gen 产生的二进制 0 ~ 999_999 数据进行bcd码转换
*/
module bcd_8421 (
input wire sys_clk ,
input wire sys_rst_n ,
input wire [19:00] data ,
output reg [03:00] unit ,
output reg [03:00] ten ,
output reg [03:00] hun ,
output reg [03:00] tho ,
output reg [03:00] t_tho ,
output reg [03:00] h_hun
);
// reg signal define
reg cnt_f ; // 二分频
reg [04:00] cnt_shift ; // 0 ~ 21
reg [43:00] data_shift ;
// cnt_f
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_f <= 0 ;
end else begin
cnt_f <= ~cnt_f ;
end
end
// [04:00] cnt_shift
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_shift <= 5'd0 ;
end else begin
if(cnt_f == 0) begin
if(cnt_shift == 5'd21) begin
cnt_shift <= 5'd0 ;
end else begin
cnt_shift <= cnt_shift + 5'd1 ;
end
end else begin
cnt_shift <= cnt_shift ;
end
end
end
// [43:00] data_shift
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
data_shift <= 44'd0 ;
end else begin
if(cnt_f == 1'b1) begin
if(cnt_shift == 5'd0) begin
data_shift <= {24'd0, data} ;
end else begin // 判断是否加 4'd3
if(cnt_shift == 5'd21) begin
data_shift <= data_shift ;
end else begin
data_shift <= ( data_shift << 1'b1 ) ;
end
end
end else begin
if(cnt_shift == 5'd0) begin
data_shift <= {24'd0, data} ;
end else begin
if(cnt_shift == 5'd21 || cnt_shift == 5'd20) begin
data_shift <= data_shift ;
end else begin // 判断是否加 4'd3 : 这种写法,所有if 都会判断一遍。 众所周知 if else 是有优先级的,但这样写,可以综合出并行电路。
if(data_shift[23:20] > 4'd4) begin
data_shift[23:20] <= data_shift[23:20] + 4'd3 ;
end else begin
data_shift[23:20] <= data_shift[23:20] ;
end
if(data_shift[27:24] > 4'd4) begin
data_shift[27:24] <= data_shift[27:24] + 4'd3 ;
end else begin
data_shift[27:24] <= data_shift[27:24] ;
end
if(data_shift[31:28] > 4'd4) begin
data_shift[31:28] <= data_shift[31:28] + 4'd3 ;
end else begin
data_shift[31:28] <= data_shift[31:28] ;
end
if(data_shift[35:32] > 4'd4) begin
data_shift[35:32] <= data_shift[35:32] + 4'd3 ;
end else begin
data_shift[35:32] <= data_shift[35:32] ;
end
if(data_shift[39:36] > 4'd4) begin
data_shift[39:36] <= data_shift[39:36] + 4'd3 ;
end else begin
data_shift[39:36] <= data_shift[39:36] ;
end
if(data_shift[43:40] > 4'd4) begin
data_shift[43:40] <= data_shift[43:40] + 4'd3 ;
end else begin
data_shift[43:40] <= data_shift[43:40] ;
end
end
end
end
end
end
// unit
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
unit <= 4'd0 ;
end else begin
if(cnt_shift == 5'd21) begin
unit <= data_shift[23:20] ;
end else begin
unit <= unit ;
end
end
end
// ten
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
ten <= 4'd0 ;
end else begin
if(cnt_shift == 5'd21) begin
ten <= data_shift[27:24] ;
end else begin
ten <= ten ;
end
end
end
// hun
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
hun <= 4'd0 ;
end else begin
if(cnt_shift == 5'd21) begin
hun <= data_shift[31:28] ;
end else begin
hun <= hun ;
end
end
end
// tho
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
tho <= 4'd0 ;
end else begin
if(cnt_shift == 5'd21) begin
tho <= data_shift[35:32] ;
end else begin
tho <= tho ;
end
end
end
// t_tho
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
t_tho <= 4'd0 ;
end else begin
if(cnt_shift == 5'd21) begin
t_tho <= data_shift[39:36] ;
end else begin
t_tho <= t_tho ;
end
end
end
// h_hun
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
h_hun <= 4'd0 ;
end else begin
if(cnt_shift == 5'd21) begin
h_hun <= data_shift[43:40] ;
end else begin
h_hun <= h_hun ;
end
end
end
endmodule
module hc595_ctrl(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [7:0] seg ,
input wire [5:0] sel ,
output wire ds ,
output wire oe ,
output reg shcp ,
output reg stcp
);
// reg signal define
wire [13:00] data ;
reg [01:00] cnt_f ;
reg [03:00] cnt_bit ;
// data
// reg [13:00] data ;
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n) begin
// data <= {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5:0]} ;
// end else begin
// data <= {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5:0]} ;
// end
// end
assign data = {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5:0]} ;
// cnt_f
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_f <= 2'd0 ;
end else begin
if(cnt_f == 2'd3) begin
cnt_f <= 2'd0 ;
end else begin
cnt_f <= cnt_f + 2'd1 ;
end
end
end
// cnt_bit
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_bit <= 4'd0 ;
end else begin
if(cnt_f == 2'd3) begin
if(cnt_bit == 4'd13) begin
cnt_bit <= 4'd0 ;
end else begin
cnt_bit <= cnt_bit + 4'd1 ;
end
end else begin
cnt_bit <= cnt_bit ;
end
end
end
// out signal
// ds
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n) begin
// ds <= data[cnt_bit] ;
// end else begin
// ds <= data[cnt_bit] ;
// end
// end
assign ds = data[cnt_bit] ;
// shcp
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
shcp <= 1'b0 ;
end else begin
if(cnt_f == 2'd2 || cnt_f == 2'd3) begin
shcp <= 1'b1 ;
end else begin
shcp <= 1'b0 ;
end
end
end
// stcp
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
stcp <= 1'b0 ;
end else begin
if(cnt_bit == 4'd0 && (cnt_f == 2'd0 || cnt_f == 2'd1)) begin
stcp <= 1'b1 ;
end else begin
stcp <= 1'b0 ;
end
end
end
// oe
assign oe = 1'b0 ;
endmodule
?
module key_filter
#(
parameter MAX_CNT_20MS = 20'd100_0000
)(
input wire sys_clk ,
input wire sys_rst_n ,
input wire key_in ,
output wire key_out
// output reg key_out
);
reg key_r_0 ;
reg key_r_1 ;
wire nege ;
wire pose ;
reg [19:00] cnt_20ms ;
wire add_cnt_20ms ;
wire end_cnt_20ms ;
reg add_cnt_flag ;
// key_r_0 key_r_1
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_r_0 <= 1'b1 ;
end else begin
key_r_0 <= key_in ;
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_r_1 <= 1'b1 ;
end else begin
key_r_1 <= key_r_0 ;
end
end
// nege pose
assign nege = ~key_r_0 && key_r_1 ;
assign pose = key_r_0 && ~key_r_1 ;
// add_cnt_flag
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
add_cnt_flag <= 1'b0 ;
end else begin
if(nege) begin
add_cnt_flag <= 1'b1 ;
end else begin
if( pose || end_cnt_20ms ) begin
add_cnt_flag <= 1'b0 ;
end else begin
add_cnt_flag <= add_cnt_flag ;
end
end
end
end
// cnt_20ms add_cnt_20ms end_cnt_20ms
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_20ms <= 20'd0 ;
end else begin
if(add_cnt_20ms) begin
if(end_cnt_20ms) begin
cnt_20ms <= 20'd0 ;
end else begin
cnt_20ms <= cnt_20ms + 20'd1 ;
end
end else begin
cnt_20ms <= 20'd0 ;
end
end
end
assign add_cnt_20ms = add_cnt_flag ;
assign end_cnt_20ms = add_cnt_20ms && cnt_20ms == ( MAX_CNT_20MS - 1'b1 ) ;
// key_out
// always @(posedge sys_clk or negedge sys_rst_n) begin
// // always @(*) begin // 这样的话 会综合成 数据选择器
// if(~sys_rst_n) begin
// key_out <= 1'b0 ;
// end else begin
// if(end_cnt_20ms) begin
// key_out <= 1'b1 ;
// end else begin
// key_out <= 1'b0 ;
// end
// end
// end
assign key_out = end_cnt_20ms ;
endmodule
// `timescale 1ns/1ns
//
// // Author : EmbedFire
// // Create Date : 2019/03/15
// // Module Name : key_filter
// // Project Name : key_filter
// // Target Devices: Altera EP4CE10F17C8N
// // Tool Versions : Quartus 13.0
// // Description : 按键消抖模块
// //
// // Revision : V1.0
// // Additional Comments:
// //
// // 实验平台: 野火_征途Pro_FPGA开发板
// // 公司 : http://www.embedfire.com
// // 论坛 : http://www.firebbs.cn
// // 淘宝 : https://fire-stm32.taobao.com
//
// module key_filter
// #(
// parameter CNT_MAX = 20'd999_999 //计数器计数最大值
// )
// (
// input wire sys_clk , //系统时钟50Mhz
// input wire sys_rst_n , //全局复位
// input wire key_in , //按键输入信号
// output reg key_flag //key_flag为1时表示消抖后检测到按键被按下
// //key_flag为0时表示没有检测到按键被按下
// );
// //********************************************************************//
// //****************** Parameter and Internal Signal *******************//
// //********************************************************************//
// //reg define
// reg [19:0] cnt_20ms ; //计数器
// //********************************************************************//
// //***************************** Main Code ****************************//
// //********************************************************************//
// //cnt_20ms:如果时钟的上升沿检测到外部按键输入的值为低电平时,计数器开始计数
// always@(posedge sys_clk or negedge sys_rst_n)
// if(sys_rst_n == 1'b0)
// cnt_20ms <= 20'b0;
// else if(key_in == 1'b1)
// cnt_20ms <= 20'b0;
// else if(cnt_20ms == CNT_MAX && key_in == 1'b0)
// cnt_20ms <= cnt_20ms;
// else
// cnt_20ms <= cnt_20ms + 1'b1;
// //key_flag:当计数满20ms后产生按键有效标志位
// //且key_flag在999_999时拉高,维持一个时钟的高电平
// always@(posedge sys_clk or negedge sys_rst_n)
// if(sys_rst_n == 1'b0)
// key_flag <= 1'b0;
// else if(cnt_20ms == CNT_MAX - 1'b1)
// key_flag <= 1'b1;
// else
// key_flag <= 1'b0;
// endmodule
module rom_ctrl (
input wire sys_clk ,
input wire sys_rst_n ,
input wire key_1 ,
input wire key_2 ,
output reg [7:0] addr
);
// reg signal define
reg [7:0] cnt_256 ;
reg [7:0] cnt_256_500ms ;
reg key_flag ;// 按键按下后输出的地址将不变。
// 0.5sec 另一种计数器风格。
reg [24:00] cnt_500ms ;
wire add_cnt_500ms ;
wire end_cnt_500ms ;
parameter MAX_CNT_500MS = 25'd25_000_000;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_500ms <= 0;
end else begin
if(add_cnt_500ms) begin
if(end_cnt_500ms) begin
cnt_500ms <= 0;
end else begin
cnt_500ms <= cnt_500ms + 25'h1;
end
end else begin
cnt_500ms <= cnt_500ms;// 保持
end
end
end
assign add_cnt_500ms = ~key_flag ;
assign end_cnt_500ms = add_cnt_500ms && ( cnt_500ms == MAX_CNT_500MS - 1'b1 );
// cnt_256_500ms
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_256_500ms <= 8'd0 ;
end else begin
if(cnt_500ms == MAX_CNT_500MS - 1'b1) begin
if(cnt_256_500ms == 8'd255) begin
cnt_256_500ms <= 8'd0 ;
end else begin
cnt_256_500ms <= cnt_256_500ms + 8'd1 ;
end
end else begin
cnt_256_500ms <= cnt_256_500ms ;
end
end
end
// reg key_flag ; // 按键按下后输出的地址将不变。
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_flag <= 0 ;
end else begin
if(key_1 == 1'b1 || key_2 == 1'b1) begin
key_flag <= ~key_flag ;
end else begin
key_flag <= key_flag ;
end
end
end
// cnt_256 ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_256 <= 8'd0 ;
end else begin
if(cnt_256 == 8'd255) begin
cnt_256 <= 8'd0 ;
end else begin
cnt_256 <= cnt_256 + 8'd1 ;
end
end
end
// addr
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
addr <= 8'd0 ;
end else begin
if(key_1 == 1'b1 || key_2 == 1'b1 || key_flag == 1'b1) begin
if(key_flag == 1'b1) begin
addr <= addr ;
end else begin
addr <= cnt_256 ;
end
end else begin
addr <= cnt_256_500ms ; // 如果按键没有按下且 key_flag == 0
end
end
end
// always @(posedge sys_clk or negedge sys_rst_n) begin
// if(~sys_rst_n) begin
// addr <= 8'd0 ;
// end else begin
// addr <= 8'd100 ;
// end
// end
endmodule
?
module seg_595_dynamic(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [19:00] data ,
input wire [05:00] point ,
input wire sign ,
input wire seg_en ,
output wire ds ,
output wire oe ,
output wire shcp ,
output wire stcp
);
// ;例化间连线
wire [05:00] sel_w ;
wire [07:00] seg_w ;
seg_dynamic
#(
.MAX_1MS (16'd49_999)
)
seg_dynamic_insert
(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.data ( data ) ,
.point ( point ) ,
.sign ( sign ) ,
.seg_en ( seg_en ) ,
.sel ( sel_w ) ,
.seg ( seg_w )
);
hc595_ctrl hc595_ctrl_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.seg ( seg_w ) ,
.sel ( sel_w ) ,
.ds ( ds ) ,
.oe ( oe ) ,
.shcp ( shcp ) ,
.stcp ( stcp )
);
endmodule
module seg_dynamic
#(
parameter MAX_1MS = 16'd49_999 // 数码管刷新时间
)(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [19:00] data ,
input wire [05:00] point , // 1 有点
input wire sign , // 1 正 0 负
input wire seg_en , // 1 work
output reg [05:00] sel ,
output reg [07:00] seg
);
// 例化连接线
wire [03:00] unit ;
wire [03:00] ten ;
wire [03:00] hun ;
wire [03:00] tho ;
wire [03:00] t_tho ;
wire [03:00] h_hun ;
bcd_8421 bcd_8421_insert(
.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 )
);
// reg signal define
reg [23:00] data_reg ;
reg [15:00] cnt_1ms ;
reg flag_1ms ;
reg [02:00] cnt_sel ;
reg [05:00] sel_reg ;
reg [03:00] data_disp ;
reg dot_disp ;
// data_reg
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
data_reg <= 24'd0 ;
end else begin
if(h_hun || point[5]) begin
data_reg <= {h_hun, t_tho, tho, hun, ten, unit} ;
end else begin
if((t_tho || point[4]) && sign == 1'b1) begin
data_reg <= {4'd10, t_tho, tho, hun, ten, unit} ;
end else begin
if((t_tho || point[4]) && sign == 1'b0) begin
data_reg <= {4'd11, t_tho, tho, hun, ten, unit} ;
end else begin
if((tho || point[3]) && sign == 1'b1) begin
data_reg <= {4'd11, 4'd10, tho, hun, ten, unit} ;
end else begin
if((tho || point[3]) && sign == 1'b0) begin
data_reg <= {4'd11, 4'd11, tho, hun, ten, unit} ;
end else begin
if((hun || point[2]) && sign == 1'b1) begin
data_reg <= {4'd11, 4'd11, 4'd10, hun, ten, unit} ;
end else begin
if((hun || point[2]) && sign == 1'b0) begin
data_reg <= {4'd11, 4'd11, 4'd11, hun, ten, unit} ;
end else begin
if((ten || point[1]) && sign == 1'b1) begin
data_reg <= {4'd11, 4'd11, 4'd11, 4'd10, ten, unit} ;
end else begin
if((ten || point[1]) && sign == 1'b0) begin
data_reg <= {4'd11, 4'd11, 4'd11, 4'd11, ten, unit} ;
end else begin
if((unit || point[0]) && sign == 1'b1) begin
data_reg <= {4'd11, 4'd11, 4'd11, 4'd11, 4'd10, unit} ;
end else begin
data_reg <= {4'd11, 4'd11, 4'd11, 4'd11, 4'd11, unit} ;
end
end
end
end
end
end
end
end
end
end
end
end
/* // localparam
localparam ZERO = 8'hc0 , // 8'b1100_0000
ONE = 8'hf9 , // 8'b1111_1001
TWO = 8'ha4 , // 8'b1010_0100
THREE = 8'hb0 , // 8'b1011_0000
FOUR = 8'h99 , // 8'b1001_1001
FIVE = 8'h92 , // 8'b1001_0010
SIX = 8'h82 , // 8'b1000_0010
SEVEN = 8'hf8 , // 8'b1111_1000
EIGHT = 8'h80 , // 8'b1000_0000
NINE = 8'h90 , // 8'b1001_0000
A = 8'h88 , // 8'b1000_1000
B = 8'h83 , // 8'b1000_0011
C = 8'hc6 , // 8'b1100_0110
D = 8'ha1 , // 8'b1011_0001
E = 8'h86 , // 8'b1000_0110
F = 8'h8e ; // 8'b1000_1110
*/
// [15:00] cnt_1ms ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_1ms <= 16'd0 ;
end else begin
if(seg_en) begin
if(cnt_1ms == MAX_1MS) begin
cnt_1ms <= 16'd0 ;
end else begin
cnt_1ms <= cnt_1ms + 16'd1 ;
end
end else begin
cnt_1ms <= 16'd0 ;
end
end
end
//flag_1ms 由于cnt_1ms 已经受seg_en 控制,所以flag_1ms 间接控制
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
flag_1ms <= 1'b0 ;
end else begin
if(cnt_1ms == ( MAX_1MS - 1'b1 )) begin
flag_1ms <= 1'b1 ;
end else begin
flag_1ms <= 1'b0 ;
end
end
end
// [02:00] cnt_sel ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_sel <= 3'd0 ;
end else begin
if(seg_en) begin
if(flag_1ms) begin
if(cnt_sel == 3'd5) begin
cnt_sel <= 3'd0 ;
end else begin
cnt_sel <= cnt_sel + 1'b1 ;
end
end else begin
cnt_sel <= cnt_sel ;
end
end else begin
cnt_sel <= 3'd0 ;
end
end
end
// [05:00] sel_reg ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
sel_reg <= 6'd0 ;
end else begin
if(seg_en) begin
if(flag_1ms) begin
case (cnt_sel)
0 : sel_reg <= 6'b000_001 ;
1 : sel_reg <= 6'b000_010 ;
2 : sel_reg <= 6'b000_100 ;
3 : sel_reg <= 6'b001_000 ;
4 : sel_reg <= 6'b010_000 ;
5 : sel_reg <= 6'b100_000 ;
default: sel_reg <= 6'b000_000 ;
endcase
end else begin
sel_reg <= sel_reg ;
end
end else begin
sel_reg <= 6'd0 ;
end
end
end
// [03:00] data_disp ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
data_disp <= 4'd0 ;
end else begin
if(seg_en) begin
if(flag_1ms) begin
case (cnt_sel)
0 : data_disp <= data_reg[03:00] ;// unit ; 000_001
1 : data_disp <= data_reg[07:04] ;// ten ; 000_010
2 : data_disp <= data_reg[11:08] ;// hun ;
3 : data_disp <= data_reg[15:12] ;// tho ;
4 : data_disp <= data_reg[19:16] ;// t_tho ;
5 : data_disp <= data_reg[23:20] ;// h_hun ;
default: data_disp <= 4'd11 ;
endcase
end else begin
data_disp <= data_disp ;
end
end else begin
data_disp <= 4'd11 ;
end
end
end
// dot_disp ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
dot_disp <= 1'b0 ;
end else begin
if(seg_en) begin
if(flag_1ms) begin
case (cnt_sel)
0 : dot_disp <= ~point[0] ;
1 : dot_disp <= ~point[1] ;
2 : dot_disp <= ~point[2] ;
3 : dot_disp <= ~point[3] ;
4 : dot_disp <= ~point[4] ;
5 : dot_disp <= ~point[5] ;
default: dot_disp <= 1'b0 ;
endcase
end else begin
dot_disp <= dot_disp ;
end
end else begin
dot_disp <= 1'b0 ;
end
end
end
/*
数码管段选 0 亮 1 不亮
数码管位选 0 没选中 1 选中
个位 对应 000——001 dig6
*/
// [05:00] sel ,
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
sel <= 6'd0 ;
end else begin
sel <= sel_reg ;
end
end
// [07:00] seg
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
seg <= 8'hff ;
end else begin
case (data_disp)
0 : seg <= {dot_disp, 7'b100_0000} ;
1 : seg <= {dot_disp, 7'b111_1001} ;
2 : seg <= {dot_disp, 7'b010_0100} ;
3 : seg <= {dot_disp, 7'b011_0000} ;
4 : seg <= {dot_disp, 7'b001_1001} ;
5 : seg <= {dot_disp, 7'b001_0010} ;
6 : seg <= {dot_disp, 7'b000_0010} ;
7 : seg <= {dot_disp, 7'b111_1000} ;
8 : seg <= {dot_disp, 7'b000_0000} ;
9 : seg <= {dot_disp, 7'b001_0000} ;
10 : seg <= 8'b1011_1111 ; // 显示负号
11 : seg <= 8'b1111_1111 ; // 不显示任何符号
default: seg <= 8'b1100_0000 ;
endcase
end
end
endmodule
`timescale 1ns/1ns
module test_rom_ctrl();
reg sys_clk ;
reg sys_rst_n ;
reg key_1 ;
reg key_2 ;
wire [7:0] addr ;
// Instantiation
rom_ctrl rom_ctrl_insert_t(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_1 ( key_1 ) ,
.key_2 ( key_2 ) ,
.addr ( addr )
);
parameter CYCLE = 20 ;
initial begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
key_1 <= 1'b0 ;
key_2 <= 1'b0 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( 210 ) ;
sys_rst_n <= 1'b0 ;
#( 10 ) ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( CYCLE * 100 ) ;
key_1 <= 1'b1 ;
#( CYCLE ) ;
key_1 <= 1'b0 ;
#( CYCLE * 100 ) ;
key_2 <= 1'b1 ;
#( CYCLE ) ;
key_2 <= 1'b0 ;
#( CYCLE * 100 ) ;
$stop ;
end
always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
// initial begin
// $timeformat(-9,0,"ns",6) ;
// /* (第一个位置)
// -9 是10 的负9次方 表示纳秒
// -3 表示毫秒
// */
// /* (第二个位置)
// 0 表示,小数点后显示的位数
// */
// /* (第三个位置)
// “打印字符” 与单位相对应
// */
// /* (第四个位置)
// 6 表示 打印的最小数字字符 是6个
// */
// $monitor("@time %t:sel=%b,seg=%b,cnt_16=%b,sum_tb=%b",$time,sel,seg,cnt_16) ; // 监测函数
// end
endmodule
?
?
?
`timescale 1ns/1ns
module test_top();
reg sys_clk ;
reg sys_rst_n ;
reg key_1 ;
reg key_2 ;
wire ds ;
wire oe ;
wire shcp ;
wire stcp ;
reg [7:0] cnt_tb ;
// Instantiation
top top_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_1 ( key_1 ) ,
.key_2 ( key_2 ) ,
.ds ( ds ) ,
.oe ( oe ) ,
.shcp ( shcp ) ,
.stcp ( stcp )
);
parameter CYCLE = 20 ;
defparam top_insert.key_filter_insert1.MAX_CNT_20MS = 50 ;
defparam top_insert.rom_ctrl_insert.MAX_CNT_500MS = 50 ;
initial begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
key_1 <= 1'b0 ;
key_2 <= 1'b0 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( 210 ) ;
sys_rst_n <= 1'b0 ;
#( 10 ) ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( CYCLE * 1000 ) ;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_tb <= 0 ;
end else begin
if(cnt_tb == 249) begin
cnt_tb <= 0 ;
end else begin
cnt_tb <= cnt_tb + 1'b1 ;
end
end
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_1 <= 1'b1 ;
end else begin
if(( 0 <= cnt_tb && cnt_tb <= 19 )||( 220 <= cnt_tb && cnt_tb <= 249 )) begin
key_1 <= 1'b1 ;
end else begin
if(( 20 <= cnt_tb && cnt_tb <= 69 )||( 170 <= cnt_tb && cnt_tb <= 219 ) ) begin
key_1 <= ($random) % 2 ;
end else begin
if(70 <= cnt_tb && cnt_tb <= 169) begin
key_1 <= 1'b0 ;
end else begin
key_1 <= key_1 ;
end
end
end
end
end
always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
// initial begin
// $timeformat(-9,0,"ns",6) ;
// /* (第一个位置)
// -9 是10 的负9次方 表示纳秒
// -3 表示毫秒
// */
// /* (第二个位置)
// 0 表示,小数点后显示的位数
// */
// /* (第三个位置)
// “打印字符” 与单位相对应
// */
// /* (第四个位置)
// 6 表示 打印的最小数字字符 是6个
// */
// $monitor("@time %t:sel=%b,seg=%b,cnt_16=%b,sum_tb=%b",$time,sel,seg,cnt_16) ; // 监测函数
// end
endmodule
?
?
?
?
?
文章来源:https://blog.csdn.net/Meng_long2022/article/details/132748090
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!