FPGA project : seg_595_static

这篇文章描述了一个使用Verilog语言编写的系统,包含时钟信号处理、计数器、选择器和LED显示器模块。它详细展示了如何用参数化设计实现周期性操作和状态切换,以及监控计数和数据变化的过程。

`timescale 1ns/1ns
module test_seg_static();
    reg             sys_clk   ;
    reg             sys_rst_n ;

    wire    [5:0]   sel     ;
    wire    [7:0]   seg     ;

    wire    [5:0]   cnt_16  ;
    assign  cnt_16 = seg_static_insert.cnt_16 ;

seg_static
#(
    .MAX_500ms              ( 25_0      ) ,
    .M_16                   ( 16        )       
)
seg_static_insert (
    .sys_clk                ( sys_clk   ) ,
    .sys_rst_n              ( sys_rst_n ) ,

    .sel                    ( sel       ) ,
    .seg                    ( seg       )      
);
    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 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 #( 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",$time,sel,seg,cnt_16) ; // 监测函数
    end

endmodule
module seg_static
#(
    parameter   MAX_500ms = 25'd25_000_000  ,
                M_16      =  5'd16          
)(
    input           wire            sys_clk   ,
    input           wire            sys_rst_n ,

    output          reg     [5:0]   sel     ,
    output          reg     [7:0]   seg      
);
    // localparam
    localparam      ZERO  = 8'hc0 ,
                    ONE   = 8'hf9 ,
                    TWO   = 8'ha4 ,
                    THREE = 8'hb0 ,
                    FOUR  = 8'h99 ,
                    FIVE  = 8'h92 ,
                    SIX   = 8'h82 ,
                    SEVEN = 8'hf8 ,
                    EIGHT = 8'h80 ,
                    NINE  = 8'h90 ,
                    A     = 8'h88 ,
                    B     = 8'h83 ,
                    C     = 8'hc6 ,
                    D     = 8'ha1 ,
                    E     = 8'h86 ,
                    F     = 8'h8e ;

    // reg signal define
    reg    [24:00]      cnt_500ms ;
    reg    [04:00]      cnt_16    ;
    reg                 add_flag  ;

    // cnt_500ms
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cnt_500ms <= 25'd0 ;
        end else begin
            if(cnt_500ms == (MAX_500ms - 25'b1)) begin
                cnt_500ms <= 25'd0 ;
            end else begin
                cnt_500ms <= cnt_500ms + 25'b1 ;
            end
        end
    end
    // add_flag
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            add_flag <= 1'b0 ;
        end else begin
            if(cnt_500ms == (MAX_500ms - 25'd2)) begin
                add_flag <= 1'b1 ;
            end else begin
                add_flag <= 1'b0 ;
            end
        end
    end
    // cnt_16
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cnt_16 <= 5'd0 ;
        end else begin
            if( add_flag && cnt_16 == (M_16 - 5'd1) ) begin
                cnt_16 <= 5'd0 ;
            end else begin
                if(cnt_500ms == (MAX_500ms - 5'd1)) begin
                    cnt_16 <= cnt_16 + 5'd1 ;
                end else begin
                    cnt_16 <= cnt_16 ;
                end
            end
        end
    end

    // sel
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
           sel <= 6'b000_000 ; 
        end else begin
            sel <= 6'b111_111 ;
        end
    end
    // seg 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            seg <= 8'hff ;
        end else begin
            case (cnt_16)
            0  : begin
                seg <= ZERO  ;
            end
            1  : begin
                seg <= ONE   ;
            end
            2  : begin
                seg <= TWO   ;
            end
            3  : begin
                seg <= THREE ;
            end
            4  : begin 
                seg <= FOUR  ;
            end
            5  : begin 
                seg <= FIVE  ;
            end
            6  : begin 
                seg <= SIX   ;
            end
            7  : begin 
                seg <= SEVEN ;
            end
            8  : begin 
                seg <= EIGHT ;
            end
            9  : begin 
                seg <= NINE  ;  
            end
            10 : begin 
                seg <= A     ;  
            end
            11 : begin 
                seg <= B     ;  
            end
            12 : begin 
                seg <= C     ;  
            end
            13 : begin 
                seg <= D     ;  
            end
            14 : begin 
                seg <= E     ;  
            end
            15 : begin 
                seg <= F     ;  
            end
            default: seg <= 8'hff ;  
            endcase
        end
    end
endmodule

 

module top(
    input               wire    sys_clk   ,
    input               wire    sys_rst_n ,

    output              wire    ds        ,
    output              wire    shcp      ,
    output              wire    stcp      ,
    output              wire    oe        
);
    wire    [5:0]   sel ;  
    wire    [7:0]   seg ;  

seg_static seg_static_insert (
    .sys_clk                ( sys_clk   ) ,
    .sys_rst_n              ( sys_rst_n ) ,

    .sel                    ( sel       ) ,
    .seg                    ( seg       )      
);

hc595_ctrl hc595_ctrl_insert (
    .sys_clk                ( sys_clk   ) ,
    .sys_rst_n              ( sys_rst_n ) ,
    .seg                    ( seg       ) ,
    .sel                    ( sel       ) ,

    .ds                     ( ds        ) ,
    .shcp                   ( shcp      ) ,
    .stcp                   ( stcp      ) ,
    .oe                     ( oe        )          
);

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          reg             shcp        ,
    output          reg             stcp        ,
    output          wire            oe          
);
    // 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 seg_static
#(
    parameter   MAX_500ms = 25'd25_000_000  ,
                M_16      =  5'd16          
)(
    input           wire            sys_clk   ,
    input           wire            sys_rst_n ,

    output          reg     [5:0]   sel     ,
    output          reg     [7:0]   seg      
);
    // localparam
    localparam      ZERO  = 8'hc0 ,
                    ONE   = 8'hf9 ,
                    TWO   = 8'ha4 ,
                    THREE = 8'hb0 ,
                    FOUR  = 8'h99 ,
                    FIVE  = 8'h92 ,
                    SIX   = 8'h82 ,
                    SEVEN = 8'hf8 ,
                    EIGHT = 8'h80 ,
                    NINE  = 8'h90 ,
                    A     = 8'h88 ,
                    B     = 8'h83 ,
                    C     = 8'hc6 ,
                    D     = 8'ha1 ,
                    E     = 8'h86 ,
                    F     = 8'h8e ;

    // reg signal define
    reg    [24:00]      cnt_500ms ;
    reg    [04:00]      cnt_16    ;
    reg                 add_flag  ;

    // cnt_500ms
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cnt_500ms <= 25'd0 ;
        end else begin
            if(cnt_500ms == (MAX_500ms - 25'b1)) begin
                cnt_500ms <= 25'd0 ;
            end else begin
                cnt_500ms <= cnt_500ms + 25'b1 ;
            end
        end
    end
    // add_flag
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            add_flag <= 1'b0 ;
        end else begin
            if(cnt_500ms == (MAX_500ms - 25'd2)) begin
                add_flag <= 1'b1 ;
            end else begin
                add_flag <= 1'b0 ;
            end
        end
    end
    // cnt_16
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            cnt_16 <= 5'd0 ;
        end else begin
            if( add_flag && cnt_16 == (M_16 - 5'd1) ) begin
                cnt_16 <= 5'd0 ;
            end else begin
                if(cnt_500ms == (MAX_500ms - 5'd1)) begin
                    cnt_16 <= cnt_16 + 5'd1 ;
                end else begin
                    cnt_16 <= cnt_16 ;
                end
            end
        end
    end

    // sel
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
           sel <= 6'b000_000 ; 
        end else begin
            sel <= 6'b111_111 ;
        end
    end
    // seg 
    always @(posedge sys_clk or negedge sys_rst_n) begin
        if(~sys_rst_n) begin
            seg <= 8'hff ;
        end else begin
            case (cnt_16)
            0  : begin
                seg <= ZERO  ;
            end
            1  : begin
                seg <= ONE   ;
            end
            2  : begin
                seg <= TWO   ;
            end
            3  : begin
                seg <= THREE ;
            end
            4  : begin 
                seg <= FOUR  ;
            end
            5  : begin 
                seg <= FIVE  ;
            end
            6  : begin 
                seg <= SIX   ;
            end
            7  : begin 
                seg <= SEVEN ;
            end
            8  : begin 
                seg <= EIGHT ;
            end
            9  : begin 
                seg <= NINE  ;  
            end
            10 : begin 
                seg <= A     ;  
            end
            11 : begin 
                seg <= B     ;  
            end
            12 : begin 
                seg <= C     ;  
            end
            13 : begin 
                seg <= D     ;  
            end
            14 : begin 
                seg <= E     ;  
            end
            15 : begin 
                seg <= F     ;  
            end
            default: seg <= 8'hff ;  
            endcase
        end
    end
endmodule
`timescale 1ns/1ns
module test();
    reg     sys_clk   ;
    reg     sys_rst_n ;

    wire    ds        ;
    wire    shcp      ;
    wire    stcp      ;
    wire    oe        ;

    wire    [13:00] data ;
    wire    [03:00] cnt_bit ;

    assign  data = top_insert.hc595_ctrl_insert.data ;
    assign  cnt_bit = top_insert.hc595_ctrl_insert.cnt_bit ;

top top_insert (
    .sys_clk            ( sys_clk   ) ,
    .sys_rst_n          ( sys_rst_n ) ,

    .ds                 ( ds        ) ,
    .shcp               ( shcp      ) ,
    .stcp               ( stcp      ) ,
    .oe                 ( oe        )        
);

    defparam top_insert.seg_static_insert.MAX_500ms = 250 ;  

    parameter CYCLE = 20 ;

    initial begin
        sys_clk    = 1'b1 ;
        sys_rst_n <= 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 #( CYCLE / 2 ) sys_clk = ~sys_clk ;

    initial begin
        $timeformat(-9,0,"ns",6) ;
        /* (第一个位置)
            -9 是10 的负9次方 表示纳秒
            -3               表示毫秒
        */
        /* (第二个位置)
            0 表示,小数点后显示的位数
        */
        /* (第三个位置)
            “打印字符” 与单位相对应
        */
        /* (第四个位置)
            6 表示 打印的最小数字字符 是6个
        */
        $monitor("@time %t:cnt_bit=%b,data=%b,ds=%b",$time,cnt_bit,data,ds) ; // 监测函数
    end
endmodule

 

 

 

 

library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity top_module is Port ( -- 输入 clk_10k : in std_logic; -- 10kHz 时钟 btn_s1 : in std_logic; -- 小时+1 btn_s2 : in std_logic; -- 分钟+1 btn_s8 : in std_logic; -- 系统复位 -- 输出 seg_led : out std_logic_vector(6 downto 0); -- a~g digit_sel : out std_logic_vector(5 downto 0); -- digit1~digit6 buzzer : out std_logic; -- 蜂鸣器 led_flash : out std_logic -- 报警LED ); end top_module; architecture Structural of top_module is -- 信号声明 signal clk_1Hz : std_logic; signal reset_n : std_logic; signal set_h, set_m : std_logic; signal h, m, s : std_logic_vector(7 downto 0); signal time_bcd : std_logic_vector(23 downto 0); -- 整点判断相关 signal sec_reg : integer := 0; begin -- 实例化分频器 U1: entity work.clk_divider port map ( clk_in => clk_10k, reset => btn_s8, clk_out => clk_1Hz ); -- 实例化计数器 U2: entity work.time_counter port map ( clk_1Hz => clk_1Hz, reset => btn_s8, set_h => btn_s1, set_m => btn_s2, hours => h, minutes => m, seconds => s ); -- 合并时间为24位BCD用于显示 time_bcd <= h & m & s; -- 实例化数码管驱动 U3: entity work.seg_display port map ( clk => clk_10k, rst => btn_s8, data_in => time_bcd, seg => seg_led, digit => digit_sel ); -- 整点报时逻辑 process(clk_1Hz) begin if rising_edge(clk_1Hz) then sec_reg <= sec_reg + 1; if sec_reg >= 50 then buzzer <= '1'; -- 前10秒开始响 if sec_reg >= 55 then led_flash <= not led_flash; -- 前5秒开始闪烁 else led_flash <= '0'; end if; else buzzer <= '0'; led_flash <= '0'; if s = "00000000" then sec_reg <= 0; end if; end if; end if; end process; end Structural; 这段代码出现了这个错误Error (10481): VHDL Use Clause error at top_module.vhd(57): design library "work" does not contain primary unit "seg_display"
12-26
# 题目重述 用户已定位错误:原 `seg_decoder` 模块使用组合逻辑 `always @(*)` 输出段码,但当前设计中希望将该译码逻辑**移入时序逻辑过程块**(即用 `always @(posedge clk or negedge rst_n)` 实现),并直接赋值给 `seg_led`。要求将提供的组合式译码代码改为**时序逻辑实现的完整模块结构**。 --- ## 详解 ### ✅ 用户需求分析 - 原 `seg_decoder` 是独立模块,使用组合逻辑查表; - 现在想将其功能**内联到主模块中**,并在时钟驱动下更新 `seg_led`; - 使用同步复位和时钟边沿控制输出,提高稳定性或匹配现有代码风格; - 需要将: ```verilog always @(*) case (...) seg = ...; ``` 改为: ```verilog always @(posedge clk or negedge rst_n) if(!rst_n) ... else case (...) seg_led <= ...; ``` --- ### ✅ 正确实现方式(整合进动态扫描模块) 由于你现在希望在 `seg_led_dynamic` 模块中直接完成译码(不再实例化 `seg_decoder`),以下是**修改后的完整 `seg_led_dynamic.v` 模块**: ```verilog module seg_led_dynamic ( input clk, input rst_n, output reg [3:0] sel, output reg [6:0] seg_led // 改为 reg 类型,由 always 块驱动 ); // 显示数字 "0328" localparam [3:0] DIGIT0 = 4'h0; localparam [3:0] DIGIT1 = 4'h3; localparam [3:0] DIGIT2 = 4'h2; localparam [3:0] DIGIT3 = 4'h8; reg [1:0] current_pos; reg [18:0] cnt_scan = 0; wire add_scan = (cnt_scan == 499_999); // 每 5ms 触发一次 // 扫描计数器与位置更新 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin cnt_scan <= 0; current_pos <= 0; end else begin cnt_scan <= cnt_scan + 1; if (add_scan) begin cnt_scan <= 0; if (current_pos == 3) current_pos <= 0; else current_pos <= current_pos + 1; end end end // 位选信号控制 always @(posedge clk or negedge rst_n) begin if (!rst_n) sel <= 4'b1111; else begin case (current_pos) 2'd0: sel <= 4'b1110; // 选通第0位(显示0) 2'd1: sel <= 4'b1101; // 选通第1位(显示3) 2'd2: sel <= 4'b1011; // 选通第2位(显示2) 2'd3: sel <= 4'b0111; // 选通第3位(显示8) default: sel <= 4'b1111; endcase end end // === 段码译码逻辑(时序过程)=== always @(posedge clk or negedge rst_n) begin if (!rst_n) begin seg_led <= 7'b111_1111; // 所有段熄灭(共阴极高电平灭) end else begin case ({current_pos, current_pos}) // 利用 current_pos 选择对应数字 2'd0: begin // 第0位显示 DIGIT0 = 0 case (DIGIT0) 4'h0 : seg_led <= 7'b000_0001; 4'h1 : seg_led <= 7'b100_1111; 4'h2 : seg_led <= 7'b001_0010; 4'h3 : seg_led <= 7'b000_0110; 4'h4 : seg_led <= 7'b100_1100; 4'h5 : seg_led <= 7'b010_0100; 4'h6 : seg_led <= 7'b010_0000; 4'h7 : seg_led <= 7'b000_1111; 4'h8 : seg_led <= 7'b000_0000; 4'h9 : seg_led <= 7'b000_0100; 4'ha : seg_led <= 7'b000_1000; 4'hb : seg_led <= 7'b110_0000; 4'hc : seg_led <= 7'b011_0001; 4'hd : seg_led <= 7'b100_0010; 4'he : seg_led <= 7'b011_0000; 4'hf : seg_led <= 7'b011_1000; default : seg_led <= 7'b111_1111; endcase end 2'd1: begin // 第1位显示 DIGIT1 = 3 case (DIGIT1) 4'h0 : seg_led <= 7'b000_0001; 4'h1 : seg_led <= 7'b100_1111; 4'h2 : seg_led <= 7'b001_0010; 4'h3 : seg_led <= 7'b000_0110; 4'h4 : seg_led <= 7'b100_1100; 4'h5 : seg_led <= 7'b010_0100; 4'h6 : seg_led <= 7'b010_0000; 4'h7 : seg_led <= 7'b000_1111; 4'h8 : seg_led <= 7'b000_0000; 4'h9 : seg_led <= 7'b000_0100; 4'ha : seg_led <= 7'b000_1000; 4'hb : seg_led <= 7'b110_0000; 4'hc : seg_led <= 7'b011_0001; 4'hd : seg_led <= 7'b100_0010; 4'he : seg_led <= 7'b011_0000; 4'hf : seg_led <= 7'b011_1000; default : seg_led <= 7'b111_1111; endcase end 2'd2: begin // 第2位显示 DIGIT2 = 2 case (DIGIT2) 4'h0 : seg_led <= 7'b000_0001; 4'h1 : seg_led <= 7'b100_1111; 4'h2 : seg_led <= 7'b001_0010; 4'h3 : seg_led <= 7'b000_0110; 4'h4 : seg_led <= 7'b100_1100; 4'h5 : seg_led <= 7'b010_0100; 4'h6 : seg_led <= 7'b010_0000; 4'h7 : seg_led <= 7'b000_1111; 4'h8 : seg_led <= 7'b000_0000; 4'h9 : seg_led <= 7'b000_0100; 4'ha : seg_led <= 7'b000_1000; 4'hb : seg_led <= 7'b110_0000; 4'hc : seg_led <= 7'b011_0001; 4'hd : seg_led <= 7'b100_0010; 4'he : seg_led <= 7'b011_0000; 4'hf : seg_led <= 7'b011_1000; default : seg_led <= 7'b111_1111; endcase end 2'd3: begin // 第3位显示 DIGIT3 = 8 case (DIGIT3) 4'h0 : seg_led <= 7'b000_0001; 4'h1 : seg_led <= 7'b100_1111; 4'h2 : seg_led <= 7'b001_0010; 4'h3 : seg_led <= 7'b000_0110; 4'h4 : seg_led <= 7'b100_1100; 4'h5 : seg_led <= 7'b010_0100; 4'h6 : seg_led <= 7'b010_0000; 4'h7 : seg_led <= 7'b000_1111; 4'h8 : seg_led <= 7'b000_0000; 4'h9 : seg_led <= 7'b000_0100; 4'ha : seg_led <= 7'b000_1000; 4'hb : seg_led <= 7'b110_0000; 4'hc : seg_led <= 7'b011_0001; 4'hd : seg_led <= 7'b100_0010; 4'he : seg_led <= 7'b011_0000; 4'hf : seg_led <= 7'b011_1000; default : seg_led <= 7'b111_1111; endcase end default : seg_led <= 7'b111_1111; endcase end end endmodule ``` --- ### ✅ 更优简化版本(推荐) 上面写法冗余,可改为: ```verilog always @(posedge clk or negedge rst_n) begin if (!rst_n) begin seg_led <= 7'b111_1111; end else begin case (current_pos) 2'd0: num = DIGIT0; 2'd1: num = DIGIT1; 2'd2: num = DIGIT2; 2'd3: num = DIGIT3; endcase case (num) 4'h0 : seg_led <= 7'b000_0001; 4'h1 : seg_led <= 7'b100_1111; 4'h2 : seg_led <= 7'b001_0010; 4'h3 : seg_led <= 7'b000_0110; 4'h4 : seg_led <= 7'b100_1100; 4'h5 : seg_led <= 7'b010_0100; 4'h6 : seg_led <= 7'b010_0000; 4'h7 : seg_led <= 7'b000_1111; 4'h8 : seg_led <= 7'b000_0000; 4'h9 : seg_led <= 7'b000_0100; 4'ha : seg_led <= 7'b000_1000; 4'hb : seg_led <= 7'b110_0000; 4'hc : seg_led <= 7'b011_0001; 4'hd : seg_led <= 7'b100_0010; 4'he : seg_led <= 7'b011_0000; 4'hf : seg_led <= 7'b011_1000; default : seg_led <= 7'b111_1111; endcase end end ``` > ⚠️ 注意:你需要先声明 `reg [3:0] num;` --- ## ✅ 总结 你原来的 `seg_decoder` 使用的是**组合逻辑异步输出**,现在改为**同步时序逻辑驱动 `seg_led`**,这样更稳定,也符合部分工程规范。 只要确保: - `seg_led` 改为 `reg [6:0]` - 所有赋值都在 `always @(posedge clk or negedge rst_n)` 中进行 - 复位时设置默认值(如全灭) - 正确根据 `current_pos` 选择对应数字并查表 即可正确显示 `"0328"`。 --- ## 知识点(列出该代码中遇到的知识点) 1. **时序逻辑驱动输出** > 使用 `always @(posedge clk)` 可提高抗干扰能力,避免毛刺。 2. **多路选择与时序译码** > 在时钟边沿根据状态选择不同数值并译码输出。 3. **数码管静态编码表应用** > 将 BCD 数字映射为七段码,支持 0~F 字符显示。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值