定点数指小数点在数中的位置是固定不变的,通常有定点整数和定点小数。在对小数点位置作出选择之后,运算中的所有数均应统一为定点整数或定点小数,在运算中不再考虑小数问题。
定点数就是指小数点的位置固定不变,小数点的位置通常有两种约定方式:定点整数(纯整数,小数点在最低有效值位之后 比如: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)