EDA(Quartus II)——8位硬件乘法器设计

实验目的:

1、学习应用移位相加原理设计8位乘法器。

2、了解移位相加原理构成乘法器与用组合逻辑电路直接设计的同样功能的电路优势。

设计方法:

方法一:(用乘号实现乘法)

module chengfaqi(a,b,dout);
input [7:0] a,b;
output [15:0] dout;
assign dout=a*b;
endmodule

仿真波形:

EDA(Quartus II)——8位硬件乘法器设计_第1张图片

方法二:(用移位相加的方法实现乘法)

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<

仿真波形:

EDA(Quartus II)——8位硬件乘法器设计_第2张图片

实验内容

主体(移位相加,时序电路)

EDA(Quartus II)——8位硬件乘法器设计_第3张图片 8位乘法器逻辑原理图 EDA(Quartus II)——8位硬件乘法器设计_第4张图片 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端口。

1位乘法器设计

设计缘由: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语句的语法格式:

    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]

各部分模块:

1)8位移位寄存器

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									//模块结束
	
EDA(Quartus II)——8位硬件乘法器设计_第5张图片 仿真波形

2)1位乘法器

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
EDA(Quartus II)——8位硬件乘法器设计_第6张图片 仿真波形

3)8位加法器

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
EDA(Quartus II)——8位硬件乘法器设计_第7张图片 仿真波形

4)16位移位寄存器

 

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									//模块结束			
	

EDA(Quartus II)——8位硬件乘法器设计_第8张图片

深入挖掘:

5)控制器

 

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

EDA(Quartus II)——8位硬件乘法器设计_第9张图片

总结与分析:

 

 

你可能感兴趣的:(EDA实践,verilog,vhdl,simulink,fpga,嵌入式)