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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。