在 Verilog 中,real 是一种实数数据类型,用于表示浮点数(双精度浮点数)。

一、基本特性

  • real 表示64位双精度浮点数

  • 遵循 IEEE 754 标准

  • 主要用于仿真和建模,通常不可综合

  • 默认初始值为 0.0

二、语法和用法

real variable_name;
real [array_size] array_name;

三、基本操作示例

module real_example;
    real temperature;
    real voltage, current;
    real pi = 3.1415926535;
    
    initial begin
        // 基本赋值
        temperature = 25.5;
        voltage = 3.3;
        current = 0.15;
        
        $display("Temperature: %f", temperature);
        $display("Voltage: %f, Current: %f", voltage, current);
        $display("PI: %f", pi);
        
        // 数学运算
        real power;
        power = voltage * current;
        $display("Power: %f", power);
        
        // 科学计数法
        real avogadro = 6.022e23;
        $display("Avogadro's number: %e", avogadro);
    end
endmodule

四、数学运算

module real_math_operations;
    real a, b, c;
    real result;
    
    initial begin
        a = 10.5;
        b = 3.2;
        
        // 基本运算
        result = a + b;      // 加法
        $display("a + b = %f", result);
        
        result = a - b;      // 减法
        $display("a - b = %f", result);
        
        result = a * b;      // 乘法
        $display("a * b = %f", result);
        
        result = a / b;      // 除法
        $display("a / b = %f", result);
        
        // 数学函数
        result = $sqrt(a);   // 平方根
        $display("sqrt(a) = %f", result);
        
        result = $ln(a);     // 自然对数
        $display("ln(a) = %f", result);
        
        result = $exp(b);    // 指数
        $display("exp(b) = %f", result);
        
        result = $sin(a);    // 正弦
        $display("sin(a) = %f", result);
        
        result = $pow(a, b); // 幂运算
        $display("a^b = %f", result);
    end
endmodule

五、实际应用场景

1. 模拟电路建模

module analog_model;
    real v_in, v_out;
    real r1 = 1000.0;  // 1kΩ
    real r2 = 2000.0;  // 2kΩ
    real gain;
    
    initial begin
        // 计算运放增益
        gain = 1.0 + (r2 / r1);
        $display("Amplifier gain: %f", gain);
        
        // 模拟输入输出关系
        for (v_in = 0.0; v_in <= 5.0; v_in = v_in + 0.5) begin
            v_out = v_in * gain;
            $display("Vin=%f V, Vout=%f V", v_in, v_out);
        end
    end
endmodule

2. 温度传感器模型

module temperature_sensor;
    real temp_c;        // 摄氏度
    real temp_f;        // 华氏度
    real voltage_out;   // 输出电压
    real sensitivity = 0.01;  // 10mV/°C
    
    task measure_temperature;
        input real ambient_temp;
        begin
            temp_c = ambient_temp;
            temp_f = (temp_c * 9.0/5.0) + 32.0;
            voltage_out = temp_c * sensitivity;
            
            $display("Temperature: %f°C (%f°F)", temp_c, temp_f);
            $display("Output voltage: %f V", voltage_out);
        end
    endtask
    
    initial begin
        measure_temperature(25.0);  // 室温
        #10;
        measure_temperature(100.0); // 沸水温度
    end
endmodule

3. 物理系统仿真

module physics_simulation;
    real time_step = 0.001;  // 1ms 时间步长
    real time = 0.0;
    real position = 0.0;
    real velocity = 10.0;    // 初始速度 10 m/s
    real acceleration = -9.8; // 重力加速度
    
    initial begin
        $display("Time(s) Position(m) Velocity(m/s)");
        
        while (position >= 0.0) begin
            $display("%f %f %f", time, position, velocity);
            
            // 更新物理量
            position = position + velocity * time_step;
            velocity = velocity + acceleration * time_step;
            time = time + time_step;
            
            #1;  // 仿真时间推进
        end
        
        $display("Object hit ground at time: %f s", time);
    end
endmodule

六、与整数类型的转换

module real_conversion;
    real float_val;
    integer int_val;
    reg [31:0] fixed_val;
    
    initial begin
        float_val = 123.456;
        
        // real → integer (截断)
        int_val = float_val;
        $display("Real: %f -> Integer: %d", float_val, int_val);
        
        // real → fixed point (Q格式)
        fixed_val = float_val * 256.0;  // Q8.24格式
        $display("Real: %f -> Fixed: %h", float_val, fixed_val);
        
        // integer → real
        float_val = 100;
        $display("Integer 100 -> Real: %f", float_val);
        
        // 使用系统函数转换
        float_val = 45.67;
        int_val = $rtoi(float_val);  // 四舍五入到整数
        $display("$rtoi(%f) = %d", float_val, int_val);
        
        float_val = $itor(89);       // 整数转实数
        $display("$itor(89) = %f", float_val);
    end
endmodule

七、实数数组

module real_array_example;
    real data_set [0:9];  // 10个实数的数组
    real matrix [0:2][0:2];  // 3x3 实数矩阵
    real average, sum;
    integer i, j;
    
    initial begin
        // 初始化数组
        for (i = 0; i < 10; i = i + 1) begin
            data_set[i] = i * 1.5;
        end
        
        // 计算平均值
        sum = 0.0;
        for (i = 0; i < 10; i = i + 1) begin
            sum = sum + data_set[i];
        end
        average = sum / 10.0;
        $display("Average: %f", average);
        
        // 矩阵操作
        for (i = 0; i < 3; i = i + 1) begin
            for (j = 0; j < 3; j = j + 1) begin
                matrix[i][j] = i * 3.0 + j * 1.0;
            end
        end
    end
endmodule

八、系统函数和任务

module real_system_functions;
    real val1, val2;
    
    initial begin
        val1 = 2.5;
        val2 = -1.8;
        
        // 数学函数
        $display("abs(%f) = %f", val2, $abs(val2));
        $display("floor(%f) = %f", val1, $floor(val1));
        $display("ceil(%f) = %f", val1, $ceil(val1));
        
        // 随机实数生成
        $display("Random real: %f", $random % 100 * 0.01);
        
        // 比较函数
        if ($greater(val1, val2)) begin
            $display("%f is greater than %f", val1, val2);
        end
    end
endmodule

九、重要注意事项

  1. 不可综合:real 类型通常只能用于仿真,不能综合成硬件

  2. 精度问题:浮点数运算可能存在精度误差

  3. 性能考虑:实数运算比整数运算慢得多

  4. 存储大小:每个 real 变量占用 64 位

  5. 初始化:默认值为 0.0,但最好显式初始化

十、适用场景

  • 算法验证和建模

  • 模拟电路行为建模

  • 物理系统仿真

  • 浮点算法原型设计

  • 测试平台中的计算

real 类型在系统级建模和验证中非常有用,但需要谨慎使用,因为它在硬件实现上有局限性。

更多推荐