精华内容
下载资源
问答
  • //有符号数AX,BX output [6:0]RX; //RX输出 reg[6:0]RX,TA; //RX[5:0]是RX的数值部分 TA是AX不断进位 reg[2:0]TB; //BX的数值部分 reg [0:0] QX ; //保存符号 always @(AX or BX) begin RX=0; TA=AX[2:0]; TB=...

    乘法器代码如下

    module muilt2b(RX,AX,BX);
    input [3:0]AX,BX;//有符号数AX,BX
    output [6:0]RX; //RX输出
    reg[6:0]RX,TA; //RX[5:0]是RX的数值部分 TA是AX不断进位
    reg[2:0]TB;  //BX的数值部分
    reg [0:0] QX ; //保存符号
    	always @(AX or BX)
    	begin
    	RX=0;
    	TA=AX[2:0];
    	TB=BX[2:0];
    	QX=AX[3]+BX[3];//计算符号
    		repeat(3)
    		begin
    			if(TB[0])
    			begin
    			RX=RX+TA;
    			end
    		TA=TA<<1;
    		TB=TB>>1;
    		end
    		RX={QX,RX[5:0]};//RX为符号位加数值位
    	end
    endmodule
    

    但是仿真的时候出现了错误

    这里AX 为1111的时候 为什么显示值是-1呢 不应该是-7么 BX 为1010 为-2 却显示为-6 计算结果RX为0001110 为14是对的

    AX为0110 值为6是对 BX为1000 为0 却显示为-8 RX为 0000000 计算结果为0是对的

    AX为1110 值应该是-6 显示为-2 BX为1100 应该是-4 显示为-4 计算结果RX为 0011000 为24 显示为24是正确的

    可见这里正数显示都是正确的 负数会显示错误 但是计算是正确的。

    即逻辑没有错误。

    其实是我忽略了一个很大问题,有符号数的负数是用补码的形式来表示的 即 -5不是1101 而是1011 -2不是1010而是1110

    我是傻逼!

    那么怎么考虑其负数是补码的情况下计算呢

    修改代码如下

    module muilt2b(RX,AX,BX);
    input [3:0]AX,BX;//有符号数AX,BX
    output [7:0]RX; //RX输出
    reg[7:0]RX,TA; //RX[5:0]是RX的数值部分 TA是AX不断进位
    reg[2:0]TB;  //BX的数值部分
    reg [0:0] QX ; //保存符号
    	always @(AX or BX)
    	begin
    	RX=0;
    	TA=AX[3]?(~AX+1'b1):AX; //若为负数就取反加1用正数乘,反之不变
    	TB=BX[3]?(~BX+1'b1):BX;  //同上
    	QX=AX[3]+BX[3];//计算符号
    		repeat(4)
    		begin
    			if(TB[0])
    			begin
    			RX=RX+TA;
    			end
    		TA=TA<<1;
    		TB=TB>>1;
    		end
    		RX=QX?(~RX+1'b1):RX;//RX为符号位加数值位
    	end
    endmodule
    

    得仿真结果如下

    可见当AX为正数时仿真正确,负数时却仿真错误。不知道为啥

    修改后代码:

    module muilt2b(DX,AX,BX);
    input [3:0]AX,BX;//有符号数AX,BX
    output [7:0]DX; //RX输出
    reg[7:0]RX,TA;//RX[5:0]是RX的数值部分 TA是AX不断进位
    reg[7:0]DX; // shuchu 
    reg[2:0]TB;  //BX的数值部分
    reg [0:0] QX ; //保存符号
    	always @(AX or BX)
    	begin
    	RX=0;
    	TA={4'b0000,AX[3]?(~AX+1'b1):AX}; //若为负数就取反加1用正数乘,反之不变
    	TB=BX[3]?(~BX+1'b1):BX;  //同上
    	QX=AX[3]+BX[3];//计算符号
    		repeat(4)
    		begin
    			if(TB[0])
    			begin
    			RX=RX+TA;
    			end
    		TA=TA<<1;
    		TB=TB>>1;
    		end
    		DX=QX?(~RX+1'b1):RX;//若QX为正则取反,反正不变
    	end
    endmodule
    

    TA赋值时确保不出错 

    仿真结果如图

    不再出错。

    所以之前可能是TA赋值出现问题

    查阅资料后发现短位赋值长位时有如下规则:资料链接:https://zhuanlan.zhihu.com/p/265295436

    所以会出现再给TA赋值时。若AX为正则无误,若AX为负则出错的情况。

    即上错例 -2*2 TA 理应赋值为00000010 错赋值为11110010 计算后得28

     

    展开全文
  • MUL和IMUL指令分别用于实现无符号数的乘法有符号数乘法运算。都只有一个源操作数,可以使寄存器或存储器,而且目标操作数隐含规定在累加中。 1)MUL指令 (a)、字节乘法,则AL×REG8/MEM8,乘积存于AX中。 ...

    本文参考了马维华老师的《微机原理与接口技术》一书

    指令格式:

    MUL REG/MEM ;REG寄存器,MEM存储器

    IMUL REG/MEM

    MUL和IMUL指令分别用于实现无符号数的乘法和有符号数的乘法运算。都只有一个源操作数,可以使寄存器或存储器,而且目标操作数隐含规定在累加器中。

    1)MUL指令

    (a)、字节乘法,则AL×REG8/MEM8,乘积存于AX中。
    
    (b)、字乘法,则AX×REG16/MEM16,乘积的高16位存放在DX中,低16位存放在AX中。
    
    (c)、32位乘法,则EAX×REG32/MEM32,乘积的高32位存放在EDX中,低32位存放在EAX中。
    
    (d)、64位乘法,则RAX×REG64/MEM64,乘积的高64位存放在RDX中,低64位存放在RAX中。
    
    当乘积的高半部分(AH、DX、EDX、RDX)中存有结果的有效数字,则CF=OF=1,否则CF=OF=0。
    

    2)IMUL指令

    IMUL指令除了是完成两个有符号数的相乘以外,其他与MUL完全类似。

    注:由于乘法指令为乘积保留了两倍于原来操作数的存储空间,因而不会出现溢出。

    自己的疑问:第2个操作数寻址方式应该可以是立即寻址方式吧?
    回答:不可以,另外一个操作数必须是在寄存器或者内存单元中。再次注意:
    如果是8位乘法,一个数字默认存放在al中,另外一个数字存放在其他8位寄存器中或者字节型内存单元中。如果是16位乘法,一个数字默认存放在ax中,另外一个数字存放在其他16位寄存器中或者字型内存单元中。所以,乘法指令中的另外一个操作数,不可以是立即数。另外一个操作数必须是在寄存器或者内存单元中。假如,想要实现bx*10的操作,那么可以参考如下的方法,用交换指令xchg,把bx和ax内容互换,将立即数10 mov到cx寄存器中,使用“mul cx”,得到的乘积在dx:cx中,若是确定乘积不会大于65536,那么可以只使用乘积低位,在ax中,再用xchg指令,把ax和bx内容交换,那么,就实现了(BX)<-- (BX) *10。
    如下:
    xchg ax,bx
    mov cx,10d
    mul cx
    xchg ax,bx
    (这也是汇编实现decibin(输入的10进制数转为2进制数存放在bx中)的代码中的一个小片段)

    展开全文
  • 四位无符号数乘法器的VHDL语言设计,四位乘法器输入信号为a_in , b_in , 均为四位无符号数,输出为c_out, 为八位无符号数,c_out = a_in × b_in 。程序设计中利用a_in与b_in (n) (n= 0, 1, 2, 3) 分别相乘后左移 ...
  • FPGA 中的有符号数乘法

    千次阅读 2020-01-31 15:39:46
      FPGA中乘法器是很稀缺的资源,但也是我们做算法必不可...在里面可以设置有符号还是无符号数乘法。   当然,我们也可以直接使用*符合来进行乘法,对于无符号的乘法 reg [7:0] ubyte_a; reg [7:0] ubyte_...

      FPGA中乘法器是很稀缺的资源,但也是我们做算法必不可少的资源。7系列及之前的FPGA都是25x18的DSP,UltraScale中是27x18,我们可以通过调IP Core的方式或者原语的方式来进行乘法操作。在里面可以设置有符号还是无符号数乘法。

      当然,我们也可以直接使用*符合来进行乘法,对于无符号的乘法

    reg [7:0] ubyte_a;
    reg [7:0] ubyte_b;
    (* use_dsp48="yes" *)
    output reg[15:0] u_res;
    
    always @ ( posedge clk ) begin 
        if(rst)
            u_res <= 'b0;
        else
            u_res <= ubyte_a * ubyte_b;
    end
    

      有符号乘法可以在Verilog中使用signed来标注。

    reg signed [7:0] byte_a;
    reg signed [7:0] byte_b;
    (* use_dsp48="yes" *)
    reg signed [15:0] res;
    
    always @ ( posedge clk ) begin 
        if(rst)
            res <= 'b0;
        else
            res <= byte_a * byte_b;
    end
    

      当然我们也要理解有符号数乘法的原理,其实就是扩位乘法,把高位都补充为符号位。

    有符号数乘法:

    reg [7:0] ubyte_a;
    reg [7:0] ubyte_b;
    (* use_dsp48="yes" *)
    reg [15:0] res_manul;
    
    always @ ( posedge clk ) begin
        if(rst)
            res_manul <= 'b0;
        else
            res_manul <= {{8{byte_a[7]}},ubyte_a} * {{8{ubyte_b[7]}},ubyte_b};
    end
    

      关于乘法输出的位宽,我们知道,两个8bits的无符号数乘法,结果的位宽是16bits,但对于两个8bits有符号数的乘法,只要两个数不同时为-128,即二进制0b1000_0000,那么输出结果的高两位都是符号位,我们只需要取低15bits即可。因此,如果我们可以保证两个输入的乘数不会同时为有符号数所能表示的负数最小值,那么乘法结果的高两位都是符号位,只取其中一位即可。

    欢迎关注微信公众号:

    在这里插入图片描述

    展开全文
  • 4*4的华莱士树乘法器实现了直接处理带符号数乘法
  • 前面一节关于乘法器的具体实现方式很多种方法,均各自的优缺点。 本节将再介绍一下两种乘法器的设计,分别用Verilog语言实现串行和流水线乘法器。 一、串行乘法器 两个N位二进制x、y的乘积用简单的方法计算...

    数字电路基础知识——乘法器的设计(二)( 串行、流水线、有符号数八位乘法器)

    前面一节关于乘法器的具体实现方式有很多种方法,均有各自的优缺点。

    本节将再介绍一下两种乘法器的设计,分别用Verilog语言实现串行和流水线乘法器。

    一、串行乘法器
    1. 移位相加的算法上节已经介绍,其核心算法为:
    always@(a or b)
    begin
    	c=0;
    	for (i=1; 1<=size;i=i+1) begin
    		c = c + ((b[i] == 1)? (a<<[i-1]):0); 	//移位相加
    	end
    end
    
    1. 两个N位二进制数x、y的乘积用简单的方法计算就是利用移位操作来实现。
    module multi_serial——mult(clk, x, y, result);
    input clk;
    input [7:0] x, y; 	//八位二级制数
    output [15:0] result;
    
    reg [15:0] result;
    
    parameter s0 = 0, s1 = 1, s2 = 2;	//状态机来实现
    reg [2:0] count = 0;
    reg [1:0] state = 0;	//初始状态为0
    reg [15:0] P, T;
    reg [7:0] y_reg;
    
    always @(posedge clk) begin
            case (state)
                s0: 
                begin		//状态s0为初始化,将y值存入寄存器y_reg,x存入T中,并将高八位置0
                    count <= 0;
                    P <= 0;
                    y_reg <= y;
                    T <= {{8{1'b0}}, x};
                    state <= s1;
                end
                
                s1: 
                begin 			//循环八次
                    if(count == 3'b111)	//8次累加
                        state <= s2;
                    else 
                    	begin
                    		if (y_reg[0] == 1'b1) 
    							P <= P + T;
    						else beign
    							P <= P;
    						end	
    						
                    		y_reg <= y_reg >> 1; //循环一次y右移一次
                    		T <= T << 1;	//并且所得值T*2
                    		state <= s1;
                    		count <= count + 1;
    				    end	
    			end	
     
                s2: 
                begin
                    result <= P;
                    state <= s0;
                end
                default: ;
            endcase
    end
    
    endmodule
    
    1. 其核心代码为状态机s1:
             s1: 
                begin 			//循环八次
                    if(count == 3'b111)	//8次累加
                        state <= s2;
                    else 
                    	begin
                    		if (y_reg[0] == 1'b1) 
    							P <= P + T;
    						else beign
    							P <= P;
    						end	
    						
                    		y_reg <= y_reg >> 1; //循环一次y右移一次
                    		T <= T << 1;	//并且所得值T*2
                    		state <= s1;
                    		count <= count + 1;
    				    end	
    			end	
     
    
    1. 串行乘法器的特性:
      优点:所占用的资源是所有类型乘法器中最少的,在低速的信号处理中有着广泛的应用。
      缺点:计算一次乘法需要8个周期。速度比较慢、时延大
    二、流水线乘法器
    1. 流水线乘法器的介绍
      一般的快速乘法器通常采用逐位并行的迭代阵列结构,将每个操作数的N位都并行地提交给乘法器。但是一般对于FPGA来讲,进位的速度快于加法的速度,这种阵列结构并不是最优的。所以可以采用多级流水线的形式,将相邻的两个部分乘积结果再加到最终的输出乘积上,即排成一个二叉树形式的结构。
    2. 4位流水线乘法器的实现
    module multi_4bits_pipelining(mul_a, mul_b, clk, rst_n, mul_out);
    
        input [3:0] mul_a, mul_b;
        input       clk;
        input       rst_n;
        output [7:0] mul_out;
    
        reg [7:0] mul_out;
    
        reg [7:0] stored0;
        reg [7:0] stored1;
        reg [7:0] stored2;
        reg [7:0] stored3;
    
        reg [7:0] add01;
        reg [7:0] add23;
    
        always @(posedge clk or negedge rst_n) begin
            if(!rst_n) begin
                mul_out <= 0;
                stored0 <= 0;
                stored1 <= 0;
                stored2 <= 0;
                stored3 <= 0;
                add01 <= 0;
                add23 <= 0;
            end
            else begin
                stored0 <= mul_b[0]? {4'b0, mul_a} : 8'b0;
                stored1 <= mul_b[1]? {3'b0, mul_a, 1'b0} : 8'b0;
                stored2 <= mul_b[2]? {2'b0, mul_a, 2'b0} : 8'b0;
                stored3 <= mul_b[3]? {1'b0, mul_a, 3'b0} : 8'b0;
    
                add01 <= stored1 + stored0;
                add23 <= stored3 + stored2;
    
                mul_out <= add01 + add23;
            end
        end
    
    endmodule
    

    流水线乘法器比串行乘法器的速度快很多很多,在非高速的信号处理中有广泛的应用。至于高速信号的乘法一般需要利用FPGA芯片中内嵌的硬核DSP单元来实现。

    三、有符号数八位乘法器

    对于用Verilog实现乘法y = a * b

    如果考虑a和b都是8bit,并且考虑有无符号数考虑三种情况:

    1) 都是无符号数
    2) 都是有符号数
    3) a是有符号数,b是无符号数

    1. 无符号数情况
      无符号数的情况只需使用 * 连接就可以了
    module Multply_Signed_Unsigned(
        input       [7:0]   dina,
        input       [7:0]   dinb,
        output      [15:0]   dout
        );
    
    assign  dout = dina * dinb;
    
    endmodule
    
    1. 有符号数
      有符号数的情况只需使用 * 连接就可以了,和无符号数类似,用补码计算结果
    module Multply_Signed_Unsigned(
        input signed    [7:0]   dina,
        input signed    [7:0]   dinb,
        output signed   [15:0]   dout
        );
    
    assign  dout = dina * dinb;
    
    endmodule
    
    
    1. 有符号数和无符号数相乘
      Verilog在进行运算时,如果两个操作数一个是有符号数,一个是无符号数,直接运算时,按无符号数运算的。解决这个问题用 $signed() 机制可以解决。
    module Multply_Signed_Unsigned(
        input           [7:0]   dina,
        input signed    [7:0]   dinb,
        output signed   [15:0]   dout
        );
    
    wire    [15:0]  dout_r;
    
    assign  dout_r = dina * dinb;			//结果为无符号数
    assign  dout = dina * $signed(dinb);	//结果为有符号数
    
    endmodule
    
    1. 关于Verilog中关于$signed的用法
      verilog中的加法和乘法操作前,会先对操作数据扩位成结果相同的位宽,然后进行加法或者乘法处理。

      比如a/b都为4位数据,c为5位数据,c = a + b,这个运算的时候会先把a和b扩位成5位,然后按照无符号加法进行相加。

      a/b没有被signed修饰的时候会按照无符号数的扩位方式进行扩位,即高位补0,加法的结果当然也是a、b为无符号数相加的结果。

      如果想把a、b作为有符号数来相加,那么就得在a/b数据定义的时候用signed修改,或者在计算的时候用$signed()来修饰,这样在c = a + b,这个运算开始的扩位就会按照有符号数的方式进行扩位,在高位补符号位,加法得出的结果就是a、b视为有符号数的结果。当然c要视为有符号数据。

      在verilog中有时会用signed修饰符来修饰定义的数据,运算的时候也会用$signed()任务来强制转换数据,那么signed的修饰是为什么呢,是为了区分有符号数和无符号数的加法和乘法吗? 其实不是的,因为有符号数和无符号数据的加法强结果和乘法器结构是一样的,signed的真正作用是决定如何对操作数扩位的问题。

    展开全文
  • 本例程采用加法器数乘法器实现17位有符号数相乘。参考《基于Verilog HDL 的数字系统应用设计》,王钿 ,桌兴旺 编著 1 module signed_mult17b_addtree ( 2 mul_a, 3 mul_b, 4 ...
  • 乘法器采用基4booth编码,输入为两个128位有符号数,输出为256位有符号数。基4的booth编码将两个128位有符号数计算成64个部分积。 64个部分积经过一层4-2压缩器得到32个部分积……在经过几层4-2压缩器,最终得到两...
  • 本例程采用加法器数乘法器实现17位有符号数相乘。参考《基于Verilog HDL 的数字系统应用设计》,王钿 ,桌兴旺 编著 1 module signed_mult17b_addtree (2 mul_a,3 mul_b,4 mul_out,5 clk...
  • verilog 乘法器代码

    2021-01-19 15:47:59
    fpga verilog 16位有符号数乘法器
  • FPGA设计中 有符号数、无符号数 今天给大侠聊一聊FPGA设计中有符号数以及无符号数,话不多说,...上述程序在 ISE 中的综合结果如下图所示,从其 RTL 结构图可以看到乘法器标注为“signed” ,为有符号数乘法器。 仿
  • 在搭建乘法器,验证波形时,多比特二进制手算比较麻烦,所以导入matlab计算正确的输出结果。 此时要注意乘法器的特性,举个例子吧 5 × 5 = 25 也就是4‘b0101(+5) * 4’b0101(+5) = 0011001(+25) 那 -5 × 5 = -...
  • 32x32Booth乘法器

    千次阅读 2019-09-30 21:49:47
    本设计是一个简单的基于Booth算法的32位有符号数乘法器,Booth算法的原理是先判断P[1:0],然后操作P空间,最后P空间移位,根据P空间的最高位来给移位后的P选择补1 or 补0。 booth乘法器是一种位操作乘法器,与传统...
  • 二进制乘法器可以分为有符号数乘法和无符号数乘法。无符号数乘法较为简单,不需要对乘数和被乘数扩展符号位,直接使用乘数和被乘数相乘相加即可。举例:比如两个无符号数3(011)和6(110)相乘,那结果应...
  • 乘法操作分为有符号操作和无符号操作两大类,无符号操作相对于 一、乘法器架构 1. 乘法器 2. 乘法器结构 二、乘法器的 Verilog 原语设计 2. Verilog代码 3. RTL结构图 4. 仿真结果如下: 5. 综合之后资源的利用
  • 乘法器

    千次阅读 2020-06-25 21:45:53
    一、乘累加乘法器 对于n比特,其二进制转换为有符号十进制的公式如下: 当B>=0,B的第n-1比特为0,则B可用下式表示: 设n=4,“5”的二进制为0101,则5=1 * 4 + 1 * 1 当B<0时,B的第n-1bit为1,B已为...
  • verilog中有符号数和无符号数在赋值、运算中的区别赋值有符号数的赋值和无符号数的赋值加减法运算两个无符号数的加减法运算两个有符号数的加减法运算有无符号数的混合加减法乘法运算无符号数/无符号数的乘法运算有无...
  • FPGA数字信号处理之乘法器system generator仿真乘法器IP核有符号定点数乘法 system generator仿真 乘法器IP核 有符号定点数乘法
  • xilinx 乘法器

    2011-03-24 19:10:44
    xilinx编写的VHDL乘法器 含有有符号数和无符号数的运算,已经做好各种模拟
  • 有符号数的计算在 Verilog 中是一个很重要的问题(也很容易会被忽视),有时为了简单方便,我常常会使用“*”来偷懒,这样就不用去调用乘法器了,但是结果常常不同,下面实际试验一下 Verilog 的乘法问题;...
  • 引言  在微处理器芯片中,乘法器是进行数字信号处理的,同时也是微处理器中进行数据处理的关键部件。...对于N位有符号数乘法A×B来说,常规的乘法运算会产生N个部分积。如果对乘数B进行基4Booth编码,每
  • Verilog 32位booth乘法器

    2019-09-30 22:38:53
    32位有符号数Booth乘法器,用Verilog代码实现,只是初级的设计。
  • FPGA 乘法器 浮点运算

    2021-03-24 23:30:16
    作者 QQ群:852283276 微信:arm80x86 ...FPGA 中的有符号数乘法 乘法器 两种实现方式,DSP Slice或组合逻辑,前者速度高,不占用逻辑资源,后者一般用于小位宽运算,延迟小。 仿真验证,待续。。。 ...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 185
精华内容 74
关键字:

有符号数乘法器