1、学习应用移位相加原理设计8位乘法器。
2、了解移位相加原理构成乘法器与用组合逻辑电路直接设计的同样功能的电路优势。
module chengfaqi(a,b,dout);
input [7:0] a,b;
output [15:0] dout;
assign dout=a*b;
endmodule
module cfq_ywxj_1(a,b,dout);
input[7:0] a,b;
output reg[15:0] dout;
reg[7:0] a_buf,b_buf;
reg[3:0] i;
always@(*)
begin
a_buf<=a;
b_buf<=b;
dout=0;
for(i=0;i<8;i=i+1)
if(a_buf[i]) dout=dout+(b_buf<
主体(移位相加,时序电路)
8位乘法器逻辑原理图 8位移位相加乘法器仿真波形图乘法可以通过逐项移位相加的原理来实现。如方法一中是一个基于时序结构的8位移位相加型乘法器。从被乘数的最低位开始,若为1,则乘数左移后与上一次的和相加;若为0,左移后以全0相加,直至被乘数的最高位。从图1所示的逻辑电路图及其乘法操作的时序图中可以清楚地看出此乘法器的工作原理。为了更好地了解其工作原理,图1中没有加入控制电路。移位的时序波形图中,LD的信号上升沿有两个功能,即模块sreg16清0和被乘数A[7..0]向移位寄存器shift8加载;其低电平则作为乘法使能信号。CLK为时钟信号,当被乘数被加载于8位右移寄存器shift8后,随着每一时钟节拍,最低位在前,由低位至高位逐位移出。当为1时,1位乘法器andarith打开,8位乘数B[7..0]在同一节拍进入8位加法器,与上一次锁存在sreg16中的高8位相加,其和在下一时钟节拍的上升沿被锁存进此锁存器。而当被乘数的移出位为0时,此addarith全0输出。如此往复,直至8个时钟脉冲后,最后乘积完整出现在sreg16端口。
设计缘由:A的每一位均需和B的每一位相乘
(1)7个时钟周期后,8位移位寄存器串行输出A的每一位,从低位至高位顺序输出
always@(posedge clk or posedge load)
begin
if(load) reg8<=A;
else reg8[6:0]<=reg8[7:1];
end
assign qb=reg8[0];
(2)A的某一位和B中的每一位相乘,使用for循环语句
for(i=0;i<=7;i=i+4'b1)
dout[i]<=B[i]&abin;
for语句的语法格式:
for (初始值设置表达式; 控制条件表达式;控制变量增值表达式)
begin
循环体语句结构;
end
“控制变量增值表达式”的值如果不随循环而改变,或导致循环次数过大,对于综合来说都将导致设计失败。
3)移位相加
(1)16位移位寄存器 高位依次左移意味着低位对于高位依次右移
A[i-1]*B的积与A[i]*B的积相比,右移一位。
reg16[6:0]<=reg16[7:1];
q[15:7]<=d[8:0]
(2)8位二进制加法器
A[i-1]*B+ A[i]*B
(对 A[i-1]*B来说,右移1位相加A[i]*B )
d[8:0]<=q[15:8]+B[7:0]
module shift8(clk,load,A,qb); //8位移位寄存器
input clk,load; //输入时钟、载路信号
input[7:0] A; //输入8位二进制数值A
output qb; //输出
reg[7:0] reg8; //8位二进制寄存器
always@(posedge clk or posedge load)// 检测敏感信号,时钟信号上升沿或载路信号上升沿
begin
if(load) reg8<=A; //如果载路信号为1,则将A值赋给寄存器reg8
else reg8[6:0]<=reg8[7:1]; //否则,将reg8中的数据向右移一位
end
assign qb=reg8[0]; //将寄存器中的最低位,赋给qb进行输出
endmodule //模块结束
仿真波形
module andarith(abin,B,dout);//1位乘法器,与门
input abin;
input[7:0] B;
output reg[7:0] dout;
reg[3:0] i;
always@(*)
begin
for(i=0;i<=7;i=i+4'b1)
dout[i]<=B[i]&abin;
end
endmodule
仿真波形
module adder8(cin,A,B,S,cout);//8位加法器
input cin;
input[7:0] A,B;
output[7:0] S;
output cout;
assign {cout,S}=cin+A+B;
endmodule
仿真波形
module sreg16(clk,clr,d,q); //16位移位寄存器
input clk,clr; //输入时钟和复位信号
input[8:0] d; //输出9位二进制数值
output[15:0] q; //输出16位二进制数值
reg[15:0] reg16; //16位二进制寄存器
always@(posedge clk or posedge clr) //时钟和复位信号的上升沿有效
begin
if(clr) reg16<=16'b0; //如果复位信号为1,则将寄存器内容全部清零
else
begin reg16[6:0]<=reg16[7:1]; //否则,向右移1位
reg16[15:7]<=d; //将输入的值,赋给寄存器的高9位
end
end
assign q=reg16; //输出寄存器中的值
endmodule //模块结束
module arictl(clk,start,ariend,clkout,rstall,cnt4);
input clk,start;
output reg ariend,clkout;
output rstall;
output reg[3:0] cnt4;
always@(posedge clk or posedge start)
begin
if(start) cnt4<=4'b0;
else if(cnt4<4'b1000) cnt4<=cnt4+4'b1;
end
always@(*)
begin
if(~start)
if((cnt4<4'b1000)&(cnt4>=4'b0001)) begin clkout<=clk;ariend<=1'b0;end
else if(cnt4==4'b0000) begin clkout<=1'b0;ariend<=1'b0;end
else begin clkout<=1'b1;ariend<=1'b1;end
else begin clkout<=1'b0;ariend<=1'b0;end
end
assign rstall=start;
endmodule