|
楼主 |
发表于 2018-10-26 10:54:14
|
显示全部楼层
上面讲了饱和截位和原因,主要针对信号处理的位宽作缩减,饱和主要针位宽的高位进行处理,类似于信号限幅,截位主要针对位宽低位,效果就是扔掉小数的后几位,也就是精度降低。 饱和和截位对信号的性能会有影响,但是通常会通过饱和和截位后的仿真评估这种影响对实际的系统是否能够接受。下面讲讲饱和和截位的实现,信号处理,通常都是处理有符号数,所以就以有符号的饱和和截位为例介绍:
饱和 (Saturation) Demo:
不考虑对称,因为前面跟大家提到过负数表示范围是不对称的,比如3bit的数据,有符号数表示-4~3,即以0位中心,负数极值是-4,正数极值是3,而不是4.
module DATA_SAT #(
parameter DIN_WIDTH = 16,
parameter DOUT_WIDTH = 8
)
(
input signed [DIN_WIDTH-1 : 0] data_in,
output reg sigend [DOUT_WIDTH-1 : 0] data_out,
output reg sat_ind
);
localparam signed [DIN_WIDTH-1:0] POS_MAX = {{(DIN_WIDTH-DOUT_WIDTH+1){1'b0}},
{DOUT_WIDTH-1{1'b1}}};
localparam signed [DIN_WIDTH-1:0] NEG_MAX = {{(DIN_WIDTH-DOUT_WIDTH+1){1'b1}},
{DOUT_WIDTH{1'b0}}};
always @(*) begin
if ($signed(data_in) > $signed(POS_MAX)) begin
data_out = POS_MAX[DOUT_WIDTH-1:0];
sat_ind = 1'b1;
end
else if ($signed(data_in) < $signed(NEG_MAX)) begin
data_out = NEG_MAX[DOUT_WIDTH-1:0];
sat_ind = 1'b1;
end
else begin
data_out = din[DOUT_WIDTH-1:0];
sat_ind = 1'b0;
end
end
endmodule
如果考虑对称饱和,则需要把负值最大饱和到正值极大值的相反值,下面给出对称饱和RTL代码示例:
module DATA_SAT #(
parameter DIN_WIDTH = 16,
parameter DOUT_WIDTH = 8
)
(
input signed [DIN_WIDTH-1 : 0] data_in,
output reg sigend [DOUT_WIDTH-1 : 0] data_out,
output reg sat_ind
);
localparam signed [DIN_WIDTH-1:0] POS_MAX = {{(DIN_WIDTH-DOUT_WIDTH+1){1'b0}},
{DOUT_WIDTH-1{1'b1}}};
localparam signed [DIN_WIDTH-1:0] NEG_MAX = {{(DIN_WIDTH-DOUT_WIDTH+1){1'b1}},
{DOUT_WIDTH{1'b0}}};
always @(*) begin
if ($signed(data_in) > $signed(POS_MAX)) begin
data_out = POS_MAX[DOUT_WIDTH-1:0];
sat_ind = 1'b1;
end
else if ($signed(data_in) < $signed(NEG_MAX)) begin
data_out = {NEG_MAX[DOUT_WIDTH-1:1],1‘b1}; // Symmetry process for negative maximum
sat_ind = 1'b1;
end
else begin
data_out = din[DOUT_WIDTH-1:0];
sat_ind = 1'b0;
end
end
endmodule
下一节介绍CUT的实现 |
|