小言_互联网的博客

数字电路基础知识——组合逻辑电路实现一些简单逻辑电路 (一)(用Verilog实现:绝对值函数运算(补码问题),取对数函数(移位寄存器),取整函数)

522人阅读  评论(0)

数字电路基础知识——组合逻辑电路实现一些简单逻辑电路 (一)(用Verilog实现:绝对值函数运算(补码问题),取对数函数(移位寄存器),取整函数)

在数字逻辑设计中,本节介绍绝对值运算函数如何用Verilog硬件描述语言来实现,本质上是补码的问题。

而取对数问题,可以归结为移位寄存器的问题。具体可以参考之前的一篇博文:数字电路基础知识——组合逻辑电路(数据选择器MUX、多路复用器)

最后介绍一下取整函数的实现。

一、用Verilog硬件描述语言来实现 取绝对值函数

基本算法思路:

function [7:0]  abs;
     input [8:0] data_in;
     if(data_in[8]) abs=1+(~data[7:0]);
     else               abs=data[7:0];
     // abs = (data_in[8] == 1'b1) ? (1+(~data[7:0]):(data[7:0]);
endfunction

对于如下 二输入差的绝对值的函数。
z = abs(x - y)

  1. 如果考虑到两个输入均为无符号8bit数
module abs(
    input   [7:0]   dina,
    input   [7:0]   dinb,
    output  [7:0]   dout
    );

assign  dout = (dina > dinb)? (dina - dinb): (dinb - dina); //使用2-MUX即可解决

endmodule
  1. 如果考虑到两个输入均为8bit有符号数(2进制补码)
    那么对于负数 A (二进制补码形式),其补码应该为 |A| = ~A + 1(按位取反加一 )
module abs(
    input  signed [7:0]   dina,
    input  signed [7:0]   dinb,
    output      [8:0]   dout // 至多9位
    );

wire   signed [8:0]   dout_r; 	//dout_r是九位二进制补码
assign  dout_r = (dina >dinb)? (dina - dinb): (dinb - dina);  
assign  dout = (dout_r[8] == 1'b1)? (~dout_r + 1): {1'b0, dout_r[7:0]};

endmodule
二、取对数函数(求log以2为低的整数)

求log以2为低的整数,具体方法上面用到的是移位寄存器,即将数据向右移位即可以得到所需最大的整数。
也可以利用下面两种方法:

  1. 利用移位寄存器
//以下两个函数任用一个
//求2的对数函数
function integer log2;
  input integer value;
  begin
    value = value-1;
    for (log2=0; value>0; log2=log2+1)
      value = value>>1;
  end

endfunction
  1. 利用数值比较器(常见算法)
 function integer log2(input integer x);
        integer i;
        begin
            log2 = 1;
            for (i = 0; 2**i < x; i = i + 1) //不用移位寄存器,只用比较器 
            begin
                log2 = i + 1;
            end
        end
 endfunction
三、用Verilog实现取整函数

用Verilog实现取整函数(ceil、floor、round)。

  1. Floor Function: the greatest integer that is less than or equal to x
  2. Ceiling Function: the least integer that is greater than or equal to x

以5bit为例,小数部分1位,取整后保留4bit。

wire [4:0] data; 
wire [3:0] data_ceil;
wire [3:0] data_floor; 
wire [3:0] data_round;
/*
ceil(x)函数,返回不小于x的最小整数值。向上取整
floor(x)函数,返回不大于x的最大整数值。向下取整
round(x)函数,返回x的四舍五入值。四舍五入取整
*/
module Ceil_floor_Round(
    input       [4:0]   data,
    output      [3:0]   data_ceil,
    output      [3:0]   data_floor,
    output      [3:0]   data_round
    );

assign  data_ceil   =   (data[0] == 0)? data[4:1]: data[4:1]+1;
assign  data_floor  =   data[4:1];
assign  data_round  =   (data[0] == 1)? (data[4:1]+1): data[4:1];
// data_round = data_ceil
endmodule

转载:https://blog.csdn.net/vivid117/article/details/100926186
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场