首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Verilog FSM被优化

Verilog FSM被优化
EN

Stack Overflow用户
提问于 2022-02-10 22:30:14
回答 2查看 202关注 0票数 -1

新的Verilog,Basys3板和Vivid 2021.2。

尝试用停止/启动和Lap/重置按钮实现一个典型的秒表。

分频器从板时钟产生1 1kHz和100 to时钟,100 to用于按钮拆卸(和7段显示复用,旁边待办),1 1kHz驱动20位5×4位BCD计数器,低16位驱动锁存显示,锁存器驱动板上的LED 16。

我已经测试了“连线”这个和模块执行预期。只有当我加入FSM的时候我才会遇到麻烦。

FSM简单,两个按钮决定状态变化,状态设置三个输出来控制计数器。

状态模块通过了许多版本,尝试使用敏感列表中的按钮,尝试使用按钮边缘和级别,尝试*,尝试阻塞和非阻塞分配,但无法正确完成。当前的错误是:

Synth 8-3332顺序元素(state/transfer_reg)未使用,将从模块秒表中删除。

错误改变了,但是它总是合成8-3332删除一些东西,甚至是curr_state或next_state。

RTL的合成原理图正好显示了我所期望的,后来的原理图显示了两个按钮,16个LED,中间什么都没有。

我在这个阶段迷失了方向,是不是错过了一些最基本的东西?

代码语言:javascript
复制
`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// 
// Create Date: 02/02/2022 0800
//  
// Module Name: state
// Project Name: Stop Watch
// Target Devices: BASYS 3
// 
// state machine
//
//      inputs:
//              start-stop button via debounce (both edg and level are available)
//              lap-reset buttonvia debounce (both edg and level are available)
//
//      outputs:
//              control 4 x 4 bit BCD counters and output latch
//              clear state
//              enabvble couter to count
//.             transfer counter value to latch
//
////////////////////////////////////////////////////////////////////////////////

module state (
    input clk,
    input lap_reset,
    input start_stop,
    output reg clear,
    output reg enable,
    output reg transfer
    );

    // state encodings
    localparam  
        RESET_0     = 3'd0,
        STOPPED_1   = 3'd1,
        RUNNING_2   = 3'd2,
        PRELAP_3    = 3'd3,
        LAP_4       = 3'd4;
                
    // state reg
    reg[2:0] curr_state;
    reg[2:0] next_state;
    
    // setup
    initial
        begin
            curr_state <= RESET_0;
            next_state <= RESET_0;
            enable <= 0;
            clear <= 0;
            transfer <= 0;                    
        end

    // sync state transitons to clk
//    always @ (posedge clk)
//        begin
//            curr_state <= next_state;
//        end

    // state machine
     always @ (posedge clk)
        begin
            curr_state <= next_state;
            case (curr_state)
                RESET_0:
                    begin
                        // init, stop counter, clear counter
                        // transfer count to latch
                        enable <= 0;
                        clear <= 1;
                        transfer <= 1;
                        next_state <= STOPPED_1;
                    end
                STOPPED_1:
                    begin
                        // stop counter, clear counter
                        enable <= 0;
                        clear <= 0;
                        transfer <= 0;
                        if (start_stop)
                            next_state <= STOPPED_1;
                        else if (lap_reset)
                            next_state <= RESET_0;
                        else
                            next_state <= curr_state;
                    end
                RUNNING_2:
                    begin
                        // start or continue counting
                        // transfer count to latch
                        enable <= 1;
                        clear <= 0;
                        transfer <= 1;
                        if (start_stop)
                            next_state <= STOPPED_1;
                        else if (lap_reset)
                            next_state <= PRELAP_3;                  
                        else
                            next_state <= curr_state;
                    end                
                PRELAP_3:
                    begin
                        // start or continue counting
                        // don't update latch
                        enable <= 1;
                        clear <= 0;
                        transfer <= 0;
                        next_state <= LAP_4;
                    end                
                LAP_4:
                    begin
                        // continue counting
                        // transfer counter to latch
                        enable <= 1;
                        clear <= 0;
                        transfer <= 1;
                        if (start_stop)
                            next_state <= RUNNING_2;
                        else if (lap_reset)
                            next_state <= PRELAP_3;
                        else
                            next_state <= curr_state;
                    end
                default:
                    begin
                        enable <= 0;
                        clear <= 0;
                        transfer <= 0;                    
                        next_state <= RESET_0;
                    end                    
            endcase            
        end
endmodule
EN

回答 2

Stack Overflow用户

发布于 2022-02-18 10:13:17

终于有进展了,谢谢大家。

在纠正了逻辑错误和几个常量0'b0之后(编译器没有抱怨它们),并建议修复我的秒表。

SM结构是三个块,同步转换,下一个状态'gotos‘和状态动作。我从建议的clk @ (*)开始,但必须更改为高级clk才能工作,但不确定原因。

去掉推断出的锁锁,现在明白它们为什么会出现了。

关于产生复位信号,我假设Artix芯片有一个,但在所提供的xdc文件中没有提到它,我试图模拟一个复位保持低(活动),然后在很短的时间后,由一个时钟分配器决定-它应该有一个重置.还可以阅读Xilinx WP272,它讲述了一个不同的故事。

再次感谢。

票数 0
EN

Stack Overflow用户

发布于 2022-02-14 18:45:33

刚从Www.javatpoint.com/verilog-初始块

“初始块是不可综合的,不能转换成带有数字元素的硬件原理图。初始块没有比模拟更多的用途。这些块主要用于初始化变量和驱动具有特定值的设计端口。”

我现在还不确定FPGA的代码,但是在普通的ASIC中,我会删除“初始”代码部分,您将使用它来实现重置行为,并在“始终”中添加一个实际的重置部分。

代码语言:javascript
复制
always@(posedge clk)
begin
  if (rst) begin
    // do the reset
    curr_state <= RESET_0;
    next_state <= RESET_0;
    enable <= 0;
    clear <= 0;
    transfer <= 0;
  end else begin
    // the rest
  end
end

编辑:

永远不要离开一个没有默认值的信号,因为它会推断锁存器而不是触发器,这在推断顺序逻辑时会产生问题(当然,锁存在某些情况下是有用的)。

当一个人想要建立一个有限状态机(FSM),有两种常见的方法:米利和摩尔。我将解释如何使用Moore FSM实现顺序逻辑:

  1. 一个同步的始终@块来写入状态: cur_state <= next状态。
  2. 一种基于next_state和输入生成cur_state值的组合块。
  3. 一种基于状态产生输出的组合块。 始终@(高级clk,rst)开始if (rst = '1') cur_state <= State_0;end State_1 cur_state <= next_state;end always_comb (cur_state,my_inputA)开始if (cur_state= State_0) if(my_inputA) next_state = State_1;else next_state = Stage_0;如果(cur_state = State_1)开始next_state = State_2;结束always_comb (cur_state )开始如果(cur_state = State_0)开始my_outputA = '1';结束如果(cur_state = State_1)开始my_outputA = '0';结束如果(cur_state= State_2)开始my_outputA = '1';结束
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71073074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档