You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于sc_fixed模板参数定义字长/整数位不同的sc_fixed变量?

问题:SystemC模板模块中基于sc_fixed输入类型定义中间定点变量

我希望编写一个通用SystemC模块,对不同表示的定点数据进行算法处理,因此将其实现为以定点输入/输出类型为模板参数的模块模板。我的算法中间操作需要比输入/输出类型更多的余量,因此想要声明一些整数位更多但小数位相同的中间定点变量。请问该如何实现?是否可以查询sc_fixed模板参数的字长/整数位长度,并在模块内利用这些值定义新的sc_fixed变量?

我尝试过使用wl()和iwl()方法,但这些方法仅在运行时求值,无法用作模板参数。

以下是无法正常工作的示例:

template <typename T>
SC_MODULE(proc)
{
    sc_in<bool> clk;    // Clock signal
    sc_in<bool> rst_n;  // Reset signal
    sc_in<T> in_sig;    // Input signal
    sc_out<T> out_sig;  // Output signal

    const T tttt;
    typedef sc_fixed<tttt.wl()+3, tttt.iwl()+3> internal_sig_t;
    internal_sig_t internal_sig_0, internal_sig_1;

    ...
}

是否存在可行的实现方式?

注:作为临时解决方案,我可以传递sc_fixed的模板参数而非预定义类型,但如果存在多个输入/输出类型且不仅字长/整数位有不同选项时,这种方式会变得非常繁琐,因此我更倾向于不采用该方案。


解决方案

可以通过**模板元编程中的类型萃取(Type Trait)**实现编译时提取sc_fixed的模板参数,进而定义符合要求的中间定点类型。核心思路是利用C++模板特化,直接获取sc_fixed的字长、整数位等编译时常量参数,而非依赖运行时的成员函数。

步骤1:编写sc_fixed的类型萃取模板

首先定义一个通用的类型萃取模板,然后对sc_fixed进行特化,提取其所有模板参数:

#include <systemc>
#include <systemc-ams>

// 通用类型萃取模板框架
template <typename T>
struct sc_fixed_traits;

// 针对sc_fixed的特化萃取,提取所有模板参数
template <int WL, int IWL, sc_q_mode Q = SC_DEFAULT_Q_MODE, 
          sc_o_mode O = SC_DEFAULT_O_MODE, int N_BITS = SC_DEFAULT_N_BITS>
struct sc_fixed_traits<sc_fixed<WL, IWL, Q, O, N_BITS>> {
    static constexpr int word_length = WL;          // 字长
    static constexpr int integer_length = IWL;      // 整数位长度
    static constexpr sc_q_mode q_mode = Q;          // 量化模式
    static constexpr sc_o_mode o_mode = O;          // 溢出模式
    static constexpr int n_bits = N_BITS;           // 舍入位数量
};

步骤2:在模块模板中使用类型萃取

在你的模板模块里,通过类型萃取获取输入类型T的参数,以此定义中间定点类型:

template <typename T>
SC_MODULE(proc)
{
    sc_in<bool> clk;    // 时钟信号
    sc_in<bool> rst_n;  // 复位信号(低有效)
    sc_in<T> in_sig;    // 输入信号
    sc_out<T> out_sig;  // 输出信号

    // 提取输入sc_fixed类型的编译时参数
    using fixed_traits = sc_fixed_traits<T>;

    // 定义中间类型:整数位+3,小数位与输入保持一致(小数位=字长-整数位,因此字长同步+3)
    using internal_sig_t = sc_fixed<
        fixed_traits::word_length + 3,
        fixed_traits::integer_length + 3,
        fixed_traits::q_mode,
        fixed_traits::o_mode,
        fixed_traits::n_bits
    >;

    internal_sig_t internal_sig_0, internal_sig_1;

    // 示例处理逻辑
    void process() {
        if (!rst_n.read()) {
            internal_sig_0 = 0;
            internal_sig_1 = 0;
            out_sig.write(0);
        } else {
            // 中间运算:利用更大的位宽避免溢出
            internal_sig_0 = in_sig.read() * 4;
            internal_sig_1 = internal_sig_0 + 1.5;
            // 最终转换回输出类型
            out_sig.write(static_cast<T>(internal_sig_1));
        }
    }

    SC_CTOR(proc) {
        SC_METHOD(process);
        sensitive << clk.pos() << rst_n.neg();
    }
};

原理说明

  • sc_fixed本身是模板类,其字长、整数位等参数都是编译时常量,类型萃取通过模板特化直接获取这些值,完全满足模板参数的编译时要求。
  • 这种方法无需额外传递sc_fixed的模板参数,即使模块有多个不同的sc_fixed输入/输出类型,也可以复用同一个类型萃取模板,避免了繁琐的参数传递。

内容的提问来源于stack exchange,提问作者monkey_nuts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 23:47:48