关于fpga多模块共用复位信号

最近在学习fpga,用的是小脚丫的 Altera STEP-MAX10 V2.0 (10M08SAM153C8G) 板子,利用提供的STP MAX10实验指导书,实验18,秒表计时器,共3个模块:主模块Couter60、子模块1(分频模块,产生秒钟信号)、子模块2(两位数码管显示模块)。先上主模块代码:

问题部分代码:

/*
* 本模块输入、输出接口
*
*/
module Counter60
(
    input wire clk,rst,    //时钟和复位信号输入
    input wire key,         //启动暂停按键
    output wire [8:0] segment_led1, segment_led2      //数码管输出
);

/*
*中间变量,只在程序内部使用;
*/
wire clk1h;         //1秒时钟
reg [7:0] cnt ;     //计时计数器
reg flag;                //暂停启动标志

initial begin
    cnt <= 8'h33;
    flag <= 1'b1;             //启动时就可以是计数;
end
//调用另外一个模块:分频器;例化1个分频器,产生秒钟信号
divideFreq #            //例化分频器产生1秒时钟信号
(
    .WIDTH(24),
    .N(12_000_000)
)u1
(
    .clk(clk),
    .rst_n(rst),
    .clkout(clk1h)
);

// rst, key 平常为高
always @(posedge clk) begin     //产生标志信号
    if(!rst)
        flag <= 1'b0;  //复位   
 
    else 
        if(!key) //  保持或者继续计数
            flag = ~flag;   //键盘按下,翻转
        else
            flag = flag;   //键盘不按,保持

end

always @(posedge clk1h) 
begin  //产生60进制计数器
    if(!rst)
        cnt <= 8'h00;       //复位初值显示00
    else 
        begin
            if(flag)           //标志位为1,计数
                begin           //完成60秒的计数
                    if(cnt[3:0] == 4'd9)                //个位满九?
                        begin
                            cnt[3:0] <= 4'd0;          //个位清零
                            if(cnt[7:4] == 4'd5)        //十位满5
                                cnt[7:4] <= 4'd0;        //十位清零
                            else
                                cnt[7:4] <= cnt[7:4] + 1'b1; //十位加一
                                    
                        end
                    else cnt[3:0] <= cnt[3:0] + 1'b1;          //个位加一

                end
            else                    //标志位为0,保持
                cnt <= cnt;
            
        end

   
end

Segment u2
(
    .seg_data_1(cnt[7:4]),
    .seg_data_2(cnt[3:0]),
    .segment_led_1(segment_led1),
    .segment_led_2(segment_led2)
);

endmodule

分配管脚,编译,下载测试,当按复位键(rst)时,数码管式中处于保持状态,不能按照程序写的复位清零。

主模块的逻辑想不出问题,fpga  初级阶段的我认为:这个是不是很难通过仿真发现内部问题在哪里啊???内部某处逻辑的问题,导致执行结果(输出)是不对的,但是内部逻辑问题出在哪里,怎么找?不像单片机,我可以单步走走去发现!!!知道如何仿真发现内部逻辑问题的可以教教我。

只能根据经验判断问题出在rst处逻辑出问题了,突然想到,是不是rst与子模块1(分频模块,产生秒钟信号)共用,是不是按键复位,搞乱了很重要的秒钟信号,从而使得此处逻辑不对?

always @(posedge clk1h) 
begin  //产生60进制计数器
    if(!rst)
        cnt <= 8'h00;       //复位初值显示00
    else  .....

于是想法验证,不共用复位逻辑:复位控制的rst,与子模块1(分频模块,产生秒钟信号)复位的控制分开,不共用进行测试:rst只管主模块的复位,clear_divideFreq管子模块1的复位:

想法验证代码:

/*
* 本模块输入、输出接口
*
*/
module Counter60
(
    input wire clk,rst, clear_divideFreq,    //时钟和复位信号输入
    input wire key,         //启动暂停按键
    output wire [8:0] segment_led1, segment_led2      //数码管输出
);

/*
*中间变量,只在程序内部使用;
*/
wire clk1h;         //1秒时钟
reg [7:0] cnt ;     //计时计数器
reg flag;                //暂停启动标志

initial begin
    cnt <= 8'h33;
    flag <= 1'b1;             //启动时就可以是计数;
end
//调用另外一个模块:分频器;例化1个分频器,产生秒钟信号
divideFreq #            //例化分频器产生1秒时钟信号
(
    .WIDTH(24),
    .N(12_000_000)
)u1
(
    .clk(clk),
    .rst_n(clear_divideFreq),
    .clkout(clk1h)
);

// rst, key 平常为高
always @(posedge clk) begin     //产生标志信号
    if(!rst)
        flag <= 1'b0;  //复位   
 
    else 
        if(!key) //  保持或者继续计数
            flag = ~flag;   //键盘按下,翻转
        else
            flag = flag;   //键盘不按,保持

end

always @(posedge clk1h) 
begin  //产生60进制计数器
    if(!rst)
        cnt <= 8'h00;       //复位初值显示00
    else 
        begin
            if(flag)           //标志位为1,计数
                begin           //完成60秒的计数
                    if(cnt[3:0] == 4'd9)                //个位满九?
                        begin
                            cnt[3:0] <= 4'd0;          //个位清零
                            if(cnt[7:4] == 4'd5)        //十位满5
                                cnt[7:4] <= 4'd0;        //十位清零
                            else
                                cnt[7:4] <= cnt[7:4] + 1'b1; //十位加一
                                    
                        end
                    else cnt[3:0] <= cnt[3:0] + 1'b1;          //个位加一

                end
            else                    //标志位为0,保持
                cnt <= cnt;
            
        end

   
end

Segment u2
(
    .seg_data_1(cnt[7:4]),
    .seg_data_2(cnt[3:0]),
    .segment_led_1(segment_led1),
    .segment_led_2(segment_led2)
);

endmodule

完美的结果出现,bug排除。

疑问: 

fpga如何像单片机一样,能够单步执行,知道每一步的结果,方便排除逻辑bug?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值