采用文本输入法设计一个 8 位的原码一位乘法运算器。
乘数和被乘数均为 8 位原码,被乘数存放在 B 寄存器中;C 寄存器的初始值存放乘数,运算结束后存放乘积的低位部分;A 寄存器用于存放部分积,其初始值为 0,运算结束后存放存放乘积的高位部分。
A 寄存器和 C 寄存器可级联在一起右移。CR 为乘法步数计数器。在每个时钟信号的上升沿处理一位乘数的累加和右移。根据乘数的最低位是否为 1 来决定是加被乘数还是 0,乘积的符号位由被乘数和乘数的符号位异或得到。
逻辑结构框图
计算流程图
一、实验分析与设计
由实验内容可得:实验有两个输入的8位原码被乘数B、乘数C。
由于input 的B、C值无法被修改,令reg [7:0] AT,BT,CT用于计算。
为判断计算步骤和输入的B、C值是否修改,令reg [3:0]CR, reg [7:0] BJ,CJ。当BJ != B || CJ != C时表示乘数或被乘数被修改,令CR = 0,表示开始计算。
1、计算部分
开始计算时,令AT= 0;BT = {0, B[6:0]}; CT = {0, C[6:0]}; Ps = B[7]^C[7](取B、C的绝对值和计算符号位)。
当CT[0] = 1时,AT = AT + BT。而后 CT = CT >> 1; CT[7] = AT[0]; AT = AT >> 1;将值右移一位。直到计算8次,结束计算,AT[7] = Ps。得到16位二进制乘积{AT, CT}。
2、显示部分
将16位二进制值转为4位十六进制值显示在4个数码管上,用reg [2:0] SEL控制。
第一位 SEL=3‘b000 :Data = AT[7:4] ;第二位 SEL=3‘b001 :Data = AT[3:0] ;
第三位 SEL=3‘b010 :Data = CT[7:4] ;第四位 SEL=3‘b011 :Data = CT[3:0] ;
而后将Data值译码,显示在七段数码管上。
二、程序代码
module sy3(clk,SEL,B,C,code);
input clk;
output[2:0]SEL;
input [7:0]B;
input [7:0]C;
output[7:0]code;
reg[7:0]AT = 8'b00000000;
reg[7:0] BT,CT;
reg Ps;
reg[3:0]CR = 4'b0000;
reg[7:0] BJ,CJ;
reg[2:0] SEL = 3'b000;
reg[7:0] code = 8'b00000000;
//计算部分
always@(posedge clk)
begin
if(BJ != B || CJ != C) CR = 4'd0;
if(CR == 4'd0) //初始化
begin
AT = 8'd0;
BT = B; BT[7] = 0;
CT = C; CT[7] = 0;
BJ = B; CJ = C;
Ps = B[7]^C[7];
CR = CR + 1;
end
else if(CR <= 4'd8) //移位计算
begin
if(CT[0] == 1) AT = AT + BT;
CT = CT >> 1;
CT[7] = AT[0];
AT = AT >> 1;
CR = CR + 1;
end
else //符号位
AT[7] = Ps;
end
//4位16进制乘积显示部分
reg[3:0] Data;
always@(posedge clk)
begin
if(SEL < 3'b011) SEL = SEL + 1;
else SEL = 3'b000;
end
always@(posedge clk)
begin
case(SEL)
3'b000: Data = AT[7:4];
3'b001: Data = AT[3:0];
3'b010: Data = CT[7:4];
3'b011: Data = CT[3:0];
endcase
end
//Data译码
always @(Data)
begin
case(Data)
4'd0 : code = 8'h3f;
4'd1 : code = 8'h06;
4'd2 : code = 8'h5b;
4'd3 : code = 8'h4f;
4'd4 : code = 8'h66;
4'd5 : code = 8'h6d;
4'd6 : code = 8'h7d;
4'd7 : code = 8'h07;
4'd8 : code = 8'h7f;
4'd9 : code = 8'h6f;
4'd10: code = 8'h77;
4'd11: code = 8'h7c;
4'd12: code = 8'h39;
4'd13: code = 8'h5e;
4'd14: code = 8'h79;
4'd15: code = 8'h71;
default : code = 8'bx;
endcase
end
endmodule
三、ModelSim仿真
Test Bench
`timescale 1 ps/ 1 ps
module sy3_vlg_tst();
reg [7:0] B;
reg [7:0] C;
reg clk;
// wires
wire [2:0] SEL;
wire [7:0] code;
sy3 i1 (
.B(B),
.C(C),
.SEL(SEL),
.clk(clk),
.code(code)
);
initial
begin
clk = 0;
B = 8'b00000000;
C = 8'b00000000;
#100
B = 8'b00001111;
C = 8'b10001010;
#1000
B = 8'b01111111;
C = 8'b11011011;
$display("Running testbench");
end
always #10 clk = ~clk;
endmodule
波形图
{AT,CT} = 10000000 10010110 = B 00001111 * C 10001010
{AT,CT} = 10101101 00100101 = B 01111111 * C 11011011