设计模式在芯片验证中的应用——状态

一、状态模式

状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。

在RTL中可能存在复杂的有限状态机FSM,在任何一个特定状态中, RTL的行为都不相同, 且可从一个状态切换到另一个状态。 不过, 根据当前状态, RTL可能会切换到另外一种状态, 也可能会保持当前状态不变。 这些数量有限且预先定义的状态切换规则被称为转移。

为了对RTL FSM进行建模,状态设计模式建议将每个状态的行为抽象成一个类,状态之间的切换相当于就是类对象的切换。主要可包括以下几个组件:

  • Context:它并不会自行实现所有行为, 而是会保存一个指向表示当前状态的状态对象的引用, 且将所有与状态相关的工作委派给该对象。
  • State:所有状态类的基类,所有状态类都必须遵循同样的接口, 而且context必须仅通过state提供的接口函数与这些对象进行交互。
  • Concrete States:会自行实现特定于状态的方法。 为了避免多个状态中包含相似代码, 你可以提供一个封装有部分通用行为的中间抽象类。状态对象可存储对于上下文对象的反向引用。 状态可以通过该引用从上下文处获取所需信息, 并且能触发状态转移。

 

下图为状态设计模式在FSM中应用的一个UML类图。

de6e2ed6960c4b66ab6a121c54e614f1.png

 

二、参考代码

状态设计模式的参考代码如下:

typedef class fsm_context;
typedef class concrete_state1;
typedef class concrete_state2;

virtual class state;
    pure virtual function int process1(fsm_context cnxt);
    pure virtual function int process2(fsm_context cnxt);
endclass : state

class concrete_state1 extends state;
    function int process1(fsm_context cnxt);
        $display("concrete_state1 : process1");
        if ( cnxt.change_state ) begin
            concrete_state2 state2 = new();
            $display("concrete_state1 change to concrete_state2");
            cnxt.st = state2;
        end
    endfunction : process1

    function int process2(fsm_context cnxt);
        $display("concrete_state1 : process2");
        if ( cnxt.change_state ) begin
            concrete_state2 state2 = new();
            $display("concrete_state1 change to concrete_state2");
            cnxt.st = state2;
        end
    endfunction : process2

endclass : concrete_state1

class concrete_state2 extends state;
    function int process1(fsm_context cnxt);
        $display("concrete_state2 : process1");
        if ( cnxt.change_state ) begin
            concrete_state1 state1 = new();
            $display("concrete_state2 change to concrete_state1");
            cnxt.st = state1;
        end
    endfunction : process1

    function int process2(fsm_context cnxt);
        $display("concrete_state2 : process2");
        if ( cnxt.change_state ) begin
            concrete_state1 state1 = new();
            $display("concrete_state2 change to concrete_state1");
            cnxt.st = state1;
        end
    endfunction : process2

endclass : concrete_state2



class fsm_context;

    state st;

    function bit change_state();
        return 1; // for simplicity
    endfunction : change_state

    function void process_req1 (/*interface signals*/);
        st.process1(this /*, interface signals*/);
    endfunction : process_req1

    function void process_req2 (/*interface signals*/);
        st.process2(this /*, interface signals*/);
    endfunction : process_req2

endclass : fsm_context

 

模拟测试代码如下:

fsm_context fsm_st = new();
fsm_st.st = concrete_state1::new();
fsm_st.process_req1();
fsm_st.process_req2();

 

使用Questasim仿真输出日志如下:

 | # concrete_state1 : process1
 | # concrete_state1 change to concrete_state2
 | # concrete_state2 : process2
 | # concrete_state2 change to concrete_state1

 

a7e3361591954200862584609ebf9e16.jpeg

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谷公子的藏经阁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值