定点数指小数点在数中的位置是固定不变的,通常有定点整数和定点小数。在对小数点位置作出选择之后,运算中的所有数均应统一为定点整数或定点小数,在运算中不再考虑小数问题。
定点数就是指小数点的位置固定不变,小数点的位置通常有两种约定方式:定点整数(纯整数,小数点在最低有效值位之后 比如:100.)和定点小数(纯小数,小数点在最高有(效数值位之前 比如:.101)。 (1)定义:数据中小数点位置固定不变的数 2)种类:定点整数 (3)小数点在符号位与有效位之间。 注:定点数受字长的限制,超出范围会有溢出。
首先着手原码的乘法运算设计
1、原码一位乘法:
根据计算机组成原理书上的算法流程结构可以得出:
迭代的过程入下:
1)取最低位进行判断
2)若最低位的值为1.则将上一步的部分积P与X相加,若最低位为0则不操作
3)右移一位,产生本次部分积
module array_multiplier(clk,rst_n,mul_x,mul_y,res ); input clk ;//系统时钟 input rst_n ;//复位信号 input [3:0] mul_x ;//被乘数 input [3:0] mul_y ;//乘数 output reg [7:0] res ;//结果 reg [3:0] mul_p ;//部分积 reg c ;//进位信号 reg [3:0] mul_y0 ;//储存乘数 reg en ;//使能信号 //使能信号模块 always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin en<=1'b0; end else if(mul_x==1'b0||mul_y==1'b0)begin en<=1'b0; end else if(cnt==8'd3)begin en<=1'b1; end else begin en<=en; end end //逻辑控制模块(计数) reg [7:0] cnt; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin cnt<=1'b0; end else if(en==1'b1)begin cnt<=8'd0; end else if(cnt==8'd3)begin cnt<=8'd0; end else begin cnt<=cnt+1'b1; end end //逻辑控制模块(加) reg con_add_en; always@(*)begin if(en==1'b1)begin con_add_en=1'b1; end else if(mul_y0[0]==1'b1)begin con_add_en=1'b0; end else begin con_add_en=1'b1; end end // always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin mul_p=1'b0; c=1'b0; mul_y0=mul_y; end else if(en==1'b1)begin mul_p=mul_p; mul_y0=mul_y0; end else if(con_add_en==1'b0)begin {c,mul_p[3:0]}=mul_x[3:0]+{c,mul_p[3:0]}; {c,mul_p[3:0],mul_y0[3:0]}={c,mul_p[3:0],mul_y0[3:0]}>>1; end else begin {c,mul_p[3:0],mul_y0[3:0]}={c,mul_p[3:0],mul_y0[3:0]}>>1; end end always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin res<=1'b0; end else if(mul_x==1'b0||mul_y==1'b0)begin res<=1'b0; end else if(en==1'b1)begin res<={mul_p,mul_y0[3:0]}; end else begin res<=res; end end endmodule module array_multiplier(clk,rst_n,mul_x,mul_y,res ); input clk ;//系统时钟 input rst_n ;//复位信号 input [3:0] mul_x ;//被乘数 input [3:0] mul_y ;//乘数 output reg [7:0] res ;//结果 reg [3:0] mul_p ;//部分积 reg c ;//进位信号 reg [3:0] mul_y0 ;//储存乘数 reg en ;//使能信号 //使能信号模块 always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin en<=1'b0; end else if(mul_x==1'b0||mul_y==1'b0)begin en<=1'b0; end else if(cnt==8'd3)begin en<=1'b1; end else begin en<=en; end end //逻辑控制模块(计数) reg [7:0] cnt; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin cnt<=1'b0; end else if(en==1'b1)begin cnt<=8'd0; end else if(cnt==8'd3)begin cnt<=8'd0; end else begin cnt<=cnt+1'b1; end end //逻辑控制模块(加) reg con_add_en; always@(*)begin if(en==1'b1)begin con_add_en=1'b1; end else if(mul_y0[0]==1'b1)begin con_add_en=1'b0; end else begin con_add_en=1'b1; end end // always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin mul_p=1'b0; c=1'b0; mul_y0=mul_y; end else if(en==1'b1)begin mul_p=mul_p; mul_y0=mul_y0; end else if(con_add_en==1'b0)begin {c,mul_p[3:0]}=mul_x[3:0]+{c,mul_p[3:0]}; {c,mul_p[3:0],mul_y0[3:0]}={c,mul_p[3:0],mul_y0[3:0]}>>1; end else begin {c,mul_p[3:0],mul_y0[3:0]}={c,mul_p[3:0],mul_y0[3:0]}>>1; end end always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin res<=1'b0; end else if(mul_x==1'b0||mul_y==1'b0)begin res<=1'b0; end else if(en==1'b1)begin res<={mul_p,mul_y0[3:0]}; end else begin res<=res; end end endmodule
仿真测试:(13*11)