PDPU代码分析(一)

我们现在开始逐行详细分析 posit_encoder.sv 文件,它的功能是将规格化的 sign、regime + exponent、mantissa 编码成最终的 Posit 格式输出


🔍 文件开头

// Posit encoder

🔹 单行注释,说明模块用途:Posit 编码器,将解码与计算后的内部格式重新封装成 N 位 Posit 编码。


module posit_encoder #(
    parameter int unsigned n = 16,
    parameter int unsigned es = 1,
    parameter int unsigned nd = pdpu_pkg::clog2(n-1),
    parameter int unsigned EXP_WIDTH = nd+es,       // not include sign bit
    parameter int unsigned MANT_WIDTH = n-es-3      // not include implicit bit
)(

🔸 模块定义与参数配置:

  • n = 16:Posit 的总位宽。
  • es = 1:exponent 的最大宽度(Posit 参数)。
  • nd = clog2(n-1):计算 regime 和 exponent 所需的最大位宽(例如 16-bit posit 最多有 log2(15) ≈ 4 位 regime)。
  • EXP_WIDTH = nd + es:regime + exponent 的总位宽。
  • MANT_WIDTH = n - es - 3:尾数部分的最大宽度(去掉 sign 位、regime 最少 1 位、exponent)。

pdpu_pkg::clog2:这是引用包中定义的 compile-time log2 计算函数。


📥 接口定义

    input logic sign_i,
    input logic signed [EXP_WIDTH:0] rg_exp_i,
    input logic [MANT_WIDTH:0] mant_norm_i,

    output logic [n-1:0] result_o
);

🔸 输入说明:

  • sign_i:结果符号位。
  • rg_exp_i:regime + exponent 合并后的有符号值。
  • mant_norm_i:规格化后的尾数(包含隐藏位,1位隐含位 + MANT_WIDTH)。

🔹 输出:

  • result_o:最终编码成的 n 位 Posit 数。

🧠 内部变量与第一段逻辑

// ---------------
// Determine whether input is effective 0
// ---------------
logic input_not_zero;
assign input_not_zero = mant_norm_i[MANT_WIDTH];

🔹 判断尾数的最高位是否为 1

  • mant_norm_i[MANT_WIDTH] 是规格化尾数中的最高有效位(MSB)
  • 如果为 1,表示输入非零,有意义;为 0 则可能是 underflow

这是前 20 行的逐行分析。接下来是否继续分析接下来的几行代码?例如 Regime 编码与尾数拼接逻辑部分?


继续对第 21–40 行进行逐行分析,主要涉及 Regime 字段与 Exponent 分离 以及初始化编码过程。


🔹 21–23:注释部分

// ---------------
// Compute regime_k and exp
// ---------------

这段注释说明下面的代码是为了从 rg_exp_i 中分离出 Regime(k 值)和 Exponent 字段。


🔸 24–25:声明变量

logic signed [EXP_WIDTH-es:0] regime_k;
logic signed [es:0] exp;
  • regime_k:表示 Posit 中的 k 值,决定 regime 编码长度(连续的 0 或 1)。
  • exp:Exponent 字段,es 位长。

注意:都使用 signed 是因为 k 值可能为负数。


🔸 27:提取 regime_k

assign regime_k = rg_exp_i[EXP_WIDTH:es];

rg_exp_i 的高位部分提取为 regime_k。即:总的 regime+exp 中,将低 es 位分给 exponent,剩下的分给 regime。


🔸 28–32:条件分支处理 exponent

if(es==0) begin
    assign exp = 0;
end
else begin
    assign exp = rg_exp_i[es-1:0];
end

如果 Posit 参数设置 es = 0,说明 exponent 不存在,这种情况在某些低精度 Posit 中出现,例如 posit<8, 0>

否则从 rg_exp_i 中提取最低的 es 位作为 exponent。


🔹 34–36:注释与初始 Regime 字段设置

// ---------------
// initial regime field
// ---------------

即将开始构造 Regime 位字段。


🔸 37–39:声明用于 Regime 的变量

logic sign_k;
logic [n-2:0] rg_const;
logic [n-2:0] regime;
  • sign_k:表示 regime 的符号(即 regime 是由连续 1 还是连续 0 构成)。
  • rg_const:用于构造 Regime 位段的模板(例如全1或全0)
  • regime:最终得到的 Regime 位段。

✅ 小结:到目前为止,代码完成了:

  • 判断是否输入为零
  • 拆分 regime_kexp
  • 初始化构建 Regime 所需变量

是否继续分析下一个阶段(Regime 编码实现、位串拼接)?


将该system verilog代码转换为verilog代码:

posted @ 2025-05-04 14:19  江左子固  阅读(86)  评论(0)    收藏  举报